From b102958a8353d097745d38328fcc20a235ec6e09 Mon Sep 17 00:00:00 2001
From: Mirko Engelpracht <engelpracht@win.ltt.rwth-aachen.de>
Date: Fri, 14 Feb 2025 16:44:16 +0100
Subject: [PATCH] Added OpenModelica version and changed to MSL 4.0

---
 README.md                                     |   11 +-
 .../AdsorptionChillers/ChillerTwoBed1.mo      |  380 ----
 .../AdsorptionChillers/ChillerTwoBed2.mo      |  324 ----
 .../AdsorptionChillers/package.mo             |    6 -
 .../AdsorptionChillers/package.order          |    2 -
 .../DesiccantSystem/DesiccantSystem.mo        |  141 --
 .../Applications/DesiccantSystem/package.mo   |    5 -
 .../DesiccantSystem/package.order             |    1 -
 SorpLib/Applications/package.mo               |    7 -
 SorpLib/Applications/package.order            |    2 -
 .../BaseClasses/PartialAdsorbatePort.mo       |   52 +
 .../BaseClasses/PartialAdsorptPort.mo         |   35 +
 .../BaseClasses/PartialFluidPort.mo           |   51 +
 .../Interfaces/BaseClasses/PartialHeatPort.mo |   34 +
 .../Basics/Interfaces/BaseClasses/package.mo  |   19 +
 .../Interfaces/BaseClasses/package.order      |    4 +
 .../Interfaces/FluidPorts/GasPort_in.mo       |   43 +
 .../Interfaces/FluidPorts/GasPort_out.mo      |   55 +
 .../Interfaces/FluidPorts/LiquidPort_in.mo    |   43 +
 .../Interfaces/FluidPorts/LiquidPort_out.mo   |   55 +
 .../Interfaces/FluidPorts/VLEPort_in.mo       |   43 +
 .../Interfaces/FluidPorts/VLEPort_out.mo      |   55 +
 .../Basics/Interfaces/FluidPorts/package.mo   |   17 +
 .../Interfaces/FluidPorts/package.order       |    6 +
 .../Interfaces/HeatPorts/HeatPort_in.mo       |   42 +
 .../Interfaces/HeatPorts/HeatPort_out.mo      |   55 +
 .../Basics/Interfaces/HeatPorts/package.mo    |   17 +
 .../Basics/Interfaces/HeatPorts/package.order |    2 +
 .../SorptionPorts/AdsorbatePort_in.mo         |   38 +
 .../SorptionPorts/AdsorbatePort_out.mo        |   50 +
 .../SorptionPorts/AdsorptPort_in.mo           |   38 +
 .../SorptionPorts/AdsorptPort_out.mo          |   50 +
 .../Interfaces/SorptionPorts/package.mo       |   17 +
 .../Interfaces/SorptionPorts/package.order    |    4 +
 SorpLib/Basics/Interfaces/package.mo          |   18 +
 SorpLib/Basics/Interfaces/package.order       |    4 +
 .../Sources/BaseClasses/PartialFluidSource.mo |  377 ++++
 SorpLib/Basics/Sources/BaseClasses/package.mo |   19 +
 .../Basics/Sources/BaseClasses/package.order  |    1 +
 SorpLib/Basics/Sources/Fluids/GasSource.mo    |  113 ++
 .../Sources/Fluids/GasVaporMixtureSource.mo   |  232 +++
 SorpLib/Basics/Sources/Fluids/LiquidSource.mo |  112 ++
 .../Sources/Fluids/Tester/Test_GasSource.mo   |  253 +++
 .../Tester/Test_GasVaporMixtureSource.mo      |  284 +++
 .../Fluids/Tester/Test_LiquidSource.mo        |  252 +++
 .../Sources/Fluids/Tester/Test_VLESource.mo   |  252 +++
 .../Basics/Sources/Fluids/Tester/package.mo   |   17 +
 .../Sources/Fluids/Tester/package.order       |    4 +
 SorpLib/Basics/Sources/Fluids/VLESource.mo    |  113 ++
 SorpLib/Basics/Sources/Fluids/package.mo      |   19 +
 SorpLib/Basics/Sources/Fluids/package.order   |    5 +
 .../Sources/Sorption/AdsorbateSource.mo       |  236 +++
 .../Basics/Sources/Sorption/AdsorptSource.mo  |  165 ++
 .../Sorption/Tester/Test_AdsorbateSource.mo   |  130 ++
 .../Sorption/Tester/Test_AdsorptSource.mo     |   92 +
 .../Basics/Sources/Sorption/Tester/package.mo |   18 +
 .../Sources/Sorption/Tester/package.order     |    2 +
 SorpLib/Basics/Sources/Sorption/package.mo    |   18 +
 SorpLib/Basics/Sources/Sorption/package.order |    3 +
 SorpLib/Basics/Sources/Thermal/HeatSource.mo  |  147 ++
 .../Sources/Thermal/Tester/Test_HeatSource.mo |   84 +
 .../Basics/Sources/Thermal/Tester/package.mo  |   18 +
 .../Sources/Thermal/Tester/package.order      |    1 +
 SorpLib/Basics/Sources/Thermal/package.mo     |   18 +
 SorpLib/Basics/Sources/Thermal/package.order  |    2 +
 SorpLib/Basics/Sources/package.mo             |   18 +
 SorpLib/Basics/Sources/package.order          |    4 +
 .../AdsorbatePureGasVolume.mo                 |  333 ++++
 .../AdsorbatePureVLEVolume.mo                 |  337 ++++
 .../Tester/Test_AdsorbatePureGasVolume.mo     |  262 +++
 .../Tester/Test_AdsorbatePureVLEVolume.mo     |  272 +++
 .../AdsorbateVolumes/Tester/package.mo        |   18 +
 .../AdsorbateVolumes/Tester/package.order     |    2 +
 .../Volumes/AdsorbateVolumes/package.mo       |   18 +
 .../Volumes/AdsorbateVolumes/package.order    |    3 +
 .../BaseClasses/PartialAdsorbateVolume.mo     |  387 ++++
 .../Volumes/BaseClasses/PartialFluidVolume.mo |  350 ++++
 .../PartialPhaseSeparatorVolume.mo            |  413 ++++
 .../PartialPureComponentAdsorbateVolume.mo    |  389 ++++
 .../Volumes/BaseClasses/PartialVolume.mo      |  323 ++++
 SorpLib/Basics/Volumes/BaseClasses/package.mo |   19 +
 .../Basics/Volumes/BaseClasses/package.order  |    5 +
 .../Volumes/FluidVolumes/GasMixtureVolume.mo  |  755 ++++++++
 .../FluidVolumes/GasVaporMixtureVolume.mo     |  791 ++++++++
 .../Basics/Volumes/FluidVolumes/GasVolume.mo  |  510 +++++
 .../Volumes/FluidVolumes/LiquidVolume.mo      |  494 +++++
 .../Tester/Test_GasMixtureVolume.mo           |  235 +++
 .../Tester/Test_GasVaporMixtureVolume.mo      |  307 +++
 .../FluidVolumes/Tester/Test_GasVolume.mo     |  429 +++++
 .../FluidVolumes/Tester/Test_LiquidVolume.mo  |  769 ++++++++
 .../FluidVolumes/Tester/Test_VLEVolume.mo     |  431 +++++
 .../Volumes/FluidVolumes/Tester/package.mo    |   17 +
 .../Volumes/FluidVolumes/Tester/package.order |    5 +
 .../Basics/Volumes/FluidVolumes/VLEVolume.mo  |  444 +++++
 .../Basics/Volumes/FluidVolumes/package.mo    |   18 +
 .../Basics/Volumes/FluidVolumes/package.order |    6 +
 .../PhaseSeparatorVolume.mo                   |  279 +++
 .../Tester/Test_PhaseSeparator.mo             |  153 ++
 .../PhaseSeparatorVolumes/Tester/package.mo   |   17 +
 .../Tester/package.order                      |    1 +
 .../Volumes/PhaseSeparatorVolumes/package.mo  |   19 +
 .../PhaseSeparatorVolumes/package.order       |    2 +
 .../Records/AdsorbateVolumeProperties.mo      |   86 +
 .../Volumes/Records/FluidVolumeProperties.mo  |   99 +
 .../Volumes/Records/PhaseSeparatorGeometry.mo |   28 +
 .../Records/PhaseSeparatorProperties.mo       |  103 +
 .../Volumes/Records/SolidVolumeProperties.mo  |   44 +
 .../Basics/Volumes/Records/VolumeGeometry.mo  |   52 +
 SorpLib/Basics/Volumes/Records/package.mo     |   18 +
 SorpLib/Basics/Volumes/Records/package.order  |    6 +
 .../Volumes/SolidVolumes/SolidVolume.mo       |  291 +++
 .../SolidVolumes/Tester/Test_SolidVolume.mo   |  221 +++
 .../Volumes/SolidVolumes/Tester/package.mo    |   17 +
 .../Volumes/SolidVolumes/Tester/package.order |    1 +
 .../Basics/Volumes/SolidVolumes/package.mo    |   17 +
 .../Basics/Volumes/SolidVolumes/package.order |    2 +
 .../Utilities/mapSorptionFluidPorts.mo        |   75 +
 SorpLib/Basics/Volumes/Utilities/package.mo   |   17 +
 .../Basics/Volumes/Utilities/package.order    |    1 +
 SorpLib/Basics/Volumes/package.mo             |   21 +
 SorpLib/Basics/Volumes/package.order          |    7 +
 SorpLib/Basics/package.mo                     |   34 +
 SorpLib/Basics/package.order                  |    3 +
 SorpLib/Choices/BalanceEquations.mo           |   11 +
 SorpLib/Choices/BoundaryFluidPotentialFlow.mo |    6 +
 .../Choices/BoundaryFluidStreamEnthalpy.mo    |    5 +
 .../BoundaryFluidStreamMassFractions.mo       |    5 +
 SorpLib/Choices/BoundaryThermal.mo            |    5 +
 .../ChangingConstantVariableOfDiagram.mo      |    6 +
 .../DiagramTypePureComponentWorkingPair.mo    |    6 +
 .../Choices/GeneralizedFunctionApproach.mo    |    7 +
 SorpLib/Choices/IASTAlgorithm.mo              |    6 +
 ...ndentVariablesMultiComponentWorkingPair.mo |    5 +
 ...endentVariablesPureComponentWorkingPair.mo |    5 +
 SorpLib/Choices/IndependentVariablesVolume.mo |    5 +
 SorpLib/Choices/InterpolationApproach.mo      |    5 +
 .../IsobaricExpansionCoefficientAdsorpt.mo    |    7 +
 .../MassFlowRateHeatTranferCorrelation.mo     |   10 +
 .../Choices/MassTransferFluidProperties.mo    |   11 +
 SorpLib/Choices/PrescripedFanVariable.mo      |    7 +
 SorpLib/Choices/PrescripedPumpVariable.mo     |    7 +
 SorpLib/Choices/ResistorFluidProperties.mo    |   15 +
 SorpLib/Choices/SorptionEnthalpy.mo           |    7 +
 .../Choices/SpecificHeatCapacityAdsorpt.mo    |   10 +
 SorpLib/Choices/SpecificHeatCapacitySolid.mo  |    6 +
 SorpLib/Choices/SpecificVolumeAdsorpt.mo      |    7 +
 SorpLib/Choices/SpecificVolumeSolid.mo        |    6 +
 .../TemperatureHeatTranferCorrelation.mo      |   12 +
 SorpLib/Choices/ThermalConductivitySolid.mo   |    6 +
 SorpLib/Choices/package.mo                    |   17 +
 SorpLib/Choices/package.order                 |   26 +
 SorpLib/Components/AdsorberColumns/package.mo |   17 +
 .../Components/AdsorberColumns/package.order  |    0
 .../Components/Cells/Adsorbent/Adsorbent.mo   |  213 ---
 .../Cells/Adsorbent/Testers/TestAdsorbent.mo  |  125 --
 .../Cells/Adsorbent/Testers/package.mo        |    5 -
 .../Cells/Adsorbent/Testers/package.order     |    1 -
 SorpLib/Components/Cells/Adsorbent/package.mo |    6 -
 .../Components/Cells/Adsorbent/package.order  |    2 -
 SorpLib/Components/Cells/Gas/Gas.mo           |  343 ----
 .../Cells/Gas/Geometry/CellGeometry.mo        |   28 -
 .../Components/Cells/Gas/Geometry/package.mo  |   11 -
 .../Cells/Gas/Geometry/package.order          |    1 -
 .../ConstantResistanceCoefficient.mo          |   43 -
 .../Partial/PartialPressureDrop.mo            |   29 -
 .../Partial/package.mo                        |    5 -
 .../Partial/package.order                     |    1 -
 .../ZeroPressureDrop.mo                       |   34 -
 .../Gas/PressureDropCorrelations/package.mo   |    8 -
 .../PressureDropCorrelations/package.order    |    3 -
 .../Components/Cells/Gas/Testers/TestGas.mo   |  133 --
 .../Components/Cells/Gas/Testers/TestGas2.mo  |  133 --
 .../Components/Cells/Gas/Testers/TestGas3.mo  |  135 --
 .../Components/Cells/Gas/Testers/TestGas4.mo  |  130 --
 .../Components/Cells/Gas/Testers/package.mo   |    8 -
 .../Cells/Gas/Testers/package.order           |    4 -
 SorpLib/Components/Cells/Gas/package.mo       |    7 -
 SorpLib/Components/Cells/Gas/package.order    |    4 -
 .../Testers/TestVLEPhaseSeparator.mo          |   90 -
 .../VLEPhaseSeparator/Testers/package.mo      |    5 -
 .../VLEPhaseSeparator/Testers/package.order   |    1 -
 .../VLEPhaseSeparator/VLEPhaseSeparator.mo    |  237 ---
 .../Cells/VLEPhaseSeparator/package.mo        |    6 -
 .../Cells/VLEPhaseSeparator/package.order     |    2 -
 .../Components/Cells/Wall/Testers/TestWall.mo |   43 -
 .../Components/Cells/Wall/Testers/package.mo  |    5 -
 .../Cells/Wall/Testers/package.order          |    1 -
 SorpLib/Components/Cells/Wall/Wall.mo         |  108 --
 SorpLib/Components/Cells/Wall/package.mo      |    6 -
 SorpLib/Components/Cells/package.mo           |    8 -
 SorpLib/Components/Cells/package.order        |    4 -
 SorpLib/Components/ClosedAdsorber/Adsorber.mo |  338 ----
 .../Geometry/Adsorber_Finned_Tubes_Alu.mo     |   14 -
 .../ClosedAdsorber/Geometry/TubeGeometry.mo   |   56 -
 .../ClosedAdsorber/Geometry/package.mo        |    6 -
 .../ClosedAdsorber/Geometry/package.order     |    2 -
 .../HeatTransferSilicaGel_Lanzerath2015.mo    |   28 -
 .../HeatTransferZeolith13X_Lanzerath2015.mo   |   28 -
 .../HeatTransfer/package.mo                   |    5 -
 .../HeatTransfer/package.order                |    2 -
 .../RecordsTransportCoefficients/package.mo   |    5 -
 .../package.order                             |    1 -
 .../ClosedAdsorber/Testers/TestAdsorber1.mo   |   96 -
 .../ClosedAdsorber/Testers/TestAdsorber2.mo   |  107 --
 .../ClosedAdsorber/Testers/package.mo         |    5 -
 .../ClosedAdsorber/Testers/package.order      |    2 -
 SorpLib/Components/ClosedAdsorber/package.mo  |    7 -
 .../Components/ClosedAdsorber/package.order   |    4 -
 SorpLib/Components/EvpCond/EvpCond.mo         |  321 ----
 .../EvpCond/Geometry/CondLanzerath2014.mo     |   34 -
 .../EvpCond/Geometry/EvpLanzerath2014.mo      |   35 -
 .../EvpCond/Geometry/TubeGeometry.mo          |   70 -
 .../Components/EvpCond/Geometry/package.mo    |    7 -
 .../Components/EvpCond/Geometry/package.order |    3 -
 .../EvpCond/Testers/TestEvpCond1.mo           |   92 -
 .../EvpCond/Testers/TestEvpCond2.mo           |   97 -
 .../EvpCond/Testers/TestEvpCond3.mo           |  126 --
 SorpLib/Components/EvpCond/Testers/package.mo |    7 -
 .../Components/EvpCond/Testers/package.order  |    3 -
 SorpLib/Components/EvpCond/package.mo         |    7 -
 SorpLib/Components/EvpCond/package.order      |    3 -
 SorpLib/Components/Fans/AffinityFan.mo        |  133 ++
 .../Fans/BaseClasses/PartialAffinityFan.mo    |  142 ++
 .../Components/Fans/BaseClasses/PartialFan.mo |  197 ++
 .../Fans/BaseClasses/PartialSimpleFan.mo      |  169 ++
 .../Components/Fans/BaseClasses/package.mo    |   19 +
 .../Components/Fans/BaseClasses/package.order |    3 +
 SorpLib/Components/Fans/SimpleFan.mo          |  117 ++
 .../Fans/Tester/Test_AffinityFan.mo           |  102 +
 .../Components/Fans/Tester/Test_SimpleFan.mo  |  102 +
 SorpLib/Components/Fans/Tester/package.mo     |   17 +
 SorpLib/Components/Fans/Tester/package.order  |    2 +
 SorpLib/Components/Fans/package.mo            |   19 +
 SorpLib/Components/Fans/package.order         |    4 +
 .../BaseClasses/PartialInertiaInducer.mo      |  189 ++
 .../Fittings/BaseClasses/PartialMultiPort.mo  |  145 ++
 .../PartialOpenAdsorberPressureLoss.mo        |   45 +
 .../BaseClasses/PartialPressureLoss.mo        | 1060 +++++++++++
 .../Fittings/BaseClasses/PartialResistance.mo |  484 +++++
 .../Fittings/BaseClasses/PartialTJunction.mo  |  408 ++++
 .../PartialTubeInsidePressureLoss.mo          |   45 +
 .../Fittings/BaseClasses/package.mo           |   19 +
 .../Fittings/BaseClasses/package.order        |    7 +
 .../InertiaInducers/GasInertiaInducer.mo      |   66 +
 .../InertiaInducers/LiquidInertiaInducer.mo   |   65 +
 .../Tester/Test_GasInertiaInducer.mo          |   77 +
 .../Tester/Test_LiquidInertiaInducer.mo       |   78 +
 .../Tester/Test_VLEInertiaInducer.mo          |   77 +
 .../InertiaInducers/Tester/package.mo         |   19 +
 .../InertiaInducers/Tester/package.order      |    3 +
 .../InertiaInducers/VLEInertiaInducer.mo      |   66 +
 .../Fittings/InertiaInducers/package.mo       |   19 +
 .../Fittings/InertiaInducers/package.order    |    4 +
 .../Fittings/MultiPorts/GasMultiPort.mo       |   46 +
 .../Fittings/MultiPorts/LiquidMultiPort.mo    |   45 +
 .../MultiPorts/Tester/Test_GasMultiPort.mo    |   84 +
 .../MultiPorts/Tester/Test_LiquidMultiPort.mo |   84 +
 .../MultiPorts/Tester/Test_VLEMultiPort.mo    |   88 +
 .../Fittings/MultiPorts/Tester/package.mo     |   17 +
 .../Fittings/MultiPorts/Tester/package.order  |    3 +
 .../Fittings/MultiPorts/VLEMultiPort.mo       |   50 +
 .../Components/Fittings/MultiPorts/package.mo |   25 +
 .../Fittings/MultiPorts/package.order         |    4 +
 .../OpenAdsorber/ConstantLambda.mo            |  163 ++
 .../OpenAdsorber/Kast.mo                      |  196 ++
 .../OpenAdsorber/LinearLambda.mo              |  163 ++
 .../OpenAdsorber/QuadraticLambda.mo           |  163 ++
 .../OpenAdsorber/ZeroFriction.mo              |  148 ++
 .../OpenAdsorber/package.mo                   |   40 +
 .../OpenAdsorber/package.order                |    5 +
 .../TubeInside/Blasius.mo                     |  213 +++
 .../TubeInside/Colebrook.mo                   |  289 +++
 .../TubeInside/ConstantLambda.mo              |  163 ++
 .../TubeInside/Konakov.mo                     |  213 +++
 .../TubeInside/LinearLambda.mo                |  163 ++
 .../TubeInside/MishraGupaSchmidt.mo           |  241 +++
 .../TubeInside/PrandtlKarman.mo               |  278 +++
 .../TubeInside/QuadraticLambda.mo             |  163 ++
 .../TubeInside/ZeroFriction.mo                |  148 ++
 .../TubeInside/package.mo                     |   56 +
 .../TubeInside/package.order                  |    9 +
 .../PressureLossCorrelations/ZeroFriction.mo  |  148 ++
 .../PressureLossCorrelations/package.mo       |   35 +
 .../PressureLossCorrelations/package.order    |    3 +
 .../Fittings/Records/FluidProperties.mo       |   33 +
 .../Records/GeometryGenericReistance.mo       |   73 +
 .../Fittings/Records/GeometryOpenAdsorber.mo  |   37 +
 .../Fittings/Records/GeometryTube.mo          |   35 +
 .../Components/Fittings/Records/package.mo    |   18 +
 .../Components/Fittings/Records/package.order |    4 +
 .../Resistors/GasGenericResistance.mo         |  448 +++++
 .../Resistors/GasOpenAdsorberResistance.mo    |  461 +++++
 .../Fittings/Resistors/GasTubeResistance.mo   |  460 +++++
 .../Resistors/LiquidGenericResistance.mo      |  447 +++++
 .../Resistors/LiquidTubeResistance.mo         |  460 +++++
 .../Tester/Test_GasGenericResistance.mo       |  115 ++
 .../Tester/Test_GasOpenAdsorberResistance.mo  |  128 ++
 .../Tester/Test_GasTubeResistance.mo          |  122 ++
 .../Test_GasVaporMixtureGenericResistance.mo  |  109 ++
 ...t_GasVaporMixtureOpenAdsorberResistance.mo |  127 ++
 .../Test_GasVaporMixtureTubeResistance.mo     |  125 ++
 .../Tester/Test_LiquidGenericResistance.mo    |  185 ++
 .../Tester/Test_LiquidTubeResistance.mo       |  199 ++
 .../Tester/Test_VLEGenericResistance.mo       |  109 ++
 .../Tester/Test_VLETubeResistance.mo          |  121 ++
 .../Fittings/Resistors/Tester/package.mo      |   19 +
 .../Fittings/Resistors/Tester/package.order   |   10 +
 .../Resistors/VLEGenericResistance.mo         |  448 +++++
 .../Fittings/Resistors/VLETubeResistance.mo   |  461 +++++
 .../Components/Fittings/Resistors/package.mo  |   23 +
 .../Fittings/Resistors/package.order          |    8 +
 .../TJunctions/GasMixtureTJunction.mo         |  316 ++++
 .../Fittings/TJunctions/GasTJunction.mo       |  303 +++
 .../TJunctions/GasVaporMixtureTJunction.mo    |  325 ++++
 .../Fittings/TJunctions/LiquidTJunction.mo    |  331 ++++
 .../Tester/Test_GasMixtureTJunction.mo        |  106 ++
 .../TJunctions/Tester/Test_GasTJunction.mo    |  101 +
 .../Tester/Test_GasVaporMixtureTJunction.mo   |  101 +
 .../TJunctions/Tester/Test_LiquidTJunction.mo |   97 +
 .../TJunctions/Tester/Test_VLETJunction.mo    |   97 +
 .../Fittings/TJunctions/Tester/package.mo     |   20 +
 .../Fittings/TJunctions/Tester/package.order  |    5 +
 .../Fittings/TJunctions/VLETJunction.mo       |  263 +++
 .../Components/Fittings/TJunctions/package.mo |   18 +
 .../Fittings/TJunctions/package.order         |    6 +
 SorpLib/Components/Fittings/package.mo        |   39 +
 SorpLib/Components/Fittings/package.order     |    7 +
 .../HeatExchanger/Adsorbers/AdsorberDP.mo     |  310 +++
 .../HeatExchanger/Adsorbers/AdsorberDX.mo     |  312 ++++
 .../Adsorbers/SimpleAdsorberDP.mo             |  375 ++++
 .../Adsorbers/SimpleAdsorberDX.mo             |  374 ++++
 .../Adsorbers/Tester/Test_AdsorberDP.mo       |  110 ++
 .../Adsorbers/Tester/Test_AdsorberDX.mo       |  110 ++
 .../Adsorbers/Tester/Test_SimpleAdsorberDP.mo |  132 ++
 .../Adsorbers/Tester/Test_SimpleAdsorberDX.mo |  132 ++
 .../HeatExchanger/Adsorbers/Tester/package.mo |   19 +
 .../Adsorbers/Tester/package.order            |    4 +
 .../HeatExchanger/Adsorbers/package.mo        |   18 +
 .../HeatExchanger/Adsorbers/package.order     |    5 +
 .../BaseClasses/PartialHeatExchanger.mo       |  132 ++
 .../PartialPureComponentAdsorber.mo           | 1161 ++++++++++++
 .../PartialPureSimpleComponentAdsorber.mo     | 1130 +++++++++++
 .../PartialSimpleCondenserEvaporator.mo       |  629 +++++++
 .../BaseClasses/PartialSimpleDryCooler.mo     |  392 ++++
 .../HeatExchanger/BaseClasses/package.mo      |   19 +
 .../HeatExchanger/BaseClasses/package.order   |    5 +
 .../CondensersEvaporators/SimpleCondenser.mo  |  155 ++
 .../CondensersEvaporators/SimpleEvaporator.mo |  156 ++
 .../Tester/Test_SimpleCondenser.mo            |  130 ++
 .../Tester/Test_SimpleEvaporator.mo           |  130 ++
 .../CondensersEvaporators/Tester/package.mo   |   19 +
 .../Tester/package.order                      |    2 +
 .../CondensersEvaporators/package.mo          |   18 +
 .../CondensersEvaporators/package.order       |    3 +
 .../Geometry/HXGeometry.mo                    |   60 -
 .../HXAirAirParallelflow/Geometry/package.mo  |   11 -
 .../Geometry/package.order                    |    1 -
 .../HXAirAirParallelflow.mo                   |  434 -----
 .../HeatAndMassTransfer/HeatTransfer.mo       |   22 -
 .../HeatTransfer/ConstantAlpha.mo             |   37 -
 .../HeatTransfer/package.mo                   |   10 -
 .../HeatTransfer/package.order                |    1 -
 .../TransportPhenomena/package.mo             |    5 -
 .../TransportPhenomena/package.order          |    1 -
 .../HeatAndMassTransfer/package.mo            |    6 -
 .../HeatAndMassTransfer/package.order         |    2 -
 .../VDIWaermeatlasN6.mo                       |   75 -
 .../PressureDropCorrelations/package.mo       |    8 -
 .../PressureDropCorrelations/package.order    |    1 -
 .../Testers/TestAirAirHX.mo                   |  105 --
 .../HXAirAirParallelflow/Testers/package.mo   |    7 -
 .../Testers/package.order                     |    1 -
 .../HXAirAirParallelflow/package.mo           |    8 -
 .../HXAirAirParallelflow/package.order        |    5 -
 .../Recoolers/SimpleDryCooler.mo              |  257 +++
 .../Recoolers/Tester/Test_SimpleDryCooler.mo  |  111 ++
 .../HeatExchanger/Recoolers/Tester/package.mo |   19 +
 .../Recoolers/Tester/package.order            |    1 +
 .../HeatExchanger/Recoolers/package.mo        |   18 +
 .../HeatExchanger/Recoolers/package.order     |    2 +
 .../Records/GeometryClosedAdsorber.mo         |  229 +++
 .../Records/GeometryCondenserEvaporator.mo    |  200 ++
 .../Records/ParametrizationDryCooler.mo       |   59 +
 .../Records/SummaryClosedAdsorber.mo          |  118 ++
 .../Records/SummaryCondenserEvaporator.mo     |   97 +
 .../Records/SummarySimpleClosedAdsorber.mo    |  101 +
 .../HeatExchanger/Records/package.mo          |   18 +
 .../HeatExchanger/Records/package.order       |    6 +
 SorpLib/Components/HeatExchanger/package.mo   |   22 +-
 .../Components/HeatExchanger/package.order    |    6 +-
 ...alClosedAdsorberHeatTransferCoefficient.mo |   50 +
 ...artialConductiveHeatTransferCoefficient.mo |   48 +
 .../PartialGenericHeatTransferCoefficient.mo  |   33 +
 .../BaseClasses/PartialHeatTransfer.mo        |  231 +++
 .../PartialHeatTransferCoefficient.mo         |   87 +
 ...tialOpenAdsorberHeatTransferCoefficient.mo |   55 +
 ...rtialPoolBoilingHeatTransferCoefficient.mo |   63 +
 ...PoolCondensationHeatTransferCoefficient.mo |   53 +
 ...PartialRadiationHeatTransferCoefficient.mo |   33 +
 ...artialTubeInsideHeatTransferCoefficient.mo |   55 +
 .../HeatTransfer/BaseClasses/package.mo       |   20 +
 .../HeatTransfer/BaseClasses/package.order    |   10 +
 .../ClosedAdsorberHeatTransfer.mo             |  106 ++
 .../HeatTransfer/ConductionHeatTransfer.mo    |  103 +
 .../HeatTransfer/GenericHeatTransfer.mo       |   94 +
 .../Components/HeatTransfer/HeatTransfer.mo   |  117 --
 .../ClosedAdsorber/ConstantAlpha.mo           |   63 +
 .../ClosedAdsorber/ConstantAlphaA.mo          |   59 +
 .../ClosedAdsorber/ExponentialAlphaA.mo       |  114 ++
 .../ClosedAdsorber/LinearAlphaA.mo            |  111 ++
 .../ClosedAdsorber/PolynomialAlphaA.mo        |  113 ++
 .../ClosedAdsorber/package.mo                 |   44 +
 .../ClosedAdsorber/package.order              |    5 +
 .../Conduction/ConstantCylindricalWall.mo     |   81 +
 .../Conduction/ConstantPlainWall.mo           |   75 +
 .../Conduction/ConstantResistance.mo          |   53 +
 .../Conduction/CylindricalWall.mo             |   76 +
 .../Conduction/PlainWall.mo                   |   72 +
 .../Conduction/package.mo                     |   40 +
 .../Conduction/package.order                  |    5 +
 .../Generic/ConstantAlpha.mo                  |   61 +
 .../Generic/ConstantAlphaA.mo                 |   58 +
 .../Generic/ExponentialAlphaA.mo              |   97 +
 .../Generic/LinearAlphaA.mo                   |   95 +
 .../Generic/PolynomialAlphaA.mo               |   97 +
 .../Generic/package.mo                        |   43 +
 .../Generic/package.order                     |    5 +
 .../OpenAdsorber/CasingGasKast.mo             |  213 +++
 .../OpenAdsorber/CasingSorbentKast.mo         |  202 ++
 .../OpenAdsorber/ConstantAlpha.mo             |   62 +
 .../OpenAdsorber/ConstantAlphaA.mo            |   57 +
 .../OpenAdsorber/package.mo                   |   39 +
 .../OpenAdsorber/package.order                |    4 +
 .../PoolBoiling/ConstantAlpha.mo              |   54 +
 .../PoolBoiling/ConstantAlphaA.mo             |   51 +
 .../PoolBoiling/LinearAlphaA_T.mo             |   96 +
 .../PoolBoiling/LinearAlphaA_fRel.mo          |   67 +
 .../PoolBoiling/package.mo                    |   39 +
 .../PoolBoiling/package.order                 |    4 +
 .../PoolCondensation/ConstantAlpha.mo         |   54 +
 .../PoolCondensation/ConstantAlphaA.mo        |   51 +
 .../PoolCondensation/LinearAlphaA_T.mo        |   96 +
 .../PoolCondensation/LinearAlphaA_fRel.mo     |   67 +
 .../PoolCondensation/package.mo               |   39 +
 .../PoolCondensation/package.order            |    4 +
 .../Radiation/ConstantResistance.mo           |   51 +
 .../Radiation/GrayCylinderInGrayCylinder.mo   |   78 +
 .../Radiation/ParallelGraySurfaces.mo         |   75 +
 .../Radiation/package.mo                      |   32 +
 .../Radiation/package.order                   |    3 +
 .../TubeInside/ConstantAlpha.mo               |   63 +
 .../TubeInside/ConstantAlphaA.mo              |   60 +
 .../TubeInside/GnielinskiDittusBoelter.mo     |  415 +++++
 .../TubeInside/Schmidt.mo                     |  338 ++++
 .../TubeInside/package.mo                     |   39 +
 .../TubeInside/package.order                  |    4 +
 .../package.mo                                |   55 +
 .../package.order                             |    8 +
 .../HeatTransferPhenomena/ConstantAlpha.mo    |   37 -
 .../HeatTransferPhenomena/ConstantAlphaA.mo   |   34 -
 .../Partial/PartialHeatTransfer.mo            |   28 -
 .../HeatTransferPhenomena/Partial/package.mo  |    6 -
 .../Partial/package.order                     |    1 -
 .../HeatTransferSilicaGel_Lanzerath2015.mo    |   25 -
 .../HeatTransferZeolith13X_Lanzerath2015.mo   |   26 -
 .../Records/package.order                     |    2 -
 .../HeatTransferPhenomena/package.mo          |    7 -
 .../HeatTransferPhenomena/package.order       |    3 -
 .../HeatTransfer/OpenAdsorberHeatTransfer.mo  |  113 ++
 .../HeatTransfer/PoolBoilingHeatTransfer.mo   |  111 ++
 .../PoolCondensationHeatTransfer.mo           |  111 ++
 .../HeatTransfer/RadiationHeatTransfer.mo     |   87 +
 .../HeatTransfer/Records/FluidProperties.mo   |   38 +
 .../Records/GeometryClosedAdsorber.mo         |   22 +
 .../Records/GeometryOpenAdsorber.mo           |  222 +++
 .../HeatTransfer/Records/GeometryTube.mo      |   22 +
 .../HeatTransfer/Records/package.mo           |   18 +
 .../HeatTransfer/Records/package.order        |    4 +
 .../Tester/Test_ClosedAdsorberHeatTransfer.mo |  121 ++
 .../Tester/Test_ConductionHeatTransfer.mo     |  354 ++++
 .../Tester/Test_GenericHeatTransfer.mo        |  184 ++
 .../Tester/Test_OpenAdsorberHeatTransfer.mo   |  183 ++
 .../Tester/Test_PoolBoilingHeatTransfer.mo    |  173 ++
 .../Test_PoolCondensationHeatTransfer.mo      |  173 ++
 .../Tester/Test_RadiationHeatTransfer.mo      |  242 +++
 .../Tester/Test_TubeInsideHeatTransfer.mo     |  164 ++
 .../Components/HeatTransfer/Tester/package.mo |   18 +
 .../HeatTransfer/Tester/package.order         |    8 +
 .../HeatTransfer/Testers/TestHeatTransfer1.mo |   27 -
 .../HeatTransfer/Testers/TestHeatTransfer2.mo |   35 -
 .../HeatTransfer/Testers/package.mo           |    6 -
 .../HeatTransfer/Testers/package.order        |    2 -
 .../HeatTransfer/TubeInsideHeatTransfer.mo    |  115 ++
 SorpLib/Components/HeatTransfer/package.mo    |   55 +-
 SorpLib/Components/HeatTransfer/package.order |   15 +-
 .../BaseClasses/PartialMassTransfer.mo        |  351 ++++
 .../PartialMassTransferCoefficient.mo         |   66 +
 ...MassTransferCoefficientClosedAdsorberDP.mo |   68 +
 ...MassTransferCoefficientClosedAdsorberDX.mo |   68 +
 .../BaseClasses/PartialPureMassTransfer.mo    |  434 +++++
 .../BaseClasses/PartialPureMassTransferDP.mo  |   73 +
 .../BaseClasses/PartialPureMassTransferDX.mo  |  119 ++
 .../MassTransfer/BaseClasses/package.mo       |   20 +
 .../MassTransfer/BaseClasses/package.order    |    7 +
 .../LoadingDriven/ConstantCoefficient.mo      |   68 +
 .../ConstantSpecificCoefficient.mo            |   71 +
 .../ClosedAdsorber/LoadingDriven/Glueckauf.mo |   84 +
 .../LoadingDriven/GlueckaufArrhenius.mo       |   95 +
 .../ClosedAdsorber/LoadingDriven/package.mo   |   38 +
 .../LoadingDriven/package.order               |    4 +
 .../PressureDriven/ConstantCoefficient.mo     |   68 +
 .../ConstantSpecificCoefficient.mo            |   71 +
 .../PressureDriven/DarcyPackedBedSpheres.mo   |   90 +
 ...edSpheresKnudsenDiffusionPoiseuilleFlow.mo |  184 ++
 .../PressureDriven/DarcyPorousMedia.mo        |   90 +
 .../PressureDriven/KnudsenDiffusion.mo        |  104 ++
 .../KnudsenDiffusionPoiseuilleFlow.mo         |  141 ++
 .../PressureDriven/LaminarConnections.mo      |   86 +
 .../PressureDriven/PoiseuilleFlow.mo          |  104 ++
 .../ClosedAdsorber/PressureDriven/package.mo  |   65 +
 .../PressureDriven/package.order              |    9 +
 .../ClosedAdsorber/package.mo                 |   30 +
 .../ClosedAdsorber/package.order              |    2 +
 .../OpenAdsorber/package.mo                   |   18 +
 .../OpenAdsorber/package.order                |    0
 .../package.mo                                |   30 +
 .../package.order                             |    2 +
 .../MassTransfer/MassTransferDiffusion.mo     |  137 --
 .../MassTransfer/MassTransferDiffusionFlow.mo |  185 --
 .../MassTransfer/MassTransferFlow.mo          |   68 -
 .../ConstantCoefficient_dp.mo                 |   34 -
 .../ConstantCoefficient_dx.mo                 |   31 -
 .../ConstantSpecificCoefficient_dp.mo         |   34 -
 .../ConstantSpecificCoefficient_dx.mo         |   33 -
 .../DarcyPackedBed_Spheres_dp.mo              |   51 -
 .../DarcyPorousMedia_dp.mo                    |   43 -
 .../GlueckaufArrhenius_dx.mo                  |   52 -
 .../MassTransferPhenomena/Glueckauf_dx.mo     |   41 -
 .../MassTransferPhenomena/Laminar_dp.mo       |   50 -
 .../Partial/PartialMassTransfer_dp.mo         |   28 -
 .../Partial/PartialMassTransfer_dx.mo         |   33 -
 .../MassTransferPhenomena/Partial/package.mo  |    6 -
 .../Partial/package.order                     |    2 -
 .../Lanzerath2015_SilicaGel.mo                |   26 -
 .../Lanzerath2015_Zeolite13X_ads.mo           |   26 -
 .../Lanzerath2015_Zeolite13X_des.mo           |   26 -
 .../SakodaSuzuki1984_SilicaGel.mo             |   26 -
 .../Records/DiffusionCoefficients/package.mo  |    8 -
 .../DiffusionCoefficients/package.order       |    4 -
 .../FlowCoefficients/FlowRes_Lanzerath_ads.mo |    8 -
 .../FlowCoefficients/FlowRes_Lanzerath_des.mo |    8 -
 .../Records/FlowCoefficients/package.mo       |    6 -
 .../Records/FlowCoefficients/package.order    |    2 -
 .../Records/package.order                     |    2 -
 .../MassTransferPhenomena/package.mo          |   14 -
 .../MassTransferPhenomena/package.order       |   10 -
 .../Partial/PartialMassTransfer.mo            |  185 --
 .../MassTransfer/Partial/package.mo           |    5 -
 .../MassTransfer/Partial/package.order        |    1 -
 .../Lanzerath2015_SilicaGel.mo                |   26 -
 .../Lanzerath2015_Zeolite13X_ads.mo           |   27 -
 .../Lanzerath2015_Zeolite13X_des.mo           |   25 -
 .../SakodaSuzuki1984_SilicaGel.mo             |   26 -
 .../Record/DiffusionCoefficients/package.mo   |    8 -
 .../DiffusionCoefficients/package.order       |    4 -
 .../FlowCoefficients/FlowRes_Lanzerath_ads.mo |    8 -
 .../FlowCoefficients/FlowRes_Lanzerath_des.mo |    8 -
 .../Record/FlowCoefficients/package.mo        |    6 -
 .../Record/FlowCoefficients/package.order     |    2 -
 .../Components/MassTransfer/Record/package.mo |    6 -
 .../MassTransfer/Record/package.order         |    2 -
 .../MassTransfer/Records/FluidProperties.mo   |   36 +
 .../Records/GeometryClosedAdsorber.mo         |   22 +
 .../Records/GeometryOpenAdsorber.mo           |  222 +++
 .../MassTransfer/Records/package.mo           |   18 +
 .../MassTransfer/Records/package.order        |    3 +
 .../Testers/TesterMassTransferDiffusion1.mo   |   54 -
 .../TesterMassTransferDiffusionFlow1.mo       |   60 -
 .../TesterMassTransferDiffusionFlow2.mo       |   66 -
 .../TesterMassTransferDiffusionFlow3.mo       |   58 -
 .../Testers/TesterMassTransferFlow1.mo        |   54 -
 .../Testers/TesterMassTransferFlow2.mo        |   46 -
 .../Testers/TesterMassTransferFlow3.mo        |   50 -
 .../Testers/TesterMassTransferFlow4.mo        |   56 -
 .../MassTransfer/Testers/package.mo           |   11 -
 .../MassTransfer/Testers/package.order        |    8 -
 .../ClosedAdsorberMassTransferDP.mo           |  226 +++
 .../ClosedAdsorberMassTransferDX.mo           |  240 +++
 .../Test_ClosedAdsorberMassTransferDP.mo      |  169 ++
 .../Test_ClosedAdsorberMassTransferDX.mo      |  179 ++
 .../VLEMassTransfers/Tester/package.mo        |   18 +
 .../VLEMassTransfers/Tester/package.order     |    2 +
 .../MassTransfer/VLEMassTransfers/package.mo  |   17 +
 .../VLEMassTransfers/package.order            |    3 +
 SorpLib/Components/MassTransfer/package.mo    |   25 +-
 SorpLib/Components/MassTransfer/package.order |   11 +-
 .../Geometry/CylindricAdsorber.mo             |   29 -
 .../Geometry/GeneralAdsorberGeometry.mo       |   61 -
 .../Geometry/RectangularAdsorber.mo           |   30 -
 .../OpenAdsorber/Geometry/package.mo          |   11 -
 .../OpenAdsorber/Geometry/package.order       |    3 -
 .../HeatAndMassTransfer/HeatTransfer.mo       |   20 -
 .../MassTransferDiffusion.mo                  |   20 -
 .../PackedBedGas_HougenMarshall1947.mo        |   45 -
 .../HeatTransfer/PackedBedGas_Kast1988.mo     |   64 -
 .../HeatTransfer/PackedBedWall_Kast1988.mo    |   58 -
 .../HeatTransfer/package.mo                   |   10 -
 .../HeatTransfer/package.order                |    3 -
 .../PackedBedGas_HougenMarshall1947.mo        |   48 -
 .../MassTransfer/PackedBedGas_Kast1988.mo     |   72 -
 .../MassTransfer/package.mo                   |    8 -
 .../MassTransfer/package.order                |    2 -
 .../TransportPhenomena/package.mo             |    5 -
 .../TransportPhenomena/package.order          |    2 -
 .../HeatAndMassTransfer/package.mo            |    6 -
 .../HeatAndMassTransfer/package.order         |    3 -
 .../Components/OpenAdsorber/OpenAdsorber.mo   |  433 -----
 .../PackedBed_Kast1988.mo                     |   52 -
 .../Partial/PartialPressureDrop.mo            |   29 -
 .../Partial/package.order                     |    1 -
 .../PressureDropCorrelations/package.mo       |    8 -
 .../PressureDropCorrelations/package.order    |    1 -
 .../OpenAdsorber/Testers/TestOpenAdsorber.mo  |   62 -
 .../OpenAdsorber/Testers/TestOpenAdsorber2.mo |   83 -
 .../OpenAdsorber/Testers/package.mo           |    5 -
 .../OpenAdsorber/Testers/package.order        |    2 -
 SorpLib/Components/OpenAdsorber/package.mo    |   13 -
 SorpLib/Components/OpenAdsorber/package.order |    5 -
 SorpLib/Components/Pumps/AffinityPump.mo      |  132 ++
 .../Pumps/BaseClasses/PartialAffinityPump.mo  |  142 ++
 .../Pumps/BaseClasses/PartialPump.mo          |  185 ++
 .../Pumps/BaseClasses/PartialSimplePump.mo    |  173 ++
 .../Components/Pumps/BaseClasses/package.mo   |   19 +
 .../Pumps/BaseClasses/package.order           |    3 +
 SorpLib/Components/Pumps/SimplePump.mo        |  120 ++
 .../Pumps/Tester/Test_AffinityPump.mo         |  100 +
 .../Pumps/Tester/Test_SimplePump.mo           |  104 ++
 SorpLib/Components/Pumps/Tester/package.mo    |   19 +
 SorpLib/Components/Pumps/Tester/package.order |    2 +
 SorpLib/Components/Pumps/package.mo           |   19 +
 SorpLib/Components/Pumps/package.order        |    4 +
 .../BaseClasses/FluidMSL/DensitySensor.mo     |   70 +
 .../FluidMSL/MassFlowRateSensor.mo            |   82 +
 .../FluidMSL/MassFractionSensor.mo            |   78 +
 .../FluidMSL/MassFractionsSensor.mo           |  175 ++
 .../FluidMSL/PressureDifferenceSensor.mo      |   80 +
 .../BaseClasses/FluidMSL/PressureSensor.mo    |   67 +
 .../FluidMSL/SpecificEnthalpySensor.mo        |   67 +
 .../FluidMSL/SpecificEntropySensor.mo         |   70 +
 .../FluidMSL/TemperatureDifferenceSensor.mo   |   95 +
 .../BaseClasses/FluidMSL/TemperatureSensor.mo |   70 +
 .../FluidMSL/ThermodynamicStateSensor.mo      |  137 ++
 .../FluidMSL/VolumeFlowRateSensor.mo          |  115 ++
 .../Sensors/BaseClasses/FluidMSL/package.mo   |   20 +
 .../BaseClasses/FluidMSL/package.order        |   12 +
 .../BaseClasses/PartialAbsoluteFluidSensor.mo |   72 +
 .../BaseClasses/PartialFlowFluidSensor.mo     |   80 +
 .../BaseClasses/PartialRelativeFluidSensor.mo |   88 +
 .../Sensors/BaseClasses/PartialSensor.mo      |  126 ++
 .../Components/Sensors/BaseClasses/package.mo |   19 +
 .../Sensors/BaseClasses/package.order         |    5 +
 .../Sensors/GasSensors/DensitySensor.mo       |   34 +
 .../Sensors/GasSensors/MassFlowRateSensor.mo  |   42 +
 .../Sensors/GasSensors/MassFractionSensor.mo  |   34 +
 .../Sensors/GasSensors/MassFractionsSensor.mo |   34 +
 .../GasSensors/PressureDifferenceSensor.mo    |   39 +
 .../Sensors/GasSensors/PressureSensor.mo      |   34 +
 .../GasSensors/SpecificEnthalpySensor.mo      |   35 +
 .../GasSensors/SpecificEntropySensor.mo       |   34 +
 .../GasSensors/TemperatureDifferenceSensor.mo |   39 +
 .../Sensors/GasSensors/TemperatureSensor.mo   |   34 +
 .../GasSensors/Tester/Test_GasSensors.mo      |  218 +++
 .../Sensors/GasSensors/Tester/package.mo      |   18 +
 .../Sensors/GasSensors/Tester/package.order   |    1 +
 .../GasSensors/ThermodynamicStateSensor.mo    |   29 +
 .../GasSensors/VolumeFlowRateSensor.mo        |   38 +
 .../Components/Sensors/GasSensors/package.mo  |   20 +
 .../Sensors/GasSensors/package.order          |   13 +
 .../GasVaporMixtureSenors/DensitySensor.mo    |   35 +
 .../MassFlowRateSensor.mo                     |   43 +
 .../MassFractionSensor.mo                     |   35 +
 .../MassFractionsSensor.mo                    |   35 +
 .../PressureDifferenceSensor.mo               |   40 +
 .../GasVaporMixtureSenors/PressureSensor.mo   |   35 +
 .../RelativeHumiditySensor.mo                 |   77 +
 .../SpecificEnthalpySensor.mo                 |   36 +
 .../SpecificEntropySensor.mo                  |   35 +
 .../TemperatureDifferenceSensor.mo            |   40 +
 .../TemperatureSensor.mo                      |   35 +
 .../Tester/Test_GasSensors.mo                 |  232 +++
 .../GasVaporMixtureSenors/Tester/package.mo   |   18 +
 .../Tester/package.order                      |    1 +
 .../ThermodynamicStateSensor.mo               |   43 +
 .../VolumeFlowRateSensor.mo                   |   39 +
 .../Sensors/GasVaporMixtureSenors/package.mo  |   20 +
 .../GasVaporMixtureSenors/package.order       |   14 +
 .../Sensors/LiquidSensors/DensitySensor.mo    |   33 +
 .../LiquidSensors/MassFlowRateSensor.mo       |   41 +
 .../LiquidSensors/MassFractionSensor.mo       |   33 +
 .../LiquidSensors/MassFractionsSensor.mo      |   33 +
 .../LiquidSensors/PressureDifferenceSensor.mo |   38 +
 .../Sensors/LiquidSensors/PressureSensor.mo   |   33 +
 .../LiquidSensors/SpecificEnthalpySensor.mo   |   34 +
 .../LiquidSensors/SpecificEntropySensor.mo    |   33 +
 .../TemperatureDifferenceSensor.mo            |   38 +
 .../LiquidSensors/TemperatureSensor.mo        |   33 +
 .../Tester/Test_LiquidSensors.mo              |  218 +++
 .../Sensors/LiquidSensors/Tester/package.mo   |   18 +
 .../LiquidSensors/Tester/package.order        |    1 +
 .../LiquidSensors/ThermodynamicStateSensor.mo |   28 +
 .../LiquidSensors/VolumeFlowRateSensor.mo     |   37 +
 .../Sensors/LiquidSensors/package.mo          |   20 +
 .../Sensors/LiquidSensors/package.order       |   13 +
 .../DifferenceTemperatureSensor.mo            |   87 +
 .../ThermalSensors/HeatFlowRateSensor.mo      |   88 +
 .../ThermalSensors/TemperatureSensor.mo       |   65 +
 .../Tester/Test_ThermalSensors.mo             |  108 ++
 .../Sensors/ThermalSensors/Tester/package.mo  |   18 +
 .../ThermalSensors/Tester/package.order       |    1 +
 .../Sensors/ThermalSensors/package.mo         |   19 +
 .../Sensors/ThermalSensors/package.order      |    4 +
 .../Sensors/VLESensors/DensitySensor.mo       |   34 +
 .../Sensors/VLESensors/MassFlowRateSensor.mo  |   42 +
 .../Sensors/VLESensors/MassFractionSensor.mo  |   34 +
 .../Sensors/VLESensors/MassFractionsSensor.mo |   34 +
 .../VLESensors/PressureDifferenceSensor.mo    |   39 +
 .../Sensors/VLESensors/PressureSensor.mo      |   34 +
 .../VLESensors/SpecificEnthalpySensor.mo      |   35 +
 .../VLESensors/SpecificEntropySensor.mo       |   34 +
 .../VLESensors/TemperatureDifferenceSensor.mo |   39 +
 .../Sensors/VLESensors/TemperatureSensor.mo   |   34 +
 .../VLESensors/Tester/Test_VLESensors.mo      |  232 +++
 .../Sensors/VLESensors/Tester/package.mo      |   17 +
 .../Sensors/VLESensors/Tester/package.order   |    1 +
 .../VLESensors/ThermodynamicStateSensor.mo    |   53 +
 .../Sensors/VLESensors/VaporQualitySensor.mo  |   84 +
 .../VLESensors/VolumeFlowRateSensor.mo        |   38 +
 .../Components/Sensors/VLESensors/package.mo  |   20 +
 .../Sensors/VLESensors/package.order          |   14 +
 SorpLib/Components/Sensors/package.mo         |  203 ++
 SorpLib/Components/Sensors/package.order      |    6 +
 .../Tubes/BaseClasses/PartialTube.mo          |  832 +++++++++
 .../Components/Tubes/BaseClasses/package.mo   |   18 +
 .../Tubes/BaseClasses/package.order           |    1 +
 SorpLib/Components/Tubes/LiquidTube.mo        |  356 ++++
 .../Components/Tubes/Records/GeometryTube.mo  |  127 ++
 SorpLib/Components/Tubes/Records/package.mo   |   18 +
 .../Components/Tubes/Records/package.order    |    1 +
 .../Tubes/Tester/Test_LiquidTube.mo           |  152 ++
 SorpLib/Components/Tubes/Tester/package.mo    |   19 +
 SorpLib/Components/Tubes/Tester/package.order |    1 +
 SorpLib/Components/Tubes/package.mo           |   18 +
 SorpLib/Components/Tubes/package.order        |    4 +
 .../PartialCompressibleThreeWayValve.mo       |  143 ++
 .../BaseClasses/PartialCompressibleValve.mo   |  177 ++
 .../PartialCondensateRefluxValve.mo           |  207 +++
 .../PartialIncompressibleThreeWayValve.mo     |   70 +
 .../BaseClasses/PartialIncompressibleValve.mo |   96 +
 .../Valves/BaseClasses/PartialOrificeValve.mo |  163 ++
 .../BaseClasses/PartialThreeWayValve.mo       |  440 +++++
 .../Valves/BaseClasses/PartialValve.mo        |  357 ++++
 .../BaseClasses/PartialValveCharacteristic.mo |   44 +
 .../Components/Valves/BaseClasses/package.mo  |   19 +
 .../Valves/BaseClasses/package.order          |    9 +
 .../GasValves/CompressibleThreeWayValve.mo    |  163 ++
 .../Valves/GasValves/CompressibleValve.mo     |  179 ++
 .../Tester/Test_CompressibleThreeWayValve.mo  |  178 ++
 .../Tester/Test_CompressibleValve.mo          |  286 +++
 .../Valves/GasValves/Tester/package.mo        |   18 +
 .../Valves/GasValves/Tester/package.order     |    2 +
 .../Components/Valves/GasValves/package.mo    |   18 +
 .../Components/Valves/GasValves/package.order |    3 +
 .../IncompressibleThreeWayValve.mo            |  138 ++
 .../LiquidValves/IncompressibleValve.mo       |  151 ++
 .../Test_IncompressibleThreeWayValve.mo       |  178 ++
 .../Tester/Test_IncompressibleValve.mo        |  280 +++
 .../Valves/LiquidValves/Tester/package.mo     |   17 +
 .../Valves/LiquidValves/Tester/package.order  |    2 +
 .../Components/Valves/LiquidValves/package.mo |   18 +
 .../Valves/LiquidValves/package.order         |    3 +
 .../Components/Valves/Utilities/Limiter.mo    |   61 +
 .../Valves/Utilities/mixStreamVariables.mo    |   61 +
 .../Components/Valves/Utilities/package.mo    |   17 +
 .../Components/Valves/Utilities/package.order |    2 +
 .../VLEValves/CompressibleThreeWayValve.mo    |  163 ++
 .../Valves/VLEValves/CompressibleValve.mo     |  179 ++
 .../Valves/VLEValves/CondensateRefluxValve.mo |  122 ++
 .../VLEValves/IncompressibleThreeWayValve.mo  |  139 ++
 .../Valves/VLEValves/IncompressibleValve.mo   |  152 ++
 .../Tester/Test_CompressibleThreeWayValve.mo  |  180 ++
 .../Tester/Test_CompressibleValve.mo          |  286 +++
 .../Tester/Test_CondensateRefluxValve.mo      |  215 +++
 .../Test_IncompressibleThreeWayValve.mo       |  178 ++
 .../Tester/Test_IncompressibleValve.mo        |  286 +++
 .../Valves/VLEValves/Tester/package.mo        |   17 +
 .../Valves/VLEValves/Tester/package.order     |    5 +
 .../Components/Valves/VLEValves/package.mo    |   18 +
 .../Components/Valves/VLEValves/package.order |    6 +
 .../Valves/VLE_Valves/Partial/PartialValve.mo |   69 -
 .../Valves/VLE_Valves/Partial/package.mo      |    5 -
 .../Valves/VLE_Valves/Partial/package.order   |    1 -
 .../Testers/TestValveConstantFillingLevel.mo  |  140 --
 .../Valves/VLE_Valves/Testers/package.mo      |    6 -
 .../Valves/VLE_Valves/Testers/package.order   |    1 -
 .../VLE_Valves/ValveConstantFillingLevel.mo   |   39 -
 .../Components/Valves/VLE_Valves/package.mo   |   13 -
 .../Valves/VLE_Valves/package.order           |    3 -
 .../Tester/Test_AllValveCharacteristics.mo    |   70 +
 .../ValveCharacteristics/Tester/package.mo    |   18 +
 .../ValveCharacteristics/Tester/package.order |    1 +
 .../equalPercentageCharacteristic.mo          |   65 +
 .../linearCharacteristic.mo                   |   31 +
 .../Valves/ValveCharacteristics/package.mo    |   17 +
 .../Valves/ValveCharacteristics/package.order |    4 +
 .../quadraticCharacteristic.mo                |   31 +
 SorpLib/Components/Valves/package.mo          |   24 +-
 SorpLib/Components/Valves/package.order       |    7 +-
 SorpLib/Components/package.mo                 |   43 +-
 SorpLib/Components/package.order              |   12 +-
 SorpLib/Examples/TwoBedAdsorptionChiller.mo   |  218 +++
 SorpLib/Examples/package.mo                   |   17 +
 SorpLib/Examples/package.order                |    1 +
 .../Icons/AdsorberColumnsPackage/package.mo   | 1305 +++++++++++++
 .../AdsorberColumnsPackage/package.order      |    0
 SorpLib/Icons/AdsorbersPackage/package.mo     |  632 +++++++
 SorpLib/Icons/AdsorbersPackage/package.order  |    0
 .../CondensersEvaporatorsPackage/package.mo   |  126 ++
 .../package.order                             |    0
 SorpLib/Icons/ControllerPackage/package.mo    |   33 +
 SorpLib/Icons/ControllerPackage/package.order |    0
 SorpLib/Icons/FansPackage/package.mo          |   60 +
 SorpLib/Icons/FansPackage/package.order       |    0
 SorpLib/Icons/FittingsPackage/package.mo      |   36 +
 SorpLib/Icons/FittingsPackage/package.order   |    0
 .../Icons/HeatExchangersPackage/package.mo    |   95 +
 .../Icons/HeatExchangersPackage/package.order |    0
 SorpLib/Icons/HeatTransfersPackage/package.mo |   62 +
 .../Icons/HeatTransfersPackage/package.order  |    0
 SorpLib/Icons/MassTransfersPackage/package.mo |  202 ++
 .../Icons/MassTransfersPackage/package.order  |    0
 SorpLib/Icons/MediaPackage/package.mo         |   46 +
 SorpLib/Icons/MediaPackage/package.order      |    0
 SorpLib/Icons/PumpsPackage/package.mo         |   35 +
 SorpLib/Icons/PumpsPackage/package.order      |    0
 SorpLib/Icons/RecoolersPackage/package.mo     |  152 ++
 SorpLib/Icons/RecoolersPackage/package.order  |    0
 SorpLib/Icons/SorpLibPackage/package.mo       |   89 +
 SorpLib/Icons/SorpLibPackage/package.order    |    0
 SorpLib/Icons/TubesPackage/package.mo         |   44 +
 SorpLib/Icons/TubesPackage/package.order      |    0
 SorpLib/Icons/ValvesPackage/package.mo        |   22 +
 SorpLib/Icons/ValvesPackage/package.order     |    0
 SorpLib/Icons/VolumesPackage/package.mo       |   50 +
 SorpLib/Icons/VolumesPackage/package.order    |    0
 SorpLib/Icons/package.mo                      |   19 +
 SorpLib/Icons/package.order                   |   16 +
 .../HeatTransfer_insideTube/Schmidt.mo        |   53 -
 .../HeatTransfer_insideTube/SiederTate.mo     |   47 -
 .../HeatTransfer_insideTube/package.mo        |   11 -
 .../HeatTransfer_insideTube/package.order     |    2 -
 .../AdditionalTransferPhenomena/package.mo    |    5 -
 .../AdditionalTransferPhenomena/package.order |    1 -
 .../ClassTypes/ApplicationPackage.mo          |   11 -
 .../Internals/ClassTypes/ComponentPackage.mo  |   11 -
 .../Internals/ClassTypes/InternalPackage.mo   |   10 -
 SorpLib/Internals/ClassTypes/ModelPackage.mo  |   10 -
 .../Internals/ClassTypes/PartialPackage.mo    |   11 -
 SorpLib/Internals/ClassTypes/Record.mo        |   13 -
 SorpLib/Internals/ClassTypes/RecordPackage.mo |   11 -
 SorpLib/Internals/ClassTypes/package.mo       |   19 -
 SorpLib/Internals/ClassTypes/package.order    |    7 -
 .../SmoothTransition/SmoothSwitch.mo          |   53 -
 .../SmoothTransition/Testers/package.mo       |   21 -
 .../SmoothTransition/Testers/package.order    |    1 -
 SorpLib/Internals/SmoothTransition/package.mo |    6 -
 .../Internals/SmoothTransition/package.order  |    2 -
 SorpLib/Internals/package.mo                  |   12 -
 SorpLib/Internals/package.order               |    4 -
 SorpLib/Internals/systime.mo                  |    9 -
 .../AQSOAZ02WaterGoldsworthy.mo               |   45 -
 .../Partial/PartialAdsorbentWater.mo          |   57 -
 .../Partial/PartialAdsorbentWaterDubinin.mo   |   34 -
 .../AdsorbentAdsorbate/Partial/package.mo     |    6 -
 .../AdsorbentAdsorbate/Partial/package.order  |    2 -
 .../SilgelGrace123WaterSchawe.mo              |   44 -
 .../SilgelGrace125WaterNunez.mo               |   47 -
 .../SilgelGrace125WaterSchawe.mo              |   45 -
 .../Testers/TestAQSOAZ02WaterGoldsworthy.mo   |   15 -
 .../Testers/TestSilgelGrace123WaterSchawe.mo  |   16 -
 .../Testers/TestSilgelGrace125WaterNunez.mo   |   16 -
 .../Testers/TestSilgelGrace125WaterSchawe.mo  |   16 -
 .../Testers/TestWorkingPairs_comp.mo          |   32 -
 .../Testers/TestZeolite13XWaterNunez.mo       |   14 -
 .../AdsorbentAdsorbate/Testers/package.mo     |   10 -
 .../AdsorbentAdsorbate/Testers/package.order  |    6 -
 .../Zeolite13XWaterNunez.mo                   |   46 -
 SorpLib/Media/AdsorbentAdsorbate/package.mo   |   11 -
 .../Media/AdsorbentAdsorbate/package.order    |    7 -
 SorpLib/Media/Functions/CharCurve1Arctan.mo   |   56 -
 .../Media/Functions/CharCurve1Arctan_dWdA.mo  |   34 -
 .../Functions/CharCurve1Arctan_inverse.mo     |   56 -
 .../Media/Functions/CharCurve2Polynomial.mo   |   53 -
 .../Functions/CharCurve2Polynomial_dWdA.mo    |   71 -
 .../BasesClasses/PartialMulti_h_ads.mo        |   87 +
 .../BasesClasses/PartialPure_dh_ads_dT.mo     |   48 +
 .../BasesClasses/PartialPure_dh_ads_dp.mo     |   48 +
 .../BasesClasses/PartialPure_h_ads.mo         |   45 +
 .../BasesClasses/PartialTestMulti.mo          |  126 ++
 .../BasesClasses/PartialTestPure.mo           |  304 +++
 .../BasesClasses/package.mo                   |   20 +
 .../BasesClasses/package.order                |    6 +
 .../Test_h_ads_clausiusClapeyron_binary.mo    |  156 ++
 .../Test_h_ads_clausiusClapeyron_ternary.mo   |  159 ++
 .../MultiComponents/Testers/package.mo        |   22 +
 .../MultiComponents/Testers/package.order     |    2 +
 .../h_ads_binary_clausiusClapeyron.mo         |  151 ++
 .../h_ads_clausiusClapeyron.mo                |  220 +++
 .../h_ads_ternary_clausiusClapeyron.mo        |  191 ++
 .../MultiComponents/package.mo                |   28 +
 .../MultiComponents/package.order             |    4 +
 .../PureComponents/Testers/Test_h_ads.mo      |  505 +++++
 .../Testers/Test_h_ads_Dubinin.mo             |  674 +++++++
 .../Testers/Test_h_ads_clausiusClapeyron.mo   |  430 +++++
 .../PureComponents/Testers/package.mo         |   20 +
 .../PureComponents/Testers/package.order      |    3 +
 .../PureComponents/dh_ads_dT.mo               |   79 +
 .../PureComponents/dh_ads_dT_Dubinin.mo       |   92 +
 .../dh_ads_dT_clausiusClapeyron.mo            |   59 +
 .../PureComponents/dh_ads_dp.mo               |   77 +
 .../PureComponents/dh_ads_dp_Dubinin.mo       |   91 +
 .../dh_ads_dp_clausiusClapeyron.mo            |   59 +
 .../PureComponents/h_ads.mo                   |   93 +
 .../PureComponents/h_ads_Dubinin.mo           |   93 +
 .../PureComponents/h_ads_clausiusClapeyron.mo |   82 +
 .../PureComponents/package.mo                 |   34 +
 .../PureComponents/package.order              |   10 +
 .../Functions/SorptionEnthalpies/package.mo   |   19 +
 .../SorptionEnthalpies/package.order          |    3 +
 .../BaseClasses/PartialMulti.mo               |   52 +
 .../BaseClasses/PartialMultiIAST.mo           |  115 ++
 .../BaseClasses/PartialMultiIAST_dx_dT.mo     |   89 +
 .../BaseClasses/PartialMultiIAST_dx_dp.mo     |   76 +
 .../BaseClasses/PartialMultiIAST_dx_dy.mo     |   79 +
 .../BaseClasses/PartialMultiIAST_p_xyT.mo     |   60 +
 .../BaseClasses/PartialMultiIAST_py_xT.mo     |   61 +
 .../BaseClasses/PartialMultiIAST_x_pyT.mo     |   60 +
 .../BaseClasses/PartialMultiIAST_y_pxT.mo     |   61 +
 .../BaseClasses/PartialMulti_dx_dT.mo         |   74 +
 .../BaseClasses/PartialMulti_dx_dp.mo         |   72 +
 .../BaseClasses/PartialMulti_dx_dy.mo         |   73 +
 .../BaseClasses/PartialMulti_p_xyT.mo         |   82 +
 .../BaseClasses/PartialMulti_py_xT.mo         |   83 +
 .../BaseClasses/PartialMulti_x_pyT.mo         |   84 +
 .../BaseClasses/PartialMulti_y_pxT.mo         |   83 +
 .../BaseClasses/PartialPure.mo                |   41 +
 .../BaseClasses/PartialPure_A_W.mo            |   68 +
 .../BaseClasses/PartialPure_A_W_num.mo        |  151 ++
 .../BaseClasses/PartialPure_W_A.mo            |   65 +
 .../BaseClasses/PartialPure_dW_dA.mo          |   56 +
 .../BaseClasses/PartialPure_ddW_dA_dA.mo      |   58 +
 .../BaseClasses/PartialPure_ddW_dA_dT.mo      |   68 +
 .../BaseClasses/PartialPure_ddx_dT_dT.mo      |   62 +
 .../BaseClasses/PartialPure_ddx_dp_dT.mo      |   57 +
 .../BaseClasses/PartialPure_ddx_dp_dp.mo      |   52 +
 .../BaseClasses/PartialPure_dx_dT.mo          |   55 +
 .../BaseClasses/PartialPure_dx_dp.mo          |   50 +
 .../BaseClasses/PartialPure_p_piT.mo          |   85 +
 .../BaseClasses/PartialPure_p_piT_num.mo      |  181 ++
 .../BaseClasses/PartialPure_p_xT.mo           |   70 +
 .../BaseClasses/PartialPure_p_xT_num.mo       |  161 ++
 .../BaseClasses/PartialPure_pi_pT.mo          |   68 +
 .../BaseClasses/PartialPure_pi_pT_num.mo      |   82 +
 .../BaseClasses/PartialPure_x_pT.mo           |   70 +
 .../BaseClasses/PartialTestMulti.mo           |  489 +++++
 .../BaseClasses/PartialTestMultiIAST.mo       |  290 +++
 .../BaseClasses/PartialTestMultiIAST_N2.mo    |  242 +++
 .../BaseClasses/PartialTestMultiIAST_N3.mo    |  326 ++++
 .../BaseClasses/PartialTestPure.mo            |  491 +++++
 .../BaseClasses/PartialTestPureDubinin.mo     |  239 +++
 .../SorptionEquilibria/BaseClasses/package.mo |   20 +
 .../BaseClasses/package.order                 |   41 +
 .../PartialMultiComponents/package.mo         |   99 +
 .../PartialMultiComponents/package.order      |    7 +
 .../PartialMultiComponentsIAST/package.mo     |  100 +
 .../PartialMultiComponentsIAST/package.order  |    7 +
 .../PartialPureComponents/package.mo          |  100 +
 .../PartialPureComponents/package.order       |    9 +
 .../PartialPureComponentsDubinin/package.mo   |  214 +++
 .../package.order                             |    9 +
 .../SorptionEquilibria/Interfaces/package.mo  |   17 +
 .../Interfaces/package.order                  |    4 +
 .../IAST_N2/Internals/package.mo              |   18 +
 .../IAST_N2/Internals/package.order           |    4 +
 .../IAST_N2/Internals/py_xT_NewtonRaphson.mo  |  327 ++++
 .../IAST_N2/Internals/x_pyT_FastIAST.mo       |  462 +++++
 .../IAST_N2/Internals/x_pyT_NestedLoop.mo     |  389 ++++
 .../IAST_N2/Internals/x_pyT_NewtonRaphson.mo  |  322 ++++
 .../MultiComponents/IAST_N2/package.mo        |  805 ++++++++
 .../MultiComponents/IAST_N2/package.order     |    8 +
 .../IAST_N3/Internals/package.mo              |   18 +
 .../IAST_N3/Internals/package.order           |    4 +
 .../IAST_N3/Internals/py_xT_NewtonRaphson.mo  |  398 ++++
 .../IAST_N3/Internals/x_pyT_FastIAST.mo       |  538 ++++++
 .../IAST_N3/Internals/x_pyT_NestedLoop.mo     |  457 +++++
 .../IAST_N3/Internals/x_pyT_NewtonRaphson.mo  |  385 ++++
 .../MultiComponents/IAST_N3/package.mo        | 1282 +++++++++++++
 .../MultiComponents/IAST_N3/package.order     |    8 +
 .../Langmuir/Internals/calc_p_i_num_i_den.mo  |   70 +
 .../Langmuir/Internals/p_i_xT.mo              |   79 +
 .../Langmuir/Internals/package.mo             |   18 +
 .../Langmuir/Internals/package.order          |    2 +
 .../MultiComponents/Langmuir/package.mo       |  387 ++++
 .../MultiComponents/Langmuir/package.order    |    8 +
 .../MechanisticTothGAB/Internals/dx_CO2_dp.mo |   63 +
 .../MechanisticTothGAB/Internals/p_i_xT.mo    |  112 ++
 .../MechanisticTothGAB/Internals/package.mo   |   18 +
 .../Internals/package.order                   |    3 +
 .../MechanisticTothGAB/Internals/x_H20_pT.mo  |   86 +
 .../MechanisticTothGAB/package.mo             |  939 ++++++++++
 .../MechanisticTothGAB/package.order          |    8 +
 .../Sips/Internals/calc_p_i_num_i_den.mo      |   71 +
 .../MultiComponents/Sips/Internals/p_i_xT.mo  |   75 +
 .../MultiComponents/Sips/Internals/package.mo |   18 +
 .../Sips/Internals/package.order              |    2 +
 .../MultiComponents/Sips/package.mo           |  405 ++++
 .../MultiComponents/Sips/package.order        |    8 +
 .../IAST_N2/Test_changing_everything.mo       |  140 ++
 .../IAST_N2/Test_changing_mole_fractions.mo   |  140 ++
 .../Testers/IAST_N2/Test_changing_pressure.mo |  139 ++
 .../IAST_N2/Test_changing_temperature.mo      |  139 ++
 .../Testers/IAST_N2/package.mo                |   22 +
 .../Testers/IAST_N2/package.order             |    4 +
 .../IAST_N3/Test_changing_everything.mo       |  190 ++
 .../IAST_N3/Test_changing_mole_fractions.mo   |  190 ++
 .../Testers/IAST_N3/Test_changing_pressure.mo |  189 ++
 .../IAST_N3/Test_changing_temperature.mo      |  189 ++
 .../Testers/IAST_N3/package.mo                |   22 +
 .../Testers/IAST_N3/package.order             |    4 +
 .../Langmuir/Test_changing_everything.mo      |   98 +
 .../Langmuir/Test_changing_mole_fractions.mo  |   99 +
 .../Langmuir/Test_changing_pressure.mo        |   97 +
 .../Langmuir/Test_changing_temperature.mo     |   97 +
 .../Testers/Langmuir/package.mo               |   22 +
 .../Testers/Langmuir/package.order            |    4 +
 .../Test_changing_everything.mo               |  321 ++++
 .../Test_changing_mole_fractions.mo           |  321 ++++
 .../Test_changing_pressure.mo                 |  320 ++++
 .../Test_changing_temperature.mo              |  320 ++++
 .../Testers/MechanisticTothGAB/package.mo     |   22 +
 .../Testers/MechanisticTothGAB/package.order  |    4 +
 .../Testers/Sips/Test_changing_everything.mo  |  121 ++
 .../Sips/Test_changing_mole_fractions.mo      |  121 ++
 .../Testers/Sips/Test_changing_pressure.mo    |  120 ++
 .../Testers/Sips/Test_changing_temperature.mo |  120 ++
 .../MultiComponents/Testers/Sips/package.mo   |   22 +
 .../Testers/Sips/package.order                |    4 +
 .../Testers/Toth/Test_changing_everything.mo  |  119 ++
 .../Toth/Test_changing_mole_fractions.mo      |  119 ++
 .../Testers/Toth/Test_changing_pressure.mo    |  118 ++
 .../Testers/Toth/Test_changing_temperature.mo |  118 ++
 .../MultiComponents/Testers/Toth/package.mo   |   22 +
 .../Testers/Toth/package.order                |    4 +
 .../Test_changing_everything.mo               |  224 +++
 .../Test_changing_mole_fractions.mo           |  224 +++
 .../Test_changing_pressure.mo                 |  223 +++
 .../Test_changing_temperature.mo              |  223 +++
 .../Testers/TothGAB_Schellevis/package.mo     |   22 +
 .../Testers/TothGAB_Schellevis/package.order  |    4 +
 .../Test_changing_everything.mo               |  194 ++
 .../Test_changing_mole_fractions.mo           |  194 ++
 .../Test_changing_pressure.mo                 |  193 ++
 .../Test_changing_temperature.mo              |  193 ++
 .../Testers/TothGAB_StampiBombelli/package.mo |   22 +
 .../TothGAB_StampiBombelli/package.order      |    4 +
 .../Test_changing_everything.mo               |  278 +++
 .../Test_changing_mole_fractions.mo           |  278 +++
 .../Test_changing_pressure.mo                 |  277 +++
 .../Test_changing_temperature.mo              |  277 +++
 .../WeightedAverageDualSiteTothGAB/package.mo |   22 +
 .../package.order                             |    4 +
 .../MultiComponents/Testers/package.mo        |   18 +
 .../MultiComponents/Testers/package.order     |    9 +
 .../Toth/Internals/calc_p_i_num_i_den_i.mo    |   82 +
 .../MultiComponents/Toth/Internals/p_i_xT.mo  |   86 +
 .../MultiComponents/Toth/Internals/package.mo |   18 +
 .../Toth/Internals/package.order              |    2 +
 .../MultiComponents/Toth/package.mo           |  457 +++++
 .../MultiComponents/Toth/package.order        |    8 +
 .../TothGAB_Schellevis/Internals/p_i_xT.mo    |  214 +++
 .../TothGAB_Schellevis/Internals/package.mo   |   18 +
 .../Internals/package.order                   |    3 +
 .../TothGAB_Schellevis/Internals/x_CO2_pT.mo  |   74 +
 .../TothGAB_Schellevis/Internals/x_H20_pT.mo  |   86 +
 .../TothGAB_Schellevis/package.mo             |  678 +++++++
 .../TothGAB_Schellevis/package.order          |    8 +
 .../Internals/dx_CO2_dp.mo                    |   63 +
 .../Internals/p_i_xT.mo                       |   85 +
 .../Internals/package.mo                      |   18 +
 .../Internals/package.order                   |    3 +
 .../Internals/x_H20_pT.mo                     |   86 +
 .../TothGAB_StampiBombelli/package.mo         |  578 ++++++
 .../TothGAB_StampiBombelli/package.order      |    8 +
 .../Internals/p_i_xT.mo                       |  205 ++
 .../Internals/package.mo                      |   19 +
 .../Internals/package.order                   |    3 +
 .../Internals/x_CO2_pTx.mo                    |   76 +
 .../Internals/x_H20_pT.mo                     |   86 +
 .../WeightedAverageDualSiteTothGAB/package.mo |  831 +++++++++
 .../package.order                             |    8 +
 .../MultiComponents/package.mo                |   66 +
 .../MultiComponents/package.order             |   10 +
 .../PureComponents/BET/package.mo             |  784 ++++++++
 .../PureComponents/BET/package.order          |    9 +
 .../PureComponents/BiLangmuir/package.mo      |  257 +++
 .../PureComponents/BiLangmuir/package.order   |    9 +
 .../PureComponents/DubininAstakhov/package.mo |  526 ++++++
 .../DubininAstakhov/package.order             |   12 +
 .../package.mo                                |  607 ++++++
 .../package.order                             |   12 +
 .../DubininEmpirical1/package.mo              |  496 +++++
 .../DubininEmpirical1/package.order           |   12 +
 .../DubininEmpirical2/package.mo              |  645 +++++++
 .../DubininEmpirical2/package.order           |   12 +
 .../DubininLorentzianCumulative/package.mo    |  558 ++++++
 .../DubininLorentzianCumulative/package.order |   12 +
 .../DubininPearsonIV/package.mo               | 1170 ++++++++++++
 .../DubininPearsonIV/package.order            |   12 +
 .../PureComponents/Freundlich/package.mo      |  242 +++
 .../PureComponents/Freundlich/package.order   |    9 +
 .../PureComponents/GAB/package.mo             |  416 +++++
 .../PureComponents/GAB/package.order          |    9 +
 .../PureComponents/Henry/package.mo           |  172 ++
 .../PureComponents/Henry/package.order        |    9 +
 .../PureComponents/Langmuir/package.mo        |  243 +++
 .../PureComponents/Langmuir/package.order     |    9 +
 .../PureComponents/Sips/package.mo            |  296 +++
 .../PureComponents/Sips/package.order         |    9 +
 .../Testers/BET/Test_changing_pressure.mo     |  119 ++
 .../BET/Test_changing_pressureTemperature.mo  |  120 ++
 .../Testers/BET/Test_changing_temperature.mo  |  119 ++
 .../PureComponents/Testers/BET/package.mo     |   21 +
 .../PureComponents/Testers/BET/package.order  |    3 +
 .../BiLangmuir/Test_changing_pressure.mo      |  112 ++
 .../Test_changing_pressureTemperature.mo      |  113 ++
 .../BiLangmuir/Test_changing_temperature.mo   |  112 ++
 .../Testers/BiLangmuir/package.mo             |   21 +
 .../Testers/BiLangmuir/package.order          |    3 +
 .../DubininAstakhov/Test_changing_pressure.mo |  110 ++
 .../Test_changing_pressureTemperature.mo      |  111 ++
 .../Test_changing_temperature.mo              |  110 ++
 .../Testers/DubininAstakhov/package.mo        |   21 +
 .../Testers/DubininAstakhov/package.order     |    3 +
 .../Test_changing_pressure.mo                 |  162 ++
 .../Test_changing_pressureTemperature.mo      |  163 ++
 .../Test_changing_temperature.mo              |  162 ++
 .../package.mo                                |   21 +
 .../package.order                             |    3 +
 .../Test_changing_pressure.mo                 |  121 ++
 .../Test_changing_pressureTemperature.mo      |  122 ++
 .../Test_changing_temperature.mo              |  121 ++
 .../Testers/DubininEmpirical1/package.mo      |   21 +
 .../Testers/DubininEmpirical1/package.order   |    3 +
 .../Test_changing_pressure.mo                 |  145 ++
 .../Test_changing_pressureTemperature.mo      |  146 ++
 .../Test_changing_temperature.mo              |  145 ++
 .../Testers/DubininEmpirical2/package.mo      |   21 +
 .../Testers/DubininEmpirical2/package.order   |    3 +
 .../Test_changing_pressure.mo                 |  119 ++
 .../Test_changing_pressureTemperature.mo      |  120 ++
 .../Test_changing_temperature.mo              |  119 ++
 .../DubininLorentzianCumulative/package.mo    |   21 +
 .../DubininLorentzianCumulative/package.order |    3 +
 .../Test_changing_pressure.mo                 |  135 ++
 .../Test_changing_pressureTemperature.mo      |  137 ++
 .../Test_changing_temperature.mo              |  136 ++
 .../Testers/DubininPearsonIV/package.mo       |   21 +
 .../Testers/DubininPearsonIV/package.order    |    3 +
 .../Freundlich/Test_changing_pressure.mo      |   88 +
 .../Test_changing_pressureTemperature.mo      |   89 +
 .../Freundlich/Test_changing_temperature.mo   |   88 +
 .../Testers/Freundlich/package.mo             |   21 +
 .../Testers/Freundlich/package.order          |    3 +
 .../Testers/GAB/Test_changing_pressure.mo     |  129 ++
 .../GAB/Test_changing_pressureTemperature.mo  |  130 ++
 .../Testers/GAB/Test_changing_temperature.mo  |  129 ++
 .../PureComponents/Testers/GAB/package.mo     |   21 +
 .../PureComponents/Testers/GAB/package.order  |    3 +
 .../Testers/Henry/Test_changing_pressure.mo   |   80 +
 .../Test_changing_pressureTemperature.mo      |   81 +
 .../Henry/Test_changing_temperature.mo        |   80 +
 .../PureComponents/Testers/Henry/package.mo   |   21 +
 .../Testers/Henry/package.order               |    3 +
 .../Langmuir/Test_changing_pressure.mo        |   92 +
 .../Test_changing_pressureTemperature.mo      |   90 +
 .../Langmuir/Test_changing_temperature.mo     |   89 +
 .../Testers/Langmuir/package.mo               |   21 +
 .../Testers/Langmuir/package.order            |    3 +
 .../Testers/Sips/Test_changing_pressure.mo    |  104 ++
 .../Sips/Test_changing_pressureTemperature.mo |  105 ++
 .../Testers/Sips/Test_changing_temperature.mo |  104 ++
 .../PureComponents/Testers/Sips/package.mo    |   21 +
 .../PureComponents/Testers/Sips/package.order |    3 +
 .../Testers/Toth/Test_changing_pressure.mo    |  105 ++
 .../Toth/Test_changing_pressureTemperature.mo |  106 ++
 .../Testers/Toth/Test_changing_temperature.mo |  105 ++
 .../PureComponents/Testers/Toth/package.mo    |   21 +
 .../PureComponents/Testers/Toth/package.order |    3 +
 .../PureComponents/Testers/package.mo         |   18 +
 .../PureComponents/Testers/package.order      |   14 +
 .../PureComponents/Toth/package.mo            |  304 +++
 .../PureComponents/Toth/package.order         |    9 +
 .../PureComponents/package.mo                 |   95 +
 .../PureComponents/package.order              |   15 +
 .../Records/NumericsIAST.mo                   |   72 +
 .../Records/NumericsIAST_PureComponents.mo    |   47 +
 .../SorptionEquilibria/Records/package.mo     |   20 +
 .../SorptionEquilibria/Records/package.order  |    2 +
 .../SorptionEquilibria/Utilities/A_ppsT.mo    |   73 +
 .../Utilities/Testers/Test_A_ppsT.mo          |  308 +++
 .../Utilities/Testers/package.mo              |   20 +
 .../Utilities/Testers/package.order           |    1 +
 .../SorptionEquilibria/Utilities/dA_dT.mo     |   61 +
 .../SorptionEquilibria/Utilities/dA_dp.mo     |   55 +
 .../SorptionEquilibria/Utilities/ddA_dT_dT.mo |   67 +
 .../SorptionEquilibria/Utilities/ddA_dp_dT.mo |   55 +
 .../SorptionEquilibria/Utilities/ddA_dp_dp.mo |   56 +
 .../SorptionEquilibria/Utilities/p_ApsT.mo    |   65 +
 .../SorptionEquilibria/Utilities/package.mo   |   18 +
 .../Utilities/package.order                   |    8 +
 .../Functions/SorptionEquilibria/package.mo   |   20 +
 .../SorptionEquilibria/package.order          |    6 +
 .../BasesClasses/PartialPureIntegrad_cp.mo    |   77 +
 .../BasesClasses/PartialPureIntegrand.mo      |   96 +
 .../BasesClasses/PartialPure_cp.mo            |   42 +
 .../BasesClasses/PartialTestPure.mo           |  173 ++
 .../BasesClasses/package.mo                   |   20 +
 .../BasesClasses/package.order                |    4 +
 .../Integrands/Interfaces/Partial_beta_pT.mo  |   46 +
 .../Integrands/Interfaces/Partial_dbeta_dT.mo |   52 +
 .../Integrands/Interfaces/Partial_dbeta_dp.mo |   52 +
 .../Partial_dh_adsorptiveToLiquid_dT.mo       |   53 +
 .../Partial_dh_adsorptiveToLiquid_dp.mo       |   53 +
 .../Integrands/Interfaces/Partial_dh_dT.mo    |   52 +
 .../Integrands/Interfaces/Partial_dv_dT.mo    |   51 +
 .../Integrands/Interfaces/Partial_dv_dp.mo    |   51 +
 .../Partial_h_adsorptiveToLiquid_pT.mo        |   46 +
 .../Integrands/Interfaces/Partial_v_pT.mo     |   45 +
 .../Integrands/Interfaces/package.mo          |   18 +
 .../Integrands/Interfaces/package.order       |   10 +
 .../PureComponents/Integrands/dh_ads_dT_x.mo  |  284 +++
 .../Integrands/dh_ads_dT_x_CC.mo              |  140 ++
 .../Integrands/dh_ads_dT_x_Dubinin.mo         |  410 ++++
 .../Integrands/dh_adsorpt_dT_x.mo             |  318 ++++
 .../Integrands/dh_adsorpt_dT_x_CC.mo          |  198 ++
 .../Integrands/dh_adsorpt_dT_x_Dubinin.mo     |  446 +++++
 .../PureComponents/Integrands/package.mo      |   24 +
 .../PureComponents/Integrands/package.order   |    7 +
 .../MediumSpecificFunctions/package.mo        |  333 ++++
 .../MediumSpecificFunctions/package.order     |   15 +
 .../Testers/Test_cp_ChakrabortyEtAl.mo        |  493 +++++
 .../Testers/Test_cp_SchwambergerSchmidt.mo    |  291 +++
 .../Testers/Test_cp_WaltonLeVan.mo            |  287 +++
 .../PureComponents/Testers/package.mo         |   20 +
 .../PureComponents/Testers/package.order      |    4 +
 .../PureComponents/cp_ChakrabortyEtAl.mo      |  106 ++
 .../PureComponents/cp_SchwambergerSchmidt.mo  |  162 ++
 .../cp_SchwambergerSchmidt_Dubinin.mo         |  216 +++
 ...p_SchwambergerSchmidt_clausiusClapeyron.mo |  122 ++
 .../PureComponents/cp_WaltonLeVan.mo          |  151 ++
 .../PureComponents/cp_WaltonLeVan_Dubinin.mo  |  206 ++
 .../cp_WaltonLeVan_clausiusClapeyron.mo       |  101 +
 .../PureComponents/package.mo                 |   28 +
 .../PureComponents/package.order              |    9 +
 .../SpecificHeatCapacitiesAdsorpt/package.mo  |   20 +
 .../package.order                             |    2 +
 .../Functions/Testers/TestCharCurve1Arctan.mo |   19 -
 .../Testers/TestCharCurve2Polynomial.mo       |   28 -
 SorpLib/Media/Functions/Testers/package.mo    |    6 -
 SorpLib/Media/Functions/Testers/package.order |    2 -
 .../BasesClasses/Partial_ddz_dT_dT.mo         |   44 +
 .../Utilities/BasesClasses/Partial_dz_dT.mo   |   44 +
 .../BasesClasses/Partial_int_z_dT.mo          |   45 +
 .../Utilities/BasesClasses/Partial_z_T.mo     |   45 +
 .../Utilities/BasesClasses/package.mo         |   19 +
 .../Utilities/BasesClasses/package.order      |    4 +
 .../Test_cubicSplineInterpolation_T.mo        |  177 ++
 .../Testers/Test_generalizedFunction_T.mo     |  617 ++++++
 .../Testers/Test_linearInterpolation_T.mo     |  161 ++
 .../Functions/Utilities/Testers/package.mo    |   20 +
 .../Functions/Utilities/Testers/package.order |    3 +
 .../Utilities/calcCubicSplineCoefficients.mo  |  176 ++
 .../Utilities/cubicSplineInterpolation_T.mo   |  102 +
 .../Utilities/dcubicSplineInterpolation_dT.mo |   69 +
 .../ddcubicSplineInterpolation_dT_dT.mo       |   69 +
 .../Utilities/ddgeneralizedFunction_dT_dT.mo  |  140 ++
 .../Utilities/ddlinearInterpolation_dT_dT.mo  |   38 +
 .../Utilities/dgeneralizedFunction_dT.mo      |  116 ++
 .../Utilities/dlinearInterpolation_dT.mo      |   68 +
 .../Utilities/generalizedFunction_T.mo        |  142 ++
 .../intCubicSplineInterpolation_dT.mo         |   74 +
 .../Utilities/intGeneralizedFunction_dT.mo    |  111 ++
 .../Utilities/intLinearInterpolation_dT.mo    |   74 +
 .../Utilities/linearInterpolation_T.mo        |   88 +
 SorpLib/Media/Functions/Utilities/package.mo  |   18 +
 .../Media/Functions/Utilities/package.order   |   15 +
 SorpLib/Media/Functions/package.mo            |   24 +-
 SorpLib/Media/Functions/package.order         |   10 +-
 .../IdealGasMixtures/DryAir_N2_O2/package.mo  |   29 +
 .../DryAir_N2_O2/package.order                |    0
 .../package.mo                                |   51 +
 .../package.order                             |    0
 .../DryAir_N2_O2_CO2_H2O/package.mo           |   35 +
 .../DryAir_N2_O2_CO2_H2O/package.order        |    0
 .../ddsaturationPressureH2O_dT_dT.mo          |  187 ++
 .../dsaturationPressureH2O_dT.mo              |  136 ++
 .../PartialIdealGasMixture/package.mo         |   29 +
 .../PartialIdealGasMixture/package.order      |    6 +
 .../partialPressures.mo                       |   48 +
 .../saturationPressureH2O_T.mo                |  109 ++
 .../specificEnthalpy_i_T.mo                   |   56 +
 .../specificEntropy_i_pTX.mo                  |   71 +
 .../IdealGasMixtures/Interfaces/package.mo    |   18 +
 .../IdealGasMixtures/Interfaces/package.order |    1 +
 .../Tester/Test_DryAir_N2_O2.mo               |  211 +++
 .../Test_DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O.mo |   29 +
 .../Tester/Test_DryAir_N2_O2_CO2_H2O.mo       |   28 +
 .../Media/IdealGasMixtures/Tester/package.mo  |   18 +
 .../IdealGasMixtures/Tester/package.order     |    3 +
 SorpLib/Media/IdealGasMixtures/package.mo     |   23 +
 SorpLib/Media/IdealGasMixtures/package.order  |    5 +
 .../ddryAirMassFractions_dX.mo                |   58 +
 .../ddryMassFractionSaturation_dT_pX.mo       |   70 +
 .../ddryMassFractionSaturation_dX_pT.mo       |   89 +
 .../ddryMassFractionSaturation_dp_TX.mo       |   66 +
 .../ddsaturationPressureH2O_dT_dT.mo          |  177 ++
 .../dh_dT_pX.mo                               |  107 ++
 .../dh_dX_pT.mo                               |  154 ++
 .../dh_dp_TX.mo                               |   90 +
 .../dmassToMoleFractions_dX.mo                |   62 +
 .../drho_dX_ph.mo                             |   44 +
 .../dryAirToMoistAirMassBasedProperties.mo    |   44 +
 .../dryAirToMoistAirMassFractions.mo          |   44 +
 .../dryMassFractionSaturation.mo              |   62 +
 .../dsaturationPressureH2O_dT.mo              |  127 ++
 .../dv_dT_pX.mo                               |   92 +
 .../dv_dX_pT.mo                               |  125 ++
 .../dv_dp_TX.mo                               |   95 +
 .../enthalpyOfCondensingComponent.mo          |   81 +
 .../enthalpyOfLiquidIce.mo                    |   79 +
 .../enthalpyOfNonCondensingComponents.mo      |   55 +
 .../enthalpyOfSolid.mo                        |   95 +
 .../enthalpyOfVapor.mo                        |   75 +
 .../entropyOfCondensingGas.mo                 |   95 +
 .../entropyOfLiquid.mo                        |   91 +
 .../entropyOfNonCondensingGas.mo              |   64 +
 .../entropyOfSolid.mo                         |   90 +
 .../massFractionSaturation.mo                 |   49 +
 .../massFractions_pTxDryPhi.mo                |   89 +
 .../moistAirToDryAirMassBasedProperties.mo    |   44 +
 .../moistAirToDryAirMassFractions.mo          |   44 +
 .../package.mo                                | 1583 ++++++++++++++++
 .../package.order                             |  104 ++
 .../partialPressures.mo                       |   71 +
 .../pressure_dTXY.mo                          |   79 +
 .../relativeHumidity.mo                       |   41 +
 .../rho_pTXY.mo                               |   96 +
 .../saturationPressureH2O_T.mo                |   99 +
 .../specificEnthalpy_i.mo                     |   84 +
 .../specificEnthalpy_pTXY.mo                  |   94 +
 .../specificEntropy_i.mo                      |   86 +
 .../specificEntropy_pTXY.mo                   |   98 +
 .../specificHeatCapacityLiquid.mo             |   80 +
 .../specificHeatCapacitySolid.mo              |   80 +
 .../specificHeatCapacityVapor.mo              |   80 +
 .../temperature_phXY.mo                       |   83 +
 .../temperature_psXY.mo                       |   83 +
 .../Interfaces/package.mo                     |   18 +
 .../Interfaces/package.order                  |    1 +
 .../MoistAir_N2_O2_Ar_H2O/package.mo          |   38 +
 .../MoistAir_N2_O2_Ar_H2O/package.order       |    0
 .../MoistAir_N2_O2_CO2_H2O/package.mo         |   37 +
 .../MoistAir_N2_O2_CO2_H2O/package.order      |    0
 .../Tester/Test_MoistAir_N2_O2_Ar_H2O.mo      | 1023 ++++++++++
 .../Tester/Test_MoistAir_N2_O2_CO2_H2O.mo     |   28 +
 .../IdealGasVaporMixtures/Tester/package.mo   |   18 +
 .../Tester/package.order                      |    2 +
 .../Media/IdealGasVaporMixtures/package.mo    |   25 +
 .../Media/IdealGasVaporMixtures/package.order |    4 +
 SorpLib/Media/IdealGases/Ar/package.mo        |   25 +
 SorpLib/Media/IdealGases/Ar/package.order     |    0
 SorpLib/Media/IdealGases/CH4/package.mo       |   25 +
 SorpLib/Media/IdealGases/CH4/package.order    |    0
 SorpLib/Media/IdealGases/CO2/package.mo       |   25 +
 SorpLib/Media/IdealGases/CO2/package.order    |    0
 SorpLib/Media/IdealGases/H2O/package.mo       |   25 +
 SorpLib/Media/IdealGases/H2O/package.order    |    0
 SorpLib/Media/IdealGases/He/package.mo        |   25 +
 SorpLib/Media/IdealGases/He/package.order     |    0
 SorpLib/Media/IdealGases/N2/package.mo        |   25 +
 SorpLib/Media/IdealGases/N2/package.order     |    0
 SorpLib/Media/IdealGases/Ne/package.mo        |   25 +
 SorpLib/Media/IdealGases/Ne/package.order     |    0
 SorpLib/Media/IdealGases/O2/package.mo        |   25 +
 SorpLib/Media/IdealGases/O2/package.order     |    0
 SorpLib/Media/IdealGases/Tester/Test_Ar.mo    |   90 +
 SorpLib/Media/IdealGases/Tester/Test_CH4.mo   |   26 +
 SorpLib/Media/IdealGases/Tester/Test_CO2.mo   |   26 +
 SorpLib/Media/IdealGases/Tester/Test_H2O.mo   |   26 +
 SorpLib/Media/IdealGases/Tester/Test_He.mo    |   26 +
 SorpLib/Media/IdealGases/Tester/Test_N2.mo    |   26 +
 SorpLib/Media/IdealGases/Tester/Test_Ne.mo    |   26 +
 SorpLib/Media/IdealGases/Tester/Test_O2.mo    |   26 +
 SorpLib/Media/IdealGases/Tester/package.mo    |   18 +
 SorpLib/Media/IdealGases/Tester/package.order |    8 +
 SorpLib/Media/IdealGases/package.mo           |   24 +
 SorpLib/Media/IdealGases/package.order        |    9 +
 .../Media/Solids/BaseClasses/PartialSolid.mo  |  844 +++++++++
 .../Media/Solids/BaseClasses/PartialTest.mo   |  133 ++
 SorpLib/Media/Solids/BaseClasses/package.mo   |   19 +
 .../Media/Solids/BaseClasses/package.order    |    2 +
 .../Solids/MetalsAndMetalAlloys/Aluminium.mo  |   75 +
 .../Solids/MetalsAndMetalAlloys/Copper.mo     |   67 +
 .../StainlessSteel_X5CrNi18_10.mo             |   76 +
 .../Solids/MetalsAndMetalAlloys/Steel_35_8.mo |   72 +
 .../Testers/Test_Aluminium.mo                 |   29 +
 .../Testers/Test_Copper.mo                    |   29 +
 .../Test_StainlessSteel_X5CrNi18_10.mo        |   31 +
 .../Testers/Test_Steel_35_8.mo                |   29 +
 .../MetalsAndMetalAlloys/Testers/package.mo   |   19 +
 .../Testers/package.order                     |    4 +
 .../Solids/MetalsAndMetalAlloys/package.mo    |   18 +
 .../Solids/MetalsAndMetalAlloys/package.order |    5 +
 .../Solids/Records/AdditionalVariables.mo     |   29 +
 .../Media/Solids/Records/StateVariables.mo    |   41 +
 SorpLib/Media/Solids/Records/package.mo       |   18 +
 SorpLib/Media/Solids/Records/package.order    |    2 +
 .../Media/Solids/Sorbents/GenericSorbent.mo   |   38 +
 SorpLib/Media/Solids/Sorbents/RDSilicaGel.mo  |   56 +
 .../Sorbents/Testers/Test_GenericSorbent.mo   |   29 +
 .../Sorbents/Testers/Test_RDSilicaGel.mo      |   29 +
 .../Media/Solids/Sorbents/Testers/package.mo  |   18 +
 .../Solids/Sorbents/Testers/package.order     |    2 +
 SorpLib/Media/Solids/Sorbents/package.mo      |   18 +
 SorpLib/Media/Solids/Sorbents/package.order   |    3 +
 SorpLib/Media/Solids/package.mo               |   41 +
 SorpLib/Media/Solids/package.order            |    4 +
 .../BaseClasses/PartialPureCharts.mo          |  251 +++
 .../BaseClasses/PartialPureTest.mo            |  143 ++
 .../BaseClasses/PartialPureWorkingPairs.mo    | 1463 +++++++++++++++
 .../BaseClasses/Partial_ddz_dT_dT.mo          |   44 +
 .../WorkingPairs/BaseClasses/Partial_dz_dT.mo |   42 +
 .../WorkingPairs/BaseClasses/Partial_z_T.mo   |   42 +
 .../Media/WorkingPairs/BaseClasses/package.mo |   20 +
 .../WorkingPairs/BaseClasses/package.order    |    6 +
 .../PureComponents/ChartWorkingPairDubinin.mo |  250 +++
 .../PureComponents/ChartWorkingPairGas.mo     |   97 +
 .../PureComponents/ChartWorkingPairVLE.mo     |  135 ++
 .../Tester/Test_ChartWorkingPairDubinin.mo    |   96 +
 .../Tester/Test_ChartWorkingPairGas.mo        |   87 +
 .../Tester/Test_ChartWorkingPairVLE.mo        |   86 +
 .../PureComponents/Tester/package.mo          |   18 +
 .../PureComponents/Tester/package.order       |    3 +
 .../PureComponents/package.mo                 |   19 +
 .../PureComponents/package.order              |    4 +
 .../FluidPropertyDiagrams/package.mo          |   18 +
 .../FluidPropertyDiagrams/package.order       |    1 +
 .../package.mo                                |  839 +++++++++
 .../package.order                             |    7 +
 .../AdsorptProperties.mo                      | 1656 +++++++++++++++++
 .../IsothermCoefficients.mo                   |   52 +
 .../calc_integrand_SchwambergerSchmidt.mo     |  272 +++
 .../calc_integrand_SchwambergerSchmidt_CC.mo  |  189 ++
 ..._integrand_SchwambergerSchmidt_Constant.mo |  106 ++
 .../calc_integrand_WaltonLeVan.mo             |  248 +++
 .../calc_integrand_WaltonLeVan_CC.mo          |  147 ++
 .../calc_integrand_h_avg_adsorpt_CC.mo        |  135 ++
 .../calc_integrand_h_avg_adsorpt_Constant.mo  |  106 ++
 .../calc_integrand_h_avg_adsorpt_Formal.mo    |  178 ++
 .../calc_integrand_s_avg_adsorpt_CC.mo        |  135 ++
 .../calc_integrand_s_avg_adsorpt_Constant.mo  |  106 ++
 .../calc_integrand_s_avg_adsorpt_Formal.mo    |  178 ++
 .../PartialPureParametrization/package.mo     | 1086 +++++++++++
 .../PartialPureParametrization/package.order  |   29 +
 .../package.mo                                |  551 ++++++
 .../package.order                             |    7 +
 .../package.mo                                |   87 +
 .../package.order                             |    7 +
 .../Media/WorkingPairs/Interfaces/package.mo  |   17 +
 .../WorkingPairs/Interfaces/package.order     |    4 +
 .../MultiComponents/Testers/package.mo        |   19 +
 .../MultiComponents/Testers/package.order     |    0
 .../WorkingPairs/MultiComponents/package.mo   |   34 +
 .../MultiComponents}/package.order            |    1 -
 .../MultiComponents/CO2_H2O/package.mo        |   18 +
 .../MultiComponents/CO2_H2O/package.order     |    0
 .../MultiComponents/package.mo                |   19 +
 .../MultiComponents/package.order             |    1 +
 .../package.mo                                |  108 ++
 .../package.order                             |    6 +
 .../package.mo                                |  131 ++
 .../package.order                             |    7 +
 .../Zeolith13X_Toth_DantasEtAl2011/package.mo |  109 ++
 .../package.order                             |    6 +
 .../package.mo                                |  134 ++
 .../package.order                             |    7 +
 .../package.mo                                |  134 ++
 .../package.order                             |    7 +
 .../PureComponents/CO2/package.mo             |   17 +
 .../PureComponents/CO2/package.order          |    5 +
 .../package.mo                                |  115 ++
 .../package.order                             |    6 +
 .../package.mo                                |  125 ++
 .../package.order                             |    6 +
 .../package.mo                                |  115 ++
 .../package.order                             |    6 +
 .../package.mo                                |  134 ++
 .../package.order                             |    9 +
 .../package.mo                                |  106 ++
 .../package.order                             |    6 +
 .../package.mo                                |  106 ++
 .../package.order                             |    6 +
 .../package.mo                                |  108 ++
 .../package.order                             |    6 +
 .../package.mo                                |  106 ++
 .../package.order                             |    6 +
 .../package.mo                                |  121 ++
 .../package.order                             |    8 +
 .../package.mo                                |  121 ++
 .../package.order                             |    8 +
 .../package.mo                                |  106 ++
 .../package.order                             |    6 +
 .../package.mo                                |  119 ++
 .../package.order                             |    8 +
 .../package.mo                                |  106 ++
 .../package.order                             |    6 +
 .../package.mo                                |  131 ++
 .../package.order                             |    7 +
 .../package.mo                                |  119 ++
 .../package.order                             |    8 +
 .../package.mo                                |  134 ++
 .../package.order                             |    9 +
 .../package.mo                                |  134 ++
 .../package.order                             |    7 +
 .../package.mo                                |  134 ++
 .../package.order                             |    7 +
 .../package.mo                                |  148 ++
 .../package.order                             |   11 +
 .../PureComponents/H2O/package.mo             |   17 +
 .../PureComponents/H2O/package.order          |   19 +
 .../MediumSpecificFunctions/Gas/package.mo    |  340 ++++
 .../MediumSpecificFunctions/Gas/package.order |    8 +
 .../MediumSpecificFunctions/VLE/package.mo    |  502 +++++
 .../MediumSpecificFunctions/VLE/package.order |    8 +
 .../MediumSpecificFunctions/package.mo        |   18 +
 .../MediumSpecificFunctions/package.order     |    2 +
 .../package.mo                                |  109 ++
 .../package.order                             |    6 +
 .../Zeolith13X_Toth_DantasEtAl2011/package.mo |  109 ++
 .../package.order                             |    6 +
 .../package.mo                                |  131 ++
 .../package.order                             |    6 +
 .../PureComponents/N2/package.mo              |   17 +
 .../PureComponents/N2/package.order           |    3 +
 .../package.mo                                |  131 ++
 .../package.order                             |    6 +
 .../PureComponents/O2/package.mo              |   17 +
 .../PureComponents/O2/package.order           |    1 +
 .../PureComponents/package.mo                 |   19 +
 .../PureComponents/package.order              |    5 +
 .../Utilities/Testers/Test_exponential1.mo    |  119 ++
 .../Utilities/Testers/Test_exponential2.mo    |  128 ++
 .../Utilities/Testers/Test_linear1.mo         |  119 ++
 .../Utilities/Testers/package.mo              |   19 +
 .../Utilities/Testers/package.order           |    3 +
 .../Utilities/ddexponential1_dT_dT.mo         |   46 +
 .../Utilities/ddexponential2_dT_dT.mo         |   58 +
 .../Utilities/ddlinear1_dT_dT.mo              |   46 +
 .../Utilities/dexponential1_dT.mo             |   45 +
 .../Utilities/dexponential2_dT.mo             |   55 +
 .../Parametrizations/Utilities/dlinear1_dT.mo |   45 +
 .../Utilities/exponential1.mo                 |   53 +
 .../Utilities/exponential2.mo                 |   63 +
 .../Parametrizations/Utilities/linear1.mo     |   53 +
 .../Parametrizations/Utilities/package.mo     |   18 +
 .../Parametrizations/Utilities/package.order  |   10 +
 .../WorkingPairs/Parametrizations/package.mo  |   37 +
 .../Parametrizations/package.order            |    3 +
 ...ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo |   46 +
 ...SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo |   43 +
 .../CO2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo |   46 +
 ...eolith13X_Toth_WangDouglasLeVan2010_Gas.mo |   49 +
 ...Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo |   49 +
 .../PureComponents/CO2/package.mo             |   18 +
 .../PureComponents/CO2/package.order          |    5 +
 ...nCumulative_Goldsworthy2014_Bau2017_VLE.mo |   53 +
 ...nCumulative_Goldsworthy2014_Bau2017_VLE.mo |   53 +
 ...nCumulative_Goldsworthy2014_Bau2017_VLE.mo |   53 +
 ...olithY_DubininEmpirical2_Schawe2000_VLE.mo |   41 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   41 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   41 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   41 +
 ...icaGelH_DubininPearsonIV_Schawe2000_VLE.mo |   41 +
 ...GelLE32_DubininPearsonIV_Schawe2000_VLE.mo |   41 +
 ...GelNAC_DubininEmpirical1_Schawe2000_VLE.mo |   41 +
 ...icaGelN_DubininPearsonIV_Schawe2000_VLE.mo |   41 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   41 +
 ...SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo |   41 +
 ...SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo |   41 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   41 +
 ...Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo |   41 +
 ...ith13X_DubininEmpirical2_Schawe2000_VLE.mo |   41 +
 ...eolith13X_Toth_WangDouglasLeVan2010_Gas.mo |   41 +
 ...eolith13X_Toth_WangDouglasLeVan2010_VLE.mo |   41 +
 ...Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo |   41 +
 ...Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo |   41 +
 ...DubininChebyshevSeries33_Schawe2000_VLE.mo |   42 +
 .../PureComponents/H2O/package.mo             |   18 +
 .../PureComponents/H2O/package.order          |   22 +
 ...ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo |   46 +
 .../N2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo  |   46 +
 ...eolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo |   45 +
 .../WorkingPairs/PureComponents/N2/package.mo |   17 +
 .../PureComponents/N2/package.order           |    3 +
 ...eolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo |   45 +
 .../WorkingPairs/PureComponents/O2/package.mo |   17 +
 .../PureComponents/O2/package.order           |    1 +
 ...ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo |   34 +
 ...est_SilicaGel_Toth_WangDouglasLeVan2010.mo |   36 +
 ...Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo |   33 +
 ...eolith13X_Toth_WangDouglasLeVan2010_Gas.mo |   36 +
 ...Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo |   37 +
 .../PureComponents/Testers/CO2/package.mo     |   18 +
 .../PureComponents/Testers/CO2/package.order  |    5 +
 ...nCumulative_Goldsworthy2014_Bau2017_VLE.mo |   38 +
 ...nCumulative_Goldsworthy2014_Bau2017_VLE.mo |   44 +
 ...nCumulative_Goldsworthy2014_Bau2017_VLE.mo |   38 +
 ...olithY_DubininEmpirical2_Schawe2000_VLE.mo |   37 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   37 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   37 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   37 +
 ...icaGelH_DubininPearsonIV_Schawe2000_VLE.mo |   37 +
 ...GelLE32_DubininPearsonIV_Schawe2000_VLE.mo |   37 +
 ...GelNAC_DubininEmpirical1_Schawe2000_VLE.mo |   37 +
 ...icaGelN_DubininPearsonIV_Schawe2000_VLE.mo |   37 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   37 +
 ...SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo |   36 +
 ...SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo |   36 +
 ...ininLorentzianCumulative_Schawe2000_VLE.mo |   38 +
 ...Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo |   37 +
 ...ith13X_DubininEmpirical2_Schawe2000_VLE.mo |   37 +
 ...eolith13X_Toth_WangDouglasLeVan2010_Gas.mo |   36 +
 ...eolith13X_Toth_WangDouglasLeVan2010_VLE.mo |   36 +
 ...Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo |   36 +
 ...Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo |   36 +
 ...DubininChebyshevSeries33_Schawe2000_VLE.mo |   37 +
 .../PureComponents/Testers/H2O/package.mo     |   18 +
 .../PureComponents/Testers/H2O/package.order  |   22 +
 ...ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo |   34 +
 ...Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo |   34 +
 ...eolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo |   33 +
 .../PureComponents/Testers/N2/package.mo      |   18 +
 .../PureComponents/Testers/N2/package.order   |    3 +
 ...eolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo |   33 +
 .../PureComponents/Testers/O2/package.mo      |   18 +
 .../PureComponents/Testers/O2/package.order   |    1 +
 .../Testers/TestWorkingPairGas.mo             |   29 +
 .../Testers/TestWorkingPairVLE.mo             |   29 +
 .../PureComponents/Testers/package.mo         |   19 +
 .../PureComponents/Testers/package.order      |    6 +
 .../PureComponents/WorkingPairGas.mo          |   41 +
 .../PureComponents/WorkingPairVLE.mo          |   42 +
 .../WorkingPairs/PureComponents/package.mo    |   34 +
 .../WorkingPairs/PureComponents/package.order |    7 +
 .../Records/DerivativesPureEntropyBalance.mo  |   51 +
 .../Records/DerivativesPureIsothermModel.mo   |   35 +
 .../DerivativesPureMassEnergyBalances.mo      |   77 +
 .../Records/PropertiesPureAdsorpt.mo          |   85 +
 .../Records/PropertiesPureAdsorptive.mo       |   81 +
 .../WorkingPairs/Records/StateVariables.mo    |   21 +
 SorpLib/Media/WorkingPairs/Records/package.mo |   18 +
 .../Media/WorkingPairs/Records/package.order  |    6 +
 SorpLib/Media/WorkingPairs/package.mo         |   64 +
 SorpLib/Media/WorkingPairs/package.order      |    7 +
 SorpLib/Media/package.mo                      |   46 +-
 SorpLib/Media/package.order                   |    6 +-
 SorpLib/Modules/Controllers/package.mo        |   17 +
 SorpLib/Modules/Controllers/package.order     |    0
 SorpLib/Modules/package.mo                    |   17 +
 SorpLib/Modules/package.order                 |    1 +
 ...regSquareWFactors_regSquareWFactors_inv.mo |   70 +
 ...eWFactors_regSquareWFactors_inv_noEvent.mo |   70 +
 ...regSquare_noEvent_regSquare_inv_noEvent.mo |   62 +
 .../Testers/Test_regSquare_regSquare_inv.mo   |   61 +
 SorpLib/Numerics/Testers/Test_regStep.mo      |   50 +
 .../Numerics/Testers/Test_regStep_noEvent.mo  |   50 +
 .../Numerics/Testers/Test_smoothTransition.mo |   60 +
 .../Testers/Test_smoothTransition_noEvent.mo  |   60 +
 SorpLib/Numerics/Testers/package.mo           |   20 +
 SorpLib/Numerics/Testers/package.order        |    8 +
 SorpLib/Numerics/package.mo                   |   35 +
 SorpLib/Numerics/package.order                |   17 +
 SorpLib/Numerics/regSquare.mo                 |   97 +
 SorpLib/Numerics/regSquareWFactors.mo         |  140 ++
 SorpLib/Numerics/regSquareWFactors_inv.mo     |   99 +
 .../Numerics/regSquareWFactors_inv_noEvent.mo |   99 +
 SorpLib/Numerics/regSquareWFactors_noEvent.mo |  140 ++
 SorpLib/Numerics/regSquare_inv.mo             |   62 +
 SorpLib/Numerics/regSquare_inv_noEvent.mo     |   62 +
 SorpLib/Numerics/regSquare_noEvent.mo         |   98 +
 SorpLib/Numerics/regStep.mo                   |   84 +
 SorpLib/Numerics/regStep_noEvent.mo           |   86 +
 SorpLib/Numerics/smoothTransition.mo          |  147 ++
 SorpLib/Numerics/smoothTransition_der.mo      |   95 +
 SorpLib/Numerics/smoothTransition_der2.mo     |  101 +
 .../Numerics/smoothTransition_der2_noEvent.mo |  101 +
 .../Numerics/smoothTransition_der_noEvent.mo  |   95 +
 SorpLib/Numerics/smoothTransition_noEvent.mo  |  148 ++
 .../Resources/Images/AdsorbensAdsorbate.png   |  Bin 5080 -> 0 bytes
 SorpLib/Resources/Images/Adsorbent.png        |  Bin 3004 -> 0 bytes
 SorpLib/Resources/Images/ClosedAdsorber.png   |  Bin 9239 -> 0 bytes
 SorpLib/Resources/Images/DeltaP.png           |  Bin 16452 -> 0 bytes
 SorpLib/Resources/Images/Evaporator.png       |  Bin 5584 -> 0 bytes
 SorpLib/Resources/Images/EvpCond.png          |  Bin 1166 -> 0 bytes
 SorpLib/Resources/Images/HXAirAir.png         |  Bin 5766 -> 0 bytes
 SorpLib/Resources/Images/HeatTransfer.png     |  Bin 1169 -> 0 bytes
 SorpLib/Resources/Images/LTT_logo_RWTH_en.png |  Bin 28127 -> 0 bytes
 SorpLib/Resources/Images/MassTransfer.png     |  Bin 1441 -> 0 bytes
 .../Images/MassTransferDiffusion.png          |  Bin 45873 -> 0 bytes
 .../Images/MassTransferDiffusionFlow.png      |  Bin 56635 -> 0 bytes
 SorpLib/Resources/Images/OpenAdsorber.png     |  Bin 17310 -> 0 bytes
 SorpLib/Resources/Images/Sorplib_info.png     |  Bin 22552 -> 0 bytes
 SorpLib/Resources/Images/Sorplib_logo.png     |  Bin 8109 -> 0 bytes
 SorpLib/Resources/Images/Wall.png             |  Bin 2784 -> 0 bytes
 SorpLib/Resources/Images/beta.png             |  Bin 14971 -> 0 bytes
 ...dia_functions_equilibria_multi_iast_n2.png |  Bin 0 -> 77325 bytes
 ...dia_functions_equilibria_multi_iast_n3.png |  Bin 0 -> 103704 bytes
 ...ia_functions_equilibria_multi_langmuir.png |  Bin 0 -> 56102 bytes
 ..._equilibria_multi_mechanistic_toth_gab.png |  Bin 0 -> 77749 bytes
 .../media_functions_equilibria_multi_sips.png |  Bin 0 -> 72093 bytes
 .../media_functions_equilibria_multi_toth.png |  Bin 0 -> 63255 bytes
 ..._functions_equilibria_multi_toth_gab_s.png |  Bin 0 -> 64711 bytes
 ...functions_equilibria_multi_toth_gab_sb.png |  Bin 0 -> 78760 bytes
 ...nctions_equilibria_multi_wads_toth_gab.png |  Bin 0 -> 66371 bytes
 .../media_functions_equilibria_pure_bet.png   |  Bin 0 -> 82032 bytes
 ..._functions_equilibria_pure_bi_langmuir.png |  Bin 0 -> 42434 bytes
 ...tions_equilibria_pure_dubinin_astakhov.png |  Bin 0 -> 56108 bytes
 ...bria_pure_dubinin_chebyshev_series_3_3.png |  Bin 0 -> 52008 bytes
 ...ns_equilibria_pure_dubinin_empirical_1.png |  Bin 0 -> 48465 bytes
 ...ns_equilibria_pure_dubinin_empirical_2.png |  Bin 0 -> 50362 bytes
 ..._pure_dubinin_lorentzian_chebyshev_3_3.png |  Bin 0 -> 21520 bytes
 ...bria_pure_dubinin_lorentzian_cumulativ.png |  Bin 0 -> 21520 bytes
 ...bria_pure_dubinin_lorentzian_pearsonIV.png |  Bin 0 -> 21520 bytes
 ...ons_equilibria_pure_dubinin_pearson_iv.png |  Bin 0 -> 52427 bytes
 ...a_functions_equilibria_pure_freundlich.png |  Bin 0 -> 37153 bytes
 .../media_functions_equilibria_pure_gab.png   |  Bin 0 -> 79581 bytes
 .../media_functions_equilibria_pure_henry.png |  Bin 0 -> 14254 bytes
 ...dia_functions_equilibria_pure_langmuir.png |  Bin 0 -> 21480 bytes
 .../media_functions_equilibria_pure_sips.png  |  Bin 0 -> 18103 bytes
 .../media_functions_equilibria_pure_toth.png  |  Bin 0 -> 17915 bytes
 SorpLib/Resources/doc/numerics_regSquare.png  |  Bin 0 -> 45331 bytes
 .../doc/numerics_regSquareWFactors.png        |  Bin 0 -> 50146 bytes
 SorpLib/Resources/doc/numerics_regStep.png    |  Bin 0 -> 38218 bytes
 .../doc/numerics_smoothTransition.png         |  Bin 0 -> 25665 bytes
 SorpLib/Scripts/libraryinfo.mos               |   13 -
 SorpLib/Units/AdsorptionPotential.mo          |    6 +
 SorpLib/Units/DerDensityByTemperature.mo      |    6 +
 .../DerDensityByTemperatureTemperature.mo     |    6 +
 ...erFilledPoreVolumeByAdsorptionPotential.mo |    7 +
 ...yAdsorptionPotentialAdsorptionPotential.mo |    7 +
 ...eVolumeByAdsorptionPotentialTemperature.mo |    7 +
 .../Units/DerFilledPoreVolumeByTemperature.mo |    7 +
 ...rIsobaricExpansionCoefficientByPressure.mo |    7 +
 ...obaricExpansionCoefficientByTemperature.mo |    7 +
 .../DerMolarAdsorptionPotentialByPressure.mo  |    7 +
 ...arAdsorptionPotentialByPressurePressure.mo |    7 +
 ...dsorptionPotentialByPressureTemperature.mo |    7 +
 ...erMolarAdsorptionPotentialByTemperature.mo |    7 +
 ...rptionPotentialByTemperatureTemperature.mo |    7 +
 SorpLib/Units/DerMolarEnthalpyByPressure.mo   |    6 +
 SorpLib/Units/DerMolarEnthalpyByUptake.mo     |    6 +
 .../DerPressureByTemperatureTemperature.mo    |    5 +
 SorpLib/Units/DerPressureByUptake.mo          |    5 +
 .../Units/DerSpecificEnthalpyByPressure.mo    |    6 +
 SorpLib/Units/DerSpecificEnthalpyByUptake.mo  |    6 +
 SorpLib/Units/DerSpecificEntropyByPressure.mo |    6 +
 .../Units/DerSpecificEntropyByTemperature.mo  |    6 +
 SorpLib/Units/DerSpecificEntropyByUptake.mo   |    6 +
 .../DerSpecificHeatCapacityByTemperature.mo   |    7 +
 ...ficHeatCapacityByTemperatureTemperature.mo |    7 +
 SorpLib/Units/DerSpecificVolumeByPressure.mo  |    6 +
 .../DerSpecificVolumeByPressureTemperature.mo |    7 +
 .../Units/DerSpecificVolumeByTemperature.mo   |    6 +
 ...rSpecificVolumeByTemperatureTemperature.mo |    6 +
 SorpLib/Units/DerSpecificVolumeByUptake.mo    |    6 +
 .../DerThermalConductivityByTemperature.mo    |    7 +
 ...malConductivityByTemperatureTemperature.mo |    7 +
 SorpLib/Units/DerUptakeByMolarFraction.mo     |    6 +
 SorpLib/Units/DerUptakeByPressure.mo          |    6 +
 SorpLib/Units/DerUptakeByPressurePressure.mo  |    6 +
 .../Units/DerUptakeByPressureTemperature.mo   |    7 +
 SorpLib/Units/DerUptakeByTemperature.mo       |    6 +
 .../DerUptakeByTemperatureTemperature.mo      |    6 +
 .../DerUptakeSpecificEnthalpyByPressure.mo    |    6 +
 .../DerUptakeSpecificEnthalpyByTemperature.mo |    6 +
 .../DerUptakeSpecificEnthalpyByUptake.mo      |    6 +
 .../DerUptakeSpecificEntropyByPressure.mo     |    6 +
 .../DerUptakeSpecificEntropyByTemperature.mo  |    6 +
 .../Units/DerUptakeSpecificEntropyByUptake.mo |    6 +
 .../DerUptakeSpecificVolumeByPressure.mo      |    6 +
 .../DerUptakeSpecificVolumeByTemperature.mo   |    6 +
 .../Units/DerUptakeSpecificVolumeByUptake.mo  |    6 +
 SorpLib/Units/FilledPoreVolume.mo             |    7 +
 .../IntegralMolarHeatCapacityByUptake.mo      |    6 +
 .../IntegralSpecificHeatCapacityByUptake.mo   |    6 +
 SorpLib/Units/MolarAdsorptionPotential.mo     |    6 +
 SorpLib/Units/MolarUptake.mo                  |    7 +
 SorpLib/Units/ReducedSpreadingPressure.mo     |    6 +
 SorpLib/Units/Uptake.mo                       |    8 +
 SorpLib/Units/package.mo                      |   53 +
 SorpLib/Units/package.order                   |   54 +
 SorpLib/UsersGuide/Connectors/package.mo      |    4 +
 SorpLib/UsersGuide/Connectors/package.order   |    0
 SorpLib/UsersGuide/Contact/package.mo         |    4 +
 SorpLib/UsersGuide/Contact/package.order      |    0
 .../NamingConvention/package.mo               |    4 +
 .../NamingConvention/package.order            |    0
 .../StructureFormat/package.mo                |    4 +
 .../StructureFormat/package.order             |    0
 .../Conventions/HTMLDocumentation/package.mo  |    4 +
 .../HTMLDocumentation/package.order           |    2 +
 .../ModelicaCode/NamingConvention/package.mo  |    4 +
 .../NamingConvention/package.order            |    0
 .../ModelicaCode/StructureFormat/package.mo   |    4 +
 .../StructureFormat/package.order             |    0
 .../Conventions/ModelicaCode/package.mo       |    4 +
 .../Conventions/ModelicaCode/package.order    |    2 +
 SorpLib/UsersGuide/Conventions/package.mo     |    4 +
 SorpLib/UsersGuide/Conventions/package.order  |    2 +
 SorpLib/UsersGuide/Overview/package.mo        |    4 +
 SorpLib/UsersGuide/Overview/package.order     |    0
 SorpLib/UsersGuide/ReleaseNotes/package.mo    |    4 +
 SorpLib/UsersGuide/ReleaseNotes/package.order |    0
 SorpLib/UsersGuide/package.mo                 |   19 +-
 SorpLib/UsersGuide/package.order              |    5 +
 SorpLib/package.mo                            |   45 +-
 SorpLib/package.order                         |    9 +-
 1846 files changed, 143200 insertions(+), 10010 deletions(-)
 delete mode 100644 SorpLib/Applications/AdsorptionChillers/ChillerTwoBed1.mo
 delete mode 100644 SorpLib/Applications/AdsorptionChillers/ChillerTwoBed2.mo
 delete mode 100644 SorpLib/Applications/AdsorptionChillers/package.mo
 delete mode 100644 SorpLib/Applications/AdsorptionChillers/package.order
 delete mode 100644 SorpLib/Applications/DesiccantSystem/DesiccantSystem.mo
 delete mode 100644 SorpLib/Applications/DesiccantSystem/package.mo
 delete mode 100644 SorpLib/Applications/DesiccantSystem/package.order
 delete mode 100644 SorpLib/Applications/package.mo
 delete mode 100644 SorpLib/Applications/package.order
 create mode 100644 SorpLib/Basics/Interfaces/BaseClasses/PartialAdsorbatePort.mo
 create mode 100644 SorpLib/Basics/Interfaces/BaseClasses/PartialAdsorptPort.mo
 create mode 100644 SorpLib/Basics/Interfaces/BaseClasses/PartialFluidPort.mo
 create mode 100644 SorpLib/Basics/Interfaces/BaseClasses/PartialHeatPort.mo
 create mode 100644 SorpLib/Basics/Interfaces/BaseClasses/package.mo
 create mode 100644 SorpLib/Basics/Interfaces/BaseClasses/package.order
 create mode 100644 SorpLib/Basics/Interfaces/FluidPorts/GasPort_in.mo
 create mode 100644 SorpLib/Basics/Interfaces/FluidPorts/GasPort_out.mo
 create mode 100644 SorpLib/Basics/Interfaces/FluidPorts/LiquidPort_in.mo
 create mode 100644 SorpLib/Basics/Interfaces/FluidPorts/LiquidPort_out.mo
 create mode 100644 SorpLib/Basics/Interfaces/FluidPorts/VLEPort_in.mo
 create mode 100644 SorpLib/Basics/Interfaces/FluidPorts/VLEPort_out.mo
 create mode 100644 SorpLib/Basics/Interfaces/FluidPorts/package.mo
 create mode 100644 SorpLib/Basics/Interfaces/FluidPorts/package.order
 create mode 100644 SorpLib/Basics/Interfaces/HeatPorts/HeatPort_in.mo
 create mode 100644 SorpLib/Basics/Interfaces/HeatPorts/HeatPort_out.mo
 create mode 100644 SorpLib/Basics/Interfaces/HeatPorts/package.mo
 create mode 100644 SorpLib/Basics/Interfaces/HeatPorts/package.order
 create mode 100644 SorpLib/Basics/Interfaces/SorptionPorts/AdsorbatePort_in.mo
 create mode 100644 SorpLib/Basics/Interfaces/SorptionPorts/AdsorbatePort_out.mo
 create mode 100644 SorpLib/Basics/Interfaces/SorptionPorts/AdsorptPort_in.mo
 create mode 100644 SorpLib/Basics/Interfaces/SorptionPorts/AdsorptPort_out.mo
 create mode 100644 SorpLib/Basics/Interfaces/SorptionPorts/package.mo
 create mode 100644 SorpLib/Basics/Interfaces/SorptionPorts/package.order
 create mode 100644 SorpLib/Basics/Interfaces/package.mo
 create mode 100644 SorpLib/Basics/Interfaces/package.order
 create mode 100644 SorpLib/Basics/Sources/BaseClasses/PartialFluidSource.mo
 create mode 100644 SorpLib/Basics/Sources/BaseClasses/package.mo
 create mode 100644 SorpLib/Basics/Sources/BaseClasses/package.order
 create mode 100644 SorpLib/Basics/Sources/Fluids/GasSource.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/GasVaporMixtureSource.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/LiquidSource.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/Tester/Test_GasSource.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/Tester/Test_GasVaporMixtureSource.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/Tester/Test_LiquidSource.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/Tester/Test_VLESource.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/Tester/package.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/Tester/package.order
 create mode 100644 SorpLib/Basics/Sources/Fluids/VLESource.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/package.mo
 create mode 100644 SorpLib/Basics/Sources/Fluids/package.order
 create mode 100644 SorpLib/Basics/Sources/Sorption/AdsorbateSource.mo
 create mode 100644 SorpLib/Basics/Sources/Sorption/AdsorptSource.mo
 create mode 100644 SorpLib/Basics/Sources/Sorption/Tester/Test_AdsorbateSource.mo
 create mode 100644 SorpLib/Basics/Sources/Sorption/Tester/Test_AdsorptSource.mo
 create mode 100644 SorpLib/Basics/Sources/Sorption/Tester/package.mo
 create mode 100644 SorpLib/Basics/Sources/Sorption/Tester/package.order
 create mode 100644 SorpLib/Basics/Sources/Sorption/package.mo
 create mode 100644 SorpLib/Basics/Sources/Sorption/package.order
 create mode 100644 SorpLib/Basics/Sources/Thermal/HeatSource.mo
 create mode 100644 SorpLib/Basics/Sources/Thermal/Tester/Test_HeatSource.mo
 create mode 100644 SorpLib/Basics/Sources/Thermal/Tester/package.mo
 create mode 100644 SorpLib/Basics/Sources/Thermal/Tester/package.order
 create mode 100644 SorpLib/Basics/Sources/Thermal/package.mo
 create mode 100644 SorpLib/Basics/Sources/Thermal/package.order
 create mode 100644 SorpLib/Basics/Sources/package.mo
 create mode 100644 SorpLib/Basics/Sources/package.order
 create mode 100644 SorpLib/Basics/Volumes/AdsorbateVolumes/AdsorbatePureGasVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/AdsorbateVolumes/AdsorbatePureVLEVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/Test_AdsorbatePureGasVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/Test_AdsorbatePureVLEVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/package.mo
 create mode 100644 SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/package.order
 create mode 100644 SorpLib/Basics/Volumes/AdsorbateVolumes/package.mo
 create mode 100644 SorpLib/Basics/Volumes/AdsorbateVolumes/package.order
 create mode 100644 SorpLib/Basics/Volumes/BaseClasses/PartialAdsorbateVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/BaseClasses/PartialFluidVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/BaseClasses/PartialPhaseSeparatorVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/BaseClasses/PartialPureComponentAdsorbateVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/BaseClasses/PartialVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/BaseClasses/package.mo
 create mode 100644 SorpLib/Basics/Volumes/BaseClasses/package.order
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/GasMixtureVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/GasVaporMixtureVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/GasVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/LiquidVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasMixtureVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasVaporMixtureVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_LiquidVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_VLEVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/Tester/package.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/Tester/package.order
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/VLEVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/package.mo
 create mode 100644 SorpLib/Basics/Volumes/FluidVolumes/package.order
 create mode 100644 SorpLib/Basics/Volumes/PhaseSeparatorVolumes/PhaseSeparatorVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/Test_PhaseSeparator.mo
 create mode 100644 SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/package.mo
 create mode 100644 SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/package.order
 create mode 100644 SorpLib/Basics/Volumes/PhaseSeparatorVolumes/package.mo
 create mode 100644 SorpLib/Basics/Volumes/PhaseSeparatorVolumes/package.order
 create mode 100644 SorpLib/Basics/Volumes/Records/AdsorbateVolumeProperties.mo
 create mode 100644 SorpLib/Basics/Volumes/Records/FluidVolumeProperties.mo
 create mode 100644 SorpLib/Basics/Volumes/Records/PhaseSeparatorGeometry.mo
 create mode 100644 SorpLib/Basics/Volumes/Records/PhaseSeparatorProperties.mo
 create mode 100644 SorpLib/Basics/Volumes/Records/SolidVolumeProperties.mo
 create mode 100644 SorpLib/Basics/Volumes/Records/VolumeGeometry.mo
 create mode 100644 SorpLib/Basics/Volumes/Records/package.mo
 create mode 100644 SorpLib/Basics/Volumes/Records/package.order
 create mode 100644 SorpLib/Basics/Volumes/SolidVolumes/SolidVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/SolidVolumes/Tester/Test_SolidVolume.mo
 create mode 100644 SorpLib/Basics/Volumes/SolidVolumes/Tester/package.mo
 create mode 100644 SorpLib/Basics/Volumes/SolidVolumes/Tester/package.order
 create mode 100644 SorpLib/Basics/Volumes/SolidVolumes/package.mo
 create mode 100644 SorpLib/Basics/Volumes/SolidVolumes/package.order
 create mode 100644 SorpLib/Basics/Volumes/Utilities/mapSorptionFluidPorts.mo
 create mode 100644 SorpLib/Basics/Volumes/Utilities/package.mo
 create mode 100644 SorpLib/Basics/Volumes/Utilities/package.order
 create mode 100644 SorpLib/Basics/Volumes/package.mo
 create mode 100644 SorpLib/Basics/Volumes/package.order
 create mode 100644 SorpLib/Basics/package.mo
 create mode 100644 SorpLib/Basics/package.order
 create mode 100644 SorpLib/Choices/BalanceEquations.mo
 create mode 100644 SorpLib/Choices/BoundaryFluidPotentialFlow.mo
 create mode 100644 SorpLib/Choices/BoundaryFluidStreamEnthalpy.mo
 create mode 100644 SorpLib/Choices/BoundaryFluidStreamMassFractions.mo
 create mode 100644 SorpLib/Choices/BoundaryThermal.mo
 create mode 100644 SorpLib/Choices/ChangingConstantVariableOfDiagram.mo
 create mode 100644 SorpLib/Choices/DiagramTypePureComponentWorkingPair.mo
 create mode 100644 SorpLib/Choices/GeneralizedFunctionApproach.mo
 create mode 100644 SorpLib/Choices/IASTAlgorithm.mo
 create mode 100644 SorpLib/Choices/IndependentVariablesMultiComponentWorkingPair.mo
 create mode 100644 SorpLib/Choices/IndependentVariablesPureComponentWorkingPair.mo
 create mode 100644 SorpLib/Choices/IndependentVariablesVolume.mo
 create mode 100644 SorpLib/Choices/InterpolationApproach.mo
 create mode 100644 SorpLib/Choices/IsobaricExpansionCoefficientAdsorpt.mo
 create mode 100644 SorpLib/Choices/MassFlowRateHeatTranferCorrelation.mo
 create mode 100644 SorpLib/Choices/MassTransferFluidProperties.mo
 create mode 100644 SorpLib/Choices/PrescripedFanVariable.mo
 create mode 100644 SorpLib/Choices/PrescripedPumpVariable.mo
 create mode 100644 SorpLib/Choices/ResistorFluidProperties.mo
 create mode 100644 SorpLib/Choices/SorptionEnthalpy.mo
 create mode 100644 SorpLib/Choices/SpecificHeatCapacityAdsorpt.mo
 create mode 100644 SorpLib/Choices/SpecificHeatCapacitySolid.mo
 create mode 100644 SorpLib/Choices/SpecificVolumeAdsorpt.mo
 create mode 100644 SorpLib/Choices/SpecificVolumeSolid.mo
 create mode 100644 SorpLib/Choices/TemperatureHeatTranferCorrelation.mo
 create mode 100644 SorpLib/Choices/ThermalConductivitySolid.mo
 create mode 100644 SorpLib/Choices/package.mo
 create mode 100644 SorpLib/Choices/package.order
 create mode 100644 SorpLib/Components/AdsorberColumns/package.mo
 create mode 100644 SorpLib/Components/AdsorberColumns/package.order
 delete mode 100644 SorpLib/Components/Cells/Adsorbent/Adsorbent.mo
 delete mode 100644 SorpLib/Components/Cells/Adsorbent/Testers/TestAdsorbent.mo
 delete mode 100644 SorpLib/Components/Cells/Adsorbent/Testers/package.mo
 delete mode 100644 SorpLib/Components/Cells/Adsorbent/Testers/package.order
 delete mode 100644 SorpLib/Components/Cells/Adsorbent/package.mo
 delete mode 100644 SorpLib/Components/Cells/Adsorbent/package.order
 delete mode 100644 SorpLib/Components/Cells/Gas/Gas.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/Geometry/CellGeometry.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/Geometry/package.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/Geometry/package.order
 delete mode 100644 SorpLib/Components/Cells/Gas/PressureDropCorrelations/ConstantResistanceCoefficient.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/PartialPressureDrop.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/package.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/package.order
 delete mode 100644 SorpLib/Components/Cells/Gas/PressureDropCorrelations/ZeroPressureDrop.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/PressureDropCorrelations/package.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/PressureDropCorrelations/package.order
 delete mode 100644 SorpLib/Components/Cells/Gas/Testers/TestGas.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/Testers/TestGas2.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/Testers/TestGas3.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/Testers/TestGas4.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/Testers/package.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/Testers/package.order
 delete mode 100644 SorpLib/Components/Cells/Gas/package.mo
 delete mode 100644 SorpLib/Components/Cells/Gas/package.order
 delete mode 100644 SorpLib/Components/Cells/VLEPhaseSeparator/Testers/TestVLEPhaseSeparator.mo
 delete mode 100644 SorpLib/Components/Cells/VLEPhaseSeparator/Testers/package.mo
 delete mode 100644 SorpLib/Components/Cells/VLEPhaseSeparator/Testers/package.order
 delete mode 100644 SorpLib/Components/Cells/VLEPhaseSeparator/VLEPhaseSeparator.mo
 delete mode 100644 SorpLib/Components/Cells/VLEPhaseSeparator/package.mo
 delete mode 100644 SorpLib/Components/Cells/VLEPhaseSeparator/package.order
 delete mode 100644 SorpLib/Components/Cells/Wall/Testers/TestWall.mo
 delete mode 100644 SorpLib/Components/Cells/Wall/Testers/package.mo
 delete mode 100644 SorpLib/Components/Cells/Wall/Testers/package.order
 delete mode 100644 SorpLib/Components/Cells/Wall/Wall.mo
 delete mode 100644 SorpLib/Components/Cells/Wall/package.mo
 delete mode 100644 SorpLib/Components/Cells/package.mo
 delete mode 100644 SorpLib/Components/Cells/package.order
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Adsorber.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Geometry/Adsorber_Finned_Tubes_Alu.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Geometry/TubeGeometry.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Geometry/package.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Geometry/package.order
 delete mode 100644 SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/HeatTransferSilicaGel_Lanzerath2015.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/HeatTransferZeolith13X_Lanzerath2015.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/package.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/package.order
 delete mode 100644 SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/package.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/package.order
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Testers/TestAdsorber1.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Testers/TestAdsorber2.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Testers/package.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/Testers/package.order
 delete mode 100644 SorpLib/Components/ClosedAdsorber/package.mo
 delete mode 100644 SorpLib/Components/ClosedAdsorber/package.order
 delete mode 100644 SorpLib/Components/EvpCond/EvpCond.mo
 delete mode 100644 SorpLib/Components/EvpCond/Geometry/CondLanzerath2014.mo
 delete mode 100644 SorpLib/Components/EvpCond/Geometry/EvpLanzerath2014.mo
 delete mode 100644 SorpLib/Components/EvpCond/Geometry/TubeGeometry.mo
 delete mode 100644 SorpLib/Components/EvpCond/Geometry/package.mo
 delete mode 100644 SorpLib/Components/EvpCond/Geometry/package.order
 delete mode 100644 SorpLib/Components/EvpCond/Testers/TestEvpCond1.mo
 delete mode 100644 SorpLib/Components/EvpCond/Testers/TestEvpCond2.mo
 delete mode 100644 SorpLib/Components/EvpCond/Testers/TestEvpCond3.mo
 delete mode 100644 SorpLib/Components/EvpCond/Testers/package.mo
 delete mode 100644 SorpLib/Components/EvpCond/Testers/package.order
 delete mode 100644 SorpLib/Components/EvpCond/package.mo
 delete mode 100644 SorpLib/Components/EvpCond/package.order
 create mode 100644 SorpLib/Components/Fans/AffinityFan.mo
 create mode 100644 SorpLib/Components/Fans/BaseClasses/PartialAffinityFan.mo
 create mode 100644 SorpLib/Components/Fans/BaseClasses/PartialFan.mo
 create mode 100644 SorpLib/Components/Fans/BaseClasses/PartialSimpleFan.mo
 create mode 100644 SorpLib/Components/Fans/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/Fans/BaseClasses/package.order
 create mode 100644 SorpLib/Components/Fans/SimpleFan.mo
 create mode 100644 SorpLib/Components/Fans/Tester/Test_AffinityFan.mo
 create mode 100644 SorpLib/Components/Fans/Tester/Test_SimpleFan.mo
 create mode 100644 SorpLib/Components/Fans/Tester/package.mo
 create mode 100644 SorpLib/Components/Fans/Tester/package.order
 create mode 100644 SorpLib/Components/Fans/package.mo
 create mode 100644 SorpLib/Components/Fans/package.order
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/PartialInertiaInducer.mo
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/PartialMultiPort.mo
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/PartialOpenAdsorberPressureLoss.mo
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/PartialPressureLoss.mo
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/PartialResistance.mo
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/PartialTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/PartialTubeInsidePressureLoss.mo
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/Fittings/BaseClasses/package.order
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/GasInertiaInducer.mo
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/LiquidInertiaInducer.mo
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/Tester/Test_GasInertiaInducer.mo
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/Tester/Test_LiquidInertiaInducer.mo
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/Tester/Test_VLEInertiaInducer.mo
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/Tester/package.mo
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/Tester/package.order
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/VLEInertiaInducer.mo
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/package.mo
 create mode 100644 SorpLib/Components/Fittings/InertiaInducers/package.order
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/GasMultiPort.mo
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/LiquidMultiPort.mo
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/Tester/Test_GasMultiPort.mo
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/Tester/Test_LiquidMultiPort.mo
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/Tester/Test_VLEMultiPort.mo
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/Tester/package.mo
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/Tester/package.order
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/VLEMultiPort.mo
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/package.mo
 create mode 100644 SorpLib/Components/Fittings/MultiPorts/package.order
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/ConstantLambda.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/Kast.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/LinearLambda.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/QuadraticLambda.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/ZeroFriction.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/package.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/package.order
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Blasius.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Colebrook.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/ConstantLambda.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Konakov.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/LinearLambda.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/MishraGupaSchmidt.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/PrandtlKarman.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/QuadraticLambda.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/ZeroFriction.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/package.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/package.order
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/ZeroFriction.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/package.mo
 create mode 100644 SorpLib/Components/Fittings/PressureLossCorrelations/package.order
 create mode 100644 SorpLib/Components/Fittings/Records/FluidProperties.mo
 create mode 100644 SorpLib/Components/Fittings/Records/GeometryGenericReistance.mo
 create mode 100644 SorpLib/Components/Fittings/Records/GeometryOpenAdsorber.mo
 create mode 100644 SorpLib/Components/Fittings/Records/GeometryTube.mo
 create mode 100644 SorpLib/Components/Fittings/Records/package.mo
 create mode 100644 SorpLib/Components/Fittings/Records/package.order
 create mode 100644 SorpLib/Components/Fittings/Resistors/GasGenericResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/GasOpenAdsorberResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/GasTubeResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/LiquidGenericResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/LiquidTubeResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_GasGenericResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_GasOpenAdsorberResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_GasTubeResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureGenericResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureOpenAdsorberResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureTubeResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_LiquidGenericResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_LiquidTubeResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_VLEGenericResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/Test_VLETubeResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/package.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/Tester/package.order
 create mode 100644 SorpLib/Components/Fittings/Resistors/VLEGenericResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/VLETubeResistance.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/package.mo
 create mode 100644 SorpLib/Components/Fittings/Resistors/package.order
 create mode 100644 SorpLib/Components/Fittings/TJunctions/GasMixtureTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/GasTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/GasVaporMixtureTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/LiquidTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/Tester/Test_GasMixtureTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/Tester/Test_GasTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/Tester/Test_GasVaporMixtureTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/Tester/Test_LiquidTJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/Tester/Test_VLETJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/Tester/package.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/Tester/package.order
 create mode 100644 SorpLib/Components/Fittings/TJunctions/VLETJunction.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/package.mo
 create mode 100644 SorpLib/Components/Fittings/TJunctions/package.order
 create mode 100644 SorpLib/Components/Fittings/package.mo
 create mode 100644 SorpLib/Components/Fittings/package.order
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/AdsorberDP.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/AdsorberDX.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/SimpleAdsorberDP.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/SimpleAdsorberDX.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_AdsorberDP.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_AdsorberDX.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_SimpleAdsorberDP.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_SimpleAdsorberDX.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/Tester/package.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/Tester/package.order
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/package.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Adsorbers/package.order
 create mode 100644 SorpLib/Components/HeatExchanger/BaseClasses/PartialHeatExchanger.mo
 create mode 100644 SorpLib/Components/HeatExchanger/BaseClasses/PartialPureComponentAdsorber.mo
 create mode 100644 SorpLib/Components/HeatExchanger/BaseClasses/PartialPureSimpleComponentAdsorber.mo
 create mode 100644 SorpLib/Components/HeatExchanger/BaseClasses/PartialSimpleCondenserEvaporator.mo
 create mode 100644 SorpLib/Components/HeatExchanger/BaseClasses/PartialSimpleDryCooler.mo
 create mode 100644 SorpLib/Components/HeatExchanger/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/HeatExchanger/BaseClasses/package.order
 create mode 100644 SorpLib/Components/HeatExchanger/CondensersEvaporators/SimpleCondenser.mo
 create mode 100644 SorpLib/Components/HeatExchanger/CondensersEvaporators/SimpleEvaporator.mo
 create mode 100644 SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/Test_SimpleCondenser.mo
 create mode 100644 SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/Test_SimpleEvaporator.mo
 create mode 100644 SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/package.mo
 create mode 100644 SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/package.order
 create mode 100644 SorpLib/Components/HeatExchanger/CondensersEvaporators/package.mo
 create mode 100644 SorpLib/Components/HeatExchanger/CondensersEvaporators/package.order
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/HXGeometry.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/package.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/package.order
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HXAirAirParallelflow.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/HeatTransfer.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/ConstantAlpha.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.order
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/package.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/package.order
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/package.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/package.order
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/VDIWaermeatlasN6.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/package.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/package.order
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/TestAirAirHX.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/package.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/package.order
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/package.mo
 delete mode 100644 SorpLib/Components/HeatExchanger/HXAirAirParallelflow/package.order
 create mode 100644 SorpLib/Components/HeatExchanger/Recoolers/SimpleDryCooler.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Recoolers/Tester/Test_SimpleDryCooler.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Recoolers/Tester/package.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Recoolers/Tester/package.order
 create mode 100644 SorpLib/Components/HeatExchanger/Recoolers/package.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Recoolers/package.order
 create mode 100644 SorpLib/Components/HeatExchanger/Records/GeometryClosedAdsorber.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Records/GeometryCondenserEvaporator.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Records/ParametrizationDryCooler.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Records/SummaryClosedAdsorber.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Records/SummaryCondenserEvaporator.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Records/SummarySimpleClosedAdsorber.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Records/package.mo
 create mode 100644 SorpLib/Components/HeatExchanger/Records/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialClosedAdsorberHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialConductiveHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialGenericHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialOpenAdsorberHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialPoolBoilingHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialPoolCondensationHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialRadiationHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/PartialTubeInsideHeatTransferCoefficient.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/BaseClasses/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/ClosedAdsorberHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/ConductionHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/GenericHeatTransfer.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ConstantAlpha.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ConstantAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ExponentialAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/LinearAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/PolynomialAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantCylindricalWall.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantPlainWall.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantResistance.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/CylindricalWall.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/PlainWall.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ConstantAlpha.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ConstantAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ExponentialAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/LinearAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/PolynomialAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/CasingGasKast.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/CasingSorbentKast.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/ConstantAlpha.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/ConstantAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/ConstantAlpha.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/ConstantAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/LinearAlphaA_T.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/LinearAlphaA_fRel.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/ConstantAlpha.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/ConstantAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/LinearAlphaA_T.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/LinearAlphaA_fRel.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/ConstantResistance.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/GrayCylinderInGrayCylinder.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/ParallelGraySurfaces.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/ConstantAlpha.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/ConstantAlphaA.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/GnielinskiDittusBoelter.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/Schmidt.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/package.order
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/ConstantAlpha.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/ConstantAlphaA.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/PartialHeatTransfer.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/package.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/package.order
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/HeatTransferSilicaGel_Lanzerath2015.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/HeatTransferZeolith13X_Lanzerath2015.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/package.order
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/package.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/HeatTransferPhenomena/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/OpenAdsorberHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/PoolBoilingHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/PoolCondensationHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/RadiationHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Records/FluidProperties.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Records/GeometryClosedAdsorber.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Records/GeometryOpenAdsorber.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Records/GeometryTube.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Records/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Records/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/Test_ClosedAdsorberHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/Test_ConductionHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/Test_GenericHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/Test_OpenAdsorberHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/Test_PoolBoilingHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/Test_PoolCondensationHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/Test_RadiationHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/Test_TubeInsideHeatTransfer.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/package.mo
 create mode 100644 SorpLib/Components/HeatTransfer/Tester/package.order
 delete mode 100644 SorpLib/Components/HeatTransfer/Testers/TestHeatTransfer1.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/Testers/TestHeatTransfer2.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/Testers/package.mo
 delete mode 100644 SorpLib/Components/HeatTransfer/Testers/package.order
 create mode 100644 SorpLib/Components/HeatTransfer/TubeInsideHeatTransfer.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransfer.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficient.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficientClosedAdsorberDP.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficientClosedAdsorberDX.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransfer.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransferDP.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransferDX.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/BaseClasses/package.order
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/ConstantCoefficient.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/ConstantSpecificCoefficient.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/Glueckauf.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/GlueckaufArrhenius.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/package.order
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/ConstantCoefficient.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/ConstantSpecificCoefficient.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPackedBedSpheres.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPorousMedia.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/KnudsenDiffusion.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/KnudsenDiffusionPoiseuilleFlow.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/LaminarConnections.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/PoiseuilleFlow.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/package.order
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/package.order
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/OpenAdsorber/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/OpenAdsorber/package.order
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferDiffusion.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferDiffusionFlow.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferFlow.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantCoefficient_dp.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantCoefficient_dx.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantSpecificCoefficient_dp.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantSpecificCoefficient_dx.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/DarcyPackedBed_Spheres_dp.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/DarcyPorousMedia_dp.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/GlueckaufArrhenius_dx.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Glueckauf_dx.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Laminar_dp.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/PartialMassTransfer_dp.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/PartialMassTransfer_dx.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_SilicaGel.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_Zeolite13X_ads.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_Zeolite13X_des.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/SakodaSuzuki1984_SilicaGel.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/FlowRes_Lanzerath_ads.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/FlowRes_Lanzerath_des.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/MassTransferPhenomena/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/Partial/PartialMassTransfer.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Partial/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Partial/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_SilicaGel.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_Zeolite13X_ads.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_Zeolite13X_des.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/SakodaSuzuki1984_SilicaGel.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/Record/FlowCoefficients/FlowRes_Lanzerath_ads.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/FlowCoefficients/FlowRes_Lanzerath_des.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/FlowCoefficients/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/FlowCoefficients/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/Record/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Record/package.order
 create mode 100644 SorpLib/Components/MassTransfer/Records/FluidProperties.mo
 create mode 100644 SorpLib/Components/MassTransfer/Records/GeometryClosedAdsorber.mo
 create mode 100644 SorpLib/Components/MassTransfer/Records/GeometryOpenAdsorber.mo
 create mode 100644 SorpLib/Components/MassTransfer/Records/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/Records/package.order
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusion1.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow1.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow2.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow3.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow1.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow2.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow3.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow4.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/package.mo
 delete mode 100644 SorpLib/Components/MassTransfer/Testers/package.order
 create mode 100644 SorpLib/Components/MassTransfer/VLEMassTransfers/ClosedAdsorberMassTransferDP.mo
 create mode 100644 SorpLib/Components/MassTransfer/VLEMassTransfers/ClosedAdsorberMassTransferDX.mo
 create mode 100644 SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/Test_ClosedAdsorberMassTransferDP.mo
 create mode 100644 SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/Test_ClosedAdsorberMassTransferDX.mo
 create mode 100644 SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/package.order
 create mode 100644 SorpLib/Components/MassTransfer/VLEMassTransfers/package.mo
 create mode 100644 SorpLib/Components/MassTransfer/VLEMassTransfers/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/Geometry/CylindricAdsorber.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/Geometry/GeneralAdsorberGeometry.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/Geometry/RectangularAdsorber.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/Geometry/package.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/Geometry/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/HeatTransfer.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/MassTransferDiffusion.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedGas_HougenMarshall1947.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedGas_Kast1988.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedWall_Kast1988.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/PackedBedGas_HougenMarshall1947.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/PackedBedGas_Kast1988.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/package.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/package.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/package.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/OpenAdsorber.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/PressureDropCorrelations/PackedBed_Kast1988.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/PressureDropCorrelations/Partial/PartialPressureDrop.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/PressureDropCorrelations/Partial/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/PressureDropCorrelations/package.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/PressureDropCorrelations/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/Testers/TestOpenAdsorber.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/Testers/TestOpenAdsorber2.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/Testers/package.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/Testers/package.order
 delete mode 100644 SorpLib/Components/OpenAdsorber/package.mo
 delete mode 100644 SorpLib/Components/OpenAdsorber/package.order
 create mode 100644 SorpLib/Components/Pumps/AffinityPump.mo
 create mode 100644 SorpLib/Components/Pumps/BaseClasses/PartialAffinityPump.mo
 create mode 100644 SorpLib/Components/Pumps/BaseClasses/PartialPump.mo
 create mode 100644 SorpLib/Components/Pumps/BaseClasses/PartialSimplePump.mo
 create mode 100644 SorpLib/Components/Pumps/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/Pumps/BaseClasses/package.order
 create mode 100644 SorpLib/Components/Pumps/SimplePump.mo
 create mode 100644 SorpLib/Components/Pumps/Tester/Test_AffinityPump.mo
 create mode 100644 SorpLib/Components/Pumps/Tester/Test_SimplePump.mo
 create mode 100644 SorpLib/Components/Pumps/Tester/package.mo
 create mode 100644 SorpLib/Components/Pumps/Tester/package.order
 create mode 100644 SorpLib/Components/Pumps/package.mo
 create mode 100644 SorpLib/Components/Pumps/package.order
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/DensitySensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFractionSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFractionsSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/PressureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/PressureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/SpecificEnthalpySensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/SpecificEntropySensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/TemperatureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/TemperatureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/ThermodynamicStateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/VolumeFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/package.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/FluidMSL/package.order
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/PartialAbsoluteFluidSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/PartialFlowFluidSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/PartialRelativeFluidSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/PartialSensor.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/Sensors/BaseClasses/package.order
 create mode 100644 SorpLib/Components/Sensors/GasSensors/DensitySensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/MassFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/MassFractionSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/MassFractionsSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/PressureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/PressureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/SpecificEnthalpySensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/SpecificEntropySensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/TemperatureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/TemperatureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/Tester/Test_GasSensors.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/Tester/package.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/Tester/package.order
 create mode 100644 SorpLib/Components/Sensors/GasSensors/ThermodynamicStateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/VolumeFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/package.mo
 create mode 100644 SorpLib/Components/Sensors/GasSensors/package.order
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/DensitySensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFractionSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFractionsSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/PressureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/PressureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/RelativeHumiditySensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/SpecificEnthalpySensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/SpecificEntropySensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/TemperatureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/TemperatureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/Test_GasSensors.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/package.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/package.order
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/ThermodynamicStateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/VolumeFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/package.mo
 create mode 100644 SorpLib/Components/Sensors/GasVaporMixtureSenors/package.order
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/DensitySensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/MassFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/MassFractionSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/MassFractionsSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/PressureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/PressureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/SpecificEnthalpySensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/SpecificEntropySensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/TemperatureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/TemperatureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/Tester/Test_LiquidSensors.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/Tester/package.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/Tester/package.order
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/ThermodynamicStateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/VolumeFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/package.mo
 create mode 100644 SorpLib/Components/Sensors/LiquidSensors/package.order
 create mode 100644 SorpLib/Components/Sensors/ThermalSensors/DifferenceTemperatureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/ThermalSensors/HeatFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/ThermalSensors/TemperatureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/ThermalSensors/Tester/Test_ThermalSensors.mo
 create mode 100644 SorpLib/Components/Sensors/ThermalSensors/Tester/package.mo
 create mode 100644 SorpLib/Components/Sensors/ThermalSensors/Tester/package.order
 create mode 100644 SorpLib/Components/Sensors/ThermalSensors/package.mo
 create mode 100644 SorpLib/Components/Sensors/ThermalSensors/package.order
 create mode 100644 SorpLib/Components/Sensors/VLESensors/DensitySensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/MassFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/MassFractionSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/MassFractionsSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/PressureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/PressureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/SpecificEnthalpySensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/SpecificEntropySensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/TemperatureDifferenceSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/TemperatureSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/Tester/Test_VLESensors.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/Tester/package.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/Tester/package.order
 create mode 100644 SorpLib/Components/Sensors/VLESensors/ThermodynamicStateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/VaporQualitySensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/VolumeFlowRateSensor.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/package.mo
 create mode 100644 SorpLib/Components/Sensors/VLESensors/package.order
 create mode 100644 SorpLib/Components/Sensors/package.mo
 create mode 100644 SorpLib/Components/Sensors/package.order
 create mode 100644 SorpLib/Components/Tubes/BaseClasses/PartialTube.mo
 create mode 100644 SorpLib/Components/Tubes/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/Tubes/BaseClasses/package.order
 create mode 100644 SorpLib/Components/Tubes/LiquidTube.mo
 create mode 100644 SorpLib/Components/Tubes/Records/GeometryTube.mo
 create mode 100644 SorpLib/Components/Tubes/Records/package.mo
 create mode 100644 SorpLib/Components/Tubes/Records/package.order
 create mode 100644 SorpLib/Components/Tubes/Tester/Test_LiquidTube.mo
 create mode 100644 SorpLib/Components/Tubes/Tester/package.mo
 create mode 100644 SorpLib/Components/Tubes/Tester/package.order
 create mode 100644 SorpLib/Components/Tubes/package.mo
 create mode 100644 SorpLib/Components/Tubes/package.order
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialCompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialCompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialCondensateRefluxValve.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialIncompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialIncompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialOrificeValve.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialValve.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/PartialValveCharacteristic.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/package.mo
 create mode 100644 SorpLib/Components/Valves/BaseClasses/package.order
 create mode 100644 SorpLib/Components/Valves/GasValves/CompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/GasValves/CompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/GasValves/Tester/Test_CompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/GasValves/Tester/Test_CompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/GasValves/Tester/package.mo
 create mode 100644 SorpLib/Components/Valves/GasValves/Tester/package.order
 create mode 100644 SorpLib/Components/Valves/GasValves/package.mo
 create mode 100644 SorpLib/Components/Valves/GasValves/package.order
 create mode 100644 SorpLib/Components/Valves/LiquidValves/IncompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/LiquidValves/IncompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/LiquidValves/Tester/Test_IncompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/LiquidValves/Tester/Test_IncompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/LiquidValves/Tester/package.mo
 create mode 100644 SorpLib/Components/Valves/LiquidValves/Tester/package.order
 create mode 100644 SorpLib/Components/Valves/LiquidValves/package.mo
 create mode 100644 SorpLib/Components/Valves/LiquidValves/package.order
 create mode 100644 SorpLib/Components/Valves/Utilities/Limiter.mo
 create mode 100644 SorpLib/Components/Valves/Utilities/mixStreamVariables.mo
 create mode 100644 SorpLib/Components/Valves/Utilities/package.mo
 create mode 100644 SorpLib/Components/Valves/Utilities/package.order
 create mode 100644 SorpLib/Components/Valves/VLEValves/CompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/CompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/CondensateRefluxValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/IncompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/IncompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/Tester/Test_CompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/Tester/Test_CompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/Tester/Test_CondensateRefluxValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/Tester/Test_IncompressibleThreeWayValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/Tester/Test_IncompressibleValve.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/Tester/package.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/Tester/package.order
 create mode 100644 SorpLib/Components/Valves/VLEValves/package.mo
 create mode 100644 SorpLib/Components/Valves/VLEValves/package.order
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/Partial/PartialValve.mo
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/Partial/package.mo
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/Partial/package.order
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/Testers/TestValveConstantFillingLevel.mo
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/Testers/package.mo
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/Testers/package.order
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/ValveConstantFillingLevel.mo
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/package.mo
 delete mode 100644 SorpLib/Components/Valves/VLE_Valves/package.order
 create mode 100644 SorpLib/Components/Valves/ValveCharacteristics/Tester/Test_AllValveCharacteristics.mo
 create mode 100644 SorpLib/Components/Valves/ValveCharacteristics/Tester/package.mo
 create mode 100644 SorpLib/Components/Valves/ValveCharacteristics/Tester/package.order
 create mode 100644 SorpLib/Components/Valves/ValveCharacteristics/equalPercentageCharacteristic.mo
 create mode 100644 SorpLib/Components/Valves/ValveCharacteristics/linearCharacteristic.mo
 create mode 100644 SorpLib/Components/Valves/ValveCharacteristics/package.mo
 create mode 100644 SorpLib/Components/Valves/ValveCharacteristics/package.order
 create mode 100644 SorpLib/Components/Valves/ValveCharacteristics/quadraticCharacteristic.mo
 create mode 100644 SorpLib/Examples/TwoBedAdsorptionChiller.mo
 create mode 100644 SorpLib/Examples/package.mo
 create mode 100644 SorpLib/Examples/package.order
 create mode 100644 SorpLib/Icons/AdsorberColumnsPackage/package.mo
 create mode 100644 SorpLib/Icons/AdsorberColumnsPackage/package.order
 create mode 100644 SorpLib/Icons/AdsorbersPackage/package.mo
 create mode 100644 SorpLib/Icons/AdsorbersPackage/package.order
 create mode 100644 SorpLib/Icons/CondensersEvaporatorsPackage/package.mo
 create mode 100644 SorpLib/Icons/CondensersEvaporatorsPackage/package.order
 create mode 100644 SorpLib/Icons/ControllerPackage/package.mo
 create mode 100644 SorpLib/Icons/ControllerPackage/package.order
 create mode 100644 SorpLib/Icons/FansPackage/package.mo
 create mode 100644 SorpLib/Icons/FansPackage/package.order
 create mode 100644 SorpLib/Icons/FittingsPackage/package.mo
 create mode 100644 SorpLib/Icons/FittingsPackage/package.order
 create mode 100644 SorpLib/Icons/HeatExchangersPackage/package.mo
 create mode 100644 SorpLib/Icons/HeatExchangersPackage/package.order
 create mode 100644 SorpLib/Icons/HeatTransfersPackage/package.mo
 create mode 100644 SorpLib/Icons/HeatTransfersPackage/package.order
 create mode 100644 SorpLib/Icons/MassTransfersPackage/package.mo
 create mode 100644 SorpLib/Icons/MassTransfersPackage/package.order
 create mode 100644 SorpLib/Icons/MediaPackage/package.mo
 create mode 100644 SorpLib/Icons/MediaPackage/package.order
 create mode 100644 SorpLib/Icons/PumpsPackage/package.mo
 create mode 100644 SorpLib/Icons/PumpsPackage/package.order
 create mode 100644 SorpLib/Icons/RecoolersPackage/package.mo
 create mode 100644 SorpLib/Icons/RecoolersPackage/package.order
 create mode 100644 SorpLib/Icons/SorpLibPackage/package.mo
 create mode 100644 SorpLib/Icons/SorpLibPackage/package.order
 create mode 100644 SorpLib/Icons/TubesPackage/package.mo
 create mode 100644 SorpLib/Icons/TubesPackage/package.order
 create mode 100644 SorpLib/Icons/ValvesPackage/package.mo
 create mode 100644 SorpLib/Icons/ValvesPackage/package.order
 create mode 100644 SorpLib/Icons/VolumesPackage/package.mo
 create mode 100644 SorpLib/Icons/VolumesPackage/package.order
 create mode 100644 SorpLib/Icons/package.mo
 create mode 100644 SorpLib/Icons/package.order
 delete mode 100644 SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/Schmidt.mo
 delete mode 100644 SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/SiederTate.mo
 delete mode 100644 SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/package.mo
 delete mode 100644 SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/package.order
 delete mode 100644 SorpLib/Internals/AdditionalTransferPhenomena/package.mo
 delete mode 100644 SorpLib/Internals/AdditionalTransferPhenomena/package.order
 delete mode 100644 SorpLib/Internals/ClassTypes/ApplicationPackage.mo
 delete mode 100644 SorpLib/Internals/ClassTypes/ComponentPackage.mo
 delete mode 100644 SorpLib/Internals/ClassTypes/InternalPackage.mo
 delete mode 100644 SorpLib/Internals/ClassTypes/ModelPackage.mo
 delete mode 100644 SorpLib/Internals/ClassTypes/PartialPackage.mo
 delete mode 100644 SorpLib/Internals/ClassTypes/Record.mo
 delete mode 100644 SorpLib/Internals/ClassTypes/RecordPackage.mo
 delete mode 100644 SorpLib/Internals/ClassTypes/package.mo
 delete mode 100644 SorpLib/Internals/ClassTypes/package.order
 delete mode 100644 SorpLib/Internals/SmoothTransition/SmoothSwitch.mo
 delete mode 100644 SorpLib/Internals/SmoothTransition/Testers/package.mo
 delete mode 100644 SorpLib/Internals/SmoothTransition/Testers/package.order
 delete mode 100644 SorpLib/Internals/SmoothTransition/package.mo
 delete mode 100644 SorpLib/Internals/SmoothTransition/package.order
 delete mode 100644 SorpLib/Internals/package.mo
 delete mode 100644 SorpLib/Internals/package.order
 delete mode 100644 SorpLib/Internals/systime.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/AQSOAZ02WaterGoldsworthy.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Partial/PartialAdsorbentWater.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Partial/PartialAdsorbentWaterDubinin.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Partial/package.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Partial/package.order
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/SilgelGrace123WaterSchawe.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/SilgelGrace125WaterNunez.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/SilgelGrace125WaterSchawe.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Testers/TestAQSOAZ02WaterGoldsworthy.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace123WaterSchawe.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace125WaterNunez.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace125WaterSchawe.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Testers/TestWorkingPairs_comp.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Testers/TestZeolite13XWaterNunez.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Testers/package.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Testers/package.order
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/Zeolite13XWaterNunez.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/package.mo
 delete mode 100644 SorpLib/Media/AdsorbentAdsorbate/package.order
 delete mode 100644 SorpLib/Media/Functions/CharCurve1Arctan.mo
 delete mode 100644 SorpLib/Media/Functions/CharCurve1Arctan_dWdA.mo
 delete mode 100644 SorpLib/Media/Functions/CharCurve1Arctan_inverse.mo
 delete mode 100644 SorpLib/Media/Functions/CharCurve2Polynomial.mo
 delete mode 100644 SorpLib/Media/Functions/CharCurve2Polynomial_dWdA.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialMulti_h_ads.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_dh_ads_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_dh_ads_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_h_ads.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialTestMulti.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialTestPure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/Test_h_ads_clausiusClapeyron_binary.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/Test_h_ads_clausiusClapeyron_ternary.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_binary_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_ternary_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads_Dubinin.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT_Dubinin.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp_Dubinin.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads_Dubinin.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEnthalpies/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dy.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_p_xyT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_py_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_x_pyT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_y_pxT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dy.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_p_xyT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_py_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_x_pyT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_y_pxT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_A_W.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_A_W_num.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_W_A.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dW_dA.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddW_dA_dA.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddW_dA_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dT_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dp_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dp_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dx_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dx_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_piT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_piT_num.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_xT_num.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_pi_pT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_pi_pT_num.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_x_pT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMulti.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST_N2.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST_N3.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestPure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestPureDubinin.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponents/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponents/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponentsIAST/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponentsIAST/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponents/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponents/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponentsDubinin/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponentsDubinin/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Interfaces/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/py_xT_NewtonRaphson.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_FastIAST.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_NestedLoop.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_NewtonRaphson.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/py_xT_NewtonRaphson.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_FastIAST.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_NestedLoop.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_NewtonRaphson.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/calc_p_i_num_i_den.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/p_i_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/dx_CO2_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/p_i_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/x_H20_pT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/calc_p_i_num_i_den.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/p_i_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_everything.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_mole_fractions.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/calc_p_i_num_i_den_i.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/p_i_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/p_i_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/x_CO2_pT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/x_H20_pT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/dx_CO2_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/p_i_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/x_H20_pT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/p_i_xT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/x_CO2_pTx.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/x_H20_pT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BET/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BET/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BiLangmuir/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BiLangmuir/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininAstakhov/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininAstakhov/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininChebyshevSeriesRaionalOrder33/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininChebyshevSeriesRaionalOrder33/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical1/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical1/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical2/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical2/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininLorentzianCumulative/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininLorentzianCumulative/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininPearsonIV/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininPearsonIV/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Freundlich/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Freundlich/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/GAB/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/GAB/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Henry/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Henry/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Langmuir/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Langmuir/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Sips/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Sips/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_pressure.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_pressureTemperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_temperature.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Toth/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Toth/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/PureComponents/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Records/NumericsIAST.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Records/NumericsIAST_PureComponents.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Records/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Records/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/A_ppsT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/Test_A_ppsT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/dA_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/dA_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dT_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dp_dT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dp_dp.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/p_ApsT.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/Utilities/package.order
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/package.mo
 create mode 100644 SorpLib/Media/Functions/SorptionEquilibria/package.order
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPureIntegrad_cp.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPureIntegrand.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPure_cp.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialTestPure.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/package.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/package.order
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_beta_pT.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dbeta_dT.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dbeta_dp.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_adsorptiveToLiquid_dT.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_adsorptiveToLiquid_dp.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_dT.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dv_dT.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dv_dp.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_h_adsorptiveToLiquid_pT.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_v_pT.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/package.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/package.order
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x_CC.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x_Dubinin.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x_CC.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x_Dubinin.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/package.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/package.order
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/MediumSpecificFunctions/package.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/MediumSpecificFunctions/package.order
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_ChakrabortyEtAl.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_SchwambergerSchmidt.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_WaltonLeVan.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/package.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/package.order
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_ChakrabortyEtAl.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt_Dubinin.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan_Dubinin.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan_clausiusClapeyron.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/package.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/package.order
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/package.mo
 create mode 100644 SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/package.order
 delete mode 100644 SorpLib/Media/Functions/Testers/TestCharCurve1Arctan.mo
 delete mode 100644 SorpLib/Media/Functions/Testers/TestCharCurve2Polynomial.mo
 delete mode 100644 SorpLib/Media/Functions/Testers/package.mo
 delete mode 100644 SorpLib/Media/Functions/Testers/package.order
 create mode 100644 SorpLib/Media/Functions/Utilities/BasesClasses/Partial_ddz_dT_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/BasesClasses/Partial_dz_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/BasesClasses/Partial_int_z_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/BasesClasses/Partial_z_T.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/BasesClasses/package.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/BasesClasses/package.order
 create mode 100644 SorpLib/Media/Functions/Utilities/Testers/Test_cubicSplineInterpolation_T.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/Testers/Test_generalizedFunction_T.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/Testers/Test_linearInterpolation_T.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/Testers/package.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/Testers/package.order
 create mode 100644 SorpLib/Media/Functions/Utilities/calcCubicSplineCoefficients.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/cubicSplineInterpolation_T.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/dcubicSplineInterpolation_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/ddcubicSplineInterpolation_dT_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/ddgeneralizedFunction_dT_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/ddlinearInterpolation_dT_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/dgeneralizedFunction_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/dlinearInterpolation_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/generalizedFunction_T.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/intCubicSplineInterpolation_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/intGeneralizedFunction_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/intLinearInterpolation_dT.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/linearInterpolation_T.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/package.mo
 create mode 100644 SorpLib/Media/Functions/Utilities/package.order
 create mode 100644 SorpLib/Media/IdealGasMixtures/DryAir_N2_O2/package.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/DryAir_N2_O2/package.order
 create mode 100644 SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O/package.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O/package.order
 create mode 100644 SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_CO2_H2O/package.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_CO2_H2O/package.order
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/ddsaturationPressureH2O_dT_dT.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/dsaturationPressureH2O_dT.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/package.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/package.order
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/partialPressures.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/saturationPressureH2O_T.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/specificEnthalpy_i_T.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/specificEntropy_i_pTX.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/package.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Interfaces/package.order
 create mode 100644 SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2_CO2_H2O.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Tester/package.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/Tester/package.order
 create mode 100644 SorpLib/Media/IdealGasMixtures/package.mo
 create mode 100644 SorpLib/Media/IdealGasMixtures/package.order
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryAirMassFractions_dX.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dT_pX.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dX_pT.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dp_TX.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddsaturationPressureH2O_dT_dT.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dT_pX.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dX_pT.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dp_TX.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dmassToMoleFractions_dX.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/drho_dX_ph.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryAirToMoistAirMassBasedProperties.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryAirToMoistAirMassFractions.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryMassFractionSaturation.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dsaturationPressureH2O_dT.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dT_pX.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dX_pT.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dp_TX.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfCondensingComponent.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfLiquidIce.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfNonCondensingComponents.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfSolid.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfVapor.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfCondensingGas.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfLiquid.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfNonCondensingGas.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfSolid.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/massFractionSaturation.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/massFractions_pTxDryPhi.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/moistAirToDryAirMassBasedProperties.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/moistAirToDryAirMassFractions.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/package.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/package.order
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/partialPressures.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/pressure_dTXY.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/relativeHumidity.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/rho_pTXY.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/saturationPressureH2O_T.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEnthalpy_i.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEnthalpy_pTXY.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEntropy_i.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEntropy_pTXY.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacityLiquid.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacitySolid.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacityVapor.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/temperature_phXY.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/temperature_psXY.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/package.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Interfaces/package.order
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_Ar_H2O/package.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_Ar_H2O/package.order
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_CO2_H2O/package.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_CO2_H2O/package.order
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Tester/Test_MoistAir_N2_O2_Ar_H2O.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Tester/Test_MoistAir_N2_O2_CO2_H2O.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Tester/package.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/Tester/package.order
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/package.mo
 create mode 100644 SorpLib/Media/IdealGasVaporMixtures/package.order
 create mode 100644 SorpLib/Media/IdealGases/Ar/package.mo
 create mode 100644 SorpLib/Media/IdealGases/Ar/package.order
 create mode 100644 SorpLib/Media/IdealGases/CH4/package.mo
 create mode 100644 SorpLib/Media/IdealGases/CH4/package.order
 create mode 100644 SorpLib/Media/IdealGases/CO2/package.mo
 create mode 100644 SorpLib/Media/IdealGases/CO2/package.order
 create mode 100644 SorpLib/Media/IdealGases/H2O/package.mo
 create mode 100644 SorpLib/Media/IdealGases/H2O/package.order
 create mode 100644 SorpLib/Media/IdealGases/He/package.mo
 create mode 100644 SorpLib/Media/IdealGases/He/package.order
 create mode 100644 SorpLib/Media/IdealGases/N2/package.mo
 create mode 100644 SorpLib/Media/IdealGases/N2/package.order
 create mode 100644 SorpLib/Media/IdealGases/Ne/package.mo
 create mode 100644 SorpLib/Media/IdealGases/Ne/package.order
 create mode 100644 SorpLib/Media/IdealGases/O2/package.mo
 create mode 100644 SorpLib/Media/IdealGases/O2/package.order
 create mode 100644 SorpLib/Media/IdealGases/Tester/Test_Ar.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/Test_CH4.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/Test_CO2.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/Test_H2O.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/Test_He.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/Test_N2.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/Test_Ne.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/Test_O2.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/package.mo
 create mode 100644 SorpLib/Media/IdealGases/Tester/package.order
 create mode 100644 SorpLib/Media/IdealGases/package.mo
 create mode 100644 SorpLib/Media/IdealGases/package.order
 create mode 100644 SorpLib/Media/Solids/BaseClasses/PartialSolid.mo
 create mode 100644 SorpLib/Media/Solids/BaseClasses/PartialTest.mo
 create mode 100644 SorpLib/Media/Solids/BaseClasses/package.mo
 create mode 100644 SorpLib/Media/Solids/BaseClasses/package.order
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Aluminium.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Copper.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/StainlessSteel_X5CrNi18_10.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Steel_35_8.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Aluminium.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Copper.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_StainlessSteel_X5CrNi18_10.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Steel_35_8.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/package.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/package.order
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/package.mo
 create mode 100644 SorpLib/Media/Solids/MetalsAndMetalAlloys/package.order
 create mode 100644 SorpLib/Media/Solids/Records/AdditionalVariables.mo
 create mode 100644 SorpLib/Media/Solids/Records/StateVariables.mo
 create mode 100644 SorpLib/Media/Solids/Records/package.mo
 create mode 100644 SorpLib/Media/Solids/Records/package.order
 create mode 100644 SorpLib/Media/Solids/Sorbents/GenericSorbent.mo
 create mode 100644 SorpLib/Media/Solids/Sorbents/RDSilicaGel.mo
 create mode 100644 SorpLib/Media/Solids/Sorbents/Testers/Test_GenericSorbent.mo
 create mode 100644 SorpLib/Media/Solids/Sorbents/Testers/Test_RDSilicaGel.mo
 create mode 100644 SorpLib/Media/Solids/Sorbents/Testers/package.mo
 create mode 100644 SorpLib/Media/Solids/Sorbents/Testers/package.order
 create mode 100644 SorpLib/Media/Solids/Sorbents/package.mo
 create mode 100644 SorpLib/Media/Solids/Sorbents/package.order
 create mode 100644 SorpLib/Media/Solids/package.mo
 create mode 100644 SorpLib/Media/Solids/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/BaseClasses/PartialPureCharts.mo
 create mode 100644 SorpLib/Media/WorkingPairs/BaseClasses/PartialPureTest.mo
 create mode 100644 SorpLib/Media/WorkingPairs/BaseClasses/PartialPureWorkingPairs.mo
 create mode 100644 SorpLib/Media/WorkingPairs/BaseClasses/Partial_ddz_dT_dT.mo
 create mode 100644 SorpLib/Media/WorkingPairs/BaseClasses/Partial_dz_dT.mo
 create mode 100644 SorpLib/Media/WorkingPairs/BaseClasses/Partial_z_T.mo
 create mode 100644 SorpLib/Media/WorkingPairs/BaseClasses/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/BaseClasses/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairDubinin.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairGas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairVLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairDubinin.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairGas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairVLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureMediumSpecificFunctions/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureMediumSpecificFunctions/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/AdsorptProperties.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/IsothermCoefficients.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt_CC.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt_Constant.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_WaltonLeVan.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_WaltonLeVan_CC.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_CC.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_Constant.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_Formal.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_CC.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_Constant.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_Formal.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationDubinin/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationDubinin/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationNonDubinin/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationNonDubinin/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Interfaces/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/MultiComponents/Testers/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/MultiComponents/Testers/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/MultiComponents/package.mo
 rename SorpLib/{Components/Cells/Wall => Media/WorkingPairs/MultiComponents}/package.order (61%)
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/CO2_H2O/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/CO2_H2O/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel123_DubininLorentzianCumulative_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel123_DubininLorentzianCumulative_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/Gas/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/Gas/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/VLE/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/VLE/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_exponential1.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_exponential2.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_linear1.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddexponential1_dT_dT.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddexponential2_dT_dT.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddlinear1_dT_dT.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dexponential1_dT.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dexponential2_dT.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dlinear1_dT.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/exponential1.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/exponential2.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/linear1.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/Utilities/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Parametrizations/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/CO2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/CO2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/H2O/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/N2/ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/N2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/N2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/O2/ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/O2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/O2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_SilicaGel_Toth_WangDouglasLeVan2010.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_NaZeolithY_DubininEmpirical2_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelH_DubininPearsonIV_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelN_DubininPearsonIV_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_DubininEmpirical2_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_Toth_WangDouglasLeVan2010_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/TestWorkingPairGas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/TestWorkingPairVLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/Testers/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/WorkingPairGas.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/WorkingPairVLE.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/PureComponents/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/Records/DerivativesPureEntropyBalance.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Records/DerivativesPureIsothermModel.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Records/DerivativesPureMassEnergyBalances.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Records/PropertiesPureAdsorpt.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Records/PropertiesPureAdsorptive.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Records/StateVariables.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Records/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/Records/package.order
 create mode 100644 SorpLib/Media/WorkingPairs/package.mo
 create mode 100644 SorpLib/Media/WorkingPairs/package.order
 create mode 100644 SorpLib/Modules/Controllers/package.mo
 create mode 100644 SorpLib/Modules/Controllers/package.order
 create mode 100644 SorpLib/Modules/package.mo
 create mode 100644 SorpLib/Modules/package.order
 create mode 100644 SorpLib/Numerics/Testers/Test_regSquareWFactors_regSquareWFactors_inv.mo
 create mode 100644 SorpLib/Numerics/Testers/Test_regSquareWFactors_regSquareWFactors_inv_noEvent.mo
 create mode 100644 SorpLib/Numerics/Testers/Test_regSquare_noEvent_regSquare_inv_noEvent.mo
 create mode 100644 SorpLib/Numerics/Testers/Test_regSquare_regSquare_inv.mo
 create mode 100644 SorpLib/Numerics/Testers/Test_regStep.mo
 create mode 100644 SorpLib/Numerics/Testers/Test_regStep_noEvent.mo
 create mode 100644 SorpLib/Numerics/Testers/Test_smoothTransition.mo
 create mode 100644 SorpLib/Numerics/Testers/Test_smoothTransition_noEvent.mo
 create mode 100644 SorpLib/Numerics/Testers/package.mo
 create mode 100644 SorpLib/Numerics/Testers/package.order
 create mode 100644 SorpLib/Numerics/package.mo
 create mode 100644 SorpLib/Numerics/package.order
 create mode 100644 SorpLib/Numerics/regSquare.mo
 create mode 100644 SorpLib/Numerics/regSquareWFactors.mo
 create mode 100644 SorpLib/Numerics/regSquareWFactors_inv.mo
 create mode 100644 SorpLib/Numerics/regSquareWFactors_inv_noEvent.mo
 create mode 100644 SorpLib/Numerics/regSquareWFactors_noEvent.mo
 create mode 100644 SorpLib/Numerics/regSquare_inv.mo
 create mode 100644 SorpLib/Numerics/regSquare_inv_noEvent.mo
 create mode 100644 SorpLib/Numerics/regSquare_noEvent.mo
 create mode 100644 SorpLib/Numerics/regStep.mo
 create mode 100644 SorpLib/Numerics/regStep_noEvent.mo
 create mode 100644 SorpLib/Numerics/smoothTransition.mo
 create mode 100644 SorpLib/Numerics/smoothTransition_der.mo
 create mode 100644 SorpLib/Numerics/smoothTransition_der2.mo
 create mode 100644 SorpLib/Numerics/smoothTransition_der2_noEvent.mo
 create mode 100644 SorpLib/Numerics/smoothTransition_der_noEvent.mo
 create mode 100644 SorpLib/Numerics/smoothTransition_noEvent.mo
 delete mode 100644 SorpLib/Resources/Images/AdsorbensAdsorbate.png
 delete mode 100644 SorpLib/Resources/Images/Adsorbent.png
 delete mode 100644 SorpLib/Resources/Images/ClosedAdsorber.png
 delete mode 100644 SorpLib/Resources/Images/DeltaP.png
 delete mode 100644 SorpLib/Resources/Images/Evaporator.png
 delete mode 100644 SorpLib/Resources/Images/EvpCond.png
 delete mode 100644 SorpLib/Resources/Images/HXAirAir.png
 delete mode 100644 SorpLib/Resources/Images/HeatTransfer.png
 delete mode 100644 SorpLib/Resources/Images/LTT_logo_RWTH_en.png
 delete mode 100644 SorpLib/Resources/Images/MassTransfer.png
 delete mode 100644 SorpLib/Resources/Images/MassTransferDiffusion.png
 delete mode 100644 SorpLib/Resources/Images/MassTransferDiffusionFlow.png
 delete mode 100644 SorpLib/Resources/Images/OpenAdsorber.png
 delete mode 100644 SorpLib/Resources/Images/Sorplib_info.png
 delete mode 100644 SorpLib/Resources/Images/Sorplib_logo.png
 delete mode 100644 SorpLib/Resources/Images/Wall.png
 delete mode 100644 SorpLib/Resources/Images/beta.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_iast_n2.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_iast_n3.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_langmuir.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_mechanistic_toth_gab.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_sips.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_toth.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_toth_gab_s.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_toth_gab_sb.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_multi_wads_toth_gab.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_bet.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_bi_langmuir.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_astakhov.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_chebyshev_series_3_3.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_empirical_1.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_empirical_2.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_chebyshev_3_3.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_cumulativ.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_pearsonIV.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_pearson_iv.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_freundlich.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_gab.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_henry.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_langmuir.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_sips.png
 create mode 100644 SorpLib/Resources/doc/media_functions_equilibria_pure_toth.png
 create mode 100644 SorpLib/Resources/doc/numerics_regSquare.png
 create mode 100644 SorpLib/Resources/doc/numerics_regSquareWFactors.png
 create mode 100644 SorpLib/Resources/doc/numerics_regStep.png
 create mode 100644 SorpLib/Resources/doc/numerics_smoothTransition.png
 delete mode 100644 SorpLib/Scripts/libraryinfo.mos
 create mode 100644 SorpLib/Units/AdsorptionPotential.mo
 create mode 100644 SorpLib/Units/DerDensityByTemperature.mo
 create mode 100644 SorpLib/Units/DerDensityByTemperatureTemperature.mo
 create mode 100644 SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotential.mo
 create mode 100644 SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential.mo
 create mode 100644 SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotentialTemperature.mo
 create mode 100644 SorpLib/Units/DerFilledPoreVolumeByTemperature.mo
 create mode 100644 SorpLib/Units/DerIsobaricExpansionCoefficientByPressure.mo
 create mode 100644 SorpLib/Units/DerIsobaricExpansionCoefficientByTemperature.mo
 create mode 100644 SorpLib/Units/DerMolarAdsorptionPotentialByPressure.mo
 create mode 100644 SorpLib/Units/DerMolarAdsorptionPotentialByPressurePressure.mo
 create mode 100644 SorpLib/Units/DerMolarAdsorptionPotentialByPressureTemperature.mo
 create mode 100644 SorpLib/Units/DerMolarAdsorptionPotentialByTemperature.mo
 create mode 100644 SorpLib/Units/DerMolarAdsorptionPotentialByTemperatureTemperature.mo
 create mode 100644 SorpLib/Units/DerMolarEnthalpyByPressure.mo
 create mode 100644 SorpLib/Units/DerMolarEnthalpyByUptake.mo
 create mode 100644 SorpLib/Units/DerPressureByTemperatureTemperature.mo
 create mode 100644 SorpLib/Units/DerPressureByUptake.mo
 create mode 100644 SorpLib/Units/DerSpecificEnthalpyByPressure.mo
 create mode 100644 SorpLib/Units/DerSpecificEnthalpyByUptake.mo
 create mode 100644 SorpLib/Units/DerSpecificEntropyByPressure.mo
 create mode 100644 SorpLib/Units/DerSpecificEntropyByTemperature.mo
 create mode 100644 SorpLib/Units/DerSpecificEntropyByUptake.mo
 create mode 100644 SorpLib/Units/DerSpecificHeatCapacityByTemperature.mo
 create mode 100644 SorpLib/Units/DerSpecificHeatCapacityByTemperatureTemperature.mo
 create mode 100644 SorpLib/Units/DerSpecificVolumeByPressure.mo
 create mode 100644 SorpLib/Units/DerSpecificVolumeByPressureTemperature.mo
 create mode 100644 SorpLib/Units/DerSpecificVolumeByTemperature.mo
 create mode 100644 SorpLib/Units/DerSpecificVolumeByTemperatureTemperature.mo
 create mode 100644 SorpLib/Units/DerSpecificVolumeByUptake.mo
 create mode 100644 SorpLib/Units/DerThermalConductivityByTemperature.mo
 create mode 100644 SorpLib/Units/DerThermalConductivityByTemperatureTemperature.mo
 create mode 100644 SorpLib/Units/DerUptakeByMolarFraction.mo
 create mode 100644 SorpLib/Units/DerUptakeByPressure.mo
 create mode 100644 SorpLib/Units/DerUptakeByPressurePressure.mo
 create mode 100644 SorpLib/Units/DerUptakeByPressureTemperature.mo
 create mode 100644 SorpLib/Units/DerUptakeByTemperature.mo
 create mode 100644 SorpLib/Units/DerUptakeByTemperatureTemperature.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificEnthalpyByPressure.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificEnthalpyByTemperature.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificEnthalpyByUptake.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificEntropyByPressure.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificEntropyByTemperature.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificEntropyByUptake.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificVolumeByPressure.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificVolumeByTemperature.mo
 create mode 100644 SorpLib/Units/DerUptakeSpecificVolumeByUptake.mo
 create mode 100644 SorpLib/Units/FilledPoreVolume.mo
 create mode 100644 SorpLib/Units/IntegralMolarHeatCapacityByUptake.mo
 create mode 100644 SorpLib/Units/IntegralSpecificHeatCapacityByUptake.mo
 create mode 100644 SorpLib/Units/MolarAdsorptionPotential.mo
 create mode 100644 SorpLib/Units/MolarUptake.mo
 create mode 100644 SorpLib/Units/ReducedSpreadingPressure.mo
 create mode 100644 SorpLib/Units/Uptake.mo
 create mode 100644 SorpLib/Units/package.mo
 create mode 100644 SorpLib/Units/package.order
 create mode 100644 SorpLib/UsersGuide/Connectors/package.mo
 create mode 100644 SorpLib/UsersGuide/Connectors/package.order
 create mode 100644 SorpLib/UsersGuide/Contact/package.mo
 create mode 100644 SorpLib/UsersGuide/Contact/package.order
 create mode 100644 SorpLib/UsersGuide/Conventions/HTMLDocumentation/NamingConvention/package.mo
 create mode 100644 SorpLib/UsersGuide/Conventions/HTMLDocumentation/NamingConvention/package.order
 create mode 100644 SorpLib/UsersGuide/Conventions/HTMLDocumentation/StructureFormat/package.mo
 create mode 100644 SorpLib/UsersGuide/Conventions/HTMLDocumentation/StructureFormat/package.order
 create mode 100644 SorpLib/UsersGuide/Conventions/HTMLDocumentation/package.mo
 create mode 100644 SorpLib/UsersGuide/Conventions/HTMLDocumentation/package.order
 create mode 100644 SorpLib/UsersGuide/Conventions/ModelicaCode/NamingConvention/package.mo
 create mode 100644 SorpLib/UsersGuide/Conventions/ModelicaCode/NamingConvention/package.order
 create mode 100644 SorpLib/UsersGuide/Conventions/ModelicaCode/StructureFormat/package.mo
 create mode 100644 SorpLib/UsersGuide/Conventions/ModelicaCode/StructureFormat/package.order
 create mode 100644 SorpLib/UsersGuide/Conventions/ModelicaCode/package.mo
 create mode 100644 SorpLib/UsersGuide/Conventions/ModelicaCode/package.order
 create mode 100644 SorpLib/UsersGuide/Conventions/package.mo
 create mode 100644 SorpLib/UsersGuide/Conventions/package.order
 create mode 100644 SorpLib/UsersGuide/Overview/package.mo
 create mode 100644 SorpLib/UsersGuide/Overview/package.order
 create mode 100644 SorpLib/UsersGuide/ReleaseNotes/package.mo
 create mode 100644 SorpLib/UsersGuide/ReleaseNotes/package.order

diff --git a/README.md b/README.md
index 7c3e961..570a8b9 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,9 @@ The library provides basic models necessary to model adsorption energy systems.
 
 ### Dependencies
 
-Regarding non-adsorption specific models, the library partly depends on the [TIL Suite](https://www.tlk-thermo.com/index.php/de/softwareprodukte/til-suite) and the [TIL Media Suite](https://www.tlk-thermo.com/index.php/de/softwareprodukte/tilmedia-suite):
+This library was mainly developed using Dymola. Additionally, it was checked that most models also work with OpenModelica.
+
+Regarding non-adsorption specific models, the library depends on the Modelica Standard Library. The comercial libraries [TIL Suite](https://www.tlk-thermo.com/index.php/de/softwareprodukte/til-suite) and [TIL Media Suite](https://www.tlk-thermo.com/index.php/de/softwareprodukte/tilmedia-suite) are not used within this branch:
 
 *TIL Suite is suitable for the stationary and transient simulation of freely configurable thermodynamic systems. Thanks to the substance property library, TILMedia – a component of the TIL Suite – system simulations can be performed extremely quickly and accurately.*
 
@@ -27,12 +29,17 @@ TIL and TILMedia are commercial libraries provided by [TLK-Thermo GmbH](https://
 
 ### Version
 
-The current version 0.1.0 is a pre-release.
+The current version 0.2.0 is a pre-release.
 
 ### How to cite SorpLib
 
 Please cite **SorpLib** as follows:
 
+- Mirko Engelpracht, Patrik Postweiler, Daniel Rezo, Niklas von der Assen. 
+  SorpLib: An open-source Modelica library for dynamic modelling and optimization of adsorption-based process and energy systems. 
+  In: RWTH Git respository, Institute of Technical Thermodynamics (LTT), RWTH Aachen University, 2025. 
+  [link](https://git.rwth-aachen.de/ltt/SorpLib/-/tree/SorpLib_V3_OpenModelica)
+  
 - Uwe Bau, Franz Lanzerath, Manuel Gräber, Heike Schreiber, Niklas Thielen, André Bardow.
   Adsorption energy systems library - Modeling adsorption based chillers, heat pumps, thermal storages and desiccant systems. 
   In: H. Tummescheit und K.-E. Årzén, Hg. Proceedings of the 10th International Modelica Conference. Linköping: Modelica Association, 2014, S. 875-883. ISBN 9789175193809.
diff --git a/SorpLib/Applications/AdsorptionChillers/ChillerTwoBed1.mo b/SorpLib/Applications/AdsorptionChillers/ChillerTwoBed1.mo
deleted file mode 100644
index 68b04f0..0000000
--- a/SorpLib/Applications/AdsorptionChillers/ChillerTwoBed1.mo
+++ /dev/null
@@ -1,380 +0,0 @@
-within SorpLib.Applications.AdsorptionChillers;
-model ChillerTwoBed1
-
-  Components.EvpCond.EvpCond evaporator(
-    nports=2,
-    enableHeatPort=false,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    enableCasing=true,
-    nCells=10,
-    freeVolume(displayUnit="l") = 0.003,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Copper,
-    massCasing=1,
-    redeclare model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    includeDefaultSummary=true,
-    generateEventsAtFlowReversal=false,
-    kports=1,
-    redeclare model VLESideHeatTransferModel =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=3000),
-    redeclare model HeatTransferModel_InternalCoupling =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=50),
-    redeclare record TubeGeometry =
-        Components.EvpCond.Geometry.EvpLanzerath2014 (length=3),
-    TInitial=283.15,
-    hx_TInitialCell1=283.15,
-    hx_TInitialCelln=283.15,
-    hx_TInitialWall=283.15,
-    TInitialCasing=283.15)
-    annotation (Placement(transformation(extent={{-15,-76},{15,-64}})));
-
-  Components.EvpCond.EvpCond condenser(
-    nports=2,
-    enableHeatPort=false,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    enableCasing=true,
-    nCells=10,
-    freeVolume(displayUnit="l") = 0.002,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Copper,
-    massCasing=1,
-    redeclare model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model HeatTransferModel_InternalCoupling =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=30),
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.Schmidt,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    includeDefaultSummary=true,
-    generateEventsAtFlowReversal=false,
-    kports=1,
-    redeclare model VLESideHeatTransferModel =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=3000),
-    redeclare record TubeGeometry =
-        Components.EvpCond.Geometry.CondLanzerath2014 (length=4.5),
-    TInitial=303.15,
-    hx_TInitialCell1=303.15,
-    hx_TInitialCelln=303.15,
-    hx_TInitialWall=303.15,
-    TInitialCasing=303.15)
-    annotation (Placement(transformation(extent={{-16,76},{16,64}})));
-
-  Components.ClosedAdsorber.Adsorber adsorber2(
-    enableHeatPort=false,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    enableCasing=true,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Aluminum,
-    redeclare record TubeGeometry =
-        Components.ClosedAdsorber.Geometry.Adsorber_Finned_Tubes_Alu,
-    nCells=10,
-    massCasing=2,
-    redeclare model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model AdsorbentAdsorbateModel =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model HeatTransferModel_HX =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=150),
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    includeDefaultSummary=true,
-    generateEventsAtFlowReversal=false,
-    xInitial=0.1,
-    massAdsorbent=2,
-    redeclare model HeatTransferModel_InternalCoupling =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=6),
-    TInitial=363.15,
-    hx_TInitialCell1=363.15,
-    hx_TInitialCelln=363.15,
-    hx_TInitialWall=363.15,
-    TInitialCasing=363.15)
-    annotation (Placement(transformation(extent={{26,-10},{52,10}})));
-
-  Components.ClosedAdsorber.Adsorber adsorber1(
-    enableHeatPort=false,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    enableCasing=true,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Aluminum,
-    redeclare record TubeGeometry =
-        Components.ClosedAdsorber.Geometry.Adsorber_Finned_Tubes_Alu,
-    nCells=10,
-    massCasing=2,
-    redeclare model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model AdsorbentAdsorbateModel =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model HeatTransferModel_HX =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=150),
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    includeDefaultSummary=true,
-    xInitial=0.1,
-    massAdsorbent=2,
-    redeclare model HeatTransferModel_InternalCoupling =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=6),
-    TInitial=303.15,
-    hx_TInitialCell1=303.15,
-    hx_TInitialCelln=303.15,
-    hx_TInitialWall=303.15,
-    TInitialCasing=303.15)
-    annotation (Placement(transformation(extent={{-24,-10},{-50,10}})));
-
-  Components.MassTransfer.MassTransferDiffusionFlow massTransfer_ads1_evp(
-    isFlap=true,
-    vleFluidType=sim.vleFluidType1,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_flow =
-        Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_ads,
-    inputChoice="dx",
-    redeclare model MassTransfer_diffusion_dx =
-        Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_SilicaGel
-        (m_ads=2)) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=90,
-        origin={-37,-30})));
-
-  Components.MassTransfer.MassTransferDiffusionFlow massTransfer_ads2_evp(
-    isFlap=true,
-    openingDirection=true,
-    vleFluidType=sim.vleFluidType1,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_flow =
-        Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_ads,
-    inputChoice="dx",
-    redeclare model MassTransfer_diffusion_dx =
-        Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_SilicaGel
-        (m_ads=2)) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=90,
-        origin={38,-30})));
-
-  Components.MassTransfer.MassTransferDiffusionFlow massTransfer_ads1_cond(
-    isFlap=true,
-    openingDirection=false,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_flow =
-        Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_des,
-    inputChoice="dx",
-    vleFluidType=sim.vleFluidType1,
-    redeclare model MassTransfer_diffusion_dx =
-        Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_SilicaGel
-        (m_ads=2)) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=270,
-        origin={-38,30})));
-
-  Components.MassTransfer.MassTransferDiffusionFlow massTransfer_ads2_cond(
-    isFlap=true,
-    openingDirection=false,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_flow =
-        Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_des,
-    inputChoice="dx",
-    vleFluidType=sim.vleFluidType1,
-    redeclare model MassTransfer_diffusion_dx =
-        Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_SilicaGel
-        (m_ads=2)) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=270,
-        origin={38,32})));
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1, redeclare
-      TILMedia.LiquidTypes.TILMedia_Water liquidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryAds2B(boundaryType="p")
-    annotation (Placement(transformation(extent={{64,2},{72,22}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryAds2A(
-    use_temperatureInput=true,
-    boundaryType="V_flow",
-    V_flowFixed(displayUnit="l/min") = -0.00016666666666667)
-    annotation (Placement(transformation(extent={{72,-22},{64,-2}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryAds1A(
-    use_temperatureInput=true,
-    boundaryType="V_flow",
-    V_flowFixed(displayUnit="l/min") = -0.00016666666666667)
-    annotation (Placement(transformation(extent={{-72,-22},{-64,-2}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryAds1B(boundaryType="p")
-    annotation (Placement(transformation(extent={{-72,2},{-64,22}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryEvpA(
-    boundaryType="V_flow",
-    V_flowFixed(displayUnit="l/min") = -0.00016666666666667,
-    TFixed=283.15)
-    annotation (Placement(transformation(extent={{-30,-82},{-22,-62}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryEvpB(boundaryType="p")
-    annotation (Placement(transformation(extent={{23,-82},{31,-62}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryCondA(
-    boundaryType="V_flow",
-    use_massFlowRateInput=false,
-    V_flowFixed(displayUnit="l/min") = -0.00016666666666667,
-    TFixed=303.15)
-    annotation (Placement(transformation(extent={{-34,62},{-26,82}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryCondB(boundaryType="p")
-    annotation (Placement(transformation(extent={{25,62},{33,82}})));
-  Components.Valves.VLE_Valves.ValveConstantFillingLevel valve_returnflow(
-    vleFluidType=sim.vleFluidType1,
-    kp=0.1,
-    ls=0.1,
-    l=condenser.volume.l_relative) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=90,
-        origin={-94,-2})));
-  Modelica.Blocks.Sources.Pulse pulse(
-    amplitude=60,
-    offset=303.15,
-    period=1000)
-    annotation (Placement(transformation(extent={{-84,-17},{-78,-11}})));
-  Modelica.Blocks.Sources.Pulse pulse1(
-    amplitude=-60,
-    offset=363.15,
-    period=1000) annotation (Placement(transformation(
-        extent={{-3,-3},{3,3}},
-        rotation=180,
-        origin={81,-14})));
-
-  /*******************Summary**********************/
-public
-  final inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-
-protected
-  record Summary
-    extends TIL.Internals.ClassTypes.Record;
-    Modelica.SIunits.Pressure p_ad_1 if include;
-    Real x_ad_1 if include;
-    Modelica.SIunits.Temperature T_ad_1 if include;
-    Modelica.SIunits.Pressure p_ad_2 if include;
-    Real x_ad_2 if include;
-    Modelica.SIunits.Temperature T_ad_2 if include;
-    Modelica.SIunits.EnthalpyFlowRate H_flow_evaporator if include;
-    Modelica.SIunits.EnthalpyFlowRate H_flow_condenser if include;
-    Modelica.SIunits.EnthalpyFlowRate H_flow_adsorber1 if include;
-    Modelica.SIunits.EnthalpyFlowRate H_flow_adsorber2 if include;
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-
-  end Summary;
-
-  replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    p_ad_1=adsorber1.adsorbent.p,
-    x_ad_1=adsorber1.adsorbent.x,
-    T_ad_1=adsorber1.adsorbent.T,
-    p_ad_2=adsorber2.adsorbent.p,
-    x_ad_2=adsorber2.adsorbent.x,
-    T_ad_2=adsorber2.adsorbent.T,
-    H_flow_evaporator = evaporator.summary.DeltaH_flow_liq,
-    H_flow_condenser = condenser.summary.DeltaH_flow_liq,
-    H_flow_adsorber1 = adsorber1.summary.DeltaH_flow_liq,
-    H_flow_adsorber2 = adsorber2.summary.DeltaH_flow_liq) annotation (Placement(transformation(extent={{77,-97},
-            {97,-77}}, rotation=0)));
-equation
-  connect(massTransfer_ads2_evp.vlePortB, adsorber2.vlePortB) annotation (Line(
-      points={{38,-20.8},{38,-20.8},{38,-7},{39.2,-7}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(adsorber1.vlePortB, massTransfer_ads1_evp.vlePortB) annotation (Line(
-      points={{-37.2,-7},{-37,-7},{-37,-20.8}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(adsorber1.vlePortA, massTransfer_ads1_cond.vlePortB) annotation (Line(
-      points={{-37.2,7.4},{-38,7.4},{-38,20.8}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(adsorber2.vlePortA, massTransfer_ads2_cond.vlePortB) annotation (Line(
-      points={{39.2,7.4},{38,7.4},{38,22.8}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(massTransfer_ads1_cond.vlePortA, condenser.vlePort_vapour[1])
-    annotation (Line(
-      points={{-38,39.1},{-38,39.1},{-38,50},{0,50},{0,65.05}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(condenser.vlePort_vapour[2], massTransfer_ads2_cond.vlePortA)
-    annotation (Line(
-      points={{0,63.55},{0,63.55},{0,50},{38,50},{38,41.1}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(massTransfer_ads2_evp.vlePortA, evaporator.vlePort_vapour[1])
-    annotation (Line(
-      points={{38,-39.1},{38,-52},{0,-52},{0,-65.05}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(evaporator.vlePort_vapour[2], massTransfer_ads1_evp.vlePortA)
-    annotation (Line(
-      points={{0,-63.55},{0,-52},{-37,-52},{-37,-39.1}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(liquidBoundaryAds2A.port, adsorber2.liquidPortA) annotation (Line(
-      points={{68,-12},{60,-12},{60,-4.2},{53,-4.2}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryAds2B.port, adsorber2.liquidPortB) annotation (Line(
-      points={{68,12},{60,12},{60,4},{53,4}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryAds1A.port, adsorber1.liquidPortA) annotation (Line(
-      points={{-68,-12},{-60,-12},{-60,-4.2},{-51,-4.2}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryAds1B.port, adsorber1.liquidPortB) annotation (Line(
-      points={{-68,12},{-60,12},{-60,4},{-51,4}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryEvpA.port, evaporator.liquidPortA) annotation (Line(
-      points={{-26,-72},{-15,-72},{-15,-71.5}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(evaporator.liquidPortB, liquidBoundaryEvpB.port) annotation (Line(
-      points={{15,-71.5},{20.5,-71.5},{20.5,-72},{27,-72}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryCondA.port, condenser.liquidPortA) annotation (Line(
-      points={{-30,72},{-16,72},{-16,71.5}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(condenser.liquidPortB, liquidBoundaryCondB.port) annotation (Line(
-      points={{16,71.5},{22,71.5},{22,72},{29,72}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(valve_returnflow.portB, condenser.vlePort_liquid[1]) annotation (Line(
-      points={{-94,6},{-94,6},{-94,80},{-94,90},{-94,92},{0,92},{0,75.7}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(valve_returnflow.portA, evaporator.vlePort_liquid[1]) annotation (
-      Line(
-      points={{-94,-10},{-94,-10},{-94,-82},{-94,-94},{0,-94},{0,-75.7}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(pulse.y, liquidBoundaryAds1A.T_in) annotation (Line(points={{-77.7,-14},
-          {-77.7,-14},{-72,-14}}, color={0,0,127}));
-  connect(liquidBoundaryAds2A.T_in, pulse1.y)
-    annotation (Line(points={{72,-14},{77.7,-14}}, color={0,0,127}));
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    experiment(StopTime=10000, Interval=1));
-end ChillerTwoBed1;
diff --git a/SorpLib/Applications/AdsorptionChillers/ChillerTwoBed2.mo b/SorpLib/Applications/AdsorptionChillers/ChillerTwoBed2.mo
deleted file mode 100644
index e5c88d0..0000000
--- a/SorpLib/Applications/AdsorptionChillers/ChillerTwoBed2.mo
+++ /dev/null
@@ -1,324 +0,0 @@
-within SorpLib.Applications.AdsorptionChillers;
-model ChillerTwoBed2
-
-  Components.EvpCond.EvpCond evpCond1(
-    nports=1,
-    enableHeatPort=false,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    enableCasing=true,
-    nCells=10,
-    freeVolume(displayUnit="l") = 0.003,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Copper,
-    massCasing=1,
-    redeclare model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    includeDefaultSummary=true,
-    generateEventsAtFlowReversal=false,
-    redeclare model VLESideHeatTransferModel =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=3000),
-    redeclare model HeatTransferModel_InternalCoupling =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=50),
-    redeclare record TubeGeometry =
-        Components.EvpCond.Geometry.EvpLanzerath2014 (length=3),
-    TInitial=283.15,
-    hx_TInitialCell1=283.15,
-    hx_TInitialCelln=283.15,
-    hx_TInitialWall=283.15,
-    TInitialCasing=283.15)
-    annotation (Placement(transformation(extent={{-52,-40},{-22,-28}})));
-
-  Components.ClosedAdsorber.Adsorber adsorber2(
-    enableHeatPort=false,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    enableCasing=true,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Aluminum,
-    redeclare record TubeGeometry =
-        Components.ClosedAdsorber.Geometry.Adsorber_Finned_Tubes_Alu,
-    nCells=10,
-    massCasing=2,
-    redeclare model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model AdsorbentAdsorbateModel =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model HeatTransferModel_HX =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=150),
-    redeclare model HeatTransferModel_InternalCoupling =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=6),
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    includeDefaultSummary=true,
-    generateEventsAtFlowReversal=false,
-    xInitial=0.1,
-    massAdsorbent=2,
-    TInitial=363.15,
-    hx_TInitialCell1=363.15,
-    hx_TInitialCelln=363.15,
-    hx_TInitialWall=363.15,
-    TInitialCasing=363.15)
-    annotation (Placement(transformation(extent={{26,14},{52,34}})));
-
-  Components.ClosedAdsorber.Adsorber adsorber1(
-    enableHeatPort=false,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    enableCasing=true,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Aluminum,
-    redeclare record TubeGeometry =
-        Components.ClosedAdsorber.Geometry.Adsorber_Finned_Tubes_Alu,
-    nCells=10,
-    massCasing=2,
-    redeclare model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model AdsorbentAdsorbateModel =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model HeatTransferModel_HX =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=150),
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    includeDefaultSummary=true,
-    xInitial=0.1,
-    massAdsorbent=2,
-    redeclare model HeatTransferModel_InternalCoupling =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=6),
-    TInitial=303.15,
-    hx_TInitialCell1=303.15,
-    hx_TInitialCelln=303.15,
-    hx_TInitialWall=303.15,
-    TInitialCasing=303.15)
-    annotation (Placement(transformation(extent={{-24,14},{-50,34}})));
-
-  Components.MassTransfer.MassTransferDiffusionFlow massTransfer_ads1_evp(
-    vleFluidType=sim.vleFluidType1,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_flow =
-        Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_ads,
-    inputChoice="dx",
-    redeclare model MassTransfer_diffusion_dx =
-        Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_SilicaGel
-        (m_ads=2),
-    isFlap=false) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=90,
-        origin={-37,-6})));
-
-  Components.MassTransfer.MassTransferDiffusionFlow massTransfer_ads2_evp(
-    vleFluidType=sim.vleFluidType1,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_flow =
-        Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_ads,
-    inputChoice="dx",
-    redeclare model MassTransfer_diffusion_dx =
-        Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_SilicaGel
-        (m_ads=2),
-    isFlap=false) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=90,
-        origin={38,-6})));
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1, redeclare
-      TILMedia.LiquidTypes.TILMedia_Water liquidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryAds2B(boundaryType="p")
-    annotation (Placement(transformation(extent={{64,26},{72,46}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryAds2A(
-    use_temperatureInput=true,
-    boundaryType="V_flow",
-    V_flowFixed(displayUnit="l/min") = -0.00016666666666667)
-    annotation (Placement(transformation(extent={{72,2},{64,22}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryAds1A(
-    use_temperatureInput=true,
-    boundaryType="V_flow",
-    V_flowFixed(displayUnit="l/min") = -0.00016666666666667)
-    annotation (Placement(transformation(extent={{-72,2},{-64,22}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryAds1B(boundaryType="p")
-    annotation (Placement(transformation(extent={{-72,26},{-64,46}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryEvpCond1A(
-    boundaryType="V_flow",
-    V_flowFixed(displayUnit="l/min") = -0.00016666666666667,
-    use_temperatureInput=true)
-    annotation (Placement(transformation(extent={{-67,-46},{-59,-26}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryEvpCond1B(boundaryType=
-       "p") annotation (Placement(transformation(extent={{-14,-46},{-6,-26}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryEvpCond2A(
-    boundaryType="V_flow",
-    use_massFlowRateInput=false,
-    V_flowFixed(displayUnit="l/min") = -0.00016666666666667,
-    use_temperatureInput=true)
-    annotation (Placement(transformation(extent={{5,-46},{13,-26}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryEvpCond2B(boundaryType=
-       "p") annotation (Placement(transformation(extent={{63,-45},{71,-25}})));
-  Modelica.Blocks.Sources.Pulse pulse(
-    amplitude=60,
-    offset=303.15,
-    period=1000)
-    annotation (Placement(transformation(extent={{-84,7},{-78,13}})));
-  Modelica.Blocks.Sources.Pulse pulse1(
-    amplitude=-60,
-    offset=363.15,
-    period=1000) annotation (Placement(transformation(
-        extent={{-3,-3},{3,3}},
-        rotation=180,
-        origin={81,10})));
-  Modelica.Blocks.Sources.Pulse pulse2(
-    period=1000,
-    amplitude=20,
-    offset=283.15)
-    annotation (Placement(transformation(extent={{-80,-41},{-74,-35}})));
-  Modelica.Blocks.Sources.Pulse pulse3(
-    period=1000,
-    amplitude=-20,
-    offset=303.15)
-    annotation (Placement(transformation(extent={{-6,-41},{0,-35}})));
-  Components.EvpCond.EvpCond evpCond2(
-    nports=1,
-    enableHeatPort=false,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    enableCasing=true,
-    nCells=10,
-    freeVolume(displayUnit="l") = 0.003,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Copper,
-    massCasing=1,
-    redeclare model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    includeDefaultSummary=true,
-    generateEventsAtFlowReversal=false,
-    redeclare model VLESideHeatTransferModel =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=3000),
-    redeclare model HeatTransferModel_InternalCoupling =
-        Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=50),
-    redeclare record TubeGeometry =
-        Components.EvpCond.Geometry.EvpLanzerath2014 (length=3),
-    TInitial=283.15,
-    hx_TInitialCell1=283.15,
-    hx_TInitialCelln=283.15,
-    hx_TInitialWall=283.15,
-    TInitialCasing=283.15)
-    annotation (Placement(transformation(extent={{23,-40},{53,-28}})));
-
-  /*******************Summary**********************/
-public
-  final inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-
-protected
-  record Summary
-    extends TIL.Internals.ClassTypes.Record;
-    Modelica.SIunits.Pressure p_ad_1 if include;
-    Real x_ad_1 if include;
-    Modelica.SIunits.Temperature T_ad_1 if include;
-    Modelica.SIunits.Pressure p_ad_2 if include;
-    Real x_ad_2 if include;
-    Modelica.SIunits.Temperature T_ad_2 if include;
-    Modelica.SIunits.EnthalpyFlowRate H_flow_evpcond1 if include;
-    Modelica.SIunits.EnthalpyFlowRate H_flow_evpcond2 if include;
-    Modelica.SIunits.EnthalpyFlowRate H_flow_adsorber1 if include;
-    Modelica.SIunits.EnthalpyFlowRate H_flow_adsorber2 if include;
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-
-  end Summary;
-
-  replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    p_ad_1=adsorber1.adsorbent.p,
-    x_ad_1=adsorber1.adsorbent.x,
-    T_ad_1=adsorber1.adsorbent.T,
-    p_ad_2=adsorber2.adsorbent.p,
-    x_ad_2=adsorber2.adsorbent.x,
-    T_ad_2=adsorber2.adsorbent.T,
-    H_flow_evpcond1 = evpCond1.summary.DeltaH_flow_liq,
-    H_flow_evpcond2 = evpCond2.summary.DeltaH_flow_liq,
-    H_flow_adsorber1 = adsorber1.summary.DeltaH_flow_liq,
-    H_flow_adsorber2 = adsorber2.summary.DeltaH_flow_liq) annotation (Placement(transformation(extent={{77,-97},
-            {97,-77}}, rotation=0)));
-
-equation
-  connect(massTransfer_ads2_evp.vlePortB, adsorber2.vlePortB) annotation (Line(
-      points={{38,3.2},{38,3.2},{38,17},{39.2,17}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(adsorber1.vlePortB, massTransfer_ads1_evp.vlePortB) annotation (Line(
-      points={{-37.2,17},{-37,17},{-37,3.2}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(evpCond1.vlePort_vapour[1], massTransfer_ads1_evp.vlePortA)
-    annotation (Line(
-      points={{-37,-28.3},{-37,-16},{-37,-15.1}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(liquidBoundaryAds2A.port, adsorber2.liquidPortA) annotation (Line(
-      points={{68,12},{60,12},{60,19.8},{53,19.8}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryAds2B.port, adsorber2.liquidPortB) annotation (Line(
-      points={{68,36},{60,36},{60,28},{53,28}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryAds1A.port, adsorber1.liquidPortA) annotation (Line(
-      points={{-68,12},{-60,12},{-60,19.8},{-51,19.8}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryAds1B.port, adsorber1.liquidPortB) annotation (Line(
-      points={{-68,36},{-60,36},{-60,28},{-51,28}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryEvpCond1A.port, evpCond1.liquidPortA) annotation (Line(
-      points={{-63,-36},{-52,-36},{-52,-35.5}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(evpCond1.liquidPortB, liquidBoundaryEvpCond1B.port) annotation (Line(
-      points={{-22,-35.5},{-16.5,-35.5},{-16.5,-36},{-10,-36}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(pulse.y, liquidBoundaryAds1A.T_in) annotation (Line(points={{-77.7,10},
-          {-77.7,10},{-72,10}}, color={0,0,127}));
-  connect(liquidBoundaryAds2A.T_in, pulse1.y)
-    annotation (Line(points={{72,10},{77.7,10}}, color={0,0,127}));
-  connect(pulse2.y, liquidBoundaryEvpCond1A.T_in)
-    annotation (Line(points={{-73.7,-38},{-67,-38}}, color={0,0,127}));
-  connect(evpCond2.liquidPortB, liquidBoundaryEvpCond2B.port) annotation (Line(
-      points={{53,-35.5},{62,-35.5},{62,-35},{67,-35}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryEvpCond2A.port, evpCond2.liquidPortA) annotation (Line(
-      points={{9,-36},{23,-36},{23,-35.5}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryEvpCond2A.T_in, pulse3.y)
-    annotation (Line(points={{5,-38},{0.3,-38}}, color={0,0,127}));
-  connect(massTransfer_ads2_evp.vlePortA, evpCond2.vlePort_vapour[1])
-    annotation (Line(
-      points={{38,-15.1},{38,-15.1},{38,-28.3}},
-      color={153,204,0},
-      thickness=0.5));
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    experiment(StopTime=10000, Interval=1));
-end ChillerTwoBed2;
diff --git a/SorpLib/Applications/AdsorptionChillers/package.mo b/SorpLib/Applications/AdsorptionChillers/package.mo
deleted file mode 100644
index 4ac2cfa..0000000
--- a/SorpLib/Applications/AdsorptionChillers/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Applications;
-package AdsorptionChillers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-end AdsorptionChillers;
diff --git a/SorpLib/Applications/AdsorptionChillers/package.order b/SorpLib/Applications/AdsorptionChillers/package.order
deleted file mode 100644
index 8eb2e6b..0000000
--- a/SorpLib/Applications/AdsorptionChillers/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-ChillerTwoBed1
-ChillerTwoBed2
diff --git a/SorpLib/Applications/DesiccantSystem/DesiccantSystem.mo b/SorpLib/Applications/DesiccantSystem/DesiccantSystem.mo
deleted file mode 100644
index 639c3d9..0000000
--- a/SorpLib/Applications/DesiccantSystem/DesiccantSystem.mo
+++ /dev/null
@@ -1,141 +0,0 @@
-within SorpLib.Applications.DesiccantSystem;
-model DesiccantSystem
-
-  Components.OpenAdsorber.OpenAdsorber openAdsorber(
-    nCells=5,
-    redeclare model PressureDropModel =
-        Components.Cells.Gas.PressureDropCorrelations.ZeroPressureDrop,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model WallMaterial = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model HeatTransfer_gasWall =
-        Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedWall_Kast1988,
-    xInitial=0.2,
-    HydraulicMassFlowPosition="gas port A",
-    redeclare Components.OpenAdsorber.Geometry.CylindricAdsorber
-      adsorberGeometry(
-      psi=0.34,
-      bulkDensity=750,
-      particleDiameter=0.002,
-      innerDiameter=0.25,
-      outerDiameter=0.27,
-      length=0.1),
-    redeclare model HeatTransfer_gasAdsorbent =
-        Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedGas_Kast1988,
-    redeclare model MassTransfer_diffusion_dp =
-        Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.MassTransfer.PackedBedGas_Kast1988,
-    generateEventsAtFlowReversal=false,
-    TInitialGas=303.15,
-    pInitial=100000,
-    TInitialAdsorbent=303.15,
-    TInitialWall=303.15)
-    annotation (Placement(transformation(extent={{-22,-14},{2,14}})));
-
-  Components.HeatExchanger.HXAirAirParallelflow.HXAirAirParallelflow
-    hXAirAirCounterflow(
-    nCells=5,
-    redeclare Components.HeatExchanger.HXAirAirParallelflow.Geometry.HXGeometry
-      hxGeometry(
-      heightDuct1=0.01,
-      heightDuct2=0.01,
-      numDucts=20,
-      length=1,
-      width=0.5,
-      tSheet=0.003,
-      tCasing=0.03),
-    redeclare model PressureDrop1 =
-        Components.Cells.Gas.PressureDropCorrelations.ZeroPressureDrop,
-    redeclare model PressureDrop2 =
-        Components.Cells.Gas.PressureDropCorrelations.ZeroPressureDrop,
-    redeclare model WallMaterial = TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model HeatTransferGasWall1 =
-        Components.HeatExchanger.HXAirAirParallelflow.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.ConstantAlpha
-        (constantAlpha=300),
-    redeclare model HeatTransferGasWall2 =
-        Components.HeatExchanger.HXAirAirParallelflow.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.ConstantAlpha
-        (constantAlpha=300),
-    generateEventsAtFlowReversal=true,
-    TInitial1=293.15,
-    TInitial2=293.15,
-    TInitialWall=293.15)
-    annotation (Placement(transformation(extent={{36,-58},{56,-42}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryA(
-    boundaryType="p",
-    use_temperatureInput=true,
-    mixingRatioFixed={0.007,1},
-    pFixed=200000)
-    annotation (Placement(transformation(extent={{-64,-10},{-56,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundary2B(boundaryType="p", pFixed=
-        200000)
-    annotation (Placement(transformation(extent={{-4,-90},{4,-70}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundary1B(
-    boundaryType="m_flow",
-    use_massFlowRateInput=true,
-    pFixed=200000)
-    annotation (Placement(transformation(extent={{84,-30},{76,-10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryB(
-    boundaryType="m_flow",
-    use_massFlowRateInput=true,
-    pFixed=200000)
-    annotation (Placement(transformation(extent={{84,10},{76,30}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundary2A(
-    boundaryType="m_flow",
-    m_flowFixed=-5,
-    pFixed=200000)
-    annotation (Placement(transformation(extent={{76,-90},{84,-70}})));
-  Modelica.Blocks.Sources.Pulse pulse(
-    amplitude=60,
-    period=1000,
-    offset=298.15)
-    annotation (Placement(transformation(extent={{-86,-9},{-80,-3}})));
-  Modelica.Blocks.Sources.Pulse pulse1(
-    period=1000,
-    amplitude=1,
-    offset=0)
-    annotation (Placement(transformation(extent={{100,19},{94,25}})));
-  Modelica.Blocks.Sources.Pulse pulse2(
-    period=1000,
-    amplitude=-1,
-    offset=1.0001)
-    annotation (Placement(transformation(extent={{100,-21},{94,-15}})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1, redeclare
-      TILMedia.GasTypes.TILMedia_MoistAir gasType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-equation
-  connect(gasBoundaryB.port, openAdsorber.gasPortB) annotation (Line(
-      points={{80,20},{20,20},{20,0},{2.2,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gasBoundary1B.port, hXAirAirCounterflow.gasPort1B) annotation (Line(
-      points={{80,-20},{70,-20},{70,-45.2},{56,-45.2}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gasBoundary2B.port, hXAirAirCounterflow.gasPort2B) annotation (Line(
-      points={{0,-80},{20,-80},{20,-54.6},{36,-54.6}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gasBoundary2A.port, hXAirAirCounterflow.gasPort2A) annotation (Line(
-      points={{80,-80},{70,-80},{70,-54.6},{56,-54.6}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(hXAirAirCounterflow.gasPort1A, openAdsorber.gasPortB) annotation (
-      Line(
-      points={{36,-45.2},{20,-45.2},{20,0},{2.2,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gasBoundaryA.port, openAdsorber.gasPortA) annotation (Line(
-      points={{-60,0},{-21.8,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gasBoundaryA.T_in, pulse.y)
-    annotation (Line(points={{-64,-6},{-79.7,-6}}, color={0,0,127}));
-  connect(gasBoundaryB.m_flow_in, pulse1.y)
-    annotation (Line(points={{84,22},{93.7,22}}, color={0,0,127}));
-  connect(gasBoundary1B.m_flow_in, pulse2.y)
-    annotation (Line(points={{84,-18},{93.7,-18}}, color={0,0,127}));
-  annotation (
-    Icon(coordinateSystem(preserveAspectRatio=false)),
-    Diagram(coordinateSystem(preserveAspectRatio=false)),
-    experiment(StopTime=5000));
-end DesiccantSystem;
diff --git a/SorpLib/Applications/DesiccantSystem/package.mo b/SorpLib/Applications/DesiccantSystem/package.mo
deleted file mode 100644
index 9250995..0000000
--- a/SorpLib/Applications/DesiccantSystem/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Applications;
-package DesiccantSystem
-  extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-end DesiccantSystem;
diff --git a/SorpLib/Applications/DesiccantSystem/package.order b/SorpLib/Applications/DesiccantSystem/package.order
deleted file mode 100644
index ff3a19d..0000000
--- a/SorpLib/Applications/DesiccantSystem/package.order
+++ /dev/null
@@ -1 +0,0 @@
-DesiccantSystem
diff --git a/SorpLib/Applications/package.mo b/SorpLib/Applications/package.mo
deleted file mode 100644
index 657f9b5..0000000
--- a/SorpLib/Applications/package.mo
+++ /dev/null
@@ -1,7 +0,0 @@
-within SorpLib;
-package Applications "Applications of adsorption energy systems"
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-annotation (Icon(graphics));
-end Applications;
diff --git a/SorpLib/Applications/package.order b/SorpLib/Applications/package.order
deleted file mode 100644
index 28af932..0000000
--- a/SorpLib/Applications/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-AdsorptionChillers
-DesiccantSystem
diff --git a/SorpLib/Basics/Interfaces/BaseClasses/PartialAdsorbatePort.mo b/SorpLib/Basics/Interfaces/BaseClasses/PartialAdsorbatePort.mo
new file mode 100644
index 0000000..daaf2aa
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/BaseClasses/PartialAdsorbatePort.mo
@@ -0,0 +1,52 @@
+within SorpLib.Basics.Interfaces.BaseClasses;
+partial connector PartialAdsorbatePort
+  "Base model for all adsorbate ports"
+
+  //
+  // Definition of parameters
+  //
+  parameter Integer no_adsorptivs = 1
+    "Number of adsorptivs (i.e., components that can be adsorbed/desorbed)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of connector variables
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure in the adsorbate port";
+
+  flow Modelica.Units.SI.MassFlowRate m_flow
+    "Mass flow rate of the sorbent: If > 0, mass flows from the outside into the 
+    component";
+
+  stream Modelica.Units.SI.SpecificEnthalpy h_outflow
+    "Specific enthalpy: If m_flow < 0, specific enthalpy equals specific enthalpy
+    close to the sorption port";
+  stream SorpLib.Units.Uptake x_outflow[no_adsorptivs]
+    "Loadings m_adsorpt_i/m_sor: If m_flow < 0, loadings equal lpadings close to
+    the adsorbate port";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This connector is the base connector for all adsorbate ports. It defines the pressure
+<i>p</i> as potential variable, the mass flow rate of the sorbent <i>m_flow</i> 
+as flow variable, and the specific enthalpy <i>h_outflow</i> as well as the loadings
+<i>x_outflow</i> as stream variables. Note that the mass flow does not indicate 
+the total mass flow rate, but only the mass flow rate of the sorbent. The mass 
+flow rates of the adsorpt components are calculated as 
+<i>m_flow * actualStram(x_outflow)</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialAdsorbatePort;
diff --git a/SorpLib/Basics/Interfaces/BaseClasses/PartialAdsorptPort.mo b/SorpLib/Basics/Interfaces/BaseClasses/PartialAdsorptPort.mo
new file mode 100644
index 0000000..36c035d
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/BaseClasses/PartialAdsorptPort.mo
@@ -0,0 +1,35 @@
+within SorpLib.Basics.Interfaces.BaseClasses;
+partial connector PartialAdsorptPort
+  "Base model for all adsorpt ports"
+
+  //
+  // Definition of connector variables
+  //
+  SorpLib.Units.Uptake x
+    "Loading";
+
+  flow Modelica.Units.SI.MassFlowRate m_flow
+    "Mass flow rate: If > 0, mass flows from the outside into the component";
+
+  stream Modelica.Units.SI.SpecificEnthalpy h_outflow
+    "Specific enthalpy: If m_flow < 0, specific enthalpy equals specific enthalpy
+    close to the sorption port";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This connector is the base connector for all adsorpt ports. It defines the loading
+<i>x</i> as potential variable, the mass flow rate <i>m_flow</i> as flow variable, 
+and the specific enthalpy <i>h_outflow</i> as stream variable.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialAdsorptPort;
diff --git a/SorpLib/Basics/Interfaces/BaseClasses/PartialFluidPort.mo b/SorpLib/Basics/Interfaces/BaseClasses/PartialFluidPort.mo
new file mode 100644
index 0000000..42ed971
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/BaseClasses/PartialFluidPort.mo
@@ -0,0 +1,51 @@
+within SorpLib.Basics.Interfaces.BaseClasses;
+partial connector PartialFluidPort "Base model for all fluid ports"
+
+  //
+  // Definition of parameters
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of connector variables
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure in the fluid port";
+
+  flow Modelica.Units.SI.MassFlowRate m_flow
+    "Mass flow rate: If > 0, mass flows from the outside into the component.";
+
+  stream Modelica.Units.SI.SpecificEnthalpy h_outflow
+    "Specific enthalpy: If m_flow < 0, specific enthalpy equals specific enthalpy
+    close to the fluid port.";
+  stream Modelica.Units.SI.MassFraction Xi_outflow[no_components-1]
+    "Independent mixture mass fractions m_i/m: If m_flow < 0, mass fractions equal
+     mass fractions close to the fluid port.";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This connector is the base connector for all fluid ports. It defines the pressure
+<i>p</i> as potential variable, the mass flow rate <i>m_flow</i> as flow variable,
+and the specific enthalpy <i>h_outflow</i>, and independent mixture mass fractions
+<i>Xi_outflow</i> as stream variables.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialFluidPort;
diff --git a/SorpLib/Basics/Interfaces/BaseClasses/PartialHeatPort.mo b/SorpLib/Basics/Interfaces/BaseClasses/PartialHeatPort.mo
new file mode 100644
index 0000000..7850409
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/BaseClasses/PartialHeatPort.mo
@@ -0,0 +1,34 @@
+within SorpLib.Basics.Interfaces.BaseClasses;
+partial connector PartialHeatPort
+  "Base model for all heat ports"
+
+  //
+  // Definition of connector variables
+  //
+  Modelica.Units.SI.Temperature T
+    "Temperature in the heat port";
+
+  flow Modelica.Units.SI.HeatFlowRate Q_flow
+    "Heat flow rate: If > 0, heat flows from the outside into the component.";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This connector is the base connector for all heat ports. It defines the temperature
+<i>T</i> as potential variable and the heat flow rate <i>Q_flow</i> as flow variable.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialHeatPort;
diff --git a/SorpLib/Basics/Interfaces/BaseClasses/package.mo b/SorpLib/Basics/Interfaces/BaseClasses/package.mo
new file mode 100644
index 0000000..f446082
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Basics.Interfaces;
+package BaseClasses "Base connectors used to create new interfaces"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial connectors. These partial containg contain fundamental 
+definitions for ports. The content of this package is only of interest when adding 
+new ports to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Basics/Interfaces/BaseClasses/package.order b/SorpLib/Basics/Interfaces/BaseClasses/package.order
new file mode 100644
index 0000000..c803305
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/BaseClasses/package.order
@@ -0,0 +1,4 @@
+PartialHeatPort
+PartialFluidPort
+PartialAdsorbatePort
+PartialAdsorptPort
diff --git a/SorpLib/Basics/Interfaces/FluidPorts/GasPort_in.mo b/SorpLib/Basics/Interfaces/FluidPorts/GasPort_in.mo
new file mode 100644
index 0000000..fc73816
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/FluidPorts/GasPort_in.mo
@@ -0,0 +1,43 @@
+within SorpLib.Basics.Interfaces.FluidPorts;
+connector GasPort_in
+  "Gas port for design inlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="gasPort_in",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={244,125,35},
+        fillColor={244,125,35},
+        fillPattern=FillPattern.Solid), Text(extent={{-150,110},{150,50}},
+          textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={        Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={244,125,35},
+        fillColor={244,125,35},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1)}),
+  Documentation(info="<html>
+<p>
+This connector is used for gas ports at the design inlet. According to the 
+Modelica sign convention, a <strong>positive</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>into</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasPort_in;
diff --git a/SorpLib/Basics/Interfaces/FluidPorts/GasPort_out.mo b/SorpLib/Basics/Interfaces/FluidPorts/GasPort_out.mo
new file mode 100644
index 0000000..208c8cc
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/FluidPorts/GasPort_out.mo
@@ -0,0 +1,55 @@
+within SorpLib.Basics.Interfaces.FluidPorts;
+connector GasPort_out
+  "Gas port for design outlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="gasPort_out",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={
+      Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={244,125,35},
+        fillColor={244,125,35},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{-30,30},{30,-30}},
+        lineColor={0,127,255},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid),
+      Text(extent={{-150,110},{150,50}}, textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={
+      Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={244,125,35},
+        fillColor={244,125,35},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1),
+      Ellipse(
+        extent={{-80,80},{80,-80}},
+        lineColor={244,125,35},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid)}),
+  Documentation(info="<html>
+<p>
+This connector is used for gas ports at the design outlet. According to the 
+Modelica sign convention, a <strong>negative</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>out</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasPort_out;
diff --git a/SorpLib/Basics/Interfaces/FluidPorts/LiquidPort_in.mo b/SorpLib/Basics/Interfaces/FluidPorts/LiquidPort_in.mo
new file mode 100644
index 0000000..3b8d2de
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/FluidPorts/LiquidPort_in.mo
@@ -0,0 +1,43 @@
+within SorpLib.Basics.Interfaces.FluidPorts;
+connector LiquidPort_in
+  "Liquid port for design inlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="liquidPort_in",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={28,108,200},
+        fillColor={28,108,200},
+        fillPattern=FillPattern.Solid), Text(extent={{-150,110},{150,50}},
+          textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={        Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={28,108,200},
+        fillColor={28,108,200},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1)}),
+  Documentation(info="<html>
+<p>
+This connector is used for liquid ports at the design inlet. According to the 
+Modelica sign convention, a <strong>positive</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>into</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LiquidPort_in;
diff --git a/SorpLib/Basics/Interfaces/FluidPorts/LiquidPort_out.mo b/SorpLib/Basics/Interfaces/FluidPorts/LiquidPort_out.mo
new file mode 100644
index 0000000..c465165
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/FluidPorts/LiquidPort_out.mo
@@ -0,0 +1,55 @@
+within SorpLib.Basics.Interfaces.FluidPorts;
+connector LiquidPort_out
+  "Liquid port for design outlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="liquidPort_out",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={
+      Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={28,108,200},
+        fillColor={28,108,200},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{-30,30},{30,-30}},
+        lineColor={0,127,255},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid),
+      Text(extent={{-150,110},{150,50}}, textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={
+      Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={28,108,200},
+        fillColor={28,108,200},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1),
+      Ellipse(
+        extent={{-80,80},{80,-80}},
+        lineColor={28,108,200},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid)}),
+  Documentation(info="<html>
+<p>
+This connector is used for liquid ports at the design outlet. According to the 
+Modelica sign convention, a <strong>negative</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>out</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LiquidPort_out;
diff --git a/SorpLib/Basics/Interfaces/FluidPorts/VLEPort_in.mo b/SorpLib/Basics/Interfaces/FluidPorts/VLEPort_in.mo
new file mode 100644
index 0000000..ec7f5d8
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/FluidPorts/VLEPort_in.mo
@@ -0,0 +1,43 @@
+within SorpLib.Basics.Interfaces.FluidPorts;
+connector VLEPort_in
+  "VLE port for design inlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="VLEPort_in",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={0,140,72},
+        fillColor={0,140,72},
+        fillPattern=FillPattern.Solid), Text(extent={{-150,110},{150,50}},
+          textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={        Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={0,140,72},
+        fillColor={0,140,72},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1)}),
+  Documentation(info="<html>
+<p>
+This connector is used for VLE ports at the design inlet. According to the 
+Modelica sign convention, a <strong>positive</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>into</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end VLEPort_in;
diff --git a/SorpLib/Basics/Interfaces/FluidPorts/VLEPort_out.mo b/SorpLib/Basics/Interfaces/FluidPorts/VLEPort_out.mo
new file mode 100644
index 0000000..1b4f65c
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/FluidPorts/VLEPort_out.mo
@@ -0,0 +1,55 @@
+within SorpLib.Basics.Interfaces.FluidPorts;
+connector VLEPort_out
+  "VLE port for design outlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="VLEPort_out",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={
+      Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={0,140,72},
+        fillColor={0,140,72},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{-30,30},{30,-30}},
+        lineColor={0,127,255},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid),
+      Text(extent={{-150,110},{150,50}}, textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={
+      Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={0,140,72},
+        fillColor={0,140,72},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1),
+      Ellipse(
+        extent={{-80,80},{80,-80}},
+        lineColor={0,140,72},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid)}),
+  Documentation(info="<html>
+<p>
+This connector is used for VLE ports at the design outlet. According to the 
+Modelica sign convention, a <strong>negative</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>out</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end VLEPort_out;
diff --git a/SorpLib/Basics/Interfaces/FluidPorts/package.mo b/SorpLib/Basics/Interfaces/FluidPorts/package.mo
new file mode 100644
index 0000000..95e7daa
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/FluidPorts/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Interfaces;
+package FluidPorts "Package containing fluid ports"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains fluid port connectors.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end FluidPorts;
diff --git a/SorpLib/Basics/Interfaces/FluidPorts/package.order b/SorpLib/Basics/Interfaces/FluidPorts/package.order
new file mode 100644
index 0000000..99f28f4
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/FluidPorts/package.order
@@ -0,0 +1,6 @@
+LiquidPort_in
+LiquidPort_out
+GasPort_in
+GasPort_out
+VLEPort_in
+VLEPort_out
diff --git a/SorpLib/Basics/Interfaces/HeatPorts/HeatPort_in.mo b/SorpLib/Basics/Interfaces/HeatPorts/HeatPort_in.mo
new file mode 100644
index 0000000..2dc0cb5
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/HeatPorts/HeatPort_in.mo
@@ -0,0 +1,42 @@
+within SorpLib.Basics.Interfaces.HeatPorts;
+connector HeatPort_in
+  "Heat port for design inlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialHeatPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="heatPort_in",
+          Icon(graphics={Rectangle(
+          extent={{-80,80},{80,-80}},
+          lineColor={238,46,47},
+          fillColor={238,46,47},
+          fillPattern=FillPattern.Solid,
+          lineThickness=1)}), Diagram(graphics={
+                                          Text(extent={{-150,110},{150,50}},
+            textString="%name"), Rectangle(
+          extent={{-40,40},{40,-40}},
+          lineColor={238,46,47},
+          lineThickness=1,
+          fillColor={238,46,47},
+          fillPattern=FillPattern.Solid)}),
+    Documentation(info="<html>
+<p>
+This connector is used for heat ports at the design inlet. According to the 
+Modelica sign convention, a <strong>positive</strong> heat flow rate 
+<strong>Q_flow</strong> is considered to flow <strong>into</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end HeatPort_in;
diff --git a/SorpLib/Basics/Interfaces/HeatPorts/HeatPort_out.mo b/SorpLib/Basics/Interfaces/HeatPorts/HeatPort_out.mo
new file mode 100644
index 0000000..1e028b1
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/HeatPorts/HeatPort_out.mo
@@ -0,0 +1,55 @@
+within SorpLib.Basics.Interfaces.HeatPorts;
+connector HeatPort_out
+  "Heat port for design outlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialHeatPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="heatPort_out",
+          Icon(graphics={Rectangle(
+          extent={{-90,88},{90,-92}},
+          lineColor={238,46,47},
+          fillColor={238,46,47},
+          fillPattern=FillPattern.Solid,
+          lineThickness=1), Rectangle(
+          extent={{-72,72},{70,-72}},
+          lineColor={255,255,255},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid)}),
+                              Diagram(graphics={
+                                          Text(extent={{-150,110},{150,50}},
+            textString="%name"),
+        Rectangle(
+          extent={{-40,40},{40,-40}},
+          lineColor={238,46,47},
+          lineThickness=1,
+          fillColor={238,46,47},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{-36,36},{36,-36}},
+          lineColor={255,255,255},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid)}),
+    Documentation(info="<html>
+<p>
+This connector is used for heat ports at the design outlet. According to the 
+Modelica sign convention, a <strong>negative</strong> heat flow rate 
+<strong>Q_flow</strong> is considered to flow <strong>out</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end HeatPort_out;
diff --git a/SorpLib/Basics/Interfaces/HeatPorts/package.mo b/SorpLib/Basics/Interfaces/HeatPorts/package.mo
new file mode 100644
index 0000000..e04f163
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/HeatPorts/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Interfaces;
+package HeatPorts "Package containing heat ports"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains heat port connectors.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end HeatPorts;
diff --git a/SorpLib/Basics/Interfaces/HeatPorts/package.order b/SorpLib/Basics/Interfaces/HeatPorts/package.order
new file mode 100644
index 0000000..3cffadd
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/HeatPorts/package.order
@@ -0,0 +1,2 @@
+HeatPort_in
+HeatPort_out
diff --git a/SorpLib/Basics/Interfaces/SorptionPorts/AdsorbatePort_in.mo b/SorpLib/Basics/Interfaces/SorptionPorts/AdsorbatePort_in.mo
new file mode 100644
index 0000000..128c215
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/SorptionPorts/AdsorbatePort_in.mo
@@ -0,0 +1,38 @@
+within SorpLib.Basics.Interfaces.SorptionPorts;
+connector AdsorbatePort_in "Adsorbate port for design inlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialAdsorbatePort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="VLEPort_in",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={0,0,0},
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid), Text(extent={{-150,110},{150,50}},
+          textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={        Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={0,0,0},
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1)}),
+  Documentation(info="<html>
+<p>
+This connector is used for adsorbate ports at the design inlet. According to the 
+Modelica sign convention, a <strong>positive</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>into</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorbatePort_in;
diff --git a/SorpLib/Basics/Interfaces/SorptionPorts/AdsorbatePort_out.mo b/SorpLib/Basics/Interfaces/SorptionPorts/AdsorbatePort_out.mo
new file mode 100644
index 0000000..e474d21
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/SorptionPorts/AdsorbatePort_out.mo
@@ -0,0 +1,50 @@
+within SorpLib.Basics.Interfaces.SorptionPorts;
+connector AdsorbatePort_out "Adsorbate port for design outlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialAdsorbatePort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="VLEPort_out",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={
+      Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={0,0,0},
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{-30,30},{30,-30}},
+        lineColor={0,127,255},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid),
+      Text(extent={{-150,110},{150,50}}, textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={
+      Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={0,0,0},
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1),
+      Ellipse(
+        extent={{-80,80},{80,-80}},
+        lineColor={0,0,0},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid)}),
+  Documentation(info="<html>
+<p>
+This connector is used for adsorbate ports at the design outlet. According to the 
+Modelica sign convention, a <strong>negative</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>out</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorbatePort_out;
diff --git a/SorpLib/Basics/Interfaces/SorptionPorts/AdsorptPort_in.mo b/SorpLib/Basics/Interfaces/SorptionPorts/AdsorptPort_in.mo
new file mode 100644
index 0000000..e648382
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/SorptionPorts/AdsorptPort_in.mo
@@ -0,0 +1,38 @@
+within SorpLib.Basics.Interfaces.SorptionPorts;
+connector AdsorptPort_in "Adsorpt port for design inlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialAdsorptPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="VLEPort_in",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={175,175,175},
+        fillColor={175,175,175},
+        fillPattern=FillPattern.Solid), Text(extent={{-150,110},{150,50}},
+          textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={        Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={175,175,175},
+        fillColor={175,175,175},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1)}),
+  Documentation(info="<html>
+<p>
+This connector is used for adsorpt ports at the design inlet. According to the 
+Modelica sign convention, a <strong>positive</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>into</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorptPort_in;
diff --git a/SorpLib/Basics/Interfaces/SorptionPorts/AdsorptPort_out.mo b/SorpLib/Basics/Interfaces/SorptionPorts/AdsorptPort_out.mo
new file mode 100644
index 0000000..1ef0a4d
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/SorptionPorts/AdsorptPort_out.mo
@@ -0,0 +1,50 @@
+within SorpLib.Basics.Interfaces.SorptionPorts;
+connector AdsorptPort_out "Adsorpt port for design outlet"
+  extends SorpLib.Basics.Interfaces.BaseClasses.PartialAdsorptPort;
+
+  //
+  // Annotations
+  //
+  annotation (defaultComponentName="VLEPort_out",
+            Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
+          -100},{100,100}}), graphics={
+      Ellipse(
+        extent={{-40,40},{40,-40}},
+        lineColor={175,175,175},
+        fillColor={175,175,175},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{-30,30},{30,-30}},
+        lineColor={0,127,255},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid),
+      Text(extent={{-150,110},{150,50}}, textString="%name")}),
+     Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
+          100,100}}), graphics={
+      Ellipse(
+        extent={{-100,100},{100,-100}},
+        lineColor={175,175,175},
+        fillColor={175,175,175},
+        fillPattern=FillPattern.Solid,
+        lineThickness=1),
+      Ellipse(
+        extent={{-80,80},{80,-80}},
+        lineColor={0,0,0},
+        fillColor={255,255,255},
+        fillPattern=FillPattern.Solid)}),
+  Documentation(info="<html>
+<p>
+This connector is used for adsorpt ports at the design outlet. According to the 
+Modelica sign convention, a <strong>negative</strong> mass flow rate 
+<strong>m_flow</strong> is considered to flow <strong>out</strong> a component. 
+This convention has to be used whenever this connector is used in a model class.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorptPort_out;
diff --git a/SorpLib/Basics/Interfaces/SorptionPorts/package.mo b/SorpLib/Basics/Interfaces/SorptionPorts/package.mo
new file mode 100644
index 0000000..31ae4e2
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/SorptionPorts/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Interfaces;
+package SorptionPorts "Package containing sorption ports"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains sorption port connectors.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SorptionPorts;
diff --git a/SorpLib/Basics/Interfaces/SorptionPorts/package.order b/SorpLib/Basics/Interfaces/SorptionPorts/package.order
new file mode 100644
index 0000000..4a01389
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/SorptionPorts/package.order
@@ -0,0 +1,4 @@
+AdsorbatePort_in
+AdsorbatePort_out
+AdsorptPort_in
+AdsorptPort_out
diff --git a/SorpLib/Basics/Interfaces/package.mo b/SorpLib/Basics/Interfaces/package.mo
new file mode 100644
index 0000000..9007d89
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics;
+package Interfaces "Interfaces for models"
+extends Modelica.Icons.InterfacesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package provides definitions of basic connectors used to aggregate more 
+complex models. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Interfaces;
diff --git a/SorpLib/Basics/Interfaces/package.order b/SorpLib/Basics/Interfaces/package.order
new file mode 100644
index 0000000..c0f4e3b
--- /dev/null
+++ b/SorpLib/Basics/Interfaces/package.order
@@ -0,0 +1,4 @@
+BaseClasses
+HeatPorts
+FluidPorts
+SorptionPorts
diff --git a/SorpLib/Basics/Sources/BaseClasses/PartialFluidSource.mo b/SorpLib/Basics/Sources/BaseClasses/PartialFluidSource.mo
new file mode 100644
index 0000000..58a2793
--- /dev/null
+++ b/SorpLib/Basics/Sources/BaseClasses/PartialFluidSource.mo
@@ -0,0 +1,377 @@
+within SorpLib.Basics.Sources.BaseClasses;
+partial model PartialFluidSource
+  "Base model for all fluid sources"
+
+  //
+  // Definition of parameters regarding the boundary type
+  //
+  parameter Integer no_components = 1
+    "Number of components within the medium"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter SorpLib.Choices.BoundaryFluidPotentialFlow boundaryTypePotentialFlow=
+    SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure
+    "Boundary type for potential or flow variable"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BoundaryFluidStreamEnthalpy boundaryTypeStreamEnthalpy=
+    SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy
+    "Boundary type for stream variable of specific enthalpy"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BoundaryFluidStreamMassFractions boundaryTypeStreamMassFractions=
+    SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions
+    "Boundary type for stream variable of mass fractions"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding potential and flow variables
+  //
+  parameter Boolean use_pInput = false
+    " = true, if p is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryTypePotentialFlow ==
+                SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Pressure p_fixed = 1.01325e5
+    "Fixed pressure at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryTypePotentialFlow ==
+                SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure)
+                and not use_pInput));
+
+  parameter Boolean use_mFlowInput = false
+    "=true, if m_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryTypePotentialFlow ==
+                SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_fixed = -0.001
+    "Fixed mass flow rate at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryTypePotentialFlow ==
+                SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate)
+                and not use_mFlowInput));
+
+  parameter Boolean use_VFlowInput = false
+    "=true, if V_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryTypePotentialFlow ==
+                SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.VolumeFlowRate V_flow_fixed = -10/60
+    "Fixed volume flow rate at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryTypePotentialFlow ==
+                SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate)
+                and not use_VFlowInput));
+
+  //
+  // Definition of parameters regarding stream variables of specific enthalpy
+  //
+  parameter Boolean use_hInput = false
+    "=true, if h is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Stream Variables - Specific Enthalpy",
+                enable=(boundaryTypeStreamEnthalpy ==
+                SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.SpecificEnthalpy h_fixed = 350e3
+    "Fixed specific enthalpy at boundary"
+    annotation (Dialog(tab="General",group="Stream Variables - Specific Enthalpy",
+                enable=(boundaryTypeStreamEnthalpy ==
+                SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy)
+                and not use_hInput));
+
+  parameter Boolean use_TInput = false
+    "=true, if T is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Stream Variables - Specific Enthalpy",
+                enable=(boundaryTypeStreamEnthalpy ==
+                SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Temperature T_fixed = 298.15
+    "Fixed temperature at boundary"
+    annotation (Dialog(tab="General",group="Stream Variables - Specific Enthalpy",
+                enable=(boundaryTypeStreamEnthalpy ==
+                SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature)
+                and not use_TInput));
+
+  //
+  // Definition of parameters regarding stream variables of mass fractions
+  //
+  parameter Boolean use_XInput = false
+    "=true, if X is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Stream Variables - Mass Fractions",
+                enable=(boundaryTypeStreamMassFractions ==
+                SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MassFraction[no_components] X_fixed=
+    fill(1/no_components, no_components)
+    "Fixed mass fractions at boundary"
+    annotation (Dialog(tab="General",group="Stream Variables - Mass Fractions",
+                enable=(boundaryTypeStreamMassFractions ==
+                SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions)
+                and not use_XInput));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_small = 1e-5
+    "Regularization value for mass flow rate to handle flow reversal and division
+    by zero"
+    annotation (Dialog(tab = "Advanced", group = "Limiter"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput p_input(final unit="Pa") if
+    (boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure and
+    use_pInput)
+    "Input for pressure"
+     annotation (Placement(transformation(extent={{-120,30},{-80,70}}),
+       iconTransformation(extent={{-22,40},{-2,60}})));
+
+  Modelica.Blocks.Interfaces.RealInput m_flow_input(final unit="kg/s") if
+    (boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate and
+    use_mFlowInput)
+    "Input for mass flow rate"
+    annotation (Placement(transformation(extent={{-120,0},{-80,40}}),
+      iconTransformation(extent={{-22,10},{-2,30}})));
+
+  Modelica.Blocks.Interfaces.RealInput V_flow_input(final unit="m3/s") if
+    (boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate and
+    use_VFlowInput)
+    "Input for volume flow rate"
+    annotation (Placement(transformation(extent={{-120,0},{-80,40}}),
+      iconTransformation(extent={{-22,10},{-2,30}})));
+
+  Modelica.Blocks.Interfaces.RealInput h_input(final unit="J/kg") if
+    (boundaryTypeStreamEnthalpy ==
+    SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy and
+    use_hInput)
+    "Input for specific enthalpy"
+    annotation (Placement(transformation(extent={{-120,0},{-80,-40}}),
+      iconTransformation(extent={{-22,-30},{-2,-10}})));
+
+  Modelica.Blocks.Interfaces.RealInput T_input(final unit="K") if
+    (boundaryTypeStreamEnthalpy ==
+    SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature and
+    use_TInput)
+    "Input for temperature"
+    annotation (Placement(transformation(extent={{-120,0},{-80,-40}}),
+      iconTransformation(extent={{-22,-30},{-2,-10}})));
+
+  Modelica.Blocks.Interfaces.RealInput[no_components] X_input(each final unit="kg/kg") if
+    (boundaryTypeStreamMassFractions ==
+    SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions and
+    use_XInput) "Input for mass fractions"
+    annotation (Placement(transformation(extent={{-120,-30},{-80,-70}}),
+      iconTransformation(extent={{-22,-60},{-2,-40}})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput p_internal(final unit="Pa")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput m_flow_internal(final unit="kg/s")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput V_flow_internal(final unit="m3/s")
+    "Needed for connecting to conditional connector";
+
+  Modelica.Blocks.Interfaces.RealInput h_internal(final unit="J/kg")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput T_internal(final unit="K")
+    "Needed for connecting to conditional connector";
+
+  Modelica.Blocks.Interfaces.RealInput[no_components] X_internal(each final unit="kg/kg")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of protected variables
+  //
+  Modelica.Units.SI.Density d_in
+    "Density calculated with pressure, specific enthalpy, and mass fractions 
+    entering the port";
+  Modelica.Units.SI.Density d_out
+    "Density calculated with pressure, specific enthalpy, and mass fractions 
+    leaving the port";
+  Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy calculated with pressure at port, temperature, and mass
+    fractions";
+
+  //
+  // Definition of ports
+  //
+public
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port
+    constrainedby SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port"
+    annotation (Placement(transformation(extent={{-4,-4},{4,4}})));
+
+equation
+  //
+  // Connectors
+  //
+  connect(p_input,p_internal);
+  connect(m_flow_input,m_flow_internal);
+  connect(V_flow_input,V_flow_internal);
+
+  connect(h_input,h_internal);
+  connect(T_input,T_internal);
+
+  connect(X_input,X_internal);
+
+  if not use_pInput then
+    p_internal = p_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_mFlowInput then
+    m_flow_internal = m_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_VFlowInput then
+    V_flow_internal = V_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  if not use_hInput then
+    h_internal = h_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_TInput then
+    T_internal = T_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  if not use_XInput then
+    X_internal = X_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Properties at port
+  //
+  if boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure then
+    port.p = p_internal
+      "Pressure at port";
+
+  elseif boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate then
+    port.m_flow = m_flow_internal
+      "Mass flow rate at port";
+
+  else
+    if not avoid_events then
+      port.m_flow = V_flow_internal *
+        SorpLib.Numerics.regStep(
+          x=V_flow_internal,
+          y1=d_in,
+          y2=d_out,
+          x_small=m_flow_small*1e-3)
+        "Mass flow rate at port";
+
+    else
+      port.m_flow = V_flow_internal *
+        SorpLib.Numerics.regStep_noEvent(
+          x=V_flow_internal,
+          y1=d_in,
+          y2=d_out,
+          x_small=m_flow_small*1e-3)
+        "Mass flow rate at port";
+
+    end if;
+  end if;
+
+  if boundaryTypeStreamEnthalpy ==
+    SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy then
+    port.h_outflow = h_internal
+      "Specific enthalpy at port";
+
+  else
+    port.h_outflow = h
+      "Specific enthalpy at port";
+
+  end if;
+
+  if boundaryTypeStreamMassFractions ==
+    SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions then
+    port.Xi_outflow = X_internal[1:no_components-1]
+      "Independent mass fractions at port";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model can be used to specify either the pressure or mass flow rate as well
+as the specific enthalpy and independent mass fractions at a fluid port.
+<br/><br/>
+Models that inherit properties from this partial model must augment equations for
+the densities <i>d_in</i>/<i>d_out</i> and specific enthalpy <i>h</i>. Furthermore, 
+the boundary type <i>boundaryTypeStreamMassFractions</i> must either be fixed or 
+equations must be augmented for the case of given dry air mass fractions and 
+relative humidity.
+</p>
+
+<h4>Options</h4>
+<ul>
+  <li>
+  <i>boundaryTypePotentialFlow</i>: Defines if pressure, mass flow rate, or volume
+  flow rate are prescribed.
+  </li>
+  <li>
+  <i>boundaryTypeStreamEnthalpy</i>: Defines if specific enthalpy or temperature
+  are prescribed.
+  </li>
+  <li>
+  <i>boundaryTypeStreamMassFractions</i>: Defines if mass fractions or mass fractions
+  of dry air and relative humidity are prescribed.
+  </li>
+</ul>  
+</html>",revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialFluidSource;
diff --git a/SorpLib/Basics/Sources/BaseClasses/package.mo b/SorpLib/Basics/Sources/BaseClasses/package.mo
new file mode 100644
index 0000000..90ce165
--- /dev/null
+++ b/SorpLib/Basics/Sources/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Basics.Sources;
+package BaseClasses "Base classes used to create new sources"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial models. These partial models contain fundamental 
+definitions for thermal and fluid source models. The content of this package is 
+only of interest when adding new source models to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Basics/Sources/BaseClasses/package.order b/SorpLib/Basics/Sources/BaseClasses/package.order
new file mode 100644
index 0000000..0d59b06
--- /dev/null
+++ b/SorpLib/Basics/Sources/BaseClasses/package.order
@@ -0,0 +1 @@
+PartialFluidSource
diff --git a/SorpLib/Basics/Sources/Fluids/GasSource.mo b/SorpLib/Basics/Sources/Fluids/GasSource.mo
new file mode 100644
index 0000000..1e2a701
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/GasSource.mo
@@ -0,0 +1,113 @@
+within SorpLib.Basics.Sources.Fluids;
+model GasSource "Boundary model of an ideal gas or ideal gas mixture"
+  extends SorpLib.Basics.Sources.BaseClasses.PartialFluidSource(
+    redeclare final Interfaces.FluidPorts.GasPort_in port,
+    final no_components = Medium.nX,
+    final boundaryTypeStreamMassFractions=
+      SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    X_fixed=Medium.reference_X);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas or ideal gas mixture"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculate properties
+  //
+  if boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate then
+      d_in = Medium.density_phX(
+        p=port.p,
+        h=inStream(port.h_outflow),
+        X=cat(1, inStream(port.Xi_outflow), {1-sum(inStream(port.Xi_outflow))}))
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      entering the port";
+
+      d_out =if boundaryTypeStreamEnthalpy <>
+        SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature then
+        Medium.density_phX(
+          p=port.p,
+          h=port.h_outflow,
+          X=cat(1, port.Xi_outflow, {1-sum(port.Xi_outflow)})) else
+        Medium.density_pTX(
+          p=port.p,
+          T=T_internal,
+          X=cat(1, port.Xi_outflow, {1-sum(port.Xi_outflow)}))
+      "Density calculated with pressure, specific enthalpy or temperature, and 
+      mass fractions  leaving the port";
+
+  else
+    d_in = m_flow_fixed / V_flow_fixed
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      entering the port: Not needed, so set dummy value";
+    d_out = m_flow_fixed / V_flow_fixed
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      leaving the port: Not needed, so set dummy value";
+
+  end if;
+
+  if boundaryTypeStreamEnthalpy ==
+    SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature then
+    h = Medium.specificEnthalpy_pTX(
+      p=port.p,
+      T=T_internal,
+      X=X_internal)
+      "Specific enthalpy calculated with pressure at port and temperature";
+
+  else
+    h = h_fixed
+      "Specific enthalpy calculated with pressure at port and temperature: Not
+      needed, so set dummy value";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(graphics={Rectangle(
+          extent={{-2,80},{2,-80}},
+          lineColor={244,125,35},
+          lineThickness=0.5,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid)}),
+          Documentation(info="<html>
+<p>
+This model can be used to specify either the pressure or mass flow rate as well as
+the specific enthalpy and independent mass fractions at an ideal gas or gas mixture
+port.
+</p>
+
+<h4>Options</h4>
+<ul>
+  <li>
+  <i>boundaryTypePotentialFlow</i>: Defines if pressure, mass flow rate, or volume
+  flow rate are prescribed.
+  </li>
+  <li>
+  <i>boundaryTypeStreamEnthalpy</i>: Defines if specific enthalpy or temperature
+  are prescribed.
+  </li>
+</ul>
+  
+</html>",revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasSource;
diff --git a/SorpLib/Basics/Sources/Fluids/GasVaporMixtureSource.mo b/SorpLib/Basics/Sources/Fluids/GasVaporMixtureSource.mo
new file mode 100644
index 0000000..cb24312
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/GasVaporMixtureSource.mo
@@ -0,0 +1,232 @@
+within SorpLib.Basics.Sources.Fluids;
+model GasVaporMixtureSource
+  "Boundary model of an ideal gas-vapor mixture"
+  extends SorpLib.Basics.Sources.BaseClasses.PartialFluidSource(
+    redeclare final Interfaces.FluidPorts.GasPort_in port,
+    final no_components = Medium.nX,
+    X_fixed=Medium.reference_X);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture
+    "Medium model of the ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding stream variables of mass fractions
+  //
+  parameter Boolean use_xDryInput = false
+    "=true, if xDry is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Stream Variables - Mass Fractions",
+                enable=(boundaryTypeStreamMassFractions ==
+                SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MassFraction[no_components-1] xDry_fixed=
+    Medium.reference_X[1:no_components-1]/sum(Medium.reference_X[1:no_components-1])
+    "Fixed mass fractions of dry air components (per dry air component mass) at boundary"
+    annotation (Dialog(tab="General",group="Stream Variables - Mass Fractions",
+                enable=(boundaryTypeStreamMassFractions ==
+                SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi)
+                and not use_xDryInput));
+
+  parameter Boolean use_phiInput = false
+    "=true, if phi is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Stream Variables - Mass Fractions",
+                enable=(boundaryTypeStreamMassFractions ==
+                SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real phi_fixed(unit="1") = 0.5
+    "Fixed relative humidity at boundary"
+    annotation (Dialog(tab="General",group="Stream Variables - Mass Fractions",
+                enable=(boundaryTypeStreamMassFractions ==
+                SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi)
+                and not use_phiInput));
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput[no_components-1]
+    XDry_input(each final unit="kg/kg") if
+    (boundaryTypeStreamMassFractions ==
+    SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi and
+    use_xDryInput)
+    "Input for mass fractions of dry gas components"
+    annotation (Placement(transformation(extent={{-120,-30},{-80,-70}}),
+                iconTransformation(extent={{-22,-60},{-2,-40}})));
+  Modelica.Blocks.Interfaces.RealInput phi_input(final unit="1") if
+    (boundaryTypeStreamMassFractions ==
+    SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi and
+    use_phiInput)
+    "Input for relative humidity"
+    annotation (Placement(transformation(extent={{-120,-60},{-80,-100}}),
+                iconTransformation(extent={{-22,-90},{-2,-70}})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput[no_components-1] xDry_internal(each final unit="kg/kg")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput phi_internal(final unit="1")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of protected variables
+  //
+  Modelica.Units.SI.MassFraction[no_components] X
+    "Mass fractions calculated with pressure and specific enthalpy leaving the 
+    port as well as dry air mass fractions and relative humidity";
+
+equation
+  //
+  // Assertions
+  //
+  if boundaryTypeStreamMassFractions ==
+    SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi then
+    assert((boundaryTypeStreamEnthalpy ==
+      SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature) and
+      (boundaryTypePotentialFlow ==
+      SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure),
+      "Can only use mass fractions of dry air components and relative humidity " +
+      "if pressure and temperature are prescribed at the boundary model!",
+      level = AssertionLevel.error);
+
+  end if;
+
+  //
+  // Connectors
+  //
+  connect(XDry_input,xDry_internal);
+  connect(phi_input,phi_internal);
+
+  if not use_xDryInput then
+    xDry_internal = xDry_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_phiInput then
+    phi_internal = phi_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Calculate properties
+  //
+  if boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate then
+      d_in = Medium.density_phX(
+        p=port.p,
+        h=inStream(port.h_outflow),
+        X=cat(1, inStream(port.Xi_outflow), {1-sum(inStream(port.Xi_outflow))}))
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      entering the port";
+
+      d_out =if boundaryTypeStreamEnthalpy <>
+        SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature then
+        Medium.density_phX(
+          p=port.p,
+          h=port.h_outflow,
+          X=cat(1, port.Xi_outflow, {1-sum(port.Xi_outflow)})) else
+        Medium.density_pTX(
+          p=port.p,
+          T=T_internal,
+          X=cat(1, port.Xi_outflow, {1-sum(port.Xi_outflow)}))
+      "Density calculated with pressure, specific enthalpy or temperature, and 
+      mass fractions  leaving the port";
+
+  else
+    d_in = m_flow_fixed / V_flow_fixed
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      entering the port: Not needed, so set dummy value";
+    d_out = m_flow_fixed / V_flow_fixed
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      leaving the port: Not needed, so set dummy value";
+
+  end if;
+
+  if boundaryTypeStreamEnthalpy ==
+    SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature then
+    h = Medium.specificEnthalpy_pTX(
+      p=port.p,
+      T=T_internal,
+      X=X_internal)
+      "Specific enthalpy calculated with pressure at port and temperature";
+
+  else
+    h = h_fixed
+      "Specific enthalpy calculated with pressure at port and temperature: Not
+      needed, so set dummy value";
+
+  end if;
+
+  if boundaryTypeStreamMassFractions ==
+    SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi then
+    X = Medium.massFractions_pTxDryPhi(
+      p = port.p,
+      T=T_internal,
+      x=xDry_internal,
+      phi=phi_internal)
+      "Mass fractions calculated with pressure and specific enthalpy leaving the 
+      port as well as dry air mass fractions and relative humidity";
+
+    port.Xi_outflow = X[1:no_components-1]
+      "Independent mass fractions at port";
+
+  else
+    X = X_fixed
+      "Mass fractions calculated with pressure and specific enthalpy leaving the 
+      port as well as dry air mass fractions and relative humidity: Not needed, 
+      so set dummy values";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(graphics={Rectangle(
+          extent={{-2,80},{2,-80}},
+          lineColor={244,125,35},
+          lineThickness=0.5,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid)}),
+          Documentation(info="<html>
+<p>
+This model can be used to specify either the pressure or mass flow rate as well as
+the specific enthalpy and independent mass fractions at an ideal gas-vapor mixture
+port.
+</p>
+
+<h4>Options</h4>
+<ul>
+  <li>
+  <i>boundaryTypePotentialFlow</i>: Defines if pressure, mass flow rate, or volume
+  flow rate are prescribed.
+  </li>
+  <li>
+  <i>boundaryTypeStreamEnthalpy</i>: Defines if specific enthalpy or temperature
+  are prescribed.
+  </li>
+  <li>
+  <i>boundaryTypeStreamMassFractions</i>: Defines if mass fractions or mass fractions
+  of dry air and relative humidity are prescribed.
+  </li></ul>
+  
+</html>",revisions="<html>
+<ul>
+  <li>
+  December 5, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasVaporMixtureSource;
diff --git a/SorpLib/Basics/Sources/Fluids/LiquidSource.mo b/SorpLib/Basics/Sources/Fluids/LiquidSource.mo
new file mode 100644
index 0000000..4101b16
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/LiquidSource.mo
@@ -0,0 +1,112 @@
+within SorpLib.Basics.Sources.Fluids;
+model LiquidSource
+  "Boundary model of an (ideal) liquid"
+  extends SorpLib.Basics.Sources.BaseClasses.PartialFluidSource(
+    redeclare final Interfaces.FluidPorts.LiquidPort_in port,
+    final no_components = Medium.nX,
+    final boundaryTypeStreamMassFractions=
+      SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    X_fixed=Medium.reference_X);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculate properties
+  //
+  if boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate then
+      d_in = Medium.density_phX(
+        p=port.p,
+        h=inStream(port.h_outflow),
+        X=cat(1, inStream(port.Xi_outflow), {1-sum(inStream(port.Xi_outflow))}))
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      entering the port";
+
+      d_out =if boundaryTypeStreamEnthalpy <>
+        SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature then
+        Medium.density_phX(
+          p=port.p,
+          h=port.h_outflow,
+          X=cat(1, port.Xi_outflow, {1-sum(port.Xi_outflow)})) else
+        Medium.density_pTX(
+          p=port.p,
+          T=T_internal,
+          X=cat(1, port.Xi_outflow, {1-sum(port.Xi_outflow)}))
+      "Density calculated with pressure, specific enthalpy or temperature, and 
+      mass fractions  leaving the port";
+
+  else
+    d_in = m_flow_fixed / V_flow_fixed
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      entering the port: Not needed, so set dummy value";
+    d_out = m_flow_fixed / V_flow_fixed
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      leaving the port: Not needed, so set dummy value";
+
+  end if;
+
+  if boundaryTypeStreamEnthalpy ==
+    SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature then
+    h = Medium.specificEnthalpy_pTX(
+      p=port.p,
+      T=T_internal,
+      X=X_internal)
+      "Specific enthalpy calculated with pressure at port and temperature";
+
+  else
+    h = h_fixed
+      "Specific enthalpy calculated with pressure at port and temperature: Not
+      needed, so set dummy value";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(graphics={Rectangle(
+          extent={{-2,80},{2,-80}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid)}),
+          Documentation(info="<html>
+<p>
+This model can be used to specify either the pressure or mass flow rate as well as
+the specific enthalpy and independent mass fractions at an (ideal) liquid port.
+</p>
+
+<h4>Options</h4>
+<ul>
+  <li>
+  <i>boundaryTypePotentialFlow</i>: Defines if pressure, mass flow rate, or volume
+  flow rate are prescribed.
+  </li>
+  <li>
+  <i>boundaryTypeStreamEnthalpy</i>: Defines if specific enthalpy or temperature
+  are prescribed.
+  </li>
+</ul>
+  
+</html>",revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LiquidSource;
diff --git a/SorpLib/Basics/Sources/Fluids/Tester/Test_GasSource.mo b/SorpLib/Basics/Sources/Fluids/Tester/Test_GasSource.mo
new file mode 100644
index 0000000..ba20feb
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/Tester/Test_GasSource.mo
@@ -0,0 +1,253 @@
+within SorpLib.Basics.Sources.Fluids.Tester;
+model Test_GasSource
+  "Tester for ideal gas or ideal gas mixture source"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasSource sourceA_pFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=1000000) "Source A: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,70},{-30,90}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource sourceB_MFlowFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=0.2,
+    T_fixed=323.15) "Source B: Fixed mass flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{30,70},{50,90}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource sourceA_pFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=1000000,
+    T_fixed=303.15) "Source A: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,50},{-30,70}})));
+  SorpLib.Basics.Sources.Fluids.GasSource sourceB_MFlowFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    m_flow_fixed=-0.2,
+    h_fixed=400e3) "Source B: Fixed mass flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{30,50},{50,70}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource sourceA_VFlowFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed(displayUnit="l/min") = -0.016666666666667,
+    T_fixed=348.15) "Source A: Fixed volume flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{-50,30},{-30,50}})));
+  SorpLib.Basics.Sources.Fluids.GasSource sourceB_pFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=500000,
+    T_fixed=283.15) "Source B: Fixed pressure and fixed temperature"
+    annotation (Placement(transformation(extent={{30,30},{50,50}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource sourceA_VFlowFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    V_flow_fixed(displayUnit="l/min") = -0.016666666666667,
+    h_fixed=275e3)
+    "Source A: Fixed volume flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,10},{-30,30}})));
+  SorpLib.Basics.Sources.Fluids.GasSource sourceB_pFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=500000,
+    h_fixed=300e3) "Source B: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{30,10},{50,30}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource sourceA_pVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_pInput=true)
+    "Source A: Variable pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-30},{-30,-10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource sourceB_MFlowVar_TVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true)
+    "Source B: Variable mass flow rate and variable temperature"
+    annotation (Placement(transformation(extent={{50,-30},{30,-10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource sourceA_pVar_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=303.15)
+    "Source A: Variable pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-50},{-30,-30}})));
+  SorpLib.Basics.Sources.Fluids.GasSource sourceB_MFlowVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    h_fixed=400e3)
+    "Source B: Variable mass flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-50},{30,-30}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource sourceA_VFlowVar_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_VFlowInput=true,
+    V_flow_fixed(displayUnit="l/min"),
+    T_fixed=348.15)
+    "Source A: Variable volume flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{-50,-70},{-30,-50}})));
+  SorpLib.Basics.Sources.Fluids.GasSource sourceB_pFixed_TVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=500000,
+    use_TInput=true)
+    "Source B: Fixed pressure and variable temperature"
+    annotation (Placement(transformation(extent={{50,-70},{30,-50}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource sourceA_VFlowVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_VFlowInput=true,
+    V_flow_fixed(displayUnit="l/min"),
+    h_fixed=275e3)
+    "Source A: Variable volume flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-90},{-30,-70}})));
+  SorpLib.Basics.Sources.Fluids.GasSource sourceB_pFixed_hVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=500000,
+    use_hInput=true) "Source B: Fixed pressure and variable specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-90},{30,-70}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=10e5 - 1e5,
+    duration=2500,
+    offset=1e5,
+    startTime=0)
+    "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_mFlowVar(
+    height=2,
+    duration=2500,
+    offset=-1,
+    startTime=0) "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{80,-30},{60,-10}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_VFlowVar(
+    height=40000/60000,
+    duration=2500,
+    offset=-20000/60000,
+    startTime=0) "Ramp to simulate input signal of volume flow rate"
+    annotation (Placement(transformation(extent={{-80,-80},{-60,-60}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_hVar(
+    height=1e5,
+    duration=2500,
+    offset=273e3,
+    startTime=0)
+    "Ramp to simulate input signal of specific enthalpy"
+    annotation (Placement(transformation(extent={{80,-90},{60,-70}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_TVar(
+    height=90,
+    duration=2500,
+    offset=283.15,
+    startTime=0) "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{80,-60},{60,-40}})),
+                HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(sourceA_pFixed_hFixed.port, sourceB_MFlowFixed_TFixed.port)
+    annotation (Line(
+      points={{-40,80},{40,80}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceB_MFlowFixed_hFixed.port, sourceA_pFixed_TFixed.port)
+    annotation (Line(
+      points={{40,60},{-40,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceA_VFlowFixed_TFixed.port, sourceB_pFixed_TFixed.port)
+    annotation (Line(
+      points={{-40,40},{40,40}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceB_pFixed_hFixed.port, sourceA_VFlowFixed_hFixed.port)
+    annotation (Line(
+      points={{40,20},{-40,20}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceA_pVar_hFixed.port, sourceB_MFlowVar_TVar.port) annotation (
+      Line(
+      points={{-40,-20},{40,-20}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceB_MFlowVar_hFixed.port, sourceA_pVar_TFixed.port) annotation (
+      Line(
+      points={{40,-40},{-40,-40}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceA_VFlowVar_TFixed.port, sourceB_pFixed_TVar.port) annotation (
+      Line(
+      points={{-40,-60},{40,-60}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceB_pFixed_hVar.port, sourceA_VFlowVar_hFixed.port) annotation (
+      Line(
+      points={{40,-80},{-40,-80}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_pVar.y, sourceA_pVar_hFixed.p_input) annotation (Line(points={{-59,-30},
+          {-50,-30},{-50,-15},{-41.2,-15}},      color={0,0,127}));
+  connect(input_pVar.y, sourceA_pVar_TFixed.p_input) annotation (Line(points={{-59,-30},
+          {-50,-30},{-50,-35},{-41.2,-35}},      color={0,0,127}));
+  connect(input_VFlowVar.y, sourceA_VFlowVar_TFixed.V_flow_input) annotation (
+      Line(points={{-59,-70},{-50,-70},{-50,-58},{-41.2,-58}}, color={0,0,127}));
+  connect(input_VFlowVar.y, sourceA_VFlowVar_hFixed.V_flow_input) annotation (
+      Line(points={{-59,-70},{-50,-70},{-50,-78},{-41.2,-78}}, color={0,0,127}));
+  connect(input_mFlowVar.y, sourceB_MFlowVar_TVar.m_flow_input) annotation (
+      Line(points={{59,-20},{54,-20},{54,-18},{41.2,-18}}, color={0,0,127}));
+  connect(input_mFlowVar.y, sourceB_MFlowVar_hFixed.m_flow_input) annotation (
+      Line(points={{59,-20},{54,-20},{54,-38},{41.2,-38}}, color={0,0,127}));
+  connect(input_TVar.y, sourceB_MFlowVar_TVar.T_input) annotation (Line(points={{59,-50},
+          {50,-50},{50,-22},{41.2,-22}},          color={0,0,127}));
+  connect(input_TVar.y, sourceB_pFixed_TVar.T_input) annotation (Line(points={{59,-50},
+          {50,-50},{50,-62},{41.2,-62}},      color={0,0,127}));
+  connect(input_hVar.y, sourceB_pFixed_hVar.h_input) annotation (Line(points={{59,-80},
+          {50,-80},{50,-82},{41.2,-82}},      color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the ideal gas or gas mixture source model used to prescribe 
+properties at a gas fluid port.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasSource;
diff --git a/SorpLib/Basics/Sources/Fluids/Tester/Test_GasVaporMixtureSource.mo b/SorpLib/Basics/Sources/Fluids/Tester/Test_GasVaporMixtureSource.mo
new file mode 100644
index 0000000..d7dce4f
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/Tester/Test_GasVaporMixtureSource.mo
@@ -0,0 +1,284 @@
+within SorpLib.Basics.Sources.Fluids.Tester;
+model Test_GasVaporMixtureSource
+  "Tester for ideal gas-vapor mixture source"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceA_pFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    p_fixed=1000000) "Source A: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,70},{-30,90}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceB_MFlowFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    m_flow_fixed=0.2,
+    T_fixed=323.15) "Source B: Fixed mass flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{30,70},{50,90}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceA_pFixed_TFixed_xDryFixed_phiFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi,
+    p_fixed=1000000,
+    T_fixed=303.15)
+    "Source A: Fixed pressure, fixed specific enthalpy, fixed dry mass fractions, and fixed relative humidity"
+    annotation (Placement(transformation(extent={{-50,50},{-30,70}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceB_MFlowFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    m_flow_fixed=-0.2,
+    h_fixed=400e3) "Source B: Fixed mass flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{30,50},{50,70}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceA_VFlowFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    V_flow_fixed(displayUnit="l/min") = -0.016666666666667,
+    T_fixed=348.15) "Source A: Fixed volume flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{-50,30},{-30,50}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceB_pFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    p_fixed=500000,
+    T_fixed=283.15) "Source B: Fixed pressure and fixed temperature"
+    annotation (Placement(transformation(extent={{30,30},{50,50}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceA_VFlowFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    V_flow_fixed(displayUnit="l/min") = -0.016666666666667,
+    h_fixed=275e3)
+    "Source A: Fixed volume flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,10},{-30,30}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceB_pFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    p_fixed=500000,
+    h_fixed=300e3) "Source B: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{30,10},{50,30}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceA_pVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    use_pInput=true)
+    "Source A: Variable pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-30},{-30,-10}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceB_MFlowVar_TVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    use_mFlowInput=true,
+    use_TInput=true)
+    "Source B: Variable mass flow rate and variable temperature"
+    annotation (Placement(transformation(extent={{50,-30},{30,-10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceA_pVar_TFixed_xDryFixed_phiVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.DryMassFractionsPhi,
+    use_pInput=true,
+    T_fixed=303.15,
+    use_phiInput=true)
+    "Source A: Variable pressure, fixed specific enthalpy, fixed dry air mass fractions, and variable relative humidity"
+    annotation (Placement(transformation(extent={{-50,-50},{-30,-30}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceB_MFlowVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    use_mFlowInput=true,
+    h_fixed=400e3)
+    "Source B: Variable mass flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-50},{30,-30}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceA_VFlowVar_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    use_VFlowInput=true,
+    V_flow_fixed(displayUnit="l/min"),
+    T_fixed=348.15)
+    "Source A: Variable volume flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{-50,-70},{-30,-50}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceB_pFixed_TVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    p_fixed=500000,
+    use_TInput=true)
+    "Source B: Fixed pressure and variable temperature"
+    annotation (Placement(transformation(extent={{50,-70},{30,-50}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceA_VFlowVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    use_VFlowInput=true,
+    V_flow_fixed(displayUnit="l/min"),
+    h_fixed=275e3)
+    "Source A: Variable volume flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-90},{-30,-70}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource sourceB_pFixed_hVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    p_fixed=500000,
+    use_hInput=true) "Source B: Fixed pressure and variable specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-90},{30,-70}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=10e5 - 1e5,
+    duration=2500,
+    offset=1e5,
+    startTime=0) "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{-80,-30},{-60,-10}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_mFlowVar(
+    height=2,
+    duration=2500,
+    offset=-1,
+    startTime=0) "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{80,-30},{60,-10}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_VFlowVar(
+    height=40000/60000,
+    duration=2500,
+    offset=-20000/60000,
+    startTime=0) "Ramp to simulate input signal of volume flow rate"
+    annotation (Placement(transformation(extent={{-80,-90},{-60,-70}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_hVar(
+    height=9e4,
+    duration=2500,
+    offset=1e4,
+    startTime=0)
+    "Ramp to simulate input signal of specific enthalpy"
+    annotation (Placement(transformation(extent={{80,-90},{60,-70}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_TVar(
+    height=90,
+    duration=2500,
+    offset=283.15,
+    startTime=0) "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{80,-60},{60,-40}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_phiVar(
+    height=1,
+    duration=2500,
+    offset=0,
+    startTime=0) "Ramp to simulate input signal of relative humidity"
+    annotation (Placement(transformation(extent={{-80,-60},{-60,-40}})),
+      HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(sourceA_pFixed_hFixed.port, sourceB_MFlowFixed_TFixed.port)
+    annotation (Line(
+      points={{-40,80},{40,80}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceB_MFlowFixed_hFixed.port,
+    sourceA_pFixed_TFixed_xDryFixed_phiFixed.port) annotation (Line(
+      points={{40,60},{-40,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceA_VFlowFixed_TFixed.port, sourceB_pFixed_TFixed.port)
+    annotation (Line(
+      points={{-40,40},{40,40}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceB_pFixed_hFixed.port, sourceA_VFlowFixed_hFixed.port)
+    annotation (Line(
+      points={{40,20},{-40,20}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceA_pVar_hFixed.port, sourceB_MFlowVar_TVar.port) annotation (
+      Line(
+      points={{-40,-20},{40,-20}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceB_MFlowVar_hFixed.port, sourceA_pVar_TFixed_xDryFixed_phiVar.port)
+    annotation (Line(
+      points={{40,-40},{-40,-40}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceA_VFlowVar_TFixed.port, sourceB_pFixed_TVar.port) annotation (
+      Line(
+      points={{-40,-60},{40,-60}},
+      color={244,125,35},
+      thickness=1));
+  connect(sourceB_pFixed_hVar.port, sourceA_VFlowVar_hFixed.port) annotation (
+      Line(
+      points={{40,-80},{-40,-80}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_pVar.y, sourceA_pVar_hFixed.p_input) annotation (Line(points={{-59,-20},
+          {-50,-20},{-50,-15},{-41.2,-15}},      color={0,0,127}));
+  connect(input_pVar.y, sourceA_pVar_TFixed_xDryFixed_phiVar.p_input)
+    annotation (Line(points={{-59,-20},{-50,-20},{-50,-35},{-41.2,-35}}, color={
+          0,0,127}));
+  connect(input_VFlowVar.y, sourceA_VFlowVar_TFixed.V_flow_input) annotation (
+      Line(points={{-59,-80},{-50,-80},{-50,-58},{-41.2,-58}}, color={0,0,127}));
+  connect(input_VFlowVar.y, sourceA_VFlowVar_hFixed.V_flow_input) annotation (
+      Line(points={{-59,-80},{-50,-80},{-50,-78},{-41.2,-78}}, color={0,0,127}));
+  connect(input_mFlowVar.y, sourceB_MFlowVar_TVar.m_flow_input) annotation (
+      Line(points={{59,-20},{54,-20},{54,-18},{41.2,-18}}, color={0,0,127}));
+  connect(input_mFlowVar.y, sourceB_MFlowVar_hFixed.m_flow_input) annotation (
+      Line(points={{59,-20},{54,-20},{54,-38},{41.2,-38}}, color={0,0,127}));
+  connect(input_TVar.y, sourceB_MFlowVar_TVar.T_input) annotation (Line(points={{59,-50},
+          {50,-50},{50,-22},{41.2,-22}},          color={0,0,127}));
+  connect(input_TVar.y, sourceB_pFixed_TVar.T_input) annotation (Line(points={{59,-50},
+          {50,-50},{50,-62},{41.2,-62}},      color={0,0,127}));
+  connect(input_hVar.y, sourceB_pFixed_hVar.h_input) annotation (Line(points={{59,-80},
+          {50,-80},{50,-82},{41.2,-82}},      color={0,0,127}));
+  connect(input_phiVar.y, sourceA_pVar_TFixed_xDryFixed_phiVar.phi_input)
+    annotation (Line(points={{-59,-50},{-50,-50},{-50,-48},{-41.2,-48}}, color={
+          0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the ideal gas-vapor mixture source model used to prescribe 
+properties at a gas fluid port.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 5, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasVaporMixtureSource;
diff --git a/SorpLib/Basics/Sources/Fluids/Tester/Test_LiquidSource.mo b/SorpLib/Basics/Sources/Fluids/Tester/Test_LiquidSource.mo
new file mode 100644
index 0000000..248e278
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/Tester/Test_LiquidSource.mo
@@ -0,0 +1,252 @@
+within SorpLib.Basics.Sources.Fluids.Tester;
+model Test_LiquidSource "Tester for ideal liquid source"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceA_pFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=1000000) "Source A: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,70},{-30,90}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceB_MFlowFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=0.2,
+    T_fixed=323.15) "Source B: Fixed mass flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{30,70},{50,90}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceA_pFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=1000000,
+    T_fixed=303.15) "Source A: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,50},{-30,70}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceB_MFlowFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    m_flow_fixed=-0.2,
+    h_fixed=400e3) "Source B: Fixed mass flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{30,50},{50,70}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceA_VFlowFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed(displayUnit="l/min") = -0.00016666666666667,
+    T_fixed=348.15) "Source A: Fixed volume flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{-50,30},{-30,50}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceB_pFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=500000,
+    T_fixed=283.15) "Source B: Fixed pressure and fixed temperature"
+    annotation (Placement(transformation(extent={{30,30},{50,50}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceA_VFlowFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    V_flow_fixed(displayUnit="l/min") = -0.00016666666666667,
+    h_fixed=275e3)
+    "Source A: Fixed volume flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,10},{-30,30}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceB_pFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=500000,
+    h_fixed=300e3) "Source B: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{30,10},{50,30}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceA_pVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_pInput=true)
+    "Source A: Variable pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-30},{-30,-10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceB_MFlowVar_TVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true)
+    "Source B: Variable mass flow rate and variable temperature"
+    annotation (Placement(transformation(extent={{50,-30},{30,-10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceA_pVar_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=303.15)
+    "Source A: Variable pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-50},{-30,-30}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceB_MFlowVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    h_fixed=400e3)
+    "Source B: Variable mass flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-50},{30,-30}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceA_VFlowVar_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_VFlowInput=true,
+    V_flow_fixed(displayUnit="l/min"),
+    T_fixed=348.15)
+    "Source A: Variable volume flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{-50,-70},{-30,-50}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceB_pFixed_TVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=500000,
+    use_TInput=true)
+    "Source B: Fixed pressure and variable temperature"
+    annotation (Placement(transformation(extent={{50,-70},{30,-50}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceA_VFlowVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_VFlowInput=true,
+    V_flow_fixed(displayUnit="l/min"),
+    h_fixed=275e3)
+    "Source A: Variable volume flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-90},{-30,-70}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource sourceB_pFixed_hVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=500000,
+    use_hInput=true) "Source B: Fixed pressure and variable specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-90},{30,-70}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=10e5 - 1e5,
+    duration=2500,
+    offset=1e5,
+    startTime=0)
+    "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_mFlowVar(
+    height=2,
+    duration=2500,
+    offset=-1,
+    startTime=0) "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{80,-30},{60,-10}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_VFlowVar(
+    height=40/60000,
+    duration=2500,
+    offset=-20/60000,
+    startTime=0) "Ramp to simulate input signal of volume flow rate"
+    annotation (Placement(transformation(extent={{-80,-80},{-60,-60}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_hVar(
+    height=3e5,
+    duration=2500,
+    offset=1e5,
+    startTime=0)
+    "Ramp to simulate input signal of specific enthalpy"
+    annotation (Placement(transformation(extent={{80,-90},{60,-70}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_TVar(
+    height=90,
+    duration=2500,
+    offset=283.15,
+    startTime=0) "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{80,-60},{60,-40}})),
+                HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(sourceA_pFixed_hFixed.port, sourceB_MFlowFixed_TFixed.port)
+    annotation (Line(
+      points={{-40,80},{40,80}},
+      color={28,108,200},
+      thickness=1));
+  connect(sourceB_MFlowFixed_hFixed.port, sourceA_pFixed_TFixed.port)
+    annotation (Line(
+      points={{40,60},{-40,60}},
+      color={28,108,200},
+      thickness=1));
+  connect(sourceA_VFlowFixed_TFixed.port, sourceB_pFixed_TFixed.port)
+    annotation (Line(
+      points={{-40,40},{40,40}},
+      color={28,108,200},
+      thickness=1));
+  connect(sourceB_pFixed_hFixed.port, sourceA_VFlowFixed_hFixed.port)
+    annotation (Line(
+      points={{40,20},{-40,20}},
+      color={28,108,200},
+      thickness=1));
+  connect(sourceA_pVar_hFixed.port, sourceB_MFlowVar_TVar.port) annotation (
+      Line(
+      points={{-40,-20},{40,-20}},
+      color={28,108,200},
+      thickness=1));
+  connect(sourceB_MFlowVar_hFixed.port, sourceA_pVar_TFixed.port) annotation (
+      Line(
+      points={{40,-40},{-40,-40}},
+      color={28,108,200},
+      thickness=1));
+  connect(sourceA_VFlowVar_TFixed.port, sourceB_pFixed_TVar.port) annotation (
+      Line(
+      points={{-40,-60},{40,-60}},
+      color={28,108,200},
+      thickness=1));
+  connect(sourceB_pFixed_hVar.port, sourceA_VFlowVar_hFixed.port) annotation (
+      Line(
+      points={{40,-80},{-40,-80}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_pVar.y, sourceA_pVar_hFixed.p_input) annotation (Line(points={{-59,-30},
+          {-50,-30},{-50,-15},{-41.2,-15}},      color={0,0,127}));
+  connect(input_pVar.y, sourceA_pVar_TFixed.p_input) annotation (Line(points={{-59,-30},
+          {-50,-30},{-50,-35},{-41.2,-35}},      color={0,0,127}));
+  connect(input_VFlowVar.y, sourceA_VFlowVar_TFixed.V_flow_input) annotation (
+      Line(points={{-59,-70},{-50,-70},{-50,-58},{-41.2,-58}}, color={0,0,127}));
+  connect(input_VFlowVar.y, sourceA_VFlowVar_hFixed.V_flow_input) annotation (
+      Line(points={{-59,-70},{-50,-70},{-50,-78},{-41.2,-78}}, color={0,0,127}));
+  connect(input_mFlowVar.y, sourceB_MFlowVar_TVar.m_flow_input) annotation (
+      Line(points={{59,-20},{54,-20},{54,-18},{41.2,-18}}, color={0,0,127}));
+  connect(input_mFlowVar.y, sourceB_MFlowVar_hFixed.m_flow_input) annotation (
+      Line(points={{59,-20},{54,-20},{54,-38},{41.2,-38}}, color={0,0,127}));
+  connect(input_TVar.y, sourceB_MFlowVar_TVar.T_input) annotation (Line(points={{59,-50},
+          {50,-50},{50,-22},{41.2,-22}},          color={0,0,127}));
+  connect(input_TVar.y, sourceB_pFixed_TVar.T_input) annotation (Line(points={{59,-50},
+          {50,-50},{50,-62},{41.2,-62}},      color={0,0,127}));
+  connect(input_hVar.y, sourceB_pFixed_hVar.h_input) annotation (Line(points={{59,-80},
+          {50,-80},{50,-82},{41.2,-82}},      color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the (ideal) liquid source model used to prescribe properties 
+at a liquid fluid port.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidSource;
diff --git a/SorpLib/Basics/Sources/Fluids/Tester/Test_VLESource.mo b/SorpLib/Basics/Sources/Fluids/Tester/Test_VLESource.mo
new file mode 100644
index 0000000..c08c55f
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/Tester/Test_VLESource.mo
@@ -0,0 +1,252 @@
+within SorpLib.Basics.Sources.Fluids.Tester;
+model Test_VLESource "Tester for VLE source"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource sourceA_pFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=1000000) "Source A: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,70},{-30,90}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource sourceB_MFlowFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=0.2,
+    T_fixed=323.15) "Source B: Fixed mass flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{30,70},{50,90}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource sourceA_pFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=1000000,
+    T_fixed=303.15) "Source A: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,50},{-30,70}})));
+  SorpLib.Basics.Sources.Fluids.VLESource sourceB_MFlowFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    m_flow_fixed=-0.2,
+    h_fixed=400e3) "Source B: Fixed mass flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{30,50},{50,70}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource sourceA_VFlowFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed(displayUnit="l/min") = -0.00016666666666667,
+    T_fixed=348.15) "Source A: Fixed volume flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{-50,30},{-30,50}})));
+  SorpLib.Basics.Sources.Fluids.VLESource sourceB_pFixed_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=500000,
+    T_fixed=283.15) "Source B: Fixed pressure and fixed temperature"
+    annotation (Placement(transformation(extent={{30,30},{50,50}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource sourceA_VFlowFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    V_flow_fixed(displayUnit="l/min") = -0.00016666666666667,
+    h_fixed=275e3)
+    "Source A: Fixed volume flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,10},{-30,30}})));
+  SorpLib.Basics.Sources.Fluids.VLESource sourceB_pFixed_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=500000,
+    h_fixed=300e3) "Source B: Fixed pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{30,10},{50,30}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource sourceA_pVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_pInput=true)
+    "Source A: Variable pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-30},{-30,-10}})));
+  SorpLib.Basics.Sources.Fluids.VLESource sourceB_MFlowVar_TVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true)
+    "Source B: Variable mass flow rate and variable temperature"
+    annotation (Placement(transformation(extent={{50,-30},{30,-10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource sourceA_pVar_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=303.15)
+    "Source A: Variable pressure and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-50},{-30,-30}})));
+  SorpLib.Basics.Sources.Fluids.VLESource sourceB_MFlowVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    h_fixed=400e3)
+    "Source B: Variable mass flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-50},{30,-30}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource sourceA_VFlowVar_TFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_VFlowInput=true,
+    V_flow_fixed(displayUnit="l/min"),
+    T_fixed=348.15)
+    "Source A: Variable volume flow rate and fixed temperature"
+    annotation (Placement(transformation(extent={{-50,-70},{-30,-50}})));
+  SorpLib.Basics.Sources.Fluids.VLESource sourceB_pFixed_TVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=500000,
+    use_TInput=true)
+    "Source B: Fixed pressure and variable temperature"
+    annotation (Placement(transformation(extent={{50,-70},{30,-50}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource sourceA_VFlowVar_hFixed(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_VFlowInput=true,
+    V_flow_fixed(displayUnit="l/min"),
+    h_fixed=275e3)
+    "Source A: Variable volume flow rate and fixed specific enthalpy"
+    annotation (Placement(transformation(extent={{-50,-90},{-30,-70}})));
+  SorpLib.Basics.Sources.Fluids.VLESource sourceB_pFixed_hVar(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    p_fixed=500000,
+    use_hInput=true) "Source B: Fixed pressure and variable specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-90},{30,-70}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=10e5 - 1e3,
+    duration=2500,
+    offset=1e3,
+    startTime=0)
+    "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_mFlowVar(
+    height=2,
+    duration=2500,
+    offset=-1,
+    startTime=0) "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{80,-30},{60,-10}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_VFlowVar(
+    height=40/60000,
+    duration=2500,
+    offset=-20/60000,
+    startTime=0) "Ramp to simulate input signal of volume flow rate"
+    annotation (Placement(transformation(extent={{-80,-80},{-60,-60}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_hVar(
+    height=3e5,
+    duration=2500,
+    offset=1e5,
+    startTime=0)
+    "Ramp to simulate input signal of specific enthalpy"
+    annotation (Placement(transformation(extent={{80,-90},{60,-70}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_TVar(
+    height=90,
+    duration=2500,
+    offset=283.15,
+    startTime=0) "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{80,-60},{60,-40}})),
+                HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(sourceA_pFixed_hFixed.port, sourceB_MFlowFixed_TFixed.port)
+    annotation (Line(
+      points={{-40,80},{40,80}},
+      color={0,140,72},
+      thickness=1));
+  connect(sourceB_MFlowFixed_hFixed.port, sourceA_pFixed_TFixed.port)
+    annotation (Line(
+      points={{40,60},{-40,60}},
+      color={0,140,72},
+      thickness=1));
+  connect(sourceA_VFlowFixed_TFixed.port, sourceB_pFixed_TFixed.port)
+    annotation (Line(
+      points={{-40,40},{40,40}},
+      color={0,140,72},
+      thickness=1));
+  connect(sourceB_pFixed_hFixed.port, sourceA_VFlowFixed_hFixed.port)
+    annotation (Line(
+      points={{40,20},{-40,20}},
+      color={0,140,72},
+      thickness=1));
+  connect(sourceA_pVar_hFixed.port, sourceB_MFlowVar_TVar.port) annotation (
+      Line(
+      points={{-40,-20},{40,-20}},
+      color={0,140,72},
+      thickness=1));
+  connect(sourceB_MFlowVar_hFixed.port, sourceA_pVar_TFixed.port) annotation (
+      Line(
+      points={{40,-40},{-40,-40}},
+      color={0,140,72},
+      thickness=1));
+  connect(sourceA_VFlowVar_TFixed.port, sourceB_pFixed_TVar.port) annotation (
+      Line(
+      points={{-40,-60},{40,-60}},
+      color={0,140,72},
+      thickness=1));
+  connect(sourceB_pFixed_hVar.port, sourceA_VFlowVar_hFixed.port) annotation (
+      Line(
+      points={{40,-80},{-40,-80}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_pVar.y, sourceA_pVar_hFixed.p_input) annotation (Line(points={{-59,-30},
+          {-50,-30},{-50,-15},{-41.2,-15}},      color={0,0,127}));
+  connect(input_pVar.y, sourceA_pVar_TFixed.p_input) annotation (Line(points={{-59,-30},
+          {-50,-30},{-50,-35},{-41.2,-35}},      color={0,0,127}));
+  connect(input_VFlowVar.y, sourceA_VFlowVar_TFixed.V_flow_input) annotation (
+      Line(points={{-59,-70},{-50,-70},{-50,-58},{-41.2,-58}}, color={0,0,127}));
+  connect(input_VFlowVar.y, sourceA_VFlowVar_hFixed.V_flow_input) annotation (
+      Line(points={{-59,-70},{-50,-70},{-50,-78},{-41.2,-78}}, color={0,0,127}));
+  connect(input_mFlowVar.y, sourceB_MFlowVar_TVar.m_flow_input) annotation (
+      Line(points={{59,-20},{54,-20},{54,-18},{41.2,-18}}, color={0,0,127}));
+  connect(input_mFlowVar.y, sourceB_MFlowVar_hFixed.m_flow_input) annotation (
+      Line(points={{59,-20},{54,-20},{54,-38},{41.2,-38}}, color={0,0,127}));
+  connect(input_TVar.y, sourceB_MFlowVar_TVar.T_input) annotation (Line(points={{59,-50},
+          {50,-50},{50,-22},{41.2,-22}},          color={0,0,127}));
+  connect(input_TVar.y, sourceB_pFixed_TVar.T_input) annotation (Line(points={{59,-50},
+          {50,-50},{50,-62},{41.2,-62}},      color={0,0,127}));
+  connect(input_hVar.y, sourceB_pFixed_hVar.h_input) annotation (Line(points={{59,-80},
+          {50,-80},{50,-82},{41.2,-82}},      color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the VLE source model used to prescribe properties at a VLE
+fluid port.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 5, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_VLESource;
diff --git a/SorpLib/Basics/Sources/Fluids/Tester/package.mo b/SorpLib/Basics/Sources/Fluids/Tester/package.mo
new file mode 100644
index 0000000..7fd6936
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Sources.Fluids;
+package Tester "Models to test and varify models for fluid sources"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented fluid sources. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Basics/Sources/Fluids/Tester/package.order b/SorpLib/Basics/Sources/Fluids/Tester/package.order
new file mode 100644
index 0000000..f90a2d9
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/Tester/package.order
@@ -0,0 +1,4 @@
+Test_LiquidSource
+Test_GasSource
+Test_GasVaporMixtureSource
+Test_VLESource
diff --git a/SorpLib/Basics/Sources/Fluids/VLESource.mo b/SorpLib/Basics/Sources/Fluids/VLESource.mo
new file mode 100644
index 0000000..9d53a3d
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/VLESource.mo
@@ -0,0 +1,113 @@
+within SorpLib.Basics.Sources.Fluids;
+model VLESource
+  "Boundary model of a real fluid (i.e., with two-phase regime)"
+  extends SorpLib.Basics.Sources.BaseClasses.PartialFluidSource(
+    redeclare final Interfaces.FluidPorts.VLEPort_in port,
+    final no_components = Medium.nX,
+    final boundaryTypeStreamMassFractions=
+      SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    X_fixed=Medium.reference_X);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculate properties
+  //
+  if boundaryTypePotentialFlow ==
+    SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate then
+      d_in = Medium.density_phX(
+        p=port.p,
+        h=inStream(port.h_outflow),
+        X=cat(1, inStream(port.Xi_outflow), {1-sum(inStream(port.Xi_outflow))}))
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      entering the port";
+
+      d_out =if boundaryTypeStreamEnthalpy <>
+        SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature then
+        Medium.density_phX(
+          p=port.p,
+          h=port.h_outflow,
+          X=cat(1, port.Xi_outflow, {1-sum(port.Xi_outflow)})) else
+        Medium.density_pTX(
+          p=port.p,
+          T=T_internal,
+          X=cat(1, port.Xi_outflow, {1-sum(port.Xi_outflow)}))
+      "Density calculated with pressure, specific enthalpy or temperature, and 
+      mass fractions  leaving the port";
+
+  else
+    d_in = m_flow_fixed / V_flow_fixed
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      entering the port: Not needed, so set dummy value";
+    d_out = m_flow_fixed / V_flow_fixed
+      "Density calculated with pressure, specific enthalpy, and mass fractions 
+      leaving the port: Not needed, so set dummy value";
+
+  end if;
+
+  if boundaryTypeStreamEnthalpy ==
+    SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature then
+    h = Medium.specificEnthalpy_pTX(
+      p=port.p,
+      T=T_internal,
+      X=X_internal)
+      "Specific enthalpy calculated with pressure at port and temperature";
+
+  else
+    h = h_fixed
+      "Specific enthalpy calculated with pressure at port and temperature: Not
+      needed, so set dummy value";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(graphics={Rectangle(
+          extent={{-2,80},{2,-80}},
+          lineColor={0,140,72},
+          lineThickness=0.5,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid)}),
+          Documentation(info="<html>
+<p>
+This model can be used to specify either the pressure or mass flow rate as well as
+the specific enthalpy and independent mass fractions at a VLE port.
+</p>
+
+<h4>Options</h4>
+<ul>
+  <li>
+  <i>boundaryTypePotentialFlow</i>: Defines if pressure, mass flow rate, or volume
+  flow rate are prescribed.
+  </li>
+  <li>
+  <i>boundaryTypeStreamEnthalpy</i>: Defines if specific enthalpy or temperature
+  are prescribed.
+  </li>
+</ul>
+  
+</html>",revisions="<html>
+<ul>
+  <li>
+  December 5, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end VLESource;
diff --git a/SorpLib/Basics/Sources/Fluids/package.mo b/SorpLib/Basics/Sources/Fluids/package.mo
new file mode 100644
index 0000000..1fecbeb
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Basics.Sources;
+package Fluids "Fluid sources used to prescribe pressure, mass flow rate, specific enthalpy, and independent mass fractions"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains sources for fluid connectors to define fixed or prescribed 
+conditions. This package calculates fluid properties based on the open-source 
+Modelica Standard Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Fluids;
diff --git a/SorpLib/Basics/Sources/Fluids/package.order b/SorpLib/Basics/Sources/Fluids/package.order
new file mode 100644
index 0000000..56391de
--- /dev/null
+++ b/SorpLib/Basics/Sources/Fluids/package.order
@@ -0,0 +1,5 @@
+LiquidSource
+GasSource
+GasVaporMixtureSource
+VLESource
+Tester
diff --git a/SorpLib/Basics/Sources/Sorption/AdsorbateSource.mo b/SorpLib/Basics/Sources/Sorption/AdsorbateSource.mo
new file mode 100644
index 0000000..ce45624
--- /dev/null
+++ b/SorpLib/Basics/Sources/Sorption/AdsorbateSource.mo
@@ -0,0 +1,236 @@
+within SorpLib.Basics.Sources.Sorption;
+model AdsorbateSource
+  "Boundary model of an adsorbate source"
+
+  //
+  // Definition of parameters regarding the boundary type
+  //
+  parameter Integer no_adsorptivs = 1
+    "Number of adsorptivs (i.e., components that can be adsorbed/desorbed)"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean boundaryTypePressure = true
+    " = true, if pressure is prescribed; otherwise, mass flow rate is prescribed"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding potential and flow variables
+  //
+  parameter Boolean use_pInput = false
+    " = true, if p is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=boundaryTypePressure),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Pressure p_fixed = 1.01325e5
+    "Fixed pressure at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=boundaryTypePressure and not use_pInput));
+
+  parameter Boolean use_mFlowInput = false
+    "=true, if m_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=not boundaryTypePressure),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_fixed = -0.1
+    "Fixed sorbent mass flow rate at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=not boundaryTypePressure and not use_mFlowInput));
+
+  //
+  // Definition of parameters regarding stream variables of specific enthalpy
+  //
+  parameter Boolean use_hInput = false
+    "=true, if h is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Stream Variables - Specific Enthalpy"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.SpecificEnthalpy h_fixed = 350e3
+    "Fixed specific enthalpy at boundary"
+    annotation (Dialog(tab="General",group="Stream Variables - Specific Enthalpy",
+                enable = not use_hInput));
+
+  //
+  // Definition of parameters regarding stream variables of loadings
+  //
+  parameter Boolean use_xInput = false
+    "=true, if x is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Stream Variables - Loadings"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Units.Uptake[no_adsorptivs] x_fixed=
+    fill(0.05, no_adsorptivs)
+    "Fixed loadings at boundary"
+    annotation (Dialog(tab="General",group="Stream Variables - Loadings",
+                enable=not use_xInput));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.MassFlowRate m_flow_total
+    "Total mass flow rate";
+  Modelica.Units.SI.MassFlowRate[no_adsorptivs] m_flow_adsorpt_i
+    "Mass flow rates of adsorpt components";
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput p_input(final unit="Pa") if
+    (boundaryTypePressure and use_pInput)
+    "Input for pressure"
+     annotation (Placement(transformation(extent={{-120,30},{-80,70}}),
+       iconTransformation(extent={{-22,40},{-2,60}})));
+
+  Modelica.Blocks.Interfaces.RealInput m_flow_input(final unit="kg/s") if
+    (not boundaryTypePressure and use_mFlowInput)
+    "Input for mass flow rate"
+    annotation (Placement(transformation(extent={{-120,0},{-80,40}}),
+      iconTransformation(extent={{-22,10},{-2,30}})));
+
+  Modelica.Blocks.Interfaces.RealInput h_input(final unit="J/kg") if
+    (use_hInput)
+    "Input for specific enthalpy"
+    annotation (Placement(transformation(extent={{-120,0},{-80,-40}}),
+      iconTransformation(extent={{-22,-30},{-2,-10}})));
+
+  Modelica.Blocks.Interfaces.RealInput[no_adsorptivs] x_input(each final unit="kg/kg") if
+    (use_xInput)
+    "Input for loadings"
+    annotation (Placement(transformation(extent={{-120,-30},{-80,-70}}),
+      iconTransformation(extent={{-22,-60},{-2,-40}})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput p_internal(final unit="Pa")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealOutput m_flow_internal(final unit="kg/s")
+    "Needed for connecting to conditional connector";
+
+  Modelica.Blocks.Interfaces.RealInput h_internal(final unit="J/kg")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput[no_adsorptivs] x_internal(each final unit="kg/kg")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of ports
+  //
+public
+  SorpLib.Basics.Interfaces.SorptionPorts.AdsorbatePort_in port
+    "Adsorbate port"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+equation
+  //
+  // Connectors
+  //
+  connect(p_input,p_internal);
+  connect(m_flow_input,m_flow_internal);
+
+  connect(h_input,h_internal);
+  connect(x_input,x_internal);
+
+  if not use_pInput then
+    p_internal = p_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_mFlowInput then
+    m_flow_internal = m_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  if not use_hInput then
+    h_internal = h_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_xInput then
+    x_internal = x_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Properties at port
+  //
+  if boundaryTypePressure then
+    port.p = p_internal
+      "Pressure at port";
+
+  else
+    port.m_flow = m_flow_internal
+      "Mass flow rate at port";
+
+  end if;
+
+  port.h_outflow = h_internal
+    "Specific enthalpy at port";
+  port.x_outflow = x_internal
+    "Loadings at port";
+
+  //
+  // Calculate mass flow rates
+  //
+  m_flow_total = port.m_flow + sum(m_flow_adsorpt_i)
+    "Total mass flow rate";
+  m_flow_adsorpt_i = if avoid_events then
+    port.m_flow .* noEvent(actualStream(port.x_outflow)) else
+    port.m_flow .* actualStream(port.x_outflow)
+    "Mass flow rates of adsorpt components";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+                             Rectangle(
+          extent={{-2,80},{2,-80}},
+          lineColor={0,0,0},
+          lineThickness=0.5,
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid)}),                      Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This model can be used to specify either the pressure or the mass flow rate as
+well as the specific enthalpy and loadings at an adsorbate port. Note that the 
+mass flow rate does not indicate the total mass flow rate, but only the mass flow 
+rate of the sorbent. The mass flow rates of the adsorpt components are calculated as 
+<i>port.m_flow * actualStram(port.x_outflow)</i>.
+</p>
+
+<h4>Options</h4>
+<ul>
+  <li>
+  <i>boundaryTypePressure</i>: Defines if pressure or mass flow rate is
+  prescribed.
+  </li>
+</ul>
+  
+</html>",revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorbateSource;
diff --git a/SorpLib/Basics/Sources/Sorption/AdsorptSource.mo b/SorpLib/Basics/Sources/Sorption/AdsorptSource.mo
new file mode 100644
index 0000000..236caea
--- /dev/null
+++ b/SorpLib/Basics/Sources/Sorption/AdsorptSource.mo
@@ -0,0 +1,165 @@
+within SorpLib.Basics.Sources.Sorption;
+model AdsorptSource "Boundary model of an adsorpt source"
+
+  //
+  // Definition of parameters regarding the boundary type
+  //
+  parameter Boolean boundaryTypeLoading = true
+    " = true, if loading is prescribed; otherwise, mass flow rate is prescribed"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding potential and flow variables
+  //
+  parameter Boolean use_xInput = false
+    " = true, if x is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=boundaryTypeLoading),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Units.Uptake x_fixed = 0.05
+    "Fixed loading at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=boundaryTypeLoading and not use_xInput));
+
+  parameter Boolean use_mFlowInput = false
+    "=true, if m_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=not boundaryTypeLoading),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_fixed = -0.001
+    "Fixed adsorpt mass flow rate at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=not boundaryTypeLoading and not use_mFlowInput));
+
+  //
+  // Definition of parameters regarding stream variables of specific enthalpy
+  //
+  parameter Boolean use_hInput = false
+    "=true, if h is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Stream Variables - Specific Enthalpy"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.SpecificEnthalpy h_fixed = 350e3
+    "Fixed specific enthalpy at boundary"
+    annotation (Dialog(tab="General",group="Stream Variables - Specific Enthalpy",
+                enable = not use_hInput));
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput x_input(final unit="kg/kg") if
+    (boundaryTypeLoading and use_xInput)
+    "Input for loading"
+     annotation (Placement(transformation(extent={{-120,30},{-80,70}}),
+       iconTransformation(extent={{-22,40},{-2,60}})));
+
+  Modelica.Blocks.Interfaces.RealInput m_flow_input(final unit="kg/s") if
+    (not boundaryTypeLoading and use_mFlowInput)
+    "Input for mass flow rate"
+    annotation (Placement(transformation(extent={{-120,0},{-80,40}}),
+      iconTransformation(extent={{-22,10},{-2,30}})));
+
+  Modelica.Blocks.Interfaces.RealInput h_input(final unit="J/kg") if
+    (use_hInput)
+    "Input for specific enthalpy"
+    annotation (Placement(transformation(extent={{-120,0},{-80,-40}}),
+      iconTransformation(extent={{-22,-30},{-2,-10}})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput x_internal(final unit="kg/kg")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealOutput m_flow_internal(final unit="kg/s")
+    "Needed for connecting to conditional connector";
+
+  Modelica.Blocks.Interfaces.RealInput h_internal(final unit="J/kg")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of ports
+  //
+public
+  SorpLib.Basics.Interfaces.SorptionPorts.AdsorptPort_in port
+    "Adsorpt port"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+equation
+  //
+  // Connectors
+  //
+  connect(x_input,x_internal);
+  connect(m_flow_input,m_flow_internal);
+  connect(h_input,h_internal);
+
+  if not use_xInput then
+    x_internal = x_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_mFlowInput then
+    m_flow_internal = m_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_hInput then
+    h_internal = h_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Properties at port
+  //
+  if boundaryTypeLoading then
+    port.x = x_internal
+      "Loading at port";
+
+  else
+    port.m_flow = m_flow_internal
+      "Mass flow rate at port";
+
+  end if;
+
+  port.h_outflow = h_internal
+    "Specific enthalpy at port";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+                             Rectangle(
+          extent={{-2,80},{2,-80}},
+          lineColor={175,175,175},
+          lineThickness=0.5,
+          fillColor={175,175,175},
+          fillPattern=FillPattern.Solid)}),                      Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This model can be used to specify either the loading or the mass flow rate as
+well as the specific enthalpy at an adsorpt port.
+</p>
+
+<h4>Options</h4>
+<ul>
+  <li>
+  <i>boundaryTypeLoading</i>: Defines if loading or mass flow rate is prescribed.
+  </li>
+</ul>
+  
+</html>",revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorptSource;
diff --git a/SorpLib/Basics/Sources/Sorption/Tester/Test_AdsorbateSource.mo b/SorpLib/Basics/Sources/Sorption/Tester/Test_AdsorbateSource.mo
new file mode 100644
index 0000000..6409539
--- /dev/null
+++ b/SorpLib/Basics/Sources/Sorption/Tester/Test_AdsorbateSource.mo
@@ -0,0 +1,130 @@
+within SorpLib.Basics.Sources.Sorption.Tester;
+model Test_AdsorbateSource "Tester for adsorbate source"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource pFixed(
+    boundaryTypePressure=false,
+    p_fixed(displayUnit="Pa"),
+    m_flow_fixed=-0.1,
+    h_fixed=151688,
+    x_fixed={0.05})
+    "Adsorbate source with fixed pressure"
+    annotation (Placement(transformation(extent={{-50,40},{-30,60}})));
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource pVar(
+    use_pInput=true,
+    h_fixed=151688,
+    x_fixed={0.05}) "Adsorbate source with variable pressure"
+    annotation (Placement(transformation(extent={{-50,-42},{-30,-22}})));
+
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource mFixed(
+    p_fixed=545200000,
+    h_fixed=151688,
+    x_fixed={0.05})
+    "Adsorbate source with fixed mass flow rate"
+    annotation (Placement(transformation(extent={{50,40},{30,60}})));
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource mVar(
+    boundaryTypePressure=false,
+    use_mFlowInput=true,
+    h_fixed=151688,
+    x_fixed={0.05}) "Adsorbate source with variable mass flow rate"
+    annotation (Placement(transformation(extent={{50,-42},{30,-22}})));
+
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource pVar_hVar_X_var(
+    use_pInput=true,
+    use_hInput=true,
+    use_xInput=true)
+    "Adsorbate source with variable pressure, specific enthaly, and loadings"
+    annotation (Placement(transformation(extent={{-50,-80},{-30,-60}})));
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource mVar_h_var(
+    boundaryTypePressure=false,
+    use_mFlowInput=true,
+    use_hInput=true,
+    x_fixed={0.05})
+    "Adsorbate source with variable mass flow rate and specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-80},{30,-60}})));
+
+protected
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=1e5-1e3,
+    duration=2500,
+    offset=1e3,
+    startTime=0) "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_mVar(
+    height=0.2,
+    duration=2500,
+    offset=-0.1,
+    startTime=0) "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{80,-40},{60,-20}})),
+    HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_hVar(
+    height=-0.5e5,
+    duration=2500,
+    offset=1.5e5,
+    startTime=0) "Ramp to simulate input signal of specific enthalpy"
+    annotation (Placement(transformation(extent={{80,-80},{60,-60}})),
+      HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_xVar(
+    height=0.2,
+    duration=2500,
+    offset=0.05,
+    startTime=0) "Ramp to simulate input signal of loading" annotation (
+      Placement(transformation(extent={{-80,-80},{-60,-60}})), HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(pFixed.port, mFixed.port) annotation (Line(
+      points={{-40,50},{40,50}},
+      color={0,0,0},
+      thickness=1));
+  connect(pVar.port, mVar.port) annotation (Line(
+      points={{-40,-32},{40,-32}},
+      color={0,0,0},
+      thickness=1));
+  connect(pVar_hVar_X_var.port, mVar_h_var.port) annotation (Line(
+      points={{-40,-70},{40,-70}},
+      color={0,0,0},
+      thickness=1));
+
+  connect(input_pVar.y, pVar.p_input) annotation (Line(points={{-59,-30},{-50,-30},
+          {-50,-27},{-41.2,-27}}, color={0,0,127}));
+  connect(input_mVar.y, mVar.m_flow_input) annotation (Line(points={{59,-30},{41.2,
+          -30}},                     color={0,0,127}));
+  connect(input_pVar.y, pVar_hVar_X_var.p_input) annotation (Line(points={{-59,-30},
+          {-50,-30},{-50,-65},{-41.2,-65}}, color={0,0,127}));
+  connect(input_mVar.y, mVar_h_var.m_flow_input) annotation (Line(points={{59,-30},
+          {50,-30},{50,-68},{41.2,-68}}, color={0,0,127}));
+  connect(input_hVar.y, mVar_h_var.h_input) annotation (Line(points={{59,-70},{50,
+          -70},{50,-72},{41.2,-72}}, color={0,0,127}));
+  connect(input_hVar.y, pVar_hVar_X_var.h_input) annotation (Line(points={{59,-70},
+          {50,-70},{50,-90},{-50,-90},{-50,-72},{-41.2,-72}}, color={0,0,127}));
+  connect(input_xVar.y, pVar_hVar_X_var.x_input[1]) annotation (Line(points={{-59,
+          -70},{-52,-70},{-52,-75},{-41.2,-75}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the adsorbate source model used to prescribe properties 
+at an adsorbate port.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AdsorbateSource;
diff --git a/SorpLib/Basics/Sources/Sorption/Tester/Test_AdsorptSource.mo b/SorpLib/Basics/Sources/Sorption/Tester/Test_AdsorptSource.mo
new file mode 100644
index 0000000..00f75cc
--- /dev/null
+++ b/SorpLib/Basics/Sources/Sorption/Tester/Test_AdsorptSource.mo
@@ -0,0 +1,92 @@
+within SorpLib.Basics.Sources.Sorption.Tester;
+model Test_AdsorptSource "Tester for adsorpt source"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Sorption.AdsorptSource xFixed(
+    m_flow_fixed=-0.1,
+    h_fixed=151688,
+    x_fixed=0.05) "Adsorbate source with fixed loading"
+    annotation (Placement(transformation(extent={{-50,40},{-30,60}})));
+  SorpLib.Basics.Sources.Sorption.AdsorptSource xVar(use_xInput=true,
+    h_fixed=151688) "Adsorbate source with variable loading"
+    annotation (Placement(transformation(extent={{-50,-60},{-30,-40}})));
+
+  SorpLib.Basics.Sources.Sorption.AdsorptSource mFixed(boundaryTypeLoading=false,
+    h_fixed=151688)
+    "Adsorbate source with fixed mass flow rate"
+    annotation (Placement(transformation(extent={{50,40},{30,60}})));
+  SorpLib.Basics.Sources.Sorption.AdsorptSource mVar_hVar(
+    boundaryTypeLoading=false,
+    use_hInput=true,
+    use_mFlowInput=true,
+    h_fixed=151688)
+    "Adsorbate source with variable mass flow rate and specific enthalpy"
+    annotation (Placement(transformation(extent={{50,-60},{30,-40}})));
+
+protected
+  Modelica.Blocks.Sources.Ramp input_xVar(
+    height=0.2,
+    duration=2500,
+    offset=0.05,
+    startTime=0) "Ramp to simulate input signal of loading"
+    annotation (Placement(transformation(extent={{-80,-58},{-60,-38}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_mVar(
+    height=0.2,
+    duration=2500,
+    offset=-0.1,
+    startTime=0) "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{80,-40},{60,-20}})),
+    HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_hVar(
+    height=-0.5e5,
+    duration=2500,
+    offset=1.5e5,
+    startTime=0) "Ramp to simulate input signal of specific enthalpy"
+    annotation (Placement(transformation(extent={{80,-80},{60,-60}})),
+      HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(xFixed.port, mFixed.port) annotation (Line(
+      points={{-40,50},{40,50}},
+      color={175,175,175},
+      thickness=1));
+  connect(xVar.port, mVar_hVar.port) annotation (Line(
+      points={{-40,-50},{40,-50}},
+      color={175,175,175},
+      thickness=1));
+
+  connect(input_xVar.y, xVar.x_input) annotation (Line(points={{-59,-48},{-50,-48},
+          {-50,-45},{-41.2,-45}}, color={0,0,127}));
+  connect(input_mVar.y, mVar_hVar.m_flow_input) annotation (Line(points={{59,-30},
+          {50,-30},{50,-48},{41.2,-48}}, color={0,0,127}));
+  connect(input_hVar.y, mVar_hVar.h_input) annotation (Line(points={{59,-70},{50,
+          -70},{50,-52},{41.2,-52}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the adsorpt source model used to prescribe properties 
+at an adsorpt port.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AdsorptSource;
diff --git a/SorpLib/Basics/Sources/Sorption/Tester/package.mo b/SorpLib/Basics/Sources/Sorption/Tester/package.mo
new file mode 100644
index 0000000..43c2507
--- /dev/null
+++ b/SorpLib/Basics/Sources/Sorption/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics.Sources.Sorption;
+package Tester "Models to test and varify models for sorption sources"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented sorption
+sources. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Basics/Sources/Sorption/Tester/package.order b/SorpLib/Basics/Sources/Sorption/Tester/package.order
new file mode 100644
index 0000000..14b729a
--- /dev/null
+++ b/SorpLib/Basics/Sources/Sorption/Tester/package.order
@@ -0,0 +1,2 @@
+Test_AdsorbateSource
+Test_AdsorptSource
diff --git a/SorpLib/Basics/Sources/Sorption/package.mo b/SorpLib/Basics/Sources/Sorption/package.mo
new file mode 100644
index 0000000..8a51ccf
--- /dev/null
+++ b/SorpLib/Basics/Sources/Sorption/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics.Sources;
+package Sorption "Sorption sources used to prescribe pressure, mass flow rate, specific enthalpy, and loadings"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains sources for sorption connectors to define fixed or prescribed 
+conditions. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Sorption;
diff --git a/SorpLib/Basics/Sources/Sorption/package.order b/SorpLib/Basics/Sources/Sorption/package.order
new file mode 100644
index 0000000..b89258b
--- /dev/null
+++ b/SorpLib/Basics/Sources/Sorption/package.order
@@ -0,0 +1,3 @@
+AdsorbateSource
+AdsorptSource
+Tester
diff --git a/SorpLib/Basics/Sources/Thermal/HeatSource.mo b/SorpLib/Basics/Sources/Thermal/HeatSource.mo
new file mode 100644
index 0000000..3dcbdbe
--- /dev/null
+++ b/SorpLib/Basics/Sources/Thermal/HeatSource.mo
@@ -0,0 +1,147 @@
+within SorpLib.Basics.Sources.Thermal;
+model HeatSource
+  "Boundary model of a heat source"
+
+  //
+  // Definition of parameters regarding the boundary type
+  //
+  parameter SorpLib.Choices.BoundaryThermal boundaryType=
+    SorpLib.Choices.BoundaryThermal.Temperature
+    "Prescribed variable for potential or flow"
+    annotation (Dialog(tab="General", group="Boundary Type"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding potential and flow variables
+  //
+  parameter Boolean use_TInput = false
+    " = true, if T is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryType ==
+                SorpLib.Choices.BoundaryThermal.Temperature)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Temperature T_fixed = 293.15
+    "Fixed temperature at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryType ==
+                SorpLib.Choices.BoundaryThermal.Temperature)
+                and not use_TInput));
+
+  parameter Boolean use_QFlowInput = false
+    "=true, if Q_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryType ==
+                SorpLib.Choices.BoundaryThermal.HeatFlowRate)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.HeatFlowRate Q_flow_fixed = 25
+    "Fixed heat flow at boundary"
+    annotation (Dialog(tab="General",group="Potential and Flow Variables",
+                enable=(boundaryType ==
+                SorpLib.Choices.BoundaryThermal.HeatFlowRate)
+                and not use_QFlowInput));
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput T_input(final unit="K") if
+    (boundaryType == SorpLib.Choices.BoundaryThermal.Temperature and
+    use_TInput)
+    "Input for temperature"
+    annotation (Placement(transformation(extent={{-40,30},{0,70}}),
+       iconTransformation(extent={{-20,42},{0,62}})));
+
+  Modelica.Blocks.Interfaces.RealInput Q_flow_input(final unit="W") if
+    (boundaryType == SorpLib.Choices.BoundaryThermal.HeatFlowRate and
+    use_QFlowInput)
+    "Input for heat flow rate"
+    annotation (Placement(transformation(extent={{-40,-70},{0,-30}}),
+      iconTransformation(extent={{-20,-60},{0,-40}})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput T_internal(final unit="K")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput Q_flow_internal(final unit="W")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of ports
+  //
+public
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in port
+    "Heat port"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+equation
+  //
+  // Connectors
+  //
+  connect(T_input,T_internal);
+  connect(Q_flow_input,Q_flow_internal);
+
+  if not use_TInput then
+    T_internal = T_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_QFlowInput then
+    Q_flow_internal = Q_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Properties at port
+  //
+  if boundaryType == SorpLib.Choices.BoundaryThermal.Temperature then
+    port.T = T_internal
+      "Temperature at port";
+
+  else
+    port.Q_flow = Q_flow_internal
+      "Heat flow rate at port";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+                             Rectangle(
+          extent={{-2,80},{2,-80}},
+          lineColor={238,46,47},
+          lineThickness=0.5,
+          fillColor={238,46,47},
+          fillPattern=FillPattern.Solid)}),                      Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This model can be used to specify either the temperature or the heat flow rate 
+at a heat port.
+</p>
+
+<h4>Options</h4>
+<ul>
+  <li>
+  <i>boundaryType</i>: Defines if temperature or heat flow rate is prescribed.
+  </li>
+</ul>
+  
+</html>",revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end HeatSource;
diff --git a/SorpLib/Basics/Sources/Thermal/Tester/Test_HeatSource.mo b/SorpLib/Basics/Sources/Thermal/Tester/Test_HeatSource.mo
new file mode 100644
index 0000000..06222ba
--- /dev/null
+++ b/SorpLib/Basics/Sources/Thermal/Tester/Test_HeatSource.mo
@@ -0,0 +1,84 @@
+within SorpLib.Basics.Sources.Thermal.Tester;
+model Test_HeatSource "Tester for heat source"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  HeatSource TFixed(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=false) "Heat source with fixed temperature"
+    annotation (Placement(transformation(extent={{-50,20},{-30,40}})));
+  HeatSource TVar(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true) "Heat source with variable temperature"
+    annotation (Placement(transformation(extent={{-50,-40},{-30,-20}})));
+
+  HeatSource QFixed(
+    boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=false) "Heat source with fixed heat flow rate"
+    annotation (Placement(transformation(extent={{50,20},{30,40}})));
+  HeatSource QVar(
+    boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=true) "Heat source with variable heat flow"
+    annotation (Placement(transformation(extent={{50,-40},{30,-20}})));
+
+  Modelica.Blocks.Sources.Ramp input_TVar(
+    height=80,
+    duration=2500,
+    offset=293.15,
+    startTime=0)
+    "Ramp to simulate input signal of temperrature"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_QVar(
+    height=2000,
+    duration=2500,
+    offset=-1000,
+    startTime=0)
+    "Ramp to simulate input signal of heat flow"
+    annotation (Placement(transformation(extent={{80,-40},{60,-20}})),
+    HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(TFixed.port, QFixed.port) annotation (Line(
+      points={{-40,30},{40,30}},
+      color={238,46,47},
+      thickness=1));
+  connect(TVar.port, QVar.port) annotation (Line(
+      points={{-40,-30},{40,-30}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_TVar.y, TVar.T_input) annotation (Line(points={{-59,-30},{-50,-30},
+          {-50,-24.8},{-41,-24.8}}, color={0,0,127}));
+  connect(input_QVar.y, QVar.Q_flow_input) annotation (Line(points={{59,-30},{50,
+          -30},{50,-36},{41,-36},{41,-35}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the heat source model used to prescribe properties at
+a heat port.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 4, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 11, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_HeatSource;
diff --git a/SorpLib/Basics/Sources/Thermal/Tester/package.mo b/SorpLib/Basics/Sources/Thermal/Tester/package.mo
new file mode 100644
index 0000000..576175c
--- /dev/null
+++ b/SorpLib/Basics/Sources/Thermal/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics.Sources.Thermal;
+package Tester "Models to test and varify models for thermal sources"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented thermal
+sources. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Basics/Sources/Thermal/Tester/package.order b/SorpLib/Basics/Sources/Thermal/Tester/package.order
new file mode 100644
index 0000000..1eba10d
--- /dev/null
+++ b/SorpLib/Basics/Sources/Thermal/Tester/package.order
@@ -0,0 +1 @@
+Test_HeatSource
diff --git a/SorpLib/Basics/Sources/Thermal/package.mo b/SorpLib/Basics/Sources/Thermal/package.mo
new file mode 100644
index 0000000..45daa54
--- /dev/null
+++ b/SorpLib/Basics/Sources/Thermal/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics.Sources;
+package Thermal "Thermal sources used to prescribe heat flow rate or temperature"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains sources for thermal connectors to define fixed or prescribed 
+conditions. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Thermal;
diff --git a/SorpLib/Basics/Sources/Thermal/package.order b/SorpLib/Basics/Sources/Thermal/package.order
new file mode 100644
index 0000000..6cdbdf9
--- /dev/null
+++ b/SorpLib/Basics/Sources/Thermal/package.order
@@ -0,0 +1,2 @@
+HeatSource
+Tester
diff --git a/SorpLib/Basics/Sources/package.mo b/SorpLib/Basics/Sources/package.mo
new file mode 100644
index 0000000..312a13f
--- /dev/null
+++ b/SorpLib/Basics/Sources/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics;
+package Sources "Library containing models defining fixed or prescribed boundary conditions"
+  extends Modelica.Icons.SourcesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains generic sources for thermal or fluid connectors to define 
+fixed or prescribed conditions. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Sources;
diff --git a/SorpLib/Basics/Sources/package.order b/SorpLib/Basics/Sources/package.order
new file mode 100644
index 0000000..4301334
--- /dev/null
+++ b/SorpLib/Basics/Sources/package.order
@@ -0,0 +1,4 @@
+BaseClasses
+Thermal
+Fluids
+Sorption
diff --git a/SorpLib/Basics/Volumes/AdsorbateVolumes/AdsorbatePureGasVolume.mo b/SorpLib/Basics/Volumes/AdsorbateVolumes/AdsorbatePureGasVolume.mo
new file mode 100644
index 0000000..b252c09
--- /dev/null
+++ b/SorpLib/Basics/Volumes/AdsorbateVolumes/AdsorbatePureGasVolume.mo
@@ -0,0 +1,333 @@
+within SorpLib.Basics.Volumes.AdsorbateVolumes;
+model AdsorbatePureGasVolume
+  "Homogenous adsorbate volume of an ideal gas for pure component adsorption"
+  extends
+    SorpLib.Basics.Volumes.BaseClasses.PartialPureComponentAdsorbateVolume(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.GasPort_in fp_sorption,
+    redeclare replaceable package Medium = SorpLib.Media.IdealGases.H2O
+      constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa,
+    redeclare replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGel_Toth_WangDouglasLeVan2009_Gas
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+      redeclare package Medium = Medium,
+      stateVariables=independentStateVariables,
+      calcCaloricProperties=true,
+      calcEntropicProperties=false,
+      calcAdsorptAdsorbateState=useAdsorbatePorts,
+      calcDerivativesIsotherm=true,
+      calcDerivativesMassEnergyBalance=true,
+      calcDerivativesEntropyBalance=false,
+      p_adsorpt=p,
+      x_adsorpt=x,
+      T_adsorpt=T,
+      avoidEvents=avoid_events));
+
+equation
+  //
+  // Mass balance
+  //
+  masor_flow = if useAdsorbatePorts then
+    ap_xMinus.m_flow + ap_xPlus.m_flow else 0
+    "Sum of all adsorbent mass flow rates across adsorbate boundaries";
+  mas_flow = if useAdsorbatePorts then (if avoid_events then
+    ap_xMinus.m_flow * sum(noEvent(actualStream(ap_xMinus.x_outflow))) +
+    ap_xPlus.m_flow * sum(noEvent(actualStream(ap_xPlus.x_outflow))) else
+    ap_xMinus.m_flow * sum(actualStream(ap_xMinus.x_outflow)) +
+    ap_xPlus.m_flow * sum(actualStream(ap_xPlus.x_outflow))) else 0
+    "Sum of all sorption mass flow rates across adsorbate boundaries";
+  md_flow = sum(dp_xMinus.m_flow) + sum(dp_xPlus.m_flow)
+    "Sum of all diffusive mass flow rates across boundaries";
+  ms_flow = sum(fp_sorption.m_flow)
+    "Sum of all sorption mass flow rates across boundaries";
+
+  //
+  // Energy balance
+  //
+  if avoid_events then
+    if useAdsorbatePorts then
+      Hb_flow =
+        ap_xMinus.m_flow * noEvent(actualStream(ap_xMinus.h_outflow)) +
+        ap_xPlus.m_flow * noEvent(actualStream(ap_xPlus.h_outflow)) +
+        sum(dp_xMinus.m_flow .* noEvent(actualStream(dp_xMinus.h_outflow))) +
+        sum(dp_xPlus.m_flow .* noEvent(actualStream(dp_xPlus.h_outflow))) +
+        sum(fp_sorption.m_flow .* noEvent(actualStream(fp_sorption.h_outflow)))
+        "Sum of all enthalpy flow rates across boundaries";
+
+    else
+      Hb_flow =
+        sum(dp_xMinus.m_flow .* noEvent(actualStream(dp_xMinus.h_outflow))) +
+        sum(dp_xPlus.m_flow .* noEvent(actualStream(dp_xPlus.h_outflow))) +
+        sum(fp_sorption.m_flow .* noEvent(actualStream(fp_sorption.h_outflow)))
+        "Sum of all enthalpy flow rates across boundaries";
+
+    end if;
+
+  else
+    if useAdsorbatePorts then
+      Hb_flow =
+        ap_xMinus.m_flow * actualStream(ap_xMinus.h_outflow) +
+        ap_xPlus.m_flow * actualStream(ap_xPlus.h_outflow) +
+        sum(dp_xMinus.m_flow .* actualStream(dp_xMinus.h_outflow)) +
+        sum(dp_xPlus.m_flow .* actualStream(dp_xPlus.h_outflow)) +
+        sum(fp_sorption.m_flow .* actualStream(fp_sorption.h_outflow))
+        "Sum of all enthalpy flow rates across boundaries";
+
+    else
+      Hb_flow =
+        sum(dp_xMinus.m_flow .* actualStream(dp_xMinus.h_outflow)) +
+        sum(dp_xPlus.m_flow .* actualStream(dp_xPlus.h_outflow)) +
+        sum(fp_sorption.m_flow .* actualStream(fp_sorption.h_outflow))
+        "Sum of all enthalpy flow rates across boundaries";
+
+    end if;
+  end if;
+
+  //
+  // Summary record
+  //
+  adsorbateProperties.ma_flow_yMinus = 0
+    "Adsorbate mass flow rate at port '-dy/2'";
+  adsorbateProperties.ma_flow_yPlus = 0
+    "Adsorbate mass flow rate at port '+dy/2'";
+  adsorbateProperties.ma_flow_zMinus = 0
+    "Adsorbate mass flow rate at port '-dz/2'";
+  adsorbateProperties.ma_flow_zPlus = 0
+    "Adsorbate mass flow rate at port '+dz/2'";
+
+  adsorbateProperties.md_flow_yMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dy/2'";
+  adsorbateProperties.md_flow_yPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dy/2'";
+  adsorbateProperties.md_flow_zMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dz/2'";
+  adsorbateProperties.md_flow_zPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents an adsorbate volume, applying a lumped modeling approach, for
+pure component adsorption of an adsorptive described by an ideal gas. Depending 
+on the volume setup, this model may have up to seven heat ports (i.e., two for 
+each spatial direction of a cartesian coordinate system and one for sorption). 
+Furthermore, this model has adsorbate and diffusive (i.e., adsorpt) ports in 
+y-direction and a sorption fluid port. These ports allow for the combination of 
+several adsorbate volumes to create a spatially distributed model.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equations are the momentum, mass, and energy balance. According to
+the staggered grid approach, the momentum balance is not solved within the volume but 
+at the volume's boundaries via so-called 
+<a href=\"Modelica://SorpLib.Components.Fittings\">flow models</a> or
+<a href=\"Modelica://SorpLib.Components.MassTransfer\">mass transfer models</a>. Hennce, 
+no pressure losses occur within the volume:
+</p>
+<pre>
+    p = ap_xMinus.p;
+</pre>
+<pre>
+    p = ap_xPlus.p;
+</pre>
+<pre>
+    p = fp_sorption.p;
+</pre>
+<p>
+For the diffusive (i.e., adsorpt) ports, the potential variables are the loading:
+</p>
+<pre>
+    x = dp_xMinus.x;
+</pre>
+<pre>
+    x = dp_xPlus.x;
+</pre>
+
+<p>
+Regarding the mass and energy balances, either steady-state or tansient balnaces
+can be selected. When using the pressure <i>p</i>, temperature <i>T</i>, and sorbent
+mass <i>m<sub>sor</sub></i> as independent states, the adsorbent mass balance is 
+defined as
+</p>
+<pre>
+    (dm<sub>sor</sub>/d&tau;) = &sum; m<sub>a,sor,flow</sub>;
+</pre>
+<p>
+the adsorpt mass balance is defined as
+</p>
+<pre>
+    (dm<sub>adsorpt</sub>/d&tau;) = (dm<sub>sor</sub>/d&tau;) * x + m<sub>sor</sub> * (dx/d&tau;) = (dm<sub>sor</sub>/d&tau;) * x + m<sub>sor</sub> * [(&part;x/&part;p)<sub>T</sub> * (dp/d&tau;) + (&part;x/&part;T)<sub>p</sub> * (dT/d&tau;)] = &sum; m<sub>s,flow</sub> + &sum; m<sub>a,s,flow</sub> + &sum; m<sub>d,flow</sub>;
+</pre> 
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU<sub>adsorbate</sub>/d&tau;) = (dm<sub>sor</sub>/d&tau;) * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [(du<sub>sor</sub>/d&tau;) + (d(x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>)/d&tau;] = (dm<sub>sor</sub>/d&tau;) * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [(v<sub>sor</sub>) + (h<sub>adsorpt</sub> - p * v<sub>adsorpt</sub>) * (&part;x/&part;p)<sub>T</sub> - (v<sub>sor</sub> + x<sub>adsorpt</sub> * v<sub>adsorpt</sub>)] * (dp/d&tau;) + m<sub>sor</sub> * [(c<sub>sor</sub>) + (c<sub>adsorpt</sub> * x<sub>adsorpt</sub> + h<sub>adsorpt</sub> * (&part;x/&part;T)<sub>p</sub> - x<sub>adsorpt</sub> * (&part;v<sub>adsorpt</sub>/&part;T)<sub>p</sub> - v<sub>adsorpt</sub> * (&part;x/&part;T)<sub>p</sub>)] * (dT/d&tau;) = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+When using the loading <i>x</i>, temperature <i>T</i>, and sorbent mass <i>m<sub>sor</sub></i> 
+as independent states, the adsorbent mass balance is defined as
+</p>
+</p>
+<pre>
+    (dm<sub>sor</sub>/d&tau;) = &sum; m<sub>a,sor,flow</sub>;
+</pre>
+<p>
+the adsorpt mass balance is defined as
+</p>
+<pre>
+    (dm<sub>adsorpt</sub>/d&tau;) = (dm<sub>sor</sub>/d&tau;) * x + m<sub>sor</sub> * (dx/d&tau;) = &sum; m<sub>s,flow</sub> + &sum; m<sub>a,s,flow</sub> + &sum; m<sub>d,flow</sub>;
+</pre> 
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU<sub>adsorbate</sub>/d&tau;) = (dm<sub>sor</sub>/d&tau;) * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [(du<sub>sor</sub>/d&tau;) + (d(x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>)/d&tau;] = (dm<sub>sor</sub>/d&tau;) * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [(h<sub>adsorpt</sub> - p * v<sub>adsorpt</sub> - x<sub>adsorpt</sub> * v<sub>adsorpt</sub> / (&part;x/&part;p)<sub>T</sub>)] * (dx/d&tau;) + m<sub>sor</sub> * [(c<sub>sor</sub>) + (c<sub>adsorpt</sub> * x<sub>adsorpt</sub> - x<sub>adsorpt</sub> * (&part;v<sub>adsorpt</sub>/&part;T)<sub>p</sub>] * (dT/d&tau;) = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+Herein, <i>dm<sub>sor</sub>/d&tau;</i> is the derivative of the adsorbent mass w.r.t. 
+time, <i>dm<sub>adsorpt</sub>/d&tau;</i> is the derivative of the adsorpt mass w.r.t. 
+time, <i>dU<sub>adsorbate</sub>/d&tau;</i> is the derivative of the uptake-averaged 
+internal energy w.r.t. time, <i>dp/d&tau;</i> is the derivative of the pressure w.r.t. 
+time, <i>dx/d&tau;</i> is the derivative of the loading w.r.t. time, and <i>dT/d&tau;</i> 
+is the derivative of the temperature w.r.t. time,
+
+The expression <i>(&part;x/&part;p)<sub>T</sub></i> describes the partial derivative of 
+the loading w.r.t. pressure at constant temperature, <i>(&part;x/&part;T)<sub>p</sub></i> 
+is the partial derivative of the loading w.r.t. temperature at constant pressure, and 
+<i>(&part;v<sub>adsorpt</sub>/&part;T)<sub>p</sub></i> is the partial derivative of the 
+specific volume of the adsorpt w.r.t. temperature at constant pressure.
+
+The expression <i>m<sub>a,sor,flow</sub></i> is the sum of the adsorbent mass flow rates 
+across the adsorbate ports, <i>m<sub>s,flow</sub></i> is the sum of the sorption mass 
+flow rates across the adsorbate ports, <i>m<sub>a,s,flow</sub></i> is the sum of the 
+sorption mass flow rates, <i>m<sub>d,flow</sub></i> is the sum of the diffusive mass flow 
+rates, <i>H<sub>b,flow</sub></i> is the sum of the enthalpy flow rates, and 
+<i>Q<sub>b,flow</sub></i> is the sum of the heat flow rates.
+
+The variable <i>v<sub>sor</sub></i> describes the specific volume of the adsorbent, 
+<i>u<sub>sor</sub></i> is the specific internal energy of the adsorbent, <i>c<sub>sor</sub></i> 
+is the specific heat capacity of the adsorbent, <i><SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub></i> 
+is the uptake-averaged specific internal energy of the adsorpt, <i>v<sub>adsorpt</sub></i> 
+is the specific volume of the last adsorbed molecule, <i>h<sub>adsorpt</sub></i> is the 
+specific enthalpy of the last adsorbed molecule, and <i>c<sub>adsorpt</sub></i> is the 
+specific heat capacity of the adsorpt.
+</p>
+
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Adsorption equilibrium with all adsorptive beeing adsorbed and in adsorpt
+  phase (i.e., chemical equilibrium).
+  </li>
+  <li>
+  The sorbent and adsorpt have the same pressure (i.e., mechanical equilibrium).
+  </li>
+  <li>
+  The sorbent and adsorpt have the same temperature (i.e., thermal equilibrium).
+  </li>
+  <li>
+  Specific volume of the adsorpt may only depend on the temperature and is thus
+  a macroscopic property without averaging.
+  </li>
+  <li>
+  Specific heat capacity of the adsorpt may only depend on the temperature or is
+  assumed to already be an uptake-averaged specific heat capacity.
+  </li>
+  <li>
+  Ideal and inert sorbent with constant specific volume.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to model the adsorbate within adsorber heat exchanger or other
+adsorption modules.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <i>useAdsorbatePorts</i>:
+  Defines if adsorbate ports are connected (requires uptake-averaged properties).
+  </li>
+  <li>
+  <i>useDiffusivePorts</i>:
+  Defines if diffusive ports are connected (requires uptake-averaged properties).
+  </li>
+  <li>
+  <i>calcUptakeAveragedProperties</i>:
+  Defines if duptake-averaged properties are calculated.
+  </li>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <br/>
+  <li>
+  <i>type_adsorbentMassBalance</i>:
+  Defines the type of the adsorbent mass balance.
+  </li>
+  <li>
+  <i>type_adsorptMassBalance</i>:
+  Defines the type of the adsorpt mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+transient mass balances are combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has two dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> and temperature <i>T</i>, or
+  </li>
+  <li>
+  loading <i>x</i> and  temperature <i>T</i> (recommended).
+  </li>
+</ul>
+<p>
+Furthermore, this model has the adsorbent mass <i>m_sor</i> as dynamic state if the
+adsorbate ports are connected to other models (see option 'useAdsorbatePorts').
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorbatePureGasVolume;
diff --git a/SorpLib/Basics/Volumes/AdsorbateVolumes/AdsorbatePureVLEVolume.mo b/SorpLib/Basics/Volumes/AdsorbateVolumes/AdsorbatePureVLEVolume.mo
new file mode 100644
index 0000000..47a7200
--- /dev/null
+++ b/SorpLib/Basics/Volumes/AdsorbateVolumes/AdsorbatePureVLEVolume.mo
@@ -0,0 +1,337 @@
+within SorpLib.Basics.Volumes.AdsorbateVolumes;
+model AdsorbatePureVLEVolume
+  "Homogenous adsorbate volume of a real fluid (i.e., with a two-phase regime) for pure component adsorption"
+  extends
+    SorpLib.Basics.Volumes.BaseClasses.PartialPureComponentAdsorbateVolume(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in fp_sorption,
+    redeclare replaceable package Medium = Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium,
+    redeclare replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+      redeclare package Medium = Medium,
+      stateVariables=independentStateVariables,
+      calcCaloricProperties=true,
+      calcEntropicProperties=false,
+      calcAdsorptAdsorbateState=useAdsorbatePorts,
+      calcDerivativesIsotherm=true,
+      calcDerivativesMassEnergyBalance=true,
+      calcDerivativesEntropyBalance=false,
+      p_adsorpt=p,
+      x_adsorpt=x,
+      T_adsorpt=T,
+      avoidEvents=avoid_events));
+
+equation
+  //
+  // Mass balance
+  //
+  masor_flow = if useAdsorbatePorts then
+    ap_xMinus.m_flow + ap_xPlus.m_flow else 0
+    "Sum of all adsorbent mass flow rates across adsorbate boundaries";
+  mas_flow = if useAdsorbatePorts then (if avoid_events then
+    ap_xMinus.m_flow * sum(noEvent(actualStream(ap_xMinus.x_outflow))) +
+    ap_xPlus.m_flow * sum(noEvent(actualStream(ap_xPlus.x_outflow))) else
+    ap_xMinus.m_flow * sum(actualStream(ap_xMinus.x_outflow)) +
+    ap_xPlus.m_flow * sum(actualStream(ap_xPlus.x_outflow))) else 0
+    "Sum of all sorption mass flow rates across adsorbate boundaries";
+  md_flow = sum(dp_xMinus.m_flow) + sum(dp_xPlus.m_flow)
+    "Sum of all diffusive mass flow rates across boundaries";
+  ms_flow = sum(fp_sorption.m_flow)
+    "Sum of all sorption mass flow rates across boundaries";
+
+  //
+  // Energy balance
+  //
+  if avoid_events then
+    if useAdsorbatePorts then
+      Hb_flow =
+        ap_xMinus.m_flow * noEvent(actualStream(ap_xMinus.h_outflow)) +
+        ap_xPlus.m_flow * noEvent(actualStream(ap_xPlus.h_outflow)) +
+        sum(dp_xMinus.m_flow .* noEvent(actualStream(dp_xMinus.h_outflow))) +
+        sum(dp_xPlus.m_flow .* noEvent(actualStream(dp_xPlus.h_outflow))) +
+        sum(fp_sorption.m_flow .* noEvent(actualStream(fp_sorption.h_outflow)))
+        "Sum of all enthalpy flow rates across boundaries";
+
+    else
+      Hb_flow =
+        sum(dp_xMinus.m_flow .* noEvent(actualStream(dp_xMinus.h_outflow))) +
+        sum(dp_xPlus.m_flow .* noEvent(actualStream(dp_xPlus.h_outflow))) +
+        sum(fp_sorption.m_flow .* noEvent(actualStream(fp_sorption.h_outflow)))
+        "Sum of all enthalpy flow rates across boundaries";
+
+    end if;
+
+  else
+    if useAdsorbatePorts then
+      Hb_flow =
+        ap_xMinus.m_flow * actualStream(ap_xMinus.h_outflow) +
+        ap_xPlus.m_flow * actualStream(ap_xPlus.h_outflow) +
+        sum(dp_xMinus.m_flow .* actualStream(dp_xMinus.h_outflow)) +
+        sum(dp_xPlus.m_flow .* actualStream(dp_xPlus.h_outflow)) +
+        sum(fp_sorption.m_flow .* actualStream(fp_sorption.h_outflow))
+        "Sum of all enthalpy flow rates across boundaries";
+
+    else
+      Hb_flow =
+        sum(dp_xMinus.m_flow .* actualStream(dp_xMinus.h_outflow)) +
+        sum(dp_xPlus.m_flow .* actualStream(dp_xPlus.h_outflow)) +
+        sum(fp_sorption.m_flow .* actualStream(fp_sorption.h_outflow))
+        "Sum of all enthalpy flow rates across boundaries";
+
+    end if;
+  end if;
+
+  //
+  // Summary record
+  //
+  adsorbateProperties.ma_flow_yMinus = 0
+    "Adsorbate mass flow rate at port '-dy/2'";
+  adsorbateProperties.ma_flow_yPlus = 0
+    "Adsorbate mass flow rate at port '+dy/2'";
+  adsorbateProperties.ma_flow_zMinus = 0
+    "Adsorbate mass flow rate at port '-dz/2'";
+  adsorbateProperties.ma_flow_zPlus = 0
+    "Adsorbate mass flow rate at port '+dz/2'";
+
+  adsorbateProperties.md_flow_yMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dy/2'";
+  adsorbateProperties.md_flow_yPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dy/2'";
+  adsorbateProperties.md_flow_zMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dz/2'";
+  adsorbateProperties.md_flow_zPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents an adsorbate volume, applying a lumped modeling approach, for
+pure component adsorption of an adsorptive described by a real fluid (i.e., with a
+two-phase regime). Depending on the volume setup, this model may have up to seven 
+heat ports (i.e., two for each spatial direction of a cartesian coordinate system 
+and one for sorption). Furthermore, this model has adsorbate and diffusive (i.e.,
+adsorpt) ports in y-direction and a sorption fluid port. These ports allow for the 
+combination of several adsorbate volumes to create a spatially distributed model.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equations are the momentum, mass, and energy balance. According to
+the staggered grid approach, the momentum balance is not solved within the volume but 
+at the volume's boundaries via so-called 
+<a href=\"Modelica://SorpLib.Components.Fittings\">flow models</a> or
+<a href=\"Modelica://SorpLib.Components.MassTransfer\">mass transfer models</a>. Hennce, 
+no pressure losses occur within the volume:
+</p>
+<pre>
+    p = ap_xMinus.p;
+</pre>
+<pre>
+    p = ap_xPlus.p;
+</pre>
+<pre>
+    p = fp_sorption.p;
+</pre>
+<p>
+For the diffusive (i.e., adsorpt) ports, the potential variables are the loading:
+</p>
+<pre>
+    x = dp_xMinus.x;
+</pre>
+<pre>
+    x = dp_xPlus.x;
+</pre>
+
+<p>
+Regarding the mass and energy balances, either steady-state or tansient balnaces
+can be selected. When using the pressure <i>p</i>, temperature <i>T</i>, and sorbent
+mass <i>m<sub>sor</sub></i> as independent states, the adsorbent mass balance is 
+defined as
+</p>
+<pre>
+    (dm<sub>sor</sub>/d&tau;) = &sum; m<sub>a,sor,flow</sub>;
+</pre>
+<p>
+the adsorpt mass balance is defined as
+</p>
+<pre>
+    (dm<sub>adsorpt</sub>/d&tau;) = (dm<sub>sor</sub>/d&tau;) * x + m<sub>sor</sub> * (dx/d&tau;) = (dm<sub>sor</sub>/d&tau;) * x + m<sub>sor</sub> * [(&part;x/&part;p)<sub>T</sub> * (dp/d&tau;) + (&part;x/&part;T)<sub>p</sub> * (dT/d&tau;)] = &sum; m<sub>s,flow</sub> + &sum; m<sub>a,s,flow</sub> + &sum; m<sub>d,flow</sub>;
+</pre> 
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU<sub>adsorbate</sub>/d&tau;) = (dm<sub>sor</sub>/d&tau;) * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [(du<sub>sor</sub>/d&tau;) + (d(x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>)/d&tau;] = (dm<sub>sor</sub>/d&tau;) * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [(v<sub>sor</sub>) + (h<sub>adsorpt</sub> - p * v<sub>adsorpt</sub>) * (&part;x/&part;p)<sub>T</sub> - (v<sub>sor</sub> + x<sub>adsorpt</sub> * v<sub>adsorpt</sub>)] * (dp/d&tau;) + m<sub>sor</sub> * [(c<sub>sor</sub>) + (c<sub>adsorpt</sub> * x<sub>adsorpt</sub> + h<sub>adsorpt</sub> * (&part;x/&part;T)<sub>p</sub> - x<sub>adsorpt</sub> * (&part;v<sub>adsorpt</sub>/&part;T)<sub>p</sub> - v<sub>adsorpt</sub> * (&part;x/&part;T)<sub>p</sub>)] * (dT/d&tau;) = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+When using the loading <i>x</i>, temperature <i>T</i>, and sorbent mass <i>m<sub>sor</sub></i> 
+as independent states, the adsorbent mass balance is defined as
+</p>
+</p>
+<pre>
+    (dm<sub>sor</sub>/d&tau;) = &sum; m<sub>a,sor,flow</sub>;
+</pre>
+<p>
+the adsorpt mass balance is defined as
+</p>
+<pre>
+    (dm<sub>adsorpt</sub>/d&tau;) = (dm<sub>sor</sub>/d&tau;) * x + m<sub>sor</sub> * (dx/d&tau;) = &sum; m<sub>s,flow</sub> + &sum; m<sub>a,s,flow</sub> + &sum; m<sub>d,flow</sub>;
+</pre> 
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU<sub>adsorbate</sub>/d&tau;) = (dm<sub>sor</sub>/d&tau;) * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [(du<sub>sor</sub>/d&tau;) + (d(x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>)/d&tau;] = (dm<sub>sor</sub>/d&tau;) * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [(h<sub>adsorpt</sub> - p * v<sub>adsorpt</sub> - x<sub>adsorpt</sub> * v<sub>adsorpt</sub> / (&part;x/&part;p)<sub>T</sub>)] * (dx/d&tau;) + m<sub>sor</sub> * [(c<sub>sor</sub>) + (c<sub>adsorpt</sub> * x<sub>adsorpt</sub> - x<sub>adsorpt</sub> * (&part;v<sub>adsorpt</sub>/&part;T)<sub>p</sub>] * (dT/d&tau;) = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+Herein, <i>dm<sub>sor</sub>/d&tau;</i> is the derivative of the adsorbent mass w.r.t. 
+time, <i>dm<sub>adsorpt</sub>/d&tau;</i> is the derivative of the adsorpt mass w.r.t. 
+time, <i>dU<sub>adsorbate</sub>/d&tau;</i> is the derivative of the uptake-averaged 
+internal energy w.r.t. time, <i>dp/d&tau;</i> is the derivative of the pressure w.r.t. 
+time, <i>dx/d&tau;</i> is the derivative of the loading w.r.t. time, and <i>dT/d&tau;</i> 
+is the derivative of the temperature w.r.t. time,
+
+The expression <i>(&part;x/&part;p)<sub>T</sub></i> describes the partial derivative of 
+the loading w.r.t. pressure at constant temperature, <i>(&part;x/&part;T)<sub>p</sub></i> 
+is the partial derivative of the loading w.r.t. temperature at constant pressure, and 
+<i>(&part;v<sub>adsorpt</sub>/&part;T)<sub>p</sub></i> is the partial derivative of the 
+specific volume of the adsorpt w.r.t. temperature at constant pressure.
+
+The expression <i>m<sub>a,sor,flow</sub></i> is the sum of the adsorbent mass flow rates 
+across the adsorbate ports, <i>m<sub>s,flow</sub></i> is the sum of the sorption mass 
+flow rates across the adsorbate ports, <i>m<sub>a,s,flow</sub></i> is the sum of the 
+sorption mass flow rates, <i>m<sub>d,flow</sub></i> is the sum of the diffusive mass flow 
+rates, <i>H<sub>b,flow</sub></i> is the sum of the enthalpy flow rates, and 
+<i>Q<sub>b,flow</sub></i> is the sum of the heat flow rates.
+
+The variable <i>v<sub>sor</sub></i> describes the specific volume of the adsorbent, 
+<i>u<sub>sor</sub></i> is the specific internal energy of the adsorbent, <i>c<sub>sor</sub></i> 
+is the specific heat capacity of the adsorbent, <i><SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub></i> 
+is the uptake-averaged specific internal energy of the adsorpt, <i>v<sub>adsorpt</sub></i> 
+is the specific volume of the last adsorbed molecule, <i>h<sub>adsorpt</sub></i> is the 
+specific enthalpy of the last adsorbed molecule, and <i>c<sub>adsorpt</sub></i> is the 
+specific heat capacity of the adsorpt.
+</p>
+
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Adsorption equilibrium with all adsorptive beeing adsorbed and in adsorpt
+  phase (i.e., chemical equilibrium).
+  </li>
+  <li>
+  The sorbent and adsorpt have the same pressure (i.e., mechanical equilibrium).
+  </li>
+  <li>
+  The sorbent and adsorpt have the same temperature (i.e., thermal equilibrium).
+  </li>
+  <li>
+  Specific volume of the adsorpt may only depend on the temperature and is thus
+  a macroscopic property without averaging.
+  </li>
+  <li>
+  Specific heat capacity of the adsorpt may only depend on the temperature or is
+  assumed to already be an uptake-averaged specific heat capacity.
+  </li>
+  <li>
+  Ideal and inert sorbent with constant specific volume.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to model the adsorbate within adsorber heat exchanger or other
+adsorption modules.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <i>useAdsorbatePorts</i>:
+  Defines if adsorbate ports are connected (requires uptake-averaged properties).
+  </li>
+  <li>
+  <i>useDiffusivePorts</i>:
+  Defines if diffusive ports are connected (requires uptake-averaged properties).
+  </li>
+  <li>
+  <i>calcUptakeAveragedProperties</i>:
+  Defines if duptake-averaged properties are calculated.
+  </li>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <br/>
+  <li>
+  <i>type_adsorbentMassBalance</i>:
+  Defines the type of the adsorbent mass balance.
+  </li>
+  <li>
+  <i>type_adsorptMassBalance</i>:
+  Defines the type of the adsorpt mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+transient mass balances are combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has two dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> and temperature <i>T</i>, or
+  </li>
+  <li>
+  loading <i>x</i> and  temperature <i>T</i> (recommended).
+  </li>
+</ul>
+<p>
+Furthermore, this model has the adsorbent mass <i>m_sor</i> as dynamic state if the
+adsorbate ports are connected to other models (see option 'useAdsorbatePorts').
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  Major revision (e.g., object-oriented approach, initialization, working pair) after restructering of the library.
+  </li>
+  <li>
+  November 18, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end AdsorbatePureVLEVolume;
diff --git a/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/Test_AdsorbatePureGasVolume.mo b/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/Test_AdsorbatePureGasVolume.mo
new file mode 100644
index 0000000..c37a70a
--- /dev/null
+++ b/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/Test_AdsorbatePureGasVolume.mo
@@ -0,0 +1,262 @@
+within SorpLib.Basics.Volumes.AdsorbateVolumes.Tester;
+model Test_AdsorbatePureGasVolume
+  "Tester for pure-component adsorbate volume with an ideal gas"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of adsorbate models
+  //
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureGasVolume
+    adsorbate_cooling_heating(
+    m_sor_initial=adsorbate_cooling_heating.geometry.V/0.0013793104,
+    T_initial=373.15,
+    geometry(
+      dx=0.2,
+      dy=0.1,
+      dz=0.6),
+    redeclare model PureWorkingPairModel =
+        Media.WorkingPairs.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+        (approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron),
+    x_initial=0.05) "Adsorbate volume that is cooled and heated"
+    annotation (Placement(transformation(extent={{-10,50},{10,70}})));
+
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureGasVolume
+    adsorbate_adsorption_desorption(
+    m_sor_initial=adsorbate_cooling_heating.geometry.V/0.0013793104,
+    T_initial=313.15,
+    geometry(
+      dx=0.2,
+      dy=0.1,
+      dz=0.6),
+    redeclare model PureWorkingPairModel =
+        Media.WorkingPairs.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+        (approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron),
+    x_initial=0.1,
+    nSorptionPorts=1)
+                   "Adsorbate volume with adsorption and desorption"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureGasVolume
+    adsorbate_adsorbatePorts(
+    m_sor_initial=adsorbate_cooling_heating.geometry.V/0.0013793104,
+    T_initial=313.15,
+    geometry(
+      dx=0.2,
+      dy=0.1,
+      dz=0.6),
+    calcUptakeAveragedProperties=true,
+    useAdsorbatePorts=true,
+    redeclare model PureWorkingPairModel =
+        Media.WorkingPairs.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+        (approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron,
+          x_adsorpt_lb=1e-2),
+    x_initial=0.1,
+    nSorptionPorts=1)
+                   "Adsorbate volume with adsorbate ports"
+    annotation (Placement(transformation(extent={{-10,-70},{10,-50}})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  SorpLib.Basics.Sources.Fluids.GasSource fs_adsorbate_adsorption_desorption(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true,
+    redeclare package Medium = Media.IdealGases.H2O)
+    "Fluid source for adsorbate volume with adsorption and desorption"
+    annotation (Placement(transformation(extent={{-30,20},{-10,40}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource fs_adsorbate_adsorbatePorts(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true,
+    redeclare package Medium = Modelica.Media.IdealGases.SingleGases.H2O)
+    "Fluid source for adsorbate volume with adsorption and desorption"
+    annotation (Placement(transformation(extent={{-30,-40},{-10,-20}})));
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource as_adsorbate_adsorbatePorts_out(
+    boundaryTypePressure=false,
+    use_mFlowInput=true,
+    h_fixed=74547.97,
+    use_xInput=false,
+    x_fixed={0.3}) "Adsorbate source for adsorbate volume with adsorbate ports"
+    annotation (Placement(transformation(extent={{30,-70},{10,-50}})));
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource as_adsorbate_adsorbatePorts_in(
+    boundaryTypePressure=false,
+    use_mFlowInput=true,
+    h_fixed=134547.97,
+    use_xInput=false,
+    x_fixed={0.1}) "Adsorbate source for adsorbate volume with adsorbate ports"
+    annotation (Placement(transformation(extent={{-30,-70},{-10,-50}})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource ts_adsorbate_cooling_heating(
+     boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=true)
+    "Thermal for adsorbate volume that is cooled and heated" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,80})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource ts_adsorbate_adsorption_desorption(boundaryType=
+        SorpLib.Choices.BoundaryThermal.HeatFlowRate, use_QFlowInput=true)
+    "Thermal for adsorbate volume with adsorption and desorption" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={20,30})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource ts_adsorbate_adsorbate_adsorbatePorts(boundaryType=
+        SorpLib.Choices.BoundaryThermal.HeatFlowRate, use_QFlowInput=true)
+    "Thermal for adsorbate volume with adsorption and desorption" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={20,-30})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Ramp input_QFlow_adsorbate_cooling_heating(
+    height=-2000,
+    duration=2500,
+    offset=1000) "Input signal for heat flow rate"
+    annotation (Placement(transformation(extent={{-20,86},{-10,96}})));
+
+  Modelica.Blocks.Sources.RealExpression
+    input_mFlow_adsorbate_adsorption_desorption(y=if time < 1250 then min(-1e-3*
+        (1.7e3 - adsorbate_adsorption_desorption.p), 0) else max(1e-3*(
+        adsorbate_adsorption_desorption.p - 3.1e3), 0))
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-52,28},{-40,40}})));
+  Modelica.Blocks.Sources.RealExpression
+    input_T_adsorbate_adsorption_desorption(y=if time < 1250 then 273.15 + 15
+         else 273.15 + 25) "Input signal for temperature"
+    annotation (Placement(transformation(extent={{-52,34},{-40,22}})));
+  Modelica.Blocks.Sources.RealExpression
+    input_QFlow_adsorbate_adsorption_desorption(y=if time < 1250 then 100*(
+        adsorbate_adsorption_desorption.T - (273.15 + 25)) else -100*((273.15 +
+        85) - adsorbate_adsorption_desorption.T))
+    "Input signal for heat flow rate"
+    annotation (Placement(transformation(extent={{52,28},{40,40}})));
+
+  Modelica.Blocks.Sources.RealExpression input_mFlow_adsorbatePorts(y=if time <
+        1250 then min(-1e-3*(5e3 - adsorbate_adsorbatePorts.p), 0) else max(1e-3
+        *(adsorbate_adsorbatePorts.p - 1.7e3), 0))
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-52,-32},{-40,-20}})));
+  Modelica.Blocks.Sources.RealExpression input_T_adsorbatePorts(y=if time < 1250
+         then 273.15 + 25 else 273.15 + 160) "Input signal for temperature"
+    annotation (Placement(transformation(extent={{-52,-26},{-40,-38}})));
+  Modelica.Blocks.Sources.RealExpression input_QFlow_adsorbatePorts(y=if time <
+        1250 then 1000*(adsorbate_adsorbatePorts.T - (273.15 + 25)) else -1000*(
+        (273.15 + 160) - adsorbate_adsorbatePorts.T))
+    "Input signal for heat flow rate"
+    annotation (Placement(transformation(extent={{52,-32},{40,-20}})));
+
+  Modelica.Blocks.Sources.Step input_mFlow_adsorbate_adsorbatePorts_in(
+    height=2*8.7,
+    offset=-8.7,
+    startTime=1250) "Input signal for adsorbate flow rate"
+    annotation (Placement(transformation(extent={{-52,-56},{-40,-44}})));
+  Modelica.Blocks.Sources.Step input_mFlow_adsorbate_adsorbatePorts_out(
+    height=-2*8.7,
+    offset=8.7,
+    startTime=1250) "Input signal for adsorbate flow rate"
+    annotation (Placement(transformation(extent={{52,-56},{40,-44}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_adsorbate_adsorption_desorption.port,
+    adsorbate_adsorption_desorption.fp_sorption[1]) annotation (Line(
+      points={{-20,30},{-1.6,30},{-1.6,4.4}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_adsorbate_adsorbatePorts.port, adsorbate_adsorbatePorts.fp_sorption[
+    1]) annotation (Line(
+      points={{-20,-30},{-1.6,-30},{-1.6,-55.6}},
+      color={244,125,35},
+      thickness=1));
+  connect(ts_adsorbate_cooling_heating.port, adsorbate_cooling_heating.hp_sorption)
+    annotation (Line(
+      points={{0,80},{0,74},{1.6,74},{1.6,67.6}},
+      color={238,46,47},
+      thickness=1));
+  connect(ts_adsorbate_adsorption_desorption.port,
+    adsorbate_adsorption_desorption.hp_sorption) annotation (Line(
+      points={{20,30},{1.6,30},{1.6,7.6}},
+      color={238,46,47},
+      thickness=1));
+  connect(as_adsorbate_adsorbatePorts_in.port, adsorbate_adsorbatePorts.ap_xMinus)
+    annotation (Line(
+      points={{-20,-60},{-14,-60},{-14,-58.2},{-4.2,-58.2}},
+      color={0,0,0},
+      thickness=1));
+  connect(as_adsorbate_adsorbatePorts_out.port, adsorbate_adsorbatePorts.ap_xPlus)
+    annotation (Line(
+      points={{20,-60},{14,-60},{14,-58.2},{7.8,-58.2}},
+      color={0,0,0},
+      thickness=1));
+
+  connect(input_QFlow_adsorbate_cooling_heating.y, ts_adsorbate_cooling_heating.Q_flow_input)
+    annotation (Line(points={{-9.5,91},{-5,91},{-5,81}}, color={0,0,127}));
+  connect(input_mFlow_adsorbate_adsorption_desorption.y,
+    fs_adsorbate_adsorption_desorption.m_flow_input) annotation (Line(points={{-39.4,
+          34},{-30,34},{-30,32},{-21.2,32}}, color={0,0,127}));
+  connect(input_T_adsorbate_adsorption_desorption.y,
+    fs_adsorbate_adsorption_desorption.T_input)
+    annotation (Line(points={{-39.4,28},{-21.2,28}}, color={0,0,127}));
+  connect(input_QFlow_adsorbate_adsorption_desorption.y,
+    ts_adsorbate_adsorption_desorption.Q_flow_input) annotation (Line(points={{39.4,
+          34},{30,34},{30,35},{21,35}}, color={0,0,127}));
+  connect(input_mFlow_adsorbate_adsorbatePorts_in.y,
+    as_adsorbate_adsorbatePorts_in.m_flow_input) annotation (Line(points={{-39.4,
+          -50},{-32,-50},{-32,-58},{-21.2,-58}}, color={0,0,127}));
+  connect(input_mFlow_adsorbate_adsorbatePorts_out.y,
+    as_adsorbate_adsorbatePorts_out.m_flow_input) annotation (Line(points={{39.4,
+          -50},{30,-50},{30,-58},{21.2,-58}}, color={0,0,127}));
+  connect(ts_adsorbate_adsorbate_adsorbatePorts.port, adsorbate_adsorbatePorts.hp_sorption)
+    annotation (Line(
+      points={{20,-30},{1.6,-30},{1.6,-52.4}},
+      color={238,46,47},
+      thickness=1));
+  connect(input_mFlow_adsorbatePorts.y, fs_adsorbate_adsorbatePorts.m_flow_input)
+    annotation (Line(points={{-39.4,-26},{-30,-26},{-30,-28},{-21.2,-28}},
+        color={0,0,127}));
+  connect(input_T_adsorbatePorts.y, fs_adsorbate_adsorbatePorts.T_input)
+    annotation (Line(points={{-39.4,-32},{-21.2,-32}}, color={0,0,127}));
+  connect(input_QFlow_adsorbatePorts.y, ts_adsorbate_adsorbate_adsorbatePorts.Q_flow_input)
+    annotation (Line(points={{39.4,-26},{30,-26},{30,-25},{21,-25}}, color={0,0,
+          127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the model of an adsorbate volume for pure comonent adsorption
+using an ideal gas
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  Extension and added documentation.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AdsorbatePureGasVolume;
diff --git a/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/Test_AdsorbatePureVLEVolume.mo b/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/Test_AdsorbatePureVLEVolume.mo
new file mode 100644
index 0000000..c5ac7ff
--- /dev/null
+++ b/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/Test_AdsorbatePureVLEVolume.mo
@@ -0,0 +1,272 @@
+within SorpLib.Basics.Volumes.AdsorbateVolumes.Tester;
+model Test_AdsorbatePureVLEVolume
+  "Tester for pure-component adsorbate volume with a real fluid"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of adsorbate models
+  //
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume
+    adsorbate_cooling_heating(
+    m_sor_initial=adsorbate_cooling_heating.geometry.V/0.0013793104,
+    T_initial=373.15,
+    geometry(
+      dx=0.2,
+      dy=0.1,
+      dz=0.6),
+    redeclare model PureWorkingPairModel =
+        Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl,
+        limitLowerPressure=true,
+        limitLowerPressureAdsorptive=true),
+    x_initial=0.05) "Adsorbate volume that is cooled and heated"
+    annotation (Placement(transformation(extent={{-10,50},{10,70}})));
+
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume
+    adsorbate_adsorption_desorption(
+    m_sor_initial=adsorbate_cooling_heating.geometry.V/0.0013793104,
+    T_initial=313.15,
+    geometry(
+      dx=0.2,
+      dy=0.1,
+      dz=0.6),
+    redeclare model PureWorkingPairModel =
+        Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl,
+        limitLowerPressure=true,
+        limitLowerPressureAdsorptive=true),
+    x_initial=0.1,
+    nSorptionPorts=1)
+                   "Adsorbate volume with adsorption and desorption"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume
+    adsorbate_adsorbatePorts(
+    m_sor_initial=adsorbate_cooling_heating.geometry.V/0.0013793104,
+    T_initial=313.15,
+    geometry(
+      dx=0.2,
+      dy=0.1,
+      dz=0.6),
+    calcUptakeAveragedProperties=true,
+    useAdsorbatePorts=true,
+    redeclare model PureWorkingPairModel =
+        Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl,
+        limitLowerPressure=true,
+        limitLowerPressureAdsorptive=true,
+        x_adsorpt_lb=1e-2),
+    x_initial=0.1,
+    nSorptionPorts=1)
+                   "Adsorbate volume with adsorbate ports"
+    annotation (Placement(transformation(extent={{-10,-70},{10,-50}})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  SorpLib.Basics.Sources.Fluids.VLESource fs_adsorbate_adsorption_desorption(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true)
+    "Fluid source for adsorbate volume with adsorption and desorption"
+    annotation (Placement(transformation(extent={{-30,20},{-10,40}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource fs_adsorbate_adsorbatePorts(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true)
+    "Fluid source for adsorbate volume with adsorption and desorption"
+    annotation (Placement(transformation(extent={{-30,-40},{-10,-20}})));
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource as_adsorbate_adsorbatePorts_out(
+    boundaryTypePressure=false,
+    use_mFlowInput=true,
+    h_fixed=74547.97,
+    use_xInput=false,
+    x_fixed={0.3}) "Adsorbate source for adsorbate volume with adsorbate ports"
+    annotation (Placement(transformation(extent={{30,-70},{10,-50}})));
+  SorpLib.Basics.Sources.Sorption.AdsorbateSource as_adsorbate_adsorbatePorts_in(
+    boundaryTypePressure=false,
+    use_mFlowInput=true,
+    h_fixed=134547.97,
+    use_xInput=false,
+    x_fixed={0.1}) "Adsorbate source for adsorbate volume with adsorbate ports"
+    annotation (Placement(transformation(extent={{-30,-70},{-10,-50}})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource ts_adsorbate_cooling_heating(
+     boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=true)
+    "Thermal for adsorbate volume that is cooled and heated" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,80})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource ts_adsorbate_adsorption_desorption(boundaryType=
+        SorpLib.Choices.BoundaryThermal.HeatFlowRate, use_QFlowInput=true)
+    "Thermal for adsorbate volume with adsorption and desorption" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={20,30})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource ts_adsorbate_adsorbate_adsorbatePorts(boundaryType=
+        SorpLib.Choices.BoundaryThermal.HeatFlowRate, use_QFlowInput=true)
+    "Thermal for adsorbate volume with adsorption and desorption" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={20,-30})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Ramp input_QFlow_adsorbate_cooling_heating(
+    height=-2000,
+    duration=2500,
+    offset=1000) "Input signal for heat flow rate"
+    annotation (Placement(transformation(extent={{-20,86},{-10,96}})));
+
+  Modelica.Blocks.Sources.RealExpression
+    input_mFlow_adsorbate_adsorption_desorption(y=if time < 1250 then min(-1e-3*
+        (1.7e3 - adsorbate_adsorption_desorption.p), 0) else max(1e-3*(
+        adsorbate_adsorption_desorption.p - 3.1e3), 0))
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-52,28},{-40,40}})));
+  Modelica.Blocks.Sources.RealExpression
+    input_T_adsorbate_adsorption_desorption(y=if time < 1250 then 273.15 + 15
+         else 273.15 + 25) "Input signal for temperature"
+    annotation (Placement(transformation(extent={{-52,34},{-40,22}})));
+  Modelica.Blocks.Sources.RealExpression
+    input_QFlow_adsorbate_adsorption_desorption(y=if time < 1250 then 100*(
+        adsorbate_adsorption_desorption.T - (273.15 + 25)) else -100*((273.15 +
+        85) - adsorbate_adsorption_desorption.T))
+    "Input signal for heat flow rate"
+    annotation (Placement(transformation(extent={{52,28},{40,40}})));
+
+  Modelica.Blocks.Sources.RealExpression input_mFlow_adsorbatePorts(y=if time <
+        1250 then min(-1e-3*(5e3 - adsorbate_adsorbatePorts.p), 0) else max(1e-3
+        *(adsorbate_adsorbatePorts.p - 1.7e3), 0))
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-52,-32},{-40,-20}})));
+  Modelica.Blocks.Sources.RealExpression input_T_adsorbatePorts(y=if time < 1250
+         then 273.15 + 25 else 273.15 + 160) "Input signal for temperature"
+    annotation (Placement(transformation(extent={{-52,-26},{-40,-38}})));
+  Modelica.Blocks.Sources.RealExpression input_QFlow_adsorbatePorts(y=if time <
+        1250 then 1000*(adsorbate_adsorbatePorts.T - (273.15 + 25)) else -1000*(
+        (273.15 + 160) - adsorbate_adsorbatePorts.T))
+    "Input signal for heat flow rate"
+    annotation (Placement(transformation(extent={{52,-32},{40,-20}})));
+
+  Modelica.Blocks.Sources.Step input_mFlow_adsorbate_adsorbatePorts_in(
+    height=2*8.7,
+    offset=-8.7,
+    startTime=1250) "Input signal for adsorbate flow rate"
+    annotation (Placement(transformation(extent={{-52,-56},{-40,-44}})));
+  Modelica.Blocks.Sources.Step input_mFlow_adsorbate_adsorbatePorts_out(
+    height=-2*8.7,
+    offset=8.7,
+    startTime=1250) "Input signal for adsorbate flow rate"
+    annotation (Placement(transformation(extent={{52,-56},{40,-44}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_adsorbate_adsorption_desorption.port,
+    adsorbate_adsorption_desorption.fp_sorption[1]) annotation (Line(
+      points={{-20,30},{-1.6,30},{-1.6,4.4}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_adsorbate_adsorbatePorts.port, adsorbate_adsorbatePorts.fp_sorption[
+    1]) annotation (Line(
+      points={{-20,-30},{-1.6,-30},{-1.6,-55.6}},
+      color={0,140,72},
+      thickness=1));
+  connect(ts_adsorbate_cooling_heating.port, adsorbate_cooling_heating.hp_sorption)
+    annotation (Line(
+      points={{0,80},{0,74},{1.6,74},{1.6,67.6}},
+      color={238,46,47},
+      thickness=1));
+  connect(ts_adsorbate_adsorption_desorption.port,
+    adsorbate_adsorption_desorption.hp_sorption) annotation (Line(
+      points={{20,30},{1.6,30},{1.6,7.6}},
+      color={238,46,47},
+      thickness=1));
+  connect(as_adsorbate_adsorbatePorts_in.port, adsorbate_adsorbatePorts.ap_xMinus)
+    annotation (Line(
+      points={{-20,-60},{-14,-60},{-14,-58.2},{-4.2,-58.2}},
+      color={0,0,0},
+      thickness=1));
+  connect(as_adsorbate_adsorbatePorts_out.port, adsorbate_adsorbatePorts.ap_xPlus)
+    annotation (Line(
+      points={{20,-60},{14,-60},{14,-58.2},{7.8,-58.2}},
+      color={0,0,0},
+      thickness=1));
+
+  connect(input_QFlow_adsorbate_cooling_heating.y, ts_adsorbate_cooling_heating.Q_flow_input)
+    annotation (Line(points={{-9.5,91},{-5,91},{-5,81}}, color={0,0,127}));
+  connect(input_mFlow_adsorbate_adsorption_desorption.y,
+    fs_adsorbate_adsorption_desorption.m_flow_input) annotation (Line(points={{-39.4,
+          34},{-30,34},{-30,32},{-21.2,32}}, color={0,0,127}));
+  connect(input_T_adsorbate_adsorption_desorption.y,
+    fs_adsorbate_adsorption_desorption.T_input)
+    annotation (Line(points={{-39.4,28},{-21.2,28}}, color={0,0,127}));
+  connect(input_QFlow_adsorbate_adsorption_desorption.y,
+    ts_adsorbate_adsorption_desorption.Q_flow_input) annotation (Line(points={{39.4,
+          34},{30,34},{30,35},{21,35}}, color={0,0,127}));
+  connect(input_mFlow_adsorbate_adsorbatePorts_in.y,
+    as_adsorbate_adsorbatePorts_in.m_flow_input) annotation (Line(points={{-39.4,
+          -50},{-32,-50},{-32,-58},{-21.2,-58}}, color={0,0,127}));
+  connect(input_mFlow_adsorbate_adsorbatePorts_out.y,
+    as_adsorbate_adsorbatePorts_out.m_flow_input) annotation (Line(points={{39.4,
+          -50},{30,-50},{30,-58},{21.2,-58}}, color={0,0,127}));
+  connect(ts_adsorbate_adsorbate_adsorbatePorts.port, adsorbate_adsorbatePorts.hp_sorption)
+    annotation (Line(
+      points={{20,-30},{1.6,-30},{1.6,-52.4}},
+      color={238,46,47},
+      thickness=1));
+  connect(input_mFlow_adsorbatePorts.y, fs_adsorbate_adsorbatePorts.m_flow_input)
+    annotation (Line(points={{-39.4,-26},{-30,-26},{-30,-28},{-21.2,-28}},
+        color={0,0,127}));
+  connect(input_T_adsorbatePorts.y, fs_adsorbate_adsorbatePorts.T_input)
+    annotation (Line(points={{-39.4,-32},{-21.2,-32}}, color={0,0,127}));
+  connect(input_QFlow_adsorbatePorts.y, ts_adsorbate_adsorbate_adsorbatePorts.Q_flow_input)
+    annotation (Line(points={{39.4,-26},{30,-26},{30,-25},{21,-25}}, color={0,0,
+          127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the model of an adsorbate volume for pure comonent adsorption
+using a real fluid with a two-phase regime.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  Extension and added documentation.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AdsorbatePureVLEVolume;
diff --git a/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/package.mo b/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/package.mo
new file mode 100644
index 0000000..7aebcf2
--- /dev/null
+++ b/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics.Volumes.AdsorbateVolumes;
+package Tester "Models to test and varify models of adsorbate volumes"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented adsorbate
+volumes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/package.order b/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/package.order
new file mode 100644
index 0000000..0722318
--- /dev/null
+++ b/SorpLib/Basics/Volumes/AdsorbateVolumes/Tester/package.order
@@ -0,0 +1,2 @@
+Test_AdsorbatePureGasVolume
+Test_AdsorbatePureVLEVolume
diff --git a/SorpLib/Basics/Volumes/AdsorbateVolumes/package.mo b/SorpLib/Basics/Volumes/AdsorbateVolumes/package.mo
new file mode 100644
index 0000000..4ee6fda
--- /dev/null
+++ b/SorpLib/Basics/Volumes/AdsorbateVolumes/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics.Volumes;
+package AdsorbateVolumes "Package containing finte volume models of adsorbates"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains finite volume models of adsorbates. This package calculates 
+fluid properties based on the open-source Modelica Standard Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end AdsorbateVolumes;
diff --git a/SorpLib/Basics/Volumes/AdsorbateVolumes/package.order b/SorpLib/Basics/Volumes/AdsorbateVolumes/package.order
new file mode 100644
index 0000000..25ad706
--- /dev/null
+++ b/SorpLib/Basics/Volumes/AdsorbateVolumes/package.order
@@ -0,0 +1,3 @@
+AdsorbatePureGasVolume
+AdsorbatePureVLEVolume
+Tester
diff --git a/SorpLib/Basics/Volumes/BaseClasses/PartialAdsorbateVolume.mo b/SorpLib/Basics/Volumes/BaseClasses/PartialAdsorbateVolume.mo
new file mode 100644
index 0000000..a46c9b2
--- /dev/null
+++ b/SorpLib/Basics/Volumes/BaseClasses/PartialAdsorbateVolume.mo
@@ -0,0 +1,387 @@
+within SorpLib.Basics.Volumes.BaseClasses;
+partial model PartialAdsorbateVolume
+  "Base model for all adsorbate volumes"
+
+  //
+  // Definition of parameters describing media
+  //
+  parameter Integer no_components = 1
+    "Number of components in the medium"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_adsorptivs(min=1, max=no_components) = 1
+    "Number of adsorptivs (i.e., components that can be adsorbed/desorbed)"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.Mass m_sor_initial = geometry.V * 725
+    "Initial value of adsorbent mass"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+  parameter Modelica.Units.SI.Temperature T_initial = 298.15
+    "Initial value of temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  parameter Modelica.Units.SI.MassFlowRate msor_flow_initialX = 1e-4
+    "Start value for adsorbent mass flow rate in x direction"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+  parameter Modelica.Units.SI.MassFlowRate ms_flow_initial = 1e-4
+    "Start value for sorption mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+  parameter Modelica.Units.SI.MassFlowRate md_flow_initialX = 1e-4
+    "Start value for diffusive mass flow rates in x direction"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialVolume;
+
+  //
+  // Definition of parameters regarding calculation setup
+  //
+  parameter Boolean calcUptakeAveragedProperties = false
+    " = true, if uptake-averaged adsorpt and abosrabte properties are calculated"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding volume setup
+  //
+  parameter Boolean useAdsorbatePorts = false
+    " = true, if adsorbate ports are connected outside the model and, thus,
+    are considered within the mass and energy balance (i.e., uptake-averaged 
+    adsorbate properties are required)"
+    annotation (Dialog(tab="Volume Setup", group="Fluid Ports",
+                enable=calcUptakeAveragedProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useDiffusivePorts = false
+    " = true, if diffusive ports are connected outside the model (i.e., uptake-
+    averaged adsorpt properties are required)"
+    annotation (Dialog(tab="Volume Setup", group="Fluid Ports",
+                enable=calcUptakeAveragedProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_adsorbentMassBalance=
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial
+    "Handling of the adsorbent mass balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations",
+                enable=useAdsorbatePorts),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BalanceEquations type_adsorptMassBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the adsorpt mass balances and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.SorptionPorts.AdsorbatePort_in ap_xMinus(
+    final no_adsorptivs=no_adsorptivs,
+    m_flow(start=msor_flow_initialX))
+    "Adsorbate fluid port at position '-dx/2'"
+    annotation (Placement(transformation(extent={{-46,14},{-38,22}}),
+                iconTransformation(extent={{-46,14},{-38,22}})));
+  SorpLib.Basics.Interfaces.SorptionPorts.AdsorbatePort_in ap_xPlus(
+    final no_adsorptivs=no_adsorptivs,
+    m_flow(start=-msor_flow_initialX))
+    "Adsorbate fluid port at position '+dx/2'"
+    annotation (Placement(transformation(extent={{74,14},{82,22}}),
+                iconTransformation(extent={{74,14},{82,22}})));
+
+  SorpLib.Basics.Interfaces.SorptionPorts.AdsorptPort_in[no_adsorptivs] dp_xMinus(
+    m_flow(each start=-md_flow_initialX))
+    "Diffusive fluid port at position '-dx/2'"
+    annotation (Placement(transformation(extent={{-82,-22},{-74,-14}}),
+                iconTransformation(extent={{-82,-22},{-74,-14}})));
+  SorpLib.Basics.Interfaces.SorptionPorts.AdsorptPort_out[no_adsorptivs] dp_xPlus(
+    m_flow(each start=md_flow_initialX))
+    "Diffusive fluid port at position '+dx/2'"
+    annotation (Placement(transformation(extent={{38,-22},{46,-14}}),
+                                iconTransformation(extent={{38,-22},{46,-14}})));
+
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_sorption
+    "Sorption heat port"
+    annotation (Placement(transformation(extent={{10,70},{22,82}}),
+                iconTransformation(extent={{10,70},{22,82}})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T(
+    start=T_initial,
+    stateSelect=StateSelect.prefer)
+    "Temperature";
+  SorpLib.Units.Uptake x
+    "Uptake";
+
+  Modelica.Units.SI.SpecificEnthalpy h(
+    stateSelect=StateSelect.avoid)
+    "Uptake-averaged specific enthalpy: h_sor + x * h_avg_adsorpt";
+  Modelica.Units.SI.SpecificInternalEnergy u
+    "Uptake-averaged specific internal energy: u_sor + x * u_avg_adsorpt";
+
+  Modelica.Units.SI.Mass m_adsorbate
+    "Adsorbate mass (i.e., total mass)";
+  Modelica.Units.SI.Mass m_sor(
+    start=m_sor_initial,
+    stateSelect= if useAdsorbatePorts then
+      StateSelect.prefer else StateSelect.avoid)
+    "Adsorbent mass";
+  Modelica.Units.SI.Mass m_adsorpt
+    "Adsorpt mass";
+
+  Modelica.Units.SI.MassFlowRate dm_adsorbate_dtau
+    "Derivative of adsorbate mass (i.e., total mass) w.r.t. time";
+  Modelica.Units.SI.MassFlowRate dm_sor_dtau
+    "Derivative of adsorbent mass w.r.t. time";
+  Modelica.Units.SI.MassFlowRate dm_adsorpt_dtau
+    "Derivative of adsorpt mass w.r.t. time";
+
+  Modelica.Units.SI.MassFlowRate masor_flow
+    "Sum of all adsorbent mass flow rates across adsorbate boundaries";
+  Modelica.Units.SI.MassFlowRate mas_flow
+    "Sum of all sorption mass flow rates across adsorbate boundaries";
+  Modelica.Units.SI.MassFlowRate ms_flow
+    "Sum of all sorption mass flow rates across boundaries";
+  Modelica.Units.SI.MassFlowRate md_flow
+    "Sum of all diffusive mass flow rates across boundaries";
+
+  Modelica.Units.SI.InternalEnergy U
+    "Uptake-averaged internal energy";
+  Real dU_dtau(final unit="W")
+    "Derivative of uptake-averaged internal energy w.r.t. time";
+  Modelica.Units.SI.EnthalpyFlowRate Hb_flow
+    "Sum of all enthalpy flow rates across boundaries";
+  Modelica.Units.SI.HeatFlowRate Qb_flow
+    "Sum of all heat flow rates across boundaries";
+
+  SorpLib.Basics.Volumes.Records.AdsorbateVolumeProperties adsorbateProperties(
+    final no_adsorptivs=no_adsorptivs)
+    "Properties of fluid volume often required for calculation of heat transfer";
+
+initial equation
+  if useAdsorbatePorts then
+    if type_adsorbentMassBalance ==
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+      m_sor = m_sor_initial
+        "Fixed initial value";
+
+    elseif type_adsorbentMassBalance ==
+      SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+      der(m_sor) = 0
+        "Steady-state initialisation of overall mass balance";
+
+    end if;
+  end if;
+
+  if type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    T = T_initial
+      "Fixed initial value";
+
+  elseif type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    der(T) = 0
+      "Steady-state initial value";
+
+  end if;
+
+equation
+  //
+  // Momentum balance
+  //
+  ap_xMinus.p = p
+    "Total pressure at the port (i.e., homogenous volume)";
+  ap_xPlus.p = p
+    "Total pressure at the port (i.e., homogenous volume)";
+
+  //
+  // Mass balance
+  //
+  m_adsorbate = m_sor + m_adsorpt
+    "Adsorbate mass (i.e., total mass)";
+  m_adsorpt = x * m_sor
+    "Adsorpt mass";
+
+  dm_adsorbate_dtau = dm_adsorpt_dtau + dm_sor_dtau
+    "Adsorbate mass balance (i.e., total mass balance)";
+  dm_sor_dtau = masor_flow
+    "Derivative of adsorbent mass w.r.t. time";
+  dm_adsorpt_dtau = ms_flow + md_flow + mas_flow
+  "Adsorpt mass balance";
+
+  if useAdsorbatePorts then
+    if type_adsorbentMassBalance==
+      SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+      dm_sor_dtau = 0
+        "Steady-state adsorbent mass balance";
+
+    else
+      dm_sor_dtau = der(m_sor)
+        "Transient adsorbent mass balance";
+
+    end if;
+
+  else
+    m_sor = m_sor_initial
+        "Sorbent mass cannot change as adsorbate ports are not used";
+
+  end if;
+
+  //
+  // Energy balance
+  //
+  U = m_adsorbate * u
+    "Uptake-averaged internal energy";
+
+  dU_dtau = Hb_flow + Qb_flow
+    "Energy balane";
+
+  Qb_flow = Q_flow_xMinus + Q_flow_xPlus +
+    Q_flow_yMinus + Q_flow_yPlus +
+    Q_flow_zMinus + Q_flow_zPlus +
+    hp_sorption.Q_flow
+    "Sum of all heat flow rates across boundaries";
+
+  T_heatPorts = T
+    "Required for conditional component";
+
+  ap_xMinus.h_outflow = h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+  ap_xPlus.h_outflow = h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  hp_sorption.T = T_heatPorts
+    "Temperature at sorption heat port";
+
+  //
+  // Summary record
+  //
+  adsorbateProperties.p = p
+    "Pressure";
+  adsorbateProperties.T = T
+    "Temperature";
+  adsorbateProperties.x = x
+    "Total loading";
+
+  adsorbateProperties.ma_flow_xMinus = if useAdsorbatePorts then ap_xMinus.m_flow *
+    (1 + (if avoid_events then sum(noEvent(actualStream(ap_xMinus.x_outflow)))
+    else sum(actualStream(ap_xMinus.x_outflow)))) else 0
+    "Adsorbate mass flow rate at port '-dx/2'";
+  adsorbateProperties.ma_flow_xPlus = if useAdsorbatePorts then ap_xPlus.m_flow *
+    (1 + (if avoid_events then sum(noEvent(actualStream(ap_xPlus.x_outflow)))
+    else sum(actualStream(ap_xPlus.x_outflow)))) else 0
+    "Adsorbate mass flow rate at port '+dx/2'";
+
+  adsorbateProperties.md_flow_xMinus = dp_xMinus.m_flow
+    "Diffusive mass flow rate at port '-dx/2'";
+  adsorbateProperties.md_flow_xPlus = dp_xPlus.m_flow
+    "Diffusive mass flow rate at port '+dx/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Rectangle(extent={{-90,30},{30,-90}}, lineColor={0,0,0}),
+        Line(points={{-90,30},{-30,90}}, color={0,0,0}),
+        Line(
+          points={{-30,-30},{-90,-90}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(points={{90,-30},{30,-90}}, color={0,0,0}),
+        Line(points={{90,90},{30,30}}, color={0,0,0}),
+        Line(points={{-30,90},{90,90},{90,-30}}, color={0,0,0}),
+        Line(
+          points={{90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-30,90},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash)}),                           Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the base model of all adsorbate volumes. It defines the 
+volume geometry, heat ports in all spatial directions, as well as adsorbate and
+diffusive (i.e., adsorpt) ports in x-direction. The required heat ports can be 
+adjusted via the volume setup. Furthermore, this model defines fundamental variables 
+for the momentum, mass, and energy balance, as well as the initialization of these 
+balances.
+<br/><br/>
+Models that inherit properties from this partial model must add a sorption port. 
+Further, inherting models may have to add further adsorbate and diffusive (i.e., 
+adsorpt) ports in the required spatial direction (e.g., y- or z-direction). 
+Furthermore, conservation equations must be added. In this context, appropriate 
+working pair models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> or loading <i>x</i> in dependence of the independent state
+  variables.
+  </li>
+  <li>
+  Uptake-averaged specific enthalpy <i>h</i>.
+  </li>
+  <li>
+  Uptake-averaged specific internal energy <i>u</i>.
+  </li>
+  <br/>
+  <li>
+  Partial derivative of the adsorpt mass w.r.t. time <i>dm_adsorpt_dtau</i>.
+  </li>
+  <li>
+  Sum of all adsorbent mass flow rates across adsorbate boundaries <i>masor_flow</i>.
+  </li>
+  <li>
+  Sum of all adsorpt mass flow rates across adsorbate boundaries <i>mas_flow</i>.
+  </li>
+  <li>
+  Sum of all sorption mass flow rates across sorption boundaries <i>ms_flow</i>.
+  </li>
+  <br/>
+  <li>
+  Partial derivative of the uptake-averaged internal energy w.r.t. time <i>dU_dtau</i>.
+  </li>
+  <li>
+  Sum of all enthalpy flow rates across boundaries <i>Hb_flow</i>.
+  </li>
+  <br/>
+  <li>
+  Variables of the summary record except for pressure <i>p</i>, temperature <i>T</i>, 
+  total loading <i>x</i>, adsorbate mass flow rates in x-direction 
+  <i>ma_flow_xMinus</i>/<i>ma_flow_xPlus</i>, and diffusive mass flow rates in 
+  x-direction <i>md_flow_xMinus</i>/<i>md_flow_xPlus</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialAdsorbateVolume;
diff --git a/SorpLib/Basics/Volumes/BaseClasses/PartialFluidVolume.mo b/SorpLib/Basics/Volumes/BaseClasses/PartialFluidVolume.mo
new file mode 100644
index 0000000..da7b7e0
--- /dev/null
+++ b/SorpLib/Basics/Volumes/BaseClasses/PartialFluidVolume.mo
@@ -0,0 +1,350 @@
+within SorpLib.Basics.Volumes.BaseClasses;
+partial model PartialFluidVolume
+  "Base model for all fluid-based volumes"
+
+  //
+  // Definition of parameters describing media
+  //
+  parameter Integer no_components = 1
+    "Number of components in the medium"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding classes
+  //
+  replaceable connector FluidPortsIn =
+    SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in
+    constrainedby SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort
+    "Fluid ports for inlet design direction"
+    annotation (Dialog(tab="Volume Setup", group="Classes"),
+                Evaluate=true,
+                HideResult=true);
+  replaceable connector FluidPortsOut =
+    SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out
+    constrainedby SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort
+    "Fluid ports for outlet design direction"
+    annotation (Dialog(tab="Volume Setup", group="Classes"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Integer nPorts_cfp_xMinus=0
+    "Number of ports at cfp_xMinus"
+    annotation (Dialog(connectorSizing=true),
+                HideResult=true);
+  parameter Integer nPorts_cfp_xPlus=0
+    "Number of ports at cfp_xPlus"
+    annotation (Dialog(connectorSizing=true),
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.Pressure p_initial = 1e5
+    "Initial value of pressure"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+  parameter Modelica.Units.SI.Temperature T_initial = 298.15
+    "Initial value of temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=(independentStateVariables==
+                  SorpLib.Choices.IndependentVariablesVolume.pTX)));
+  parameter Modelica.Units.SI.SpecificEnthalpy h_initial = 0
+    "Initial value of specific enthalpy"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=(independentStateVariables==
+                  SorpLib.Choices.IndependentVariablesVolume.phX)));
+
+  parameter Modelica.Units.SI.MassFlowRate mc_flow_initialX = 1e-4
+    "Start value for convective mass flow rate in x direction"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialVolume;
+
+  //
+  // Definition of parameters regarding calculation setup
+  //
+  parameter SorpLib.Choices.IndependentVariablesVolume independentStateVariables=
+    SorpLib.Choices.IndependentVariablesVolume.phX
+    "Independent state variables"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean pressureNoStateVariable = true
+    " = true, if pressure is not a state variable and is not needed to calculate
+    fluid properties like density (e.g., incompressible fluid)"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean neglectTermVp = false
+    " = true, if term p * v is neglected for the specific internal energy (i.e., 
+    u = h)"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean calculateAdditionalProperties = false
+    "= true, if additional properties required for tranport models are calculated"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_overallMassBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the overall mass balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of ports
+  //
+  FluidPortsIn[nPorts_cfp_xMinus] cfp_xMinus(
+    each final no_components=no_components,
+    m_flow(each start=mc_flow_initialX))
+    "Convective fluid port at position '-dx/2'"
+    annotation (Placement(transformation(extent={{-46,14},{-38,22}}),
+                iconTransformation(extent={{-46,14},{-38,22}})));
+  FluidPortsOut[nPorts_cfp_xPlus] cfp_xPlus(
+    each final no_components=no_components,
+    m_flow(each start=-mc_flow_initialX))
+    "Convective fluid port at position '+dx/2'"
+    annotation (Placement(transformation(extent={{74,14},{82,22}}),
+                iconTransformation(extent={{74,14},{82,22}})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p(
+    start=p_initial,
+    stateSelect= if not pressureNoStateVariable then StateSelect.prefer
+      else StateSelect.avoid)
+    "Pressure";
+  Modelica.Units.SI.Temperature T(
+    start=T_initial,
+    stateSelect= if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then StateSelect.prefer
+      else StateSelect.avoid)
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+  Modelica.Units.SI.Density rho
+    "Density";
+
+  Modelica.Units.SI.SpecificEnthalpy h(
+    start=h_initial,
+    stateSelect= if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.phX then StateSelect.prefer
+      else StateSelect.avoid)
+    "Specific enthalpy";
+  Modelica.Units.SI.SpecificInternalEnergy u
+    "Specific internal energy";
+
+  Modelica.Units.SI.Mass m
+    "Mass";
+  Modelica.Units.SI.MassFlowRate dm_dtau
+    "Derivative of mass w.r.t. time";
+  Modelica.Units.SI.MassFlowRate mc_flow
+    "Sum of all convective mass flow rates across boundaries";
+
+  Modelica.Units.SI.InternalEnergy U
+    "Internal energy";
+  Real dU_dtau(final unit="W")
+    "Derivative of internal energy w.r.t. time";
+  Modelica.Units.SI.EnthalpyFlowRate Hb_flow
+    "Sum of all enthalpy flow rates across boundaries";
+  Modelica.Units.SI.HeatFlowRate Qb_flow
+    "Sum of all heat flow rates across boundaries";
+
+  SorpLib.Basics.Volumes.Records.FluidVolumeProperties fluidProperties(
+    final no_components=no_components)
+    "Properties of fluid volume often required for calculation of heat transfer";
+
+initial equation
+  if not pressureNoStateVariable and type_overallMassBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    p = p_initial
+      "Fixed initial value";
+
+  elseif not pressureNoStateVariable and type_overallMassBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    der(p) = 0
+      "Steady-state initialisation of overall mass balance";
+
+  end if;
+
+  if type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      T = T_initial
+        "Fixed initial value";
+
+    else
+      h = h_initial
+        "Fixed initial value";
+
+    end if;
+
+  elseif type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      der(T) = 0
+        "Steady-state initial value";
+
+    else
+      der(h) = 0
+        "Steady-state initial value";
+
+    end if;
+  end if;
+
+equation
+  //
+  // Property calculation
+  //
+  u = if neglectTermVp then h else h - p * v
+    "Specific internal energy";
+
+  //
+  // Momentum balance
+  //
+  cfp_xMinus.p = fill(p, nPorts_cfp_xMinus)
+    "Total pressure at the port (i.e., homogenous volume)";
+  cfp_xPlus.p = fill(p, nPorts_cfp_xPlus)
+    "Total pressure at the port (i.e., homogenous volume)";
+
+  //
+  // Mass balance
+  //
+  m = geometry.V / v
+    "Mass";
+
+  //
+  // Energy balance
+  //
+  U = m * u
+    "Internal energy";
+
+  cfp_xMinus.h_outflow = fill(h, nPorts_cfp_xMinus)
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+  cfp_xPlus.h_outflow = fill(h, nPorts_cfp_xPlus)
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  T_heatPorts = T
+    "Required for conditional component";
+
+  //
+  // Summary record
+  //
+  fluidProperties.p = p
+    "Pressure";
+  fluidProperties.T = T
+    "Temperature";
+  fluidProperties.v = v
+    "Specific volume";
+
+  fluidProperties.mc_flow_xMinus = sum(cfp_xMinus.m_flow)
+    "Total convective mass flow rate at port '-dx/2'";
+  fluidProperties.mc_flow_xPlus = sum(cfp_xPlus.m_flow)
+    "Total convective mass flow rate at port '+dx/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Rectangle(extent={{-90,30},{30,-90}}, lineColor={0,0,0}),
+        Line(points={{-90,30},{-30,90}}, color={0,0,0}),
+        Line(
+          points={{-30,-30},{-90,-90}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(points={{90,-30},{30,-90}}, color={0,0,0}),
+        Line(points={{90,90},{30,30}}, color={0,0,0}),
+        Line(points={{-30,90},{90,90},{90,-30}}, color={0,0,0}),
+        Line(
+          points={{90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-30,90},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash)}),                           Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the base model of all fluid-based volumes. It defines the 
+volume geometry, heat ports in all spatial directions, and convective fluid ports 
+in x-direction. The required heat ports can be adjusted via the volume setup. The
+implementation of the fluid ports follows the 'connectorSizing' principle. Furthermore, 
+this model defines fundamental variables for the momentum, mass, and energy balance, 
+as well as the initialization of these balances.
+<br/><br/>
+Models that inherit properties from this partial model must redeclare the fluid port
+and may have to add further convective fluid ports (e.g., y- or z-direction) and 
+diffusive fluid ports in the required spatial direction. Furthermore, conservation 
+equations must be added. In this context, appropriate fluid property models are 
+required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Temperature <i>T</i>.
+  </li>
+  <li>
+  Specific volume <i>v</i> and density <i>&rho;</i>.
+  </li>
+  <li>
+  Specific enthalpy <i>h</i>.
+  </li>
+  <br/>
+  <li>
+  Mass balance using at least the variables <i>dm_dtau</i> and <i>mc_flow</i>.
+  </li>
+  <li>
+  Partial derivative of the overall mass w.r.t. time <i>dm_dtau</i>.
+  </li>
+  <li>
+  Sum of all convective mass flow rates <i>mc_flow</i>.
+  </li>
+  <br/>
+  <li>
+  Energy balance using at least the variables <i>dU_dtau</i>, <i>Hb_flow</i>,
+  and <i>Qb_flow</i>.
+  </li>
+  <li>
+  Partial derivative of the internal energy w.r.t. time <i>dU_dtau</i>.
+  </li>
+  <li>
+  Sum of all enthalpy flow rates across boundaries <i>Hb_flow</i>.
+  </li>
+  <li>
+  Sum of all heat flow rates across boundaries <i>Qb_flow</i>.
+  </li>
+  <br/>
+  <li>
+  Variables of the summary record except for pressure <i>p</i>, temperature <i>T</i>, 
+  specific volume <i>v</i>, and mass flow rates in x-direction 
+  <i>mc_flow_xMinus</i>/<i>mc_flow_xPlus</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 7, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialFluidVolume;
diff --git a/SorpLib/Basics/Volumes/BaseClasses/PartialPhaseSeparatorVolume.mo b/SorpLib/Basics/Volumes/BaseClasses/PartialPhaseSeparatorVolume.mo
new file mode 100644
index 0000000..61d94cc
--- /dev/null
+++ b/SorpLib/Basics/Volumes/BaseClasses/PartialPhaseSeparatorVolume.mo
@@ -0,0 +1,413 @@
+within SorpLib.Basics.Volumes.BaseClasses;
+partial model PartialPhaseSeparatorVolume
+  "Base model for all phase saprator volumes"
+
+  //
+  // Definition of parameters describing media
+  //
+  parameter Integer no_components = 1
+    "Number of components in the medium"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding classes
+  //
+  parameter Integer nPorts_cfp_xMinus=0
+    "Number of ports at cfp_xMinus"
+    annotation (Dialog(connectorSizing=true),
+                HideResult=true);
+  parameter Integer nPorts_cfp_xPlus=0
+    "Number of ports at cfp_xPlus"
+    annotation (Dialog(connectorSizing=true),
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.Temperature T_initial = 298.15
+    "Initial value of temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+  parameter Modelica.Units.SI.Density rho_initial = 200
+    "Initial value of density"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  parameter Modelica.Units.SI.MassFlowRate mc_flow_initialX = 1e-4
+    "Start value for convective mass flow rate in x direction"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialVolume(
+    redeclare replaceable SorpLib.Basics.Volumes.Records.PhaseSeparatorGeometry geometry
+    constrainedby SorpLib.Basics.Volumes.Records.PhaseSeparatorGeometry);
+
+  //
+  // Definition of parameters regarding calculation setup
+  //
+  parameter Boolean calculateAdditionalProperties = false
+    "= true, if additional properties required for tranport models are calculated"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_overallMassBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the overall mass balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean useStateLimiter = true
+    "= true, if specific enthalpy of vapor or liquid is limited at ports (i.e.,
+    vapor port is slightly overheated and liquid port is slightly supercooled)"
+    annotation (Dialog(tab = "Advanced", group = "Limits"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Modelica.Units.SI.SpecificEnthalpy dh = 10
+    "Specific enthalpy used for superheating and supercooling"
+    annotation (Dialog(tab = "Advanced", group = "Limits",
+                enable = useStateLimiter),
+                HideResult = true);
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in[nPorts_cfp_xMinus] cfp_xMinus(
+    each final no_components=no_components,
+    m_flow(each start=mc_flow_initialX))
+    "Convective fluid port at position '-dx/2' (i.e., liquid port)"
+    annotation (Placement(transformation(extent={{-46,14},{-38,22}}),
+                iconTransformation(extent={{-46,14},{-38,22}})));
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out[nPorts_cfp_xPlus] cfp_xPlus(
+    each final no_components=no_components,
+    m_flow(each start=-mc_flow_initialX))
+    "Convective fluid port at position '+dx/2' (i.e., vapor port)"
+    annotation (Placement(transformation(extent={{74,14},{82,22}}),
+                iconTransformation(extent={{74,14},{82,22}})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p(
+    stateSelect=StateSelect.avoid)
+    "Pressure";
+  Modelica.Units.SI.Temperature T(
+    start=T_initial,
+    stateSelect=StateSelect.prefer)
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+  Modelica.Units.SI.Density rho(
+    start=rho_initial,
+    stateSelect=StateSelect.prefer)
+    "Density";
+
+  Modelica.Units.SI.SpecificEnthalpy h(
+    stateSelect=StateSelect.avoid)
+    "Specific enthalpy";
+  Modelica.Units.SI.SpecificInternalEnergy u
+    "Specific internal energy";
+
+  Modelica.Units.SI.Density rho_liq
+    "Density at saturated liquid line";
+  Modelica.Units.SI.Density rho_vap
+    "Density at saturated vapor line";
+  Modelica.Units.SI.SpecificEnthalpy h_liq
+    "Specific enthalpy at saturated liquid line";
+  Modelica.Units.SI.SpecificEnthalpy h_vap
+    "Specific enthalpy at saturated vapor line";
+  Real q(unit="kg/kg")
+    "Vapor mass fraction in phase seperator";
+
+  Modelica.Units.SI.Length l_liq
+    "Height of liquid phase";
+  Real l_liq_rel(unit="1")
+    "Relative height of liquid phase";
+
+  Modelica.Units.SI.Mass m
+    "Mass";
+  Modelica.Units.SI.Mass m_liq
+    "Liquid mass";
+  Modelica.Units.SI.Mass m_vap
+    "Vapor mass";
+
+  Modelica.Units.SI.MassFlowRate dm_dtau
+    "Derivative of mass w.r.t. time";
+  Modelica.Units.SI.MassFlowRate mc_flow
+    "Sum of all convective mass flow rates across boundaries";
+
+  Modelica.Units.SI.InternalEnergy U
+    "Internal energy";
+
+  Real dU_dtau(final unit="W")
+    "Derivative of internal energy w.r.t. time";
+  Modelica.Units.SI.EnthalpyFlowRate Hb_flow
+    "Sum of all enthalpy flow rates across boundaries";
+  Modelica.Units.SI.HeatFlowRate Qb_flow
+    "Sum of all heat flow rates across boundaries";
+
+  SorpLib.Basics.Volumes.Records.PhaseSeparatorProperties phaseSepratorProperties(
+    final no_components=no_components)
+    "Properties of phase separator volume often required for calculation of 
+    heat transfer";
+
+initial equation
+  if type_overallMassBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    rho = rho_initial
+      "Fixed initial value";
+
+  elseif type_overallMassBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    der(rho) = 0
+      "Steady-state initialisation of overall mass balance";
+
+  end if;
+
+  if type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    T = T_initial
+      "Fixed initial value";
+
+  elseif type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    der(T) = 0
+      "Steady-state initial value";
+
+  end if;
+
+equation
+  //
+  // Assertations
+  //
+  assert(no_components <= 1,
+    "The liquid volume model can only handel pure fluids (i.e., with one component)!",
+    level = AssertionLevel.error);
+
+  assert(not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Property calculation
+  //
+  v = 1 / rho
+    "Specific volume";
+
+  h = h_liq + q * (h_vap - h_liq)
+    "Specific enthalpy";
+  u = h - p * v
+    "Specific internal energy";
+
+  //
+  // Additional property calculation
+  //
+  q = (1/rho - 1/rho_liq) / (1/rho_vap - 1/rho_liq)
+    "Vapor mass fraction";
+
+  l_liq = m_liq / (rho_liq * geometry.A_base)
+    "Liquid filling height";
+  l_liq_rel = l_liq / (geometry.V / geometry.A_base)
+    "Relative height of liquid phase";
+
+  //
+  // Momentum balance
+  //
+  cfp_xMinus.p = fill(p, nPorts_cfp_xMinus)
+    "Total pressure at the port (i.e., homogenous volume)";
+  cfp_xPlus.p = fill(p, nPorts_cfp_xPlus)
+    "Total pressure at the port (i.e., homogenous volume)";
+
+  //
+  // Mass balance
+  //
+  m = geometry.V / v
+    "Mass";
+  m_liq = (1 - q) * m
+    "Liquid mass";
+  m_vap = q * m
+    "Vapor mass";
+
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    dm_dtau = geometry.V * der(rho)
+      "Transient overall mass balance";
+
+  end if;
+
+  //
+  // Energy balance
+  //
+  U = m * u
+    "Internal energy";
+
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    dU_dtau = u * dm_dtau + m * (
+      phaseSepratorProperties.cv * der(T) +
+      1/rho^2 * (-p + (h_vap - h_liq) / (1/rho_vap - 1/rho_liq)) * der(rho))
+      "Transient energy balance";
+
+  end if;
+
+  if useStateLimiter then
+    cfp_xMinus.h_outflow = fill(h_liq - dh, nPorts_cfp_xMinus)
+      "Specific enthalpy leaving the port (i.e., homogenous volume)";
+    cfp_xPlus.h_outflow = fill(h_vap + dh, nPorts_cfp_xPlus)
+      "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  else
+    cfp_xMinus.h_outflow = fill(h_liq, nPorts_cfp_xMinus)
+      "Specific enthalpy leaving the port (i.e., homogenous volume)";
+    cfp_xPlus.h_outflow = fill(h_vap, nPorts_cfp_xPlus)
+      "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  end if;
+
+  T_heatPorts = T
+    "Required for conditional component";
+
+  //
+  // Summary record
+  //
+  phaseSepratorProperties.p = p
+    "Pressure";
+  phaseSepratorProperties.T = T
+    "Temperature";
+  phaseSepratorProperties.v = v
+    "Specific volume";
+
+  phaseSepratorProperties.l_liq = l_liq
+    "Height of liquid phase";
+  phaseSepratorProperties.l_liq_rel = l_liq_rel
+    "Relative height of liquid phase";
+
+  phaseSepratorProperties.Pr = if calculateAdditionalProperties then
+    phaseSepratorProperties.eta * phaseSepratorProperties.cp /
+    phaseSepratorProperties.lambda else 0
+    "Prandtl number";
+
+  phaseSepratorProperties.mc_flow_xMinus = sum(cfp_xMinus.m_flow)
+    "Total convective mass flow rate at port '-dx/2'";
+  phaseSepratorProperties.mc_flow_xPlus = sum(cfp_xPlus.m_flow)
+    "Total convective mass flow rate at port '+dx/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Rectangle(extent={{-90,30},{30,-90}}, lineColor={0,0,0}),
+        Line(points={{-90,30},{-30,90}}, color={0,0,0}),
+        Line(
+          points={{-30,-30},{-90,-90}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(points={{90,-30},{30,-90}}, color={0,0,0}),
+        Line(points={{90,90},{30,30}}, color={0,0,0}),
+        Line(points={{-30,90},{90,90},{90,-30}}, color={0,0,0}),
+        Line(
+          points={{90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-30,90},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+                          Polygon(
+          points={{-90,-90},{-30,-30},{-30,90},{-90,30},{-90,-90}},
+          lineColor={28,108,200},
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid)}),                      Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the base model of all phase separatpr volumes. It defines the 
+volume geometry, heat ports in all spatial directions, and convective fluid ports 
+in x-direction. The required heat ports can be adjusted via the volume setup. The
+implementation of the fluid ports follows the 'connectorSizing' principle. Furthermore, 
+this model defines fundamental variables for the momentum, mass, and energy balance, 
+as well as the initialization of these balances.
+<br/><br/>
+Models that inherit properties from this partial model may have to add further 
+convective fluid ports (e.g., y- or z-direction) and diffusive fluid ports in the 
+required spatial direction. Furthermore, conservation equations must be finalized.  
+In this context, appropriate fluid property models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i>.
+  </li>
+  <li>
+  Density at saturated liquid line <i>&rho;<sub>liq</sub></i>.
+  </li>
+  <li>
+  Density at saturated vapor line <i>&rho;<sub>vap</sub></i>.
+  </li>
+  <li>
+  Specific enthalpy at saturated liquid line <i>h<sub>liq</sub></i>.
+  </li>
+  <li>
+  Specific enthalpy at saturated vapor line <i>h<sub>vap</sub></i>.
+  </li>
+  <br/>
+  <li>
+  Mass balance using at least the variables <i>dm_dtau</i> and <i>mc_flow</i>.
+  </li>
+  <li>
+  Sum of all convective mass flow rates <i>mc_flow</i>.
+  </li>
+  <br/>
+  <li>
+  Energy balance using at least the variables <i>dU_dtau</i>, <i>Hb_flow</i>,
+  and <i>Qb_flow</i>.
+  </li>
+  <li>
+  Sum of all enthalpy flow rates across boundaries <i>Hb_flow</i>.
+  </li>
+  <li>
+  Sum of all heat flow rates across boundaries <i>Qb_flow</i>.
+  </li>
+  <br/>
+  <li>
+  Variables of the summary record except for pressure <i>p</i>, temperature <i>T</i>, 
+  specific volume <i>v</i>, height of liquid phase <i>l_liq</i>, relative heigt of
+  liquid phase <i>l_liq_rel</i>, Prandtl number <i>Pr</i>, and mass flow rates in 
+  x-direction <i>mc_flow_xMinus</i>/<i>mc_flow_xPlus</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 14, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 13, 2021, by Mirko Engelpracht:<br/>
+  Major revisions (e.g., object-oriented approach, options) after restructuring 
+  of the library.
+  </li>
+  <li>
+  November 22, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end PartialPhaseSeparatorVolume;
diff --git a/SorpLib/Basics/Volumes/BaseClasses/PartialPureComponentAdsorbateVolume.mo b/SorpLib/Basics/Volumes/BaseClasses/PartialPureComponentAdsorbateVolume.mo
new file mode 100644
index 0000000..e23fa32
--- /dev/null
+++ b/SorpLib/Basics/Volumes/BaseClasses/PartialPureComponentAdsorbateVolume.mo
@@ -0,0 +1,389 @@
+within SorpLib.Basics.Volumes.BaseClasses;
+partial model PartialPureComponentAdsorbateVolume
+  "Base model for all adsorbate models for pure component adsorption"
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialAdsorbateVolume(
+    final no_components=Medium.nX,
+    final no_adsorptivs=1,
+    p(final start=p_initial,
+      final stateSelect= if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+      StateSelect.prefer else StateSelect.avoid),
+    x(final start=x_initial,
+      final stateSelect= if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT then
+      StateSelect.prefer else StateSelect.avoid),
+    useHeatPorts=true,
+    useHeatPortsX=true,
+    type_adsorbentMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_adsorptMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of general parameters
+  //
+  parameter Integer nSorptionPorts = 0
+    "Number of sorption ports"
+    annotation (Dialog(connectorSizing=true),
+                HideResult = true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the fluid"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+    constrainedby
+    SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs
+    "Pure working pair model"
+    annotation (Dialog(tab="General", group="Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding calculation setup
+  //
+  parameter SorpLib.Choices.IndependentVariablesPureComponentWorkingPair independentStateVariables=
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT
+    "Independent state variables"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.Pressure p_initial = 2e3
+    "Initial value of pressure"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=(independentStateVariables==
+                  SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT)));
+  parameter SorpLib.Units.Uptake x_initial = 0.3
+    "Initial value of uptake"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=(independentStateVariables==
+                  SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT)));
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in[nSorptionPorts] fp_sorption
+  constrainedby SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort(
+    each final no_components=no_components,
+    each m_flow(start=ms_flow_initial))
+    "Sorption fluid port"
+    annotation (Placement(transformation(extent={{-20,40},{-12,48}}),
+                iconTransformation(extent={{-20,40},{-12,48}})));
+
+  //
+  // Definition of variables
+  //
+  PureWorkingPairModel workingPair(
+    redeclare final package Medium = Medium,
+    final stateVariables=independentStateVariables,
+    final calcCaloricProperties=true,
+    final calcAdsorptAdsorbateState=calcUptakeAveragedProperties or
+      useAdsorbatePorts or useDiffusivePorts,
+    final calcDerivativesIsotherm=true,
+    final calcDerivativesMassEnergyBalance=true,
+    final p_adsorpt=p,
+    final x_adsorpt=x,
+    final T_adsorpt=T,
+    final avoidEvents=avoid_events)
+    "Thermodynamic properties and partial derivatives of the pure working pair";
+
+initial equation
+  if type_adsorptMassBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+      p = p_initial
+        "Fixed initial value";
+
+    else
+      x = x_initial
+        "Fixed initial value";
+
+    end if;
+
+  elseif type_adsorptMassBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+      der(p) = 0
+        "Steady-state initialisation of overall mass balance";
+
+    else
+      der(x) = 0
+        "Steady-state initialisation of overall mass balance";
+
+    end if;
+  end if;
+
+equation
+  //
+  // Assertations
+  //
+  assert(no_components <= 1,
+    "The VLE adsorbate volume model can only handel pure fluids (i.e., with one " +
+    "component)!",
+    level = AssertionLevel.error);
+
+  assert(no_adsorptivs <= 1,
+    "The VLE adsorbate volume model can only handel one adsorptive!",
+    level = AssertionLevel.error);
+
+  assert(not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    (type_adsorbentMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_adsorptMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial)),
+    "Steady-state mass balances combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  if useAdsorbatePorts then
+    assert(calcUptakeAveragedProperties,
+      "When using adsorbate ports, uptake-averaged properties must be calculated!",
+      level = AssertionLevel.error);
+  end if;
+
+  if useDiffusivePorts then
+    assert(calcUptakeAveragedProperties,
+      "When using diffusive ports, uptake-averaged properties must be calculated!",
+      level = AssertionLevel.error);
+  end if;
+
+  //
+  // Calculation of properties
+  //
+  h = workingPair.state_averageAdsorbate.h
+    "Uptake-averaged specific enthalpy: h_sor + x * h_avg_adsorpt";
+  u = workingPair.state_averageAdsorbate.u
+    "Uptake-averaged specific internal energy: u_sor + x * u_avg_adsorpt";
+
+  //
+  // Momentum balance
+  //
+  dp_xMinus[1].x = x
+    "Loading at the port (i.e., homogenous volume)";
+  dp_xPlus[1].x = x
+    "Loading at the port (i.e., homogenous volume)";
+
+  fp_sorption.p = fill(p, nSorptionPorts)
+    "Total pressure at the port (i.e., homogenous volume)";
+
+  //
+  // Mass balance
+  //
+  if type_adsorptMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_adsorpt_dtau = 0
+      "Steady-state adsorpt mass balance";
+
+  else
+    if useAdsorbatePorts then
+      if independentStateVariables==
+        SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+        dm_adsorpt_dtau = dm_sor_dtau * x + m_sor * (
+          workingPair.derivatives_isotherm.dx_dp_T * der(p) +
+          workingPair.derivatives_isotherm.dx_dT_p * der(T))
+          "Transient adsorpt mass balance";
+
+      else
+        dm_adsorpt_dtau = dm_sor_dtau * x + m_sor * der(x)
+          "Transient adsorpt mass balance";
+
+      end if;
+
+    else
+      if independentStateVariables==
+        SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+        dm_adsorpt_dtau = m_sor * (
+          workingPair.derivatives_isotherm.dx_dp_T * der(p) +
+          workingPair.derivatives_isotherm.dx_dT_p * der(T))
+          "Transient adsorpt mass balance";
+
+      else
+        dm_adsorpt_dtau = m_sor * der(x)
+          "Transient adsorpt mass balance";
+
+      end if;
+
+    end if;
+  end if;
+
+  ap_xMinus.x_outflow = {x}
+    "Loading leaving the port (i.e., homogenous volume)";
+  ap_xPlus.x_outflow = {x}
+    "Loading leaving the port (i.e., homogenous volume)";
+
+  //
+  // Energy balance
+  //
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if useAdsorbatePorts then
+      if independentStateVariables==
+        SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+        dU_dtau = dm_sor_dtau * u + m_sor * der(T) * (
+          (workingPair.derivatives_massEnergy.dh_sorbent_dT_p -
+           p * workingPair.derivatives_massEnergy.dv_sorbent_dT_p) +
+          (workingPair.derivatives_massEnergy.dxh_avg_adsorpt_dT_p -
+           p * workingPair.derivatives_massEnergy.dxv_avg_adsorpt_dT_p)) +
+           m_sor * der(p) * (
+          (workingPair.derivatives_massEnergy.dh_sorbent_dp_T -
+           p * workingPair.derivatives_massEnergy.dv_sorbent_dp_T) +
+          (workingPair.derivatives_massEnergy.dxh_avg_adsorpt_dp_T -
+           p * workingPair.derivatives_massEnergy.dxv_avg_adsorpt_dp_T) -
+          (workingPair.state_sorbent.v + x *
+          workingPair.state_lastAdsorbedMolecule.v))
+          "Transient energy balance";
+
+      else
+        dU_dtau = dm_sor_dtau * u + m_sor * der(T) * (
+          (workingPair.derivatives_massEnergy.dh_sorbent_dT_x -
+           p * workingPair.derivatives_massEnergy.dv_sorbent_dT_x -
+           workingPair.state_sorbent.v * workingPair.derivatives_isotherm.dp_dT_x) +
+          (workingPair.derivatives_massEnergy.dxh_avg_adsorpt_dT_x -
+           p * workingPair.derivatives_massEnergy.dxv_avg_adsorpt_dT_x -
+           x * workingPair.state_lastAdsorbedMolecule.v *
+           workingPair.derivatives_isotherm.dp_dT_x)) +
+           m_sor * der(x) * (
+          (workingPair.derivatives_massEnergy.dh_sorbent_dx_T -
+           p * workingPair.derivatives_massEnergy.dv_sorbent_dx_T -
+           workingPair.state_sorbent.v * workingPair.derivatives_isotherm.dp_dx_T) +
+          (workingPair.derivatives_massEnergy.dxh_avg_adsorpt_dx_T -
+           p * workingPair.derivatives_massEnergy.dxv_avg_adsorpt_dx_T -
+           x * workingPair.state_lastAdsorbedMolecule.v *
+           workingPair.derivatives_isotherm.dp_dx_T))
+          "Transient energy balance";
+
+      end if;
+
+    else
+      if independentStateVariables==
+        SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+        dU_dtau = m_sor * der(T) * (
+          (workingPair.derivatives_massEnergy.dh_sorbent_dT_p -
+           p * workingPair.derivatives_massEnergy.dv_sorbent_dT_p) +
+          (workingPair.derivatives_massEnergy.dxh_avg_adsorpt_dT_p -
+           p * workingPair.derivatives_massEnergy.dxv_avg_adsorpt_dT_p)) +
+           m_sor * der(p) * (
+          (workingPair.derivatives_massEnergy.dh_sorbent_dp_T -
+           p * workingPair.derivatives_massEnergy.dv_sorbent_dp_T) +
+          (workingPair.derivatives_massEnergy.dxh_avg_adsorpt_dp_T -
+           p * workingPair.derivatives_massEnergy.dxv_avg_adsorpt_dp_T) -
+          (workingPair.state_sorbent.v + x *
+          workingPair.state_lastAdsorbedMolecule.v))
+          "Transient energy balance";
+
+      else
+        dU_dtau = m_sor * der(T) * (
+          (workingPair.derivatives_massEnergy.dh_sorbent_dT_x -
+           p * workingPair.derivatives_massEnergy.dv_sorbent_dT_x -
+           workingPair.state_sorbent.v * workingPair.derivatives_isotherm.dp_dT_x) +
+          (workingPair.derivatives_massEnergy.dxh_avg_adsorpt_dT_x -
+           p * workingPair.derivatives_massEnergy.dxv_avg_adsorpt_dT_x -
+           x * workingPair.state_lastAdsorbedMolecule.v *
+           workingPair.derivatives_isotherm.dp_dT_x)) +
+           m_sor * der(x) * (
+          (workingPair.derivatives_massEnergy.dh_sorbent_dx_T -
+           p * workingPair.derivatives_massEnergy.dv_sorbent_dx_T -
+           workingPair.state_sorbent.v * workingPair.derivatives_isotherm.dp_dx_T) +
+          (workingPair.derivatives_massEnergy.dxh_avg_adsorpt_dx_T -
+           p * workingPair.derivatives_massEnergy.dxv_avg_adsorpt_dx_T -
+           x * workingPair.state_lastAdsorbedMolecule.v *
+           workingPair.derivatives_isotherm.dp_dx_T))
+          "Transient energy balance";
+
+      end if;
+
+    end if;
+  end if;
+
+  dp_xMinus[1].h_outflow = workingPair.state_averageAdsorpt.h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+  dp_xPlus[1].h_outflow = workingPair.state_averageAdsorpt.h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  fp_sorption.h_outflow = fill(workingPair.state_adsorptive.h, nSorptionPorts)
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  //
+  // Summary record
+  //
+  adsorbateProperties.x_i[1] = x
+    "Loading of each component";
+
+  adsorbateProperties.cp = workingPair.cp_adsorpt
+    "Specific heat capacity";
+  adsorbateProperties.dh_ads = workingPair.h_ads
+    "Specific enthalpy of adsorption";
+
+  adsorbateProperties.m_flow_sorption = ms_flow
+    "Total mass flow rate at port 'sorption'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all adsorbate volumes for pure component
+adsorption. It defines the volume geometry, heat ports in all spatial directions, 
+as well as adsorbate and diffusive (i.e., adsorpt) ports in x-direction. The required 
+heat ports can be adjusted via the volume setup. Furthermore, this model defines 
+fundamental variables for the momentum, mass, and energy balance, as well as the 
+initialization of these balances.
+<br/><br/>
+Models that inherit properties from this partial model must redeclare the fluid port
+and may have to add further adsorbate and diffusive (i.e., adsorpt) ports in the 
+required spatial direction (e.g., y- or z-direction). Furthermore, the working pair
+model must be redeclared.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Sum of all adsorbent mass flow rates across adsorbate boundaries <i>masor_flow</i>.
+  </li>
+  <li>
+  Sum of all adsorpt mass flow rates across adsorbate boundaries <i>mas_flow</i>.
+  </li>
+  <li>
+  Sum of all sorption mass flow rates across sorption boundaries <i>ms_flow</i>.
+  </li>
+  <br/>
+  <li>
+  Sum of all enthalpy flow rates across boundaries <i>Hb_flow</i>.
+  </li>
+  <br/>
+  <li>
+  Variables of the summary record: Adsorbate mass flow rates in y-direction 
+  <i>ma_flow_yMinus</i>/<i>ma_flow_yPlus</i> and in z-direction 
+  <i>ma_flow_zMinus</i>/<i>ma_flow_zPlus</i>, as well as diffusive mass flow 
+  rates in y-direction <i>md_flow_yMinus</i>/<i>md_flow_yPlus</i> and in
+  z-direction <i>md_flow_zMinus</i>/<i>md_flow_zPlus</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureComponentAdsorbateVolume;
diff --git a/SorpLib/Basics/Volumes/BaseClasses/PartialVolume.mo b/SorpLib/Basics/Volumes/BaseClasses/PartialVolume.mo
new file mode 100644
index 0000000..3a76a8d
--- /dev/null
+++ b/SorpLib/Basics/Volumes/BaseClasses/PartialVolume.mo
@@ -0,0 +1,323 @@
+within SorpLib.Basics.Volumes.BaseClasses;
+partial model PartialVolume
+  "Base model for all volumes"
+
+  //
+  // Definition of parameters regarding volume setup
+  //
+  parameter Boolean useHeatPorts = false
+    " = true, if heat ports are required"
+    annotation (Dialog(tab="Volume Setup", group="Heat Ports"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useHeatPortsX = false
+    " = true, if heat ports are required in the x direction"
+    annotation (Dialog(tab="Volume Setup", group="Heat Ports",
+                enable=useHeatPorts),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useHeatPortsY = false
+    " = true, if heat ports are required in the y direction"
+    annotation (Dialog(tab="Volume Setup", group="Heat Ports",
+                enable=useHeatPorts),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useHeatPortsZ = false
+    " = true, if heat ports are required in the z direction"
+    annotation (Dialog(tab="Volume Setup", group="Heat Ports",
+                enable=useHeatPorts),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding geometry
+  //
+  replaceable parameter SorpLib.Basics.Volumes.Records.VolumeGeometry geometry
+    constrainedby SorpLib.Basics.Volumes.Records.VolumeGeometry
+    "Volume geometry"
+    annotation (Dialog(tab = "General", group = "Geometry"),
+                choicesAllMatching=true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_energyBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the energy balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult = true);
+
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_xMinus(
+    final T=T_xMinus,
+    final Q_flow=Q_flow_xMinus) if
+    useHeatPorts and useHeatPortsX
+    "Heat port at position '-dx/2'"
+    annotation (Placement(transformation(extent={{-66,-6},{-54,6}}),
+                                  iconTransformation(extent={{-66,-6},{-54,6}})));
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_out hp_xPlus(
+    final T=T_xPlus,
+    final Q_flow=Q_flow_xPlus) if
+    useHeatPorts and useHeatPortsX
+    "Heat port at position '+dx/2'"
+    annotation (Placement(transformation(extent={{54,-6},{66,6}}),
+                                iconTransformation(extent={{54,-6},{66,6}})));
+
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_yMinus(
+    final T=T_yMinus,
+    final Q_flow=Q_flow_yMinus) if
+    useHeatPorts and useHeatPortsY "Heat port at position '-dy/2'"
+    annotation (Placement(transformation(extent={{-6,-66},{6,-54}}),
+                                 iconTransformation(extent={{-6,-66},{6,-54}})));
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_out hp_yPlus(
+    final T=T_yPlus,
+    final Q_flow=Q_flow_yPlus) if
+    useHeatPorts and useHeatPortsY
+    "Heat port at position '+dy/2'"
+    annotation (Placement(transformation(extent={{-6,54},{6,66}}),
+                               iconTransformation(extent={{-6,54},{6,66}})));
+
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_zMinus(
+    final T=T_zMinus,
+    final Q_flow=Q_flow_zMinus) if
+    useHeatPorts and useHeatPortsZ
+    "Heat port at position '-dz/2'"
+    annotation (Placement(transformation(extent={{24,24},{36,36}}),
+                               iconTransformation(extent={{24,24},{36,36}})));
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_out hp_zPlus(
+    final T=T_zPlus,
+    final Q_flow=Q_flow_zPlus) if
+    useHeatPorts and useHeatPortsZ
+    "Heat port at position '+dz/2'"
+    annotation (Placement(transformation(extent={{-36,-36},{-24,-24}}),
+                                   iconTransformation(extent={{-36,-36},{-24,-24}})));
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.Temperature T_heatPorts
+    "Required for conditional connectors";
+
+  Modelica.Units.SI.Temperature T_xMinus
+    "Required for conditional connector";
+  Modelica.Units.SI.Temperature T_xPlus
+    "Required for conditional connector";
+
+  Modelica.Units.SI.Temperature T_yMinus
+    "Required for conditional connector";
+  Modelica.Units.SI.Temperature T_yPlus
+    "Required for conditional connector";
+
+  Modelica.Units.SI.Temperature T_zMinus
+    "Required for conditional connector";
+  Modelica.Units.SI.Temperature T_zPlus
+    "Required for conditional connector";
+
+  Modelica.Units.SI.HeatFlowRate Q_flow_xMinus
+    "Required for conditional connector";
+  Modelica.Units.SI.HeatFlowRate Q_flow_xPlus
+    "Required for conditional connector";
+
+  Modelica.Units.SI.HeatFlowRate Q_flow_yMinus
+    "Required for conditional connector";
+  Modelica.Units.SI.HeatFlowRate Q_flow_yPlus
+    "Required for conditional connector";
+
+  Modelica.Units.SI.HeatFlowRate Q_flow_zMinus
+    "Required for conditional connector";
+  Modelica.Units.SI.HeatFlowRate Q_flow_zPlus
+    "Required for conditional connector";
+
+equation
+  //
+  // Assertations
+  //
+  if not useHeatPorts then
+    assert(not (useHeatPortsX or useHeatPortsY or useHeatPortsZ),
+      "Deactivate individual heat ports if heat ports are not considered!",
+      level = AssertionLevel.error);
+  end if;
+
+  //
+  // Variables of heat ports
+  //
+  T_xMinus = T_heatPorts
+    "Required for conditional connector";
+  T_xPlus = T_heatPorts
+    "Required for conditional connector";
+
+  T_yMinus = T_heatPorts
+    "Required for conditional connector";
+  T_yPlus = T_heatPorts
+    "Required for conditional connector";
+
+  T_zMinus = T_heatPorts
+    "Required for conditional connector";
+  T_zPlus = T_heatPorts
+    "Required for conditional connector";
+
+  if not useHeatPortsX then
+    Q_flow_xMinus = 0
+      "Required for conditional connector";
+    Q_flow_xPlus = 0
+      "Required for conditional connector";
+  end if;
+
+  if not useHeatPortsY then
+    Q_flow_yMinus = 0
+      "Required for conditional connector";
+    Q_flow_yPlus = 0
+      "Required for conditional connector";
+  end if;
+
+  if not useHeatPortsZ then
+    Q_flow_zMinus = 0
+      "Required for conditional connector";
+    Q_flow_zPlus = 0
+      "Required for conditional connector";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Rectangle(extent={{-90,30},{30,-90}}, lineColor={0,0,0}),
+        Line(points={{-90,30},{-30,90}}, color={0,0,0}),
+        Line(
+          points={{-30,-30},{-90,-90}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(points={{90,-30},{30,-90}}, color={0,0,0}),
+        Line(points={{90,90},{30,30}}, color={0,0,0}),
+        Line(points={{-30,90},{90,90},{90,-30}}, color={0,0,0}),
+        Line(
+          points={{90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-30,90},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-60,-60},{60,-60},{60,60},{-60,60},{-60,-60}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{30,-30},{-30,-90},{-30,30},{30,90},{30,30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{-30,30},{-90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{30,-30},{90,30},{30,30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot)}),                            Diagram(
+        coordinateSystem(preserveAspectRatio=false), graphics={
+        Line(
+          points={{80,-90},{100,-90}},
+          color={0,0,0},
+          arrow={Arrow.None,Arrow.Filled}),
+        Line(
+          points={{80,-90},{80,-70}},
+          color={0,0,0},
+          arrow={Arrow.None,Arrow.Filled}),
+        Line(
+          points={{80,-90},{70,-100}},
+          color={0,0,0},
+          arrow={Arrow.None,Arrow.Filled}),
+        Text(
+          extent={{96,-98},{100,-94}},
+          lineColor={0,0,0},
+          fontSize=24,
+          textString="x",
+          textStyle={TextStyle.Bold}),
+        Text(
+          extent={{84,-74},{88,-70}},
+          lineColor={0,0,0},
+          fontSize=24,
+          textStyle={TextStyle.Bold},
+          textString="y"),
+        Text(
+          extent={{76,-100},{80,-96}},
+          lineColor={0,0,0},
+          fontSize=24,
+          textStyle={TextStyle.Bold},
+          textString="z"),
+        Rectangle(extent={{-90,30},{30,-90}}, lineColor={0,0,0}),
+        Line(points={{-90,30},{-30,90}}, color={0,0,0}),
+        Line(
+          points={{-30,-30},{-90,-90}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(points={{90,-30},{30,-90}}, color={0,0,0}),
+        Line(points={{90,90},{30,30}}, color={0,0,0}),
+        Line(points={{-30,90},{90,90},{90,-30}}, color={0,0,0}),
+        Line(
+          points={{90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-30,90},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-60,-60},{60,-60},{60,60},{-60,60},{-60,-60}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{30,-30},{-30,-90},{-30,30},{30,90},{30,30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{-30,30},{-90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{30,-30},{90,30},{30,30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot)}),
+    Documentation(info="<html>
+<p>
+This partial model is the base model of all finite volumes. It defines the volume 
+geometry and heat ports in all spatial directions. The required heat ports can be 
+adjusted via the volume setup.
+<br/><br/>
+Models that inherit properties from this partial model may have to add fluid ports
+and corresponding parameters to specify the fluid port setup. Furthermore, conservation
+equations and corresponding variables must be added. In this context, fluid property
+models may be required. Finally, records summarizing thermodynamic volume properties 
+should be added.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  The variable <i>T_heatPorts</i> that defines the temperature at the heat ports.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 6, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialVolume;
diff --git a/SorpLib/Basics/Volumes/BaseClasses/package.mo b/SorpLib/Basics/Volumes/BaseClasses/package.mo
new file mode 100644
index 0000000..c9c6bc2
--- /dev/null
+++ b/SorpLib/Basics/Volumes/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Basics.Volumes;
+package BaseClasses "Base classes used to create new finite volume models"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial basic functions and models. These partial functions
+and models contain fundamental definitions of all volume models. The content of 
+this package is only of interest when adding new volume models to the library.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Basics/Volumes/BaseClasses/package.order b/SorpLib/Basics/Volumes/BaseClasses/package.order
new file mode 100644
index 0000000..ea6049e
--- /dev/null
+++ b/SorpLib/Basics/Volumes/BaseClasses/package.order
@@ -0,0 +1,5 @@
+PartialVolume
+PartialAdsorbateVolume
+PartialPureComponentAdsorbateVolume
+PartialFluidVolume
+PartialPhaseSeparatorVolume
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/GasMixtureVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/GasMixtureVolume.mo
new file mode 100644
index 0000000..6d1350c
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/GasMixtureVolume.mo
@@ -0,0 +1,755 @@
+within SorpLib.Basics.Volumes.FluidVolumes;
+model GasMixtureVolume "Homogenous volume of an ideal gas mixture"
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialFluidVolume(
+    final no_components = Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final neglectTermVp = false,
+    redeclare final connector FluidPortsIn =
+      SorpLib.Basics.Interfaces.FluidPorts.GasPort_in,
+    redeclare final connector FluidPortsOut =
+      SorpLib.Basics.Interfaces.FluidPorts.GasPort_out,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    useHeatPorts=true,
+    useHeatPortsY=true,
+    h_initial=Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=X_i_initial),
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture
+    "Medium model of the ideal gas mixture"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  parameter Integer no_adsorptivs(min=1, max=no_components) = 1
+    "Number of adsorptivs (i.e., components that can be adsorbed/desorbed)"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer[no_adsorptivs] ind_adsorptivs=
+    fill(Medium.nX, no_adsorptivs)
+    "Indexes of adsorptivs in the ideal gas mixture"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+  final parameter Integer[no_components] mapped_ind_adsorptivs=
+    SorpLib.Basics.Volumes.Utilities.mapSorptionFluidPorts(
+      no_components=no_components,
+      ind_adsorptivs=ind_adsorptivs)
+    "Indices of sorption fluid ports mapped to component indices: I.e., value of
+    zero if component cannot be adsorbed/desorbed; otherwise, value of sorption
+    fluid port"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean idealGasMixture = true
+    " = true, if medium is an ideal gas mixture and govering equations are  
+    explicitly written for an ideal gas mixture"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.MassFraction[no_components] X_i_initial=
+    Medium.reference_X
+    "Initial values of mass fractions"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  parameter Modelica.Units.SI.MassFlowRate md_flow_initialX = 1e-4
+    "Start value for diffusive mass flow rates in x direction"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+  parameter Modelica.Units.SI.MassFlowRate ms_flow_initial = 1e-4
+    "Start value for sorption mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_independentMassBalances=
+    type_overallMassBalance
+    "Handling of independent mass balances and corresponding initialisations"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_sorption
+    "Sorption heat port"
+    annotation (Placement(transformation(extent={{10,-50},{22,-38}}),
+                iconTransformation(extent={{10,-50},{22,-38}})));
+
+  FluidPortsIn[no_components] dfp_xMinus(
+    each final no_components=1,
+    m_flow(each start=-md_flow_initialX))
+    "Diffusive fluid port at position '-dx/2'"
+    annotation (Placement(transformation(extent={{-82,-22},{-74,-14}}),
+                iconTransformation(extent={{-82,-22},{-74,-14}})));
+  FluidPortsOut[no_components] dfp_xPlus(
+    each final no_components=1,
+    m_flow(each start=md_flow_initialX))
+    "Diffusive fluid port at position '+dx/2'"
+    annotation (Placement(transformation(extent={{38,-22},{46,-14}}),
+                                iconTransformation(extent={{38,-22},{46,-14}})));
+
+  FluidPortsIn[no_adsorptivs] fp_sorption(
+    each final no_components=1,
+    m_flow(each start=ms_flow_initial))
+    "Sorption fluid port"
+    annotation (Placement(transformation(extent={{-20,-80},{-12,-72}}),
+                iconTransformation(extent={{-20,-80},{-12,-72}})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure[no_components] p_i
+    "Partial pressures";
+  Modelica.Units.SI.MassFraction[no_components] X_i(
+    start=X_i_initial,
+    each stateSelect=StateSelect.prefer)
+    "Mass fractions";
+
+  Modelica.Units.SI.SpecificEnthalpy[no_components] h_i
+    "Specific enthalpy of individual components";
+
+  Modelica.Units.SI.Mass[no_components] m_i
+    "Mass of individual components";
+
+  Modelica.Units.SI.MassFlowRate[no_components] dm_i_dtau
+    "Derivative of individual components' masses w.r.t. time";
+
+  Modelica.Units.SI.MassFlowRate[no_components] mc_i_flow
+    "Sum of all individual components' convective mass flow rates across 
+    boundaries";
+  Modelica.Units.SI.MassFlowRate md_flow
+    "Sum of all diffusive mass flow rates across boundaries";
+  Modelica.Units.SI.MassFlowRate[no_components] md_i_flow
+    "Sum of all individual components' diffusive mass flow rates across 
+    boundaries";
+  Modelica.Units.SI.MassFlowRate ms_flow
+    "Sum of all sorption mass flow rates across boundaries";
+  Modelica.Units.SI.MassFlowRate[no_components] ms_i_flow
+    "Sum of all individual components' sorption mass flow rates across 
+    boundaries";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+initial equation
+  if type_independentMassBalances ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    X_i = X_i_initial
+      "Fixed initial values";
+
+  elseif type_independentMassBalances ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    der(X_i) = zeros(no_components)
+      "Steady-state initialisation of independent mass balances";
+
+  end if;
+
+equation
+  //
+  // Assertations
+  //
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=X_i)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=X_i)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  p_i = Medium.partialPressures(state=state)
+    "Partial pressures";
+  v = 1 / rho
+    "Specific volume";
+  rho = Medium.density(state=state)
+    "Density";
+
+  for ind in 1:no_components loop
+    h_i[ind] = Medium.specificEnthalpy_i_T(ind_component=ind, T=T)
+      "Specific enthalpy of individual components";
+  end for;
+
+  //
+  // Momentum balance
+  //
+  dfp_xMinus.p = p_i
+    "Partial pressures at the port (i.e., homogenous volume)";
+  dfp_xPlus.p = p_i
+    "Partial pressures at the port (i.e., homogenous volume)";
+
+  for ind in 1:no_adsorptivs loop
+    fp_sorption[ind].p = p_i[ind_adsorptivs[ind]]
+      "Partial pressures at the port (i.e., homogenous volume)";
+  end for;
+
+  //
+  // Mass balance
+  //
+  m_i = m .* X_i
+    "Mass of individual components";
+
+  dm_dtau = mc_flow + md_flow + ms_flow
+    "Overall mass balance";
+  dm_i_dtau = mc_i_flow + md_i_flow + ms_i_flow
+    "Individual components' mass balances";
+
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dm_dtau = geometry.V * (Medium.density_derX(state=state) * der(X_i) +
+        rho * (fluidProperties.kappa *der(p) - fluidProperties.beta * der(T)))
+        "Transient overall mass balance";
+
+    else
+      if idealGasMixture then
+        dm_dtau = geometry.V * (rho * (fluidProperties.kappa * der(p) -
+          fluidProperties.beta / fluidProperties.cp * der(h)) +
+          (Medium.density_derX(state=state) .+ rho .* fluidProperties.beta .*
+          h_i ./ fluidProperties.cp) * der(X_i))
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = geometry.V * (rho * ((fluidProperties.kappa -
+          fluidProperties.beta * fluidProperties.my) * der(p) -
+          fluidProperties.beta / fluidProperties.cp * der(h)) +
+          (Medium.density_derX(state=state) .+ rho .* fluidProperties.beta .*
+          h_i ./ fluidProperties.cp) * der(X_i))
+          "Transient overall mass balance";
+
+      end if;
+    end if;
+  end if;
+
+  if type_independentMassBalances==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_i_dtau = zeros(no_components)
+      "Steady-state independent mass balances";
+
+  else
+    dm_i_dtau = X_i .* dm_dtau .+ m .* der(X_i)
+      "Transient independent mass balances";
+
+  end if;
+
+  mc_flow = sum(cfp_xMinus.m_flow) + sum(cfp_xPlus.m_flow)
+    "Sum of all convective mass flow rates across boundaries";
+  md_flow = sum(dfp_xMinus.m_flow) + sum(dfp_xPlus.m_flow)
+    "Sum of all diffusive mass flow rates across boundaries";
+  ms_flow = sum(fp_sorption.m_flow)
+    "Sum of all sorption mass flow rates across boundaries";
+
+  if avoid_events then
+    for ind_comp in 1:no_components loop
+      if ind_comp <> no_components then
+        mc_i_flow[ind_comp] =
+          sum(cfp_xMinus[ind_port].m_flow *
+          noEvent(actualStream(cfp_xMinus[ind_port].Xi_outflow[ind_comp]))
+          for ind_port in 1:nPorts_cfp_xMinus) +
+          sum(cfp_xPlus[ind_port].m_flow *
+          noEvent(actualStream(cfp_xPlus[ind_port].Xi_outflow[ind_comp]))
+          for ind_port in 1:nPorts_cfp_xPlus)
+          "Sum of all convective mass flow rates of component ind_comp across 
+          boundaries";
+
+      else
+        mc_i_flow[ind_comp] =  mc_flow - sum(mc_i_flow[1:no_components-1])
+          "Sum of all convective mass flow rates of last component across 
+          boundaries";
+
+      end if;
+    end for;
+
+  else
+    for ind_comp in 1:no_components loop
+      if ind_comp <> no_components then
+        mc_i_flow[ind_comp] =
+          sum(cfp_xMinus[ind_port].m_flow *
+          actualStream(cfp_xMinus[ind_port].Xi_outflow[ind_comp])
+          for ind_port in 1:nPorts_cfp_xMinus) +
+          sum(cfp_xPlus[ind_port].m_flow *
+          actualStream(cfp_xPlus[ind_port].Xi_outflow[ind_comp])
+          for ind_port in 1:nPorts_cfp_xPlus)
+          "Sum of all convective mass flow rates of component ind_comp across 
+          boundaries";
+
+      else
+        mc_i_flow[ind_comp] =  mc_flow - sum(mc_i_flow[1:no_components-1])
+          "Sum of all convective mass flow rates of last component across 
+          boundaries";
+
+      end if;
+    end for;
+  end if;
+
+  md_i_flow = dfp_xMinus.m_flow .+ dfp_xPlus.m_flow
+    "Sum of all individual components' diffusive mass flow rates across 
+    boundaries";
+
+  for ind in 1:no_components loop
+    ms_i_flow[ind] = if mapped_ind_adsorptivs[ind] == 0 then 0 else
+      fp_sorption[mapped_ind_adsorptivs[ind]].m_flow
+      "Sum of all individual components' sorption mass flow rates across 
+      boundaries";
+  end for;
+
+  for ind in 1:nPorts_cfp_xMinus loop
+    cfp_xMinus[ind].Xi_outflow = X_i[1:no_components-1]
+      "Independent mass fractions leaving the port (i.e., homogenous volume)";
+  end for;
+  for ind in 1:nPorts_cfp_xPlus loop
+    cfp_xPlus[ind].Xi_outflow = X_i[1:no_components-1]
+      "Independent mass fractions leaving the port (i.e., homogenous volume)";
+  end for;
+
+  //
+  // Energy balance
+  //
+  dU_dtau = Hb_flow + Qb_flow
+    "Energy balane";
+
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if idealGasMixture then
+        dU_dtau = u * dm_dtau + m * (
+          (fluidProperties.cp - p * v * fluidProperties.beta) * der(T) +
+          (h_i .+ p .* v.^2 .* Medium.density_derX(state=state)) * der(X_i))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (
+          v * (p * fluidProperties.kappa - T * fluidProperties.beta) * der(p) +
+          (fluidProperties.cp - p * v * fluidProperties.beta) * der(T) +
+          (h_i .+ p .* v.^2 .* Medium.density_derX(state=state)) * der(X_i))
+          "Transient energy balance";
+
+      end if;
+
+    else
+      if idealGasMixture then
+        dU_dtau = u * dm_dtau + m * (
+          (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h) +
+          p .* v.^2 .* (Medium.density_derX(state=state) .+ rho .*
+          fluidProperties.beta .* h_i ./ fluidProperties.cp) * der(X_i))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (
+          (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h) +
+          v * (p * (fluidProperties.kappa - fluidProperties.beta *
+          fluidProperties.my) - 1) * der(p) +
+          p .* v.^2 .* (Medium.density_derX(state=state) .+ rho .*
+          fluidProperties.beta .* h_i ./ fluidProperties.cp) * der(X_i))
+          "Transient energy balance";
+
+      end if;
+    end if;
+  end if;
+
+  if avoid_events then
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* noEvent(actualStream(cfp_xMinus.h_outflow))) +
+      sum(cfp_xPlus.m_flow .* noEvent(actualStream(cfp_xPlus.h_outflow))) +
+      sum(dfp_xMinus.m_flow .* noEvent(actualStream(dfp_xMinus.h_outflow))) +
+      sum(dfp_xPlus.m_flow .* noEvent(actualStream(dfp_xPlus.h_outflow))) +
+      sum(fp_sorption.m_flow .* noEvent(actualStream(fp_sorption.h_outflow)))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  else
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* actualStream(cfp_xMinus.h_outflow)) +
+      sum(cfp_xPlus.m_flow .* actualStream(cfp_xPlus.h_outflow)) +
+      sum(dfp_xMinus.m_flow .* actualStream(dfp_xMinus.h_outflow)) +
+      sum(dfp_xPlus.m_flow .* actualStream(dfp_xPlus.h_outflow)) +
+      sum(fp_sorption.m_flow .* actualStream(fp_sorption.h_outflow))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  end if;
+
+  Qb_flow = Q_flow_xMinus + Q_flow_xPlus +
+    Q_flow_yMinus + Q_flow_yPlus +
+    Q_flow_zMinus + Q_flow_zPlus +
+    hp_sorption.Q_flow
+    "Sum of all heat flow rates across boundaries";
+
+  dfp_xMinus.h_outflow = h_i
+    "Specific enthalpies leaving the port (i.e., homogenous volume)";
+  dfp_xPlus.h_outflow = h_i
+    "Specific enthalpies leaving the port (i.e., homogenous volume)";
+
+  for ind in 1:no_adsorptivs loop
+    fp_sorption[ind].h_outflow = h_i[ind_adsorptivs[ind]]
+      "Specific enthalpy leaving the port (i.e., homogenous volume)";
+  end for;
+
+  hp_sorption.T = T
+    "Temperature at sorption heat port";
+
+  //
+  // Summary record
+  //
+  fluidProperties.cp = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  fluidProperties.lambda = if calculateAdditionalProperties then
+    Medium.thermalConductivity(state=state) else 0
+    "Thermal conductivity";
+  fluidProperties.eta = if calculateAdditionalProperties then
+    Medium.dynamicViscosity(state=state) else 0
+    "Dynamic viscosity";
+
+  fluidProperties.beta = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  fluidProperties.kappa = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  fluidProperties.my = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)))) then
+    v / fluidProperties.cp * (fluidProperties.beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  fluidProperties.Pr = if calculateAdditionalProperties then
+    fluidProperties.eta * fluidProperties.cp / fluidProperties.lambda else 0
+    "Prandtl number";
+
+  fluidProperties.m_flow_sorption = ms_flow
+    "Total mass flow rate at port 'sorption'";
+
+  fluidProperties.mc_flow_yMinus = 0
+    "Convective mass flow rate at port '-dy/2'";
+  fluidProperties.mc_flow_yPlus = 0
+    "Convective mass flow rate at port '+dy/2'";
+  fluidProperties.mc_flow_zMinus = 0
+    "Convective mass flow rate at port '-dz/2'";
+  fluidProperties.mc_flow_zPlus = 0
+    "Convective mass flow rate at port '+dz/2'";
+
+  fluidProperties.md_flow_xMinus = dfp_xMinus.m_flow
+    "Diffusive mass flow rate at port '-dx/2'";
+  fluidProperties.md_flow_xPlus = dfp_xPlus.m_flow
+    "Diffusive mass flow rate at port '+dx/2'";
+  fluidProperties.md_flow_yMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dy/2'";
+  fluidProperties.md_flow_yPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dy/2'";
+  fluidProperties.md_flow_zMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dz/2'";
+  fluidProperties.md_flow_zPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a gas-mixture volume, applying a lumped modeling approach. 
+Depending on the volume setup, this model may have up to seven heat ports (i.e., two 
+for each spatial direction of a cartesian coordinate system and one for an adsorbate
+volume). Furthermore, this model has convective fluid ports in y-direction, following 
+the 'connectorSizing' principle, diffusive fluid ports in y-direction, and a sorption
+fluid port. These ports allow for the combination of several fluid volumes to create a 
+spatially distributed model.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equations are the momentum, mass, and energy balance. According to
+the staggered grid approach, the momentum balance is not solved within the volume but 
+at the volume's boundaries via so-called 
+<a href=\"Modelica://SorpLib.Components.Fittings\">flow models</a>. Hennce, no pressure 
+losses occur within the volume:
+</p>
+<pre>
+    p = cfp_xMinus.p;
+</pre>
+<pre>
+    p = cfp_xPlus.p;
+</pre>
+<p>
+The pressure at the diffusive fluid ports and sorption fluid ports correspnds to the
+correct partial pressure:
+</p>
+<pre>
+    p_i[i] = dfp_xMinus[i].p;
+</pre>
+<pre>
+    p_i[i] = dfp_xPlus[i].p;
+</pre>
+<pre>
+    p_i[i] = fp_sorption[i].p;
+</pre>
+
+<br/>
+<p>
+Regarding the mass and energy balances, either steady-state or tansient balnaces can be 
+selected. When using the pressure <i>p</i>, temperature <i>T</i>, and mass fractions 
+<i>X<sub>i</sub></i> as independent states, the overall mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * [&rho; * (&kappa; * (dp/d&tau;) - &beta; * (dT/d&tau;)) + &sum; (&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; m<sub>c,flow</sub> + &sum; m<sub>d,flow</sub>+ &sum; m<sub>s,flow</sub>;
+</pre>
+<p>
+the component-specific mass balances are defined as
+</p>
+<pre>
+    (dm<sub>i</sub>/d&tau;) = X<sub>i</sub> * (dm/d&tau;) + m * (dX<sub>i</sub>/d&tau;) = &sum; m<sub>c,i,flow</sub> + &sum; m<sub>d,i,flow</sub>+ &sum; m<sub>s,i,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * &kappa; - T * &beta;) * (dp/d&tau;) + (c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;) + &sum; ((&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) + p * v<sup>2</sup> * (&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>)) * (dX<sub>i</sub>/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<br/>
+<p>
+When using the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions 
+<i>X<sub>i</sub></i> as independent states, the overall mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * [&rho; * ((&kappa; - &beta; * &mu;) * (dp/d&tau;) - &beta; / c<sub>p</sub> * (dh/d&tau;)) + &sum; ((&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) + &rho; * &beta; * (&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) / c<sub>p</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; m<sub>c,flow</sub> + &sum; m<sub>d,flow</sub>+ &sum; m<sub>s,flow</sub>;
+</pre>
+<p>
+the component-specific mass balances are defined as
+</p>
+<pre>
+    (dm<sub>i</sub>/d&tau;) = X<sub>i</sub> * (dm/d&tau;) + m * (dX<sub>i</sub>/d&tau;) = &sum; m<sub>c,i,flow</sub> + &sum; m<sub>d,i,flow</sub>+ &sum; m<sub>s,i,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * (&kappa; - &beta; * &mu;) - 1) * (dp/d&tau;) + (1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;) + &sum; p * v<sup>2</sup> * ((&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) + &rho; * &beta; * (&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) / c<sub>p</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<br/>
+<p>
+Herein, <i>(dm/d&tau;)</i> is the derivative of the mass w.r.t. time, <i>(dU/d&tau;)</i> 
+is the derivative of the internal energy w.r.t. time, <i>(d&rho;/d&tau;)</i> is the 
+derivative of the density w.r.t. time, <i>(du/d&tau;)</i> is the derivative of the specific 
+internal energy w.r.t.time, <i>(dp/d&tau;)</i> is the derivative of the pressure w.r.t. 
+time, <i>(dT/d&tau;)</i> is the derivative of the temperature w.r.t. time, <i>(dh/d&tau;)</i> 
+is the derivative of the specific enthalpy w.r.t. time, <i>(dX<sub>i</sub>/d&tau;)</i> are the 
+derivatives of the mass fractions w.r.t. time, <i>(&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>)</i> is 
+the partial derivative of the density w.r.t. mass fractions at constant pressure and temperatre,
+<i>(&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>)</i> is the partial derivative of the specific enthaly w.r.t. 
+mass fractions at constant pressure and temperature, <i>V</i> is the volume, <i>m</i> is the mass, 
+<i>v</i> is the specific volume, <i>&rho;</i> is the density, <i>&kappa;</i> is the isothermal 
+compressibility, <i>&beta;</i> is the isobaric expansion coefficient, <i>&mu;</i> is the Joule-Thomson 
+coefficient, <i>c<sub>p</sub></i> is the specific heat capacity at constant pressure, 
+<i>m<sub>c,flow</sub></i> is the sum of the convective mass flow rates, <i>m<sub>d,flow</sub></i> is 
+the sum of the diffusive mass flow rates, <i>m<sub>s,flow</sub></i> is the sum of the sorption mass 
+flow rates, <i>H<sub>b,flow</sub></i> is the sum of the enthalpy flow rates, and <i>Q<sub>b,flow</sub></i> 
+is the sum of the heat flow rates. Mass flow rates with index <i>i</i> describe component-specific 
+mass flow rates.
+</p>
+
+<h4>Main equations for an ideal gas mixture</h4>
+<p>
+For an ideal gas mixture, the isothermal compressibility <i>&kappa;</i> is <i>1/p</i> and the
+isbaric expansion coefficient <i>&beta;</i> is <i>1/T</i>, leading to a Joule-Thomson coefficient 
+<i>&mu;</i> of zero. Hence, the overall mass and energy balances can be simplified. When using the 
+pressure <i>p</i>, temperature <i>T</i>, and mass fractions <i>X<sub>i</sub></i> as independent 
+states, the overall mass balance still reads as
+</p>
+<pre>
+    (dm/d&tau;) = V * [&rho; * (&kappa; * (dp/d&tau;) - &beta; * (dT/d&tau;)) + &sum; (&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; m<sub>c,flow</sub> + &sum; m<sub>d,flow</sub>+ &sum; m<sub>s,flow</sub>;
+</pre>
+<p>
+but the energy balance now reads as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * [(c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;) + &sum; ((&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) + p * v<sup>2</sup> * (&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>)) * (dX<sub>i</sub>/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<br/>
+<p>
+When using the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions 
+<i>X<sub>i</sub></i> as independent states, the overall mass balance now reads as
+</p>
+<pre>
+    (dm/d&tau;) = V * [&rho; * (&kappa; * (dp/d&tau;) - &beta; / c<sub>p</sub> * (dh/d&tau;)) + &sum; ((&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) + &rho; * &beta; * (&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) / c<sub>p</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; m<sub>c,flow</sub> + &sum; m<sub>d,flow</sub>+ &sum; m<sub>s,flow</sub>;
+</pre>
+<p>
+and the energy balance now reads as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * [(1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;) + &sum; p * v<sup>2</sup> * ((&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) + &rho; * &beta; * (&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) / c<sub>p</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Ideal gas mixture
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to model the adsorptive of open adsorption systems.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>idealGasMixture</i>:
+  Defines if the medium is an ideal gas mixture and, thus, the governing equations 
+  can be simplified.
+  </li>
+  <li>
+  <i>calculateAdditionalProperties</i>:
+  Defines if additional properties like transport properties shall be calculated.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_independentMassBalances</i>:
+  Defines the type of the independent mass balances.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has two dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i>, temperature <i>T</i>, and mass fractions <i>X<sub>i</sub></i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions <i>X<sub>i</sub></i>.
+  </li>
+</ul>
+<p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 12, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasMixtureVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/GasVaporMixtureVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/GasVaporMixtureVolume.mo
new file mode 100644
index 0000000..e579975
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/GasVaporMixtureVolume.mo
@@ -0,0 +1,791 @@
+within SorpLib.Basics.Volumes.FluidVolumes;
+model GasVaporMixtureVolume "Homogenous volume of an ideal gas-vapor mixture"
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialFluidVolume(
+    final no_components = Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final neglectTermVp = false,
+    redeclare final connector FluidPortsIn =
+      SorpLib.Basics.Interfaces.FluidPorts.GasPort_in,
+    redeclare final connector FluidPortsOut =
+      SorpLib.Basics.Interfaces.FluidPorts.GasPort_out,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    useHeatPorts=true,
+    useHeatPortsY=true,
+    h_initial=Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=X_i_initial),
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture
+    "Medium model of the ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  parameter Integer no_adsorptivs(min=1, max=no_components) = 1
+    "Number of adsorptivs (i.e., components that can be adsorbed/desorbed)"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer[no_adsorptivs] ind_adsorptivs=
+    fill(Medium.nX, no_adsorptivs)
+    "Indexes of adsorptivs in the ideal gas mixture"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+  final parameter Integer[no_components] mapped_ind_adsorptivs=
+    SorpLib.Basics.Volumes.Utilities.mapSorptionFluidPorts(
+      no_components=no_components,
+      ind_adsorptivs=ind_adsorptivs)
+    "Indices of sorption fluid ports mapped to component indices: I.e., value of
+    zero if component cannot be adsorbed/desorbed; otherwise, value of sorption
+    fluid port"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean idealGasVaporMixture = true
+    " = true, if medium is an ideal gas-vapoor mixture and govering equations are  
+    explicitly written for an ideal gas mixture (i.e., unsaturated air)"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.MassFraction[no_components] X_i_initial=
+    Medium.reference_X
+    "Initial values of mass fractions"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  parameter Modelica.Units.SI.MassFlowRate md_flow_initialX = 1e-4
+    "Start value for diffusive mass flow rates in x direction"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+  parameter Modelica.Units.SI.MassFlowRate ms_flow_initial = 1e-4
+    "Start value for sorption mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_independentMassBalances=
+    type_overallMassBalance
+    "Handling of independent mass balances and corresponding initialisations"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_sorption
+    "Sorption heat port"
+    annotation (Placement(transformation(extent={{10,-50},{22,-38}}),
+                iconTransformation(extent={{10,-50},{22,-38}})));
+
+  FluidPortsIn[no_components] dfp_xMinus(
+    each final no_components=1,
+    m_flow(each start=-md_flow_initialX))
+    "Diffusive fluid port at position '-dx/2'"
+    annotation (Placement(transformation(extent={{-82,-22},{-74,-14}}),
+                iconTransformation(extent={{-82,-22},{-74,-14}})));
+  FluidPortsOut[no_components] dfp_xPlus(
+    each final no_components=1,
+    m_flow(each start=md_flow_initialX))
+    "Diffusive fluid port at position '+dx/2'"
+    annotation (Placement(transformation(extent={{38,-22},{46,-14}}),
+                                iconTransformation(extent={{38,-22},{46,-14}})));
+
+  FluidPortsIn[no_adsorptivs] fp_sorption(
+    each final no_components=1,
+    m_flow(each start=ms_flow_initial))
+    "Sorption fluid port"
+    annotation (Placement(transformation(extent={{-20,-80},{-12,-72}}),
+                iconTransformation(extent={{-20,-80},{-12,-72}})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure[no_components] p_i
+    "Partial pressures";
+  Modelica.Units.SI.MassFraction[no_components] X_i(
+    start=X_i_initial,
+    each stateSelect=StateSelect.prefer)
+    "Mass fractions";
+
+  Modelica.Units.SI.SpecificEnthalpy[no_components] h_i
+    "Specific enthalpy of individual components";
+
+  Modelica.Units.SI.Mass[no_components] m_i
+    "Mass of individual components";
+
+  Modelica.Units.SI.MassFlowRate[no_components] dm_i_dtau
+    "Derivative of individual components' masses w.r.t. time";
+
+  Modelica.Units.SI.MassFlowRate[no_components] mc_i_flow
+    "Sum of all individual components' convective mass flow rates across 
+    boundaries";
+  Modelica.Units.SI.MassFlowRate md_flow
+    "Sum of all diffusive mass flow rates across boundaries";
+  Modelica.Units.SI.MassFlowRate[no_components] md_i_flow
+    "Sum of all individual components' diffusive mass flow rates across 
+    boundaries";
+  Modelica.Units.SI.MassFlowRate ms_flow
+    "Sum of all sorption mass flow rates across boundaries";
+  Modelica.Units.SI.MassFlowRate[no_components] ms_i_flow
+    "Sum of all individual components' sorption mass flow rates across 
+    boundaries";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+initial equation
+  if type_independentMassBalances ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    X_i = X_i_initial
+      "Fixed initial values";
+
+  elseif type_independentMassBalances ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    der(X_i) = zeros(no_components)
+      "Steady-state initialisation of independent mass balances";
+
+  end if;
+
+equation
+  //
+  // Assertations
+  //
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  if idealGasVaporMixture then
+    assert(Medium.relativeHumidity(state=state) < 1.0,
+      "Govering equations according to ideal gas mixture can only be applied if " +
+      "dry air is not saturatred! Results may not be reasonable!",
+      level = AssertionLevel.warning);
+
+  end if;
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=X_i)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=X_i)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  p_i = Medium.partialPressures(state=state)
+    "Partial pressures";
+  v = 1 / rho
+    "Specific volume";
+  rho = Medium.density(state=state)
+    "Density";
+
+  for ind in 1:no_components loop
+    h_i[ind] = Medium.specificEnthalpy_i(ind_component=ind, state=state)
+      "Specific enthalpy of individual components";
+  end for;
+
+  //
+  // Momentum balance
+  //
+  dfp_xMinus.p = p_i
+    "Partial pressures at the port (i.e., homogenous volume)";
+  dfp_xPlus.p = p_i
+    "Partial pressures at the port (i.e., homogenous volume)";
+
+  for ind in 1:no_adsorptivs loop
+    fp_sorption[ind].p = p_i[ind_adsorptivs[ind]]
+      "Partial pressures at the port (i.e., homogenous volume)";
+  end for;
+
+  //
+  // Mass balance
+  //
+  m_i = m .* X_i
+    "Mass of individual components";
+
+  dm_dtau = mc_flow + md_flow + ms_flow
+    "Overall mass balance";
+  dm_i_dtau = mc_i_flow + md_i_flow + ms_i_flow
+    "Individual components' mass balances";
+
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dm_dtau = geometry.V * (Medium.density_derX(state=state) * der(X_i) +
+        rho * (fluidProperties.kappa *der(p) - fluidProperties.beta * der(T)))
+        "Transient overall mass balance";
+      /*dm_dtau = geometry.V * (Medium.density_derp_T(state=state) * der(p) +
+        Medium.density_derT_p(state=state) * der(T) +
+        Medium.density_derX(state=state) * der(X_i))
+        "Transient overall mass balance";*/
+
+    else
+      if idealGasVaporMixture then
+        dm_dtau = geometry.V * (rho * (fluidProperties.kappa * der(p) -
+          fluidProperties.beta / fluidProperties.cp * der(h)) +
+          (Medium.density_derX(state=state) .+ rho .* fluidProperties.beta .*
+          Medium.dh_dX_pT(state=state) ./ fluidProperties.cp) * der(X_i))
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = geometry.V * (rho * ((fluidProperties.kappa -
+          fluidProperties.beta * fluidProperties.my) * der(p) -
+          fluidProperties.beta / fluidProperties.cp * der(h)) +
+          (Medium.density_derX(state=state) .+ rho .* fluidProperties.beta .*
+          Medium.dh_dX_pT(state=state) ./ fluidProperties.cp) * der(X_i))
+          "Transient overall mass balance";
+        /*dm_dtau = geometry.V * (Medium.density_derp_h(state=state) * der(p) +
+          Medium.density_derh_p(state=state) * der(h) +
+          Medium.drho_dX_ph(state=state) * der(X_i))
+          "Transient overall mass balance";*/
+
+      end if;
+    end if;
+  end if;
+
+  if type_independentMassBalances==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_i_dtau = zeros(no_components)
+      "Steady-state independent mass balances";
+
+  else
+    dm_i_dtau = X_i .* dm_dtau .+ m .* der(X_i)
+      "Transient independent mass balances";
+
+  end if;
+
+  mc_flow = sum(cfp_xMinus.m_flow) + sum(cfp_xPlus.m_flow)
+    "Sum of all convective mass flow rates across boundaries";
+  md_flow = sum(dfp_xMinus.m_flow) + sum(dfp_xPlus.m_flow)
+    "Sum of all diffusive mass flow rates across boundaries";
+  ms_flow = sum(fp_sorption.m_flow)
+    "Sum of all sorption mass flow rates across boundaries";
+
+  if avoid_events then
+    for ind_comp in 1:no_components loop
+      if ind_comp <> no_components then
+        mc_i_flow[ind_comp] =
+          sum(cfp_xMinus[ind_port].m_flow *
+          noEvent(actualStream(cfp_xMinus[ind_port].Xi_outflow[ind_comp]))
+          for ind_port in 1:nPorts_cfp_xMinus) +
+          sum(cfp_xPlus[ind_port].m_flow *
+          noEvent(actualStream(cfp_xPlus[ind_port].Xi_outflow[ind_comp]))
+          for ind_port in 1:nPorts_cfp_xPlus)
+          "Sum of all convective mass flow rates of component ind_comp across 
+          boundaries";
+
+      else
+        mc_i_flow[ind_comp] =  mc_flow - sum(mc_i_flow[1:no_components-1])
+          "Sum of all convective mass flow rates of last component across 
+          boundaries";
+
+      end if;
+    end for;
+
+  else
+    for ind_comp in 1:no_components loop
+      if ind_comp <> no_components then
+        mc_i_flow[ind_comp] =
+          sum(cfp_xMinus[ind_port].m_flow *
+          actualStream(cfp_xMinus[ind_port].Xi_outflow[ind_comp])
+          for ind_port in 1:nPorts_cfp_xMinus) +
+          sum(cfp_xPlus[ind_port].m_flow *
+          actualStream(cfp_xPlus[ind_port].Xi_outflow[ind_comp])
+          for ind_port in 1:nPorts_cfp_xPlus)
+          "Sum of all convective mass flow rates of component ind_comp across 
+          boundaries";
+
+      else
+        mc_i_flow[ind_comp] =  mc_flow - sum(mc_i_flow[1:no_components-1])
+          "Sum of all convective mass flow rates of last component across 
+          boundaries";
+
+      end if;
+    end for;
+  end if;
+
+  md_i_flow = dfp_xMinus.m_flow .+ dfp_xPlus.m_flow
+    "Sum of all individual components' diffusive mass flow rates across 
+    boundaries";
+
+  for ind in 1:no_components loop
+    ms_i_flow[ind] = if mapped_ind_adsorptivs[ind] == 0 then 0 else
+      fp_sorption[mapped_ind_adsorptivs[ind]].m_flow
+      "Sum of all individual components' sorption mass flow rates across 
+      boundaries";
+  end for;
+
+  for ind in 1:nPorts_cfp_xMinus loop
+    cfp_xMinus[ind].Xi_outflow = X_i[1:no_components-1]
+      "Independent mass fractions leaving the port (i.e., homogenous volume)";
+  end for;
+  for ind in 1:nPorts_cfp_xPlus loop
+    cfp_xPlus[ind].Xi_outflow = X_i[1:no_components-1]
+      "Independent mass fractions leaving the port (i.e., homogenous volume)";
+  end for;
+
+  //
+  // Energy balance
+  //
+  dU_dtau = Hb_flow + Qb_flow
+    "Energy balane";
+
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if idealGasVaporMixture then
+        dU_dtau = u * dm_dtau + m * (
+          (fluidProperties.cp - p * v * fluidProperties.beta) * der(T) +
+          (Medium.dh_dX_pT(state=state) .+ p .* v.^2 .*
+          Medium.density_derX(state=state)) * der(X_i))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (
+          v * (p * fluidProperties.kappa - T * fluidProperties.beta) * der(p) +
+          (fluidProperties.cp - p * v * fluidProperties.beta) * der(T) +
+          (Medium.dh_dX_pT(state=state) .+ p .* v.^2 .*
+          Medium.density_derX(state=state)) * der(X_i))
+          "Transient energy balance";
+        /*dU_dtau = u * dm_dtau + m * (
+          (Medium.dh_dp_TX(state=state) * der(p) +
+          Medium.dh_dT_pX(state=state) * der(T) +
+          Medium.dh_dX_pT(state=state) * der(X_i)) -
+          1 / rho * der(p) +
+          p / rho^2 * (Medium.density_derp_T(state=state) * der(p) +
+          Medium.density_derT_p(state=state) * der(T) +
+          Medium.density_derX(state=state) * der(X_i)))
+          "Transient energy balance";*/
+
+      end if;
+
+    else
+      if idealGasVaporMixture then
+        dU_dtau = u * dm_dtau + m * (
+          (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h) +
+          p .* v.^2 .* (Medium.density_derX(state=state) .+ rho .*
+          fluidProperties.beta .* Medium.dh_dX_pT(state=state) ./
+          fluidProperties.cp) * der(X_i))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (
+          (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h) +
+          v * (p * (fluidProperties.kappa - fluidProperties.beta *
+          fluidProperties.my) - 1) * der(p) +
+          p .* v.^2 .* (Medium.density_derX(state=state) .+ rho .*
+          fluidProperties.beta .* Medium.dh_dX_pT(state=state) ./
+          fluidProperties.cp) * der(X_i))
+          "Transient energy balance";
+        /*dU_dtau = u * dm_dtau + m * (
+          der(h) -
+          1 / rho * der(p) +
+          p / rho^2 * (Medium.density_derp_h(state=state) * der(p) +
+          Medium.density_derh_p(state=state) * der(h) +
+          Medium.drho_dX_ph(state=state) * der(X_i)))
+          "Transient energy balance";*/
+
+      end if;
+    end if;
+  end if;
+
+  if avoid_events then
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* noEvent(actualStream(cfp_xMinus.h_outflow))) +
+      sum(cfp_xPlus.m_flow .* noEvent(actualStream(cfp_xPlus.h_outflow))) +
+      sum(dfp_xMinus.m_flow .* noEvent(actualStream(dfp_xMinus.h_outflow))) +
+      sum(dfp_xPlus.m_flow .* noEvent(actualStream(dfp_xPlus.h_outflow))) +
+      sum(fp_sorption.m_flow .* noEvent(actualStream(fp_sorption.h_outflow)))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  else
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* actualStream(cfp_xMinus.h_outflow)) +
+      sum(cfp_xPlus.m_flow .* actualStream(cfp_xPlus.h_outflow)) +
+      sum(dfp_xMinus.m_flow .* actualStream(dfp_xMinus.h_outflow)) +
+      sum(dfp_xPlus.m_flow .* actualStream(dfp_xPlus.h_outflow)) +
+      sum(fp_sorption.m_flow .* actualStream(fp_sorption.h_outflow))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  end if;
+
+  Qb_flow = Q_flow_xMinus + Q_flow_xPlus +
+    Q_flow_yMinus + Q_flow_yPlus +
+    Q_flow_zMinus + Q_flow_zPlus +
+    hp_sorption.Q_flow
+    "Sum of all heat flow rates across boundaries";
+
+  dfp_xMinus.h_outflow = h_i
+    "Specific enthalpies leaving the port (i.e., homogenous volume)";
+  dfp_xPlus.h_outflow = h_i
+    "Specific enthalpies leaving the port (i.e., homogenous volume)";
+
+  for ind in 1:no_adsorptivs loop
+    fp_sorption[ind].h_outflow = h_i[ind_adsorptivs[ind]]
+      "Specific enthalpy leaving the port (i.e., homogenous volume)";
+  end for;
+
+  hp_sorption.T = T
+    "Temperature at sorption heat port";
+
+  //
+  // Summary record
+  //
+  fluidProperties.cp = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  fluidProperties.lambda = if calculateAdditionalProperties then
+    Medium.thermalConductivity(state=state) else 0
+    "Thermal conductivity";
+  fluidProperties.eta = if calculateAdditionalProperties then
+    Medium.dynamicViscosity(state=state) else 0
+    "Dynamic viscosity";
+
+  fluidProperties.beta = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  fluidProperties.kappa = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  fluidProperties.my = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)))) then
+    v / fluidProperties.cp * (fluidProperties.beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  fluidProperties.Pr = if calculateAdditionalProperties then
+    fluidProperties.eta * fluidProperties.cp / fluidProperties.lambda else 0
+    "Prandtl number";
+
+  fluidProperties.m_flow_sorption = ms_flow
+    "Total mass flow rate at port 'sorption'";
+
+  fluidProperties.mc_flow_yMinus = 0
+    "Convective mass flow rate at port '-dy/2'";
+  fluidProperties.mc_flow_yPlus = 0
+    "Convective mass flow rate at port '+dy/2'";
+  fluidProperties.mc_flow_zMinus = 0
+    "Convective mass flow rate at port '-dz/2'";
+  fluidProperties.mc_flow_zPlus = 0
+    "Convective mass flow rate at port '+dz/2'";
+
+  fluidProperties.md_flow_xMinus = dfp_xMinus.m_flow
+    "Diffusive mass flow rate at port '-dx/2'";
+  fluidProperties.md_flow_xPlus = dfp_xPlus.m_flow
+    "Diffusive mass flow rate at port '+dx/2'";
+  fluidProperties.md_flow_yMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dy/2'";
+  fluidProperties.md_flow_yPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dy/2'";
+  fluidProperties.md_flow_zMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dz/2'";
+  fluidProperties.md_flow_zPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a gas-vapor-mixture volume, applying a lumped modeling approach. 
+Depending on the volume setup, this model may have up to seven heat ports (i.e., two 
+for each spatial direction of a cartesian coordinate system and one for an adsorbate
+volume). Furthermore, this model has convective fluid ports in y-direction, following 
+the 'connectorSizing' principle, diffusive fluid ports in y-direction, and a sorption
+fluid port. These ports allow for the combination of several fluid volumes to create a 
+spatially distributed model.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equations are the momentum, mass, and energy balance. According to
+the staggered grid approach, the momentum balance is not solved within the volume but 
+at the volume's boundaries via so-called 
+<a href=\"Modelica://SorpLib.Components.Fittings\">flow models</a>. Hennce, no pressure 
+losses occur within the volume:
+</p>
+<pre>
+    p = cfp_xMinus.p;
+</pre>
+<pre>
+    p = cfp_xPlus.p;
+</pre>
+<p>
+The pressure at the diffusive fluid ports and sorption fluid ports correspnds to the
+correct partial pressure:
+</p>
+<pre>
+    p_i[i] = dfp_xMinus[i].p;
+</pre>
+<pre>
+    p_i[i] = dfp_xPlus[i].p;
+</pre>
+<pre>
+    p_i[i] = fp_sorption[i].p;
+</pre>
+
+<br/>
+<p>
+Regarding the mass and energy balances, either steady-state or tansient balnaces can be 
+selected. When using the pressure <i>p</i>, temperature <i>T</i>, and mass fractions 
+<i>X<sub>i</sub></i> as independent states, the overall mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * [&rho; * (&kappa; * (dp/d&tau;) - &beta; * (dT/d&tau;)) + &sum; (&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; m<sub>c,flow</sub> + &sum; m<sub>d,flow</sub>+ &sum; m<sub>s,flow</sub>;
+</pre>
+<p>
+the component-specific mass balances are defined as
+</p>
+<pre>
+    (dm<sub>i</sub>/d&tau;) = X<sub>i</sub> * (dm/d&tau;) + m * (dX<sub>i</sub>/d&tau;) = &sum; m<sub>c,i,flow</sub> + &sum; m<sub>d,i,flow</sub>+ &sum; m<sub>s,i,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * &kappa; - T * &beta;) * (dp/d&tau;) + (c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;) + &sum; ((&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) + p * v<sup>2</sup> * (&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>)) * (dX<sub>i</sub>/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<br/>
+<p>
+When using the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions 
+<i>X<sub>i</sub></i> as independent states, the overall mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * [&rho; * ((&kappa; - &beta; * &mu;) * (dp/d&tau;) - &beta; / c<sub>p</sub> * (dh/d&tau;)) + &sum; ((&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) + &rho; * &beta; * (&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) / c<sub>p</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; m<sub>c,flow</sub> + &sum; m<sub>d,flow</sub>+ &sum; m<sub>s,flow</sub>;
+</pre>
+<p>
+the component-specific mass balances are defined as
+</p>
+<pre>
+    (dm<sub>i</sub>/d&tau;) = X<sub>i</sub> * (dm/d&tau;) + m * (dX<sub>i</sub>/d&tau;) = &sum; m<sub>c,i,flow</sub> + &sum; m<sub>d,i,flow</sub>+ &sum; m<sub>s,i,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * (&kappa; - &beta; * &mu;) - 1) * (dp/d&tau;) + (1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;) + &sum; p * v<sup>2</sup> * ((&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) + &rho; * &beta; * (&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) / c<sub>p</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<br/>
+<p>
+Herein, <i>(dm/d&tau;)</i> is the derivative of the mass w.r.t. time, <i>(dU/d&tau;)</i> 
+is the derivative of the internal energy w.r.t. time, <i>(d&rho;/d&tau;)</i> is the 
+derivative of the density w.r.t. time, <i>(du/d&tau;)</i> is the derivative of the specific 
+internal energy w.r.t.time, <i>(dp/d&tau;)</i> is the derivative of the pressure w.r.t. 
+time, <i>(dT/d&tau;)</i> is the derivative of the temperature w.r.t. time, <i>(dh/d&tau;)</i> 
+is the derivative of the specific enthalpy w.r.t. time, <i>(dX<sub>i</sub>/d&tau;)</i> are the 
+derivatives of the mass fractions w.r.t. time, <i>(&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>)</i> is 
+the partial derivative of the density w.r.t. mass fractions at constant pressure and temperatre,
+<i>(&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>)</i> is the partial derivative of the specific enthaly w.r.t. 
+mass fractions at constant pressure and temperature, <i>V</i> is the volume, <i>m</i> is the mass, 
+<i>v</i> is the specific volume, <i>&rho;</i> is the density, <i>&kappa;</i> is the isothermal 
+compressibility, <i>&beta;</i> is the isobaric expansion coefficient, <i>&mu;</i> is the Joule-Thomson 
+coefficient, <i>c<sub>p</sub></i> is the specific heat capacity at constant pressure, 
+<i>m<sub>c,flow</sub></i> is the sum of the convective mass flow rates, <i>m<sub>d,flow</sub></i> is 
+the sum of the diffusive mass flow rates, <i>m<sub>s,flow</sub></i> is the sum of the sorption mass 
+flow rates, <i>H<sub>b,flow</sub></i> is the sum of the enthalpy flow rates, and <i>Q<sub>b,flow</sub></i> 
+is the sum of the heat flow rates. Mass flow rates with index <i>i</i> describe component-specific 
+mass flow rates.
+</p>
+
+<h4>Main equations for an ideal gas mixture</h4>
+<p>
+For an ideal gas mixture, the isothermal compressibility <i>&kappa;</i> is <i>1/p</i> and the
+isbaric expansion coefficient <i>&beta;</i> is <i>1/T</i>, leading to a Joule-Thomson coefficient 
+<i>&mu;</i> of zero. Hence, the overall mass and energy balances can be simplified. When using the 
+pressure <i>p</i>, temperature <i>T</i>, and mass fractions <i>X<sub>i</sub></i> as independent 
+states, the overall mass balance still reads as
+</p>
+<pre>
+    (dm/d&tau;) = V * [&rho; * (&kappa; * (dp/d&tau;) - &beta; * (dT/d&tau;)) + &sum; (&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; m<sub>c,flow</sub> + &sum; m<sub>d,flow</sub>+ &sum; m<sub>s,flow</sub>;
+</pre>
+<p>
+but the energy balance now reads as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * [(c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;) + &sum; ((&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) + p * v<sup>2</sup> * (&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>)) * (dX<sub>i</sub>/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<br/>
+<p>
+When using the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions 
+<i>X<sub>i</sub></i> as independent states, the overall mass balance now reads as
+</p>
+<pre>
+    (dm/d&tau;) = V * [&rho; * (&kappa; * (dp/d&tau;) - &beta; / c<sub>p</sub> * (dh/d&tau;)) + &sum; ((&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) + &rho; * &beta; * (&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) / c<sub>p</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; m<sub>c,flow</sub> + &sum; m<sub>d,flow</sub>+ &sum; m<sub>s,flow</sub>;
+</pre>
+<p>
+and the energy balance now reads as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * [(1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;) + &sum; p * v<sup>2</sup> * ((&part;&rho;/&part;X<sub>i</sub>|<sub>p,T</sub>) + &rho; * &beta; * (&part;h/&part;X<sub>i</sub>|<sub>p,T</sub>) / c<sub>p</sub>) * (dX<sub>i</sub>/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Ideal gas-vapor mixture
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to model the adsorptive of open adsorption systems.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>idealGasVaporMixture</i>:
+  Defines if the medium is an ideal gas-vapor mixture and, thus, the governing  
+  equations can be simplified.
+  </li>
+  <li>
+  <i>calculateAdditionalProperties</i>:
+  Defines if additional properties like transport properties shall be calculated.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_independentMassBalances</i>:
+  Defines the type of the independent mass balances.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has two dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i>, temperature <i>T</i>, and mass fractions <i>X<sub>i</sub></i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions <i>X<sub>i</sub></i>.
+  </li>
+</ul>
+<p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 13, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasVaporMixtureVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/GasVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/GasVolume.mo
new file mode 100644
index 0000000..7ea8547
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/GasVolume.mo
@@ -0,0 +1,510 @@
+within SorpLib.Basics.Volumes.FluidVolumes;
+model GasVolume "Homogenous volume of an ideal gas"
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialFluidVolume(
+    final no_components = Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final neglectTermVp = false,
+    redeclare final connector FluidPortsIn =
+      SorpLib.Basics.Interfaces.FluidPorts.GasPort_in,
+    redeclare final connector FluidPortsOut =
+      SorpLib.Basics.Interfaces.FluidPorts.GasPort_out,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    useHeatPorts=true,
+    useHeatPortsY=true,
+    h_initial=Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=Medium.reference_X),
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = SorpLib.Media.IdealGases.N2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium model of the ideal gas"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean idealGas = true
+    " = true, if medium is an ideal gas and govering equations are explicitly 
+    written for an ideal gas"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.MassFlowRate ms_flow_initial = 1e-4
+    "Start value for sorption mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_sorption
+    "Sorption heat port"
+    annotation (Placement(transformation(extent={{10,-50},{22,-38}}),
+                iconTransformation(extent={{10,-50},{22,-38}})));
+
+  FluidPortsIn fp_sorption(
+    final no_components=no_components,
+    m_flow(start=ms_flow_initial))
+    "Sorption fluid port"
+    annotation (Placement(transformation(extent={{-20,-80},{-12,-72}}),
+                iconTransformation(extent={{-20,-80},{-12,-72}})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.MassFlowRate ms_flow
+    "Sum of all sorption mass flow rates across boundaries";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+equation
+  //
+  // Assertations
+  //
+  assert(no_components <= 1,
+    "The gas volume model can only handel pure fluids (i.e., with one component)!",
+    level = AssertionLevel.error);
+
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  v = 1 / rho
+    "Specific volume";
+  rho = Medium.density(state=state)
+    "Density";
+
+  //
+  // Momentum balance
+  //
+  fp_sorption.p = p
+    "Total pressure at the port (i.e., homogenous volume)";
+
+  //
+  // Mass balance
+  //
+  dm_dtau = mc_flow + ms_flow
+    "Overall mass balance";
+
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dm_dtau = geometry.V * rho *
+        (fluidProperties.kappa *der(p) - fluidProperties.beta * der(T))
+        "Transient overall mass balance";
+
+    else
+      if idealGas then
+        dm_dtau = geometry.V * rho * (
+          fluidProperties.kappa * der(p) -
+          fluidProperties.beta / fluidProperties.cp * der(h))
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = geometry.V * rho * ((fluidProperties.kappa -
+        fluidProperties.beta * fluidProperties.my) * der(p) -
+        fluidProperties.beta / fluidProperties.cp * der(h))
+        "Transient overall mass balance";
+
+      end if;
+    end if;
+  end if;
+
+  mc_flow = sum(cfp_xMinus.m_flow) + sum(cfp_xPlus.m_flow)
+    "Sum of all convective mass flow rates across boundaries";
+  ms_flow = fp_sorption.m_flow
+    "Sum of all sorption mass flow rates across boundaries";
+
+  //
+  // Energy balance
+  //
+  dU_dtau = Hb_flow + Qb_flow
+    "Energy balane";
+
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if idealGas then
+        dU_dtau = u * dm_dtau + m * (
+          (fluidProperties.cp - p * v * fluidProperties.beta) * der(T))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (
+        v * (p * fluidProperties.kappa - T * fluidProperties.beta) * der(p) +
+        (fluidProperties.cp - p * v * fluidProperties.beta) * der(T))
+        "Transient energy balance";
+
+      end if;
+
+    else
+      if idealGas then
+        dU_dtau = u * dm_dtau + m * (
+          (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (
+        (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h) +
+        v * (p * (fluidProperties.kappa - fluidProperties.beta *
+        fluidProperties.my) - 1) * der(p))
+        "Transient energy balance";
+
+      end if;
+    end if;
+  end if;
+
+  if avoid_events then
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* noEvent(actualStream(cfp_xMinus.h_outflow))) +
+      sum(cfp_xPlus.m_flow .* noEvent(actualStream(cfp_xPlus.h_outflow))) +
+      fp_sorption.m_flow * noEvent(actualStream(fp_sorption.h_outflow))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  else
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* actualStream(cfp_xMinus.h_outflow)) +
+      sum(cfp_xPlus.m_flow .* actualStream(cfp_xPlus.h_outflow)) +
+      fp_sorption.m_flow * actualStream(fp_sorption.h_outflow)
+      "Sum of all enthalpy flow rates across boundaries";
+
+  end if;
+
+  Qb_flow = Q_flow_xMinus + Q_flow_xPlus +
+    Q_flow_yMinus + Q_flow_yPlus +
+    Q_flow_zMinus + Q_flow_zPlus +
+    hp_sorption.Q_flow
+    "Sum of all heat flow rates across boundaries";
+
+  fp_sorption.h_outflow = h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  hp_sorption.T = T
+    "Temperature at sorption heat port";
+
+  //
+  // Summary record
+  //
+  fluidProperties.cp = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  fluidProperties.lambda = if calculateAdditionalProperties then
+    Medium.thermalConductivity(state=state) else 0
+    "Thermal conductivity";
+  fluidProperties.eta = if calculateAdditionalProperties then
+    Medium.dynamicViscosity(state=state) else 0
+    "Dynamic viscosity";
+
+  fluidProperties.beta = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  fluidProperties.kappa = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  fluidProperties.my = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)))) then
+    v / fluidProperties.cp * (fluidProperties.beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  fluidProperties.Pr = if calculateAdditionalProperties then
+    fluidProperties.eta * fluidProperties.cp / fluidProperties.lambda else 0
+    "Prandtl number";
+
+  fluidProperties.m_flow_sorption = ms_flow
+    "Total mass flow rate at port 'sorption'";
+
+  fluidProperties.mc_flow_yMinus = 0
+    "Convective mass flow rate at port '-dy/2'";
+  fluidProperties.mc_flow_yPlus = 0
+    "Convective mass flow rate at port '+dy/2'";
+  fluidProperties.mc_flow_zMinus = 0
+    "Convective mass flow rate at port '-dz/2'";
+  fluidProperties.mc_flow_zPlus = 0
+    "Convective mass flow rate at port '+dz/2'";
+
+  fluidProperties.md_flow_xMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dx/2'";
+  fluidProperties.md_flow_xPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dx/2'";
+  fluidProperties.md_flow_yMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dy/2'";
+  fluidProperties.md_flow_yPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dy/2'";
+  fluidProperties.md_flow_zMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dz/2'";
+  fluidProperties.md_flow_zPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a gas volume, applying a lumped modeling approach. Depending 
+on the volume setup, this model may have up to seven heat ports (i.e., two for each 
+spatial direction of a cartesian coordinate system and one for an adsorbate volume).
+Furthermore, this model has convective fluid ports in y-direction, following the 
+'connectorSizing' principle, and a sorption fluid port. These ports allow for the 
+combination of several fluid volumes to create a spatially distributed model.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equations are the momentum, mass, and energy balance. According to
+the staggered grid approach, the momentum balance is not solved within the volume but 
+at the volume's boundaries via so-called 
+<a href=\"Modelica://SorpLib.Components.Fittings\">flow models</a>. Hennce, no pressure 
+losses occur within the volume:
+</p>
+<pre>
+    p = cfp_xMinus.p;
+</pre>
+<pre>
+    p = cfp_xPlus.p;
+</pre>
+<pre>
+    p = fp_sorption.p;
+</pre>
+
+<p>
+Regarding the mass and energy balances, either steady-state or tansient balnaces
+can be selected. When using the pressure <i>p</i> and temperature <i>T</i> as  
+independent states, the mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * &rho; * [&kappa; * (dp/d&tau;) - &beta; * (dT/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * &kappa; - T * &beta;) * (dp/d&tau;) + (c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+When using the pressure <i>p</i> and specific enthalpy <i>h</i> as independent 
+states, the mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * &rho; * [(&kappa; - &beta; * &mu;) * (dp/d&tau;) - &beta; / c<sub>p</sub> * (dh/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * (&kappa; - &beta; * &mu;) - 1) * (dp/d&tau;) + (1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+Herein, <i>(dm/d&tau;)</i> is the derivative of the mass w.r.t. time, <i>(dU/d&tau;)</i> 
+is the derivative of the internal energy w.r.t. time, <i>(d&rho;/d&tau;)</i> is the 
+derivative of the density w.r.t. time, <i>(du/d&tau;)</i> is the derivative of the specific 
+internal energy w.r.t.time, <i>(dp/d&tau;)</i> is the derivative of the pressure w.r.t. 
+time, <i>(dT/d&tau;)</i> is the derivative of the temperature w.r.t. time, <i>(dh/d&tau;)</i> 
+is the derivative of the specific enthalpy w.r.t. time,  <i>V</i> is the volume, <i>m</i> is 
+the mass, <i>v</i> is the specific volume, <i>&rho;</i> is the density, <i>&kappa;</i> is 
+the isothermal compressibility, <i>&beta;</i> is the isobaric expansion coefficient, <i>&mu;</i> 
+is the Joule-Thomson coefficient, <i>c<sub>p</sub></i> is the specific heat capacity at 
+constant pressure,<i>m<sub>c,flow</sub></i> is the sum of the convective mass flow rates, 
+<i>H<sub>b,flow</sub></i> is the sum of the enthalpy flow rates, and <i>Q<sub>b,flow</sub></i> 
+is the sum of the heat flow rates.
+</p>
+
+<h4>Main equations for an ideal gas</h4>
+<p>
+For an ideal gas, the isothermal compressibility <i>&kappa;</i> is <i>1/p</i> and the
+isbaric expansion coefficient <i>&beta;</i> is <i>1/T</i>, leading to a Joule-Thomson 
+coefficient <i>&mu;</i> of zero. Hence, the mass and energy balances can be simplified. 
+When using the pressure <i>p</i> and temperature <i>T</i> as independent states, the mass 
+balance still reads as
+</p>
+<pre>
+    (dm/d&tau;) = V * &rho; * [&kappa; * (dp/d&tau;) - &beta; * (dT/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+but the energy balance now reads as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;) = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+When using the pressure <i>p</i> and specific enthalpy <i>h</i> as independent 
+states, the mass balance now reads as
+</p>
+<pre>
+    (dm/d&tau;) = V * &rho; * [&kappa; * (dp/d&tau;) - &beta; / c<sub>p</sub> * (dh/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance now reads as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;) = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Ideal gas
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to model the adsorptive of open adsorption systems.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>idealGas</i>:
+  Defines if the medium is an ideal gas and, thus, the governing equations can
+  be simplified.
+  </li>
+  <li>
+  <i>calculateAdditionalProperties</i>:
+  Defines if additional properties like transport properties shall be calculated.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has two dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> and temperature <i>T</i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i> and specific enthalpy <i>h</i>.
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid property model is a single state model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 11, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/LiquidVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/LiquidVolume.mo
new file mode 100644
index 0000000..f50d23e
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/LiquidVolume.mo
@@ -0,0 +1,494 @@
+within SorpLib.Basics.Volumes.FluidVolumes;
+model LiquidVolume "Homogenous (ideal) liquid volume"
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialFluidVolume(
+    final no_components = Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    redeclare final connector FluidPortsIn =
+      SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in,
+    redeclare final connector FluidPortsOut =
+      SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    useHeatPorts=true,
+    useHeatPortsY=true,
+    h_initial=
+      Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=Medium.reference_X),
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean incompressibleLiquid = Medium.singleState
+    " = true, if medium is incompressible (i.e., partial derivative of specific
+    volume w.r.t. pressure at constant temperature is constant) and govering
+    equations are explicitly written for an incompressible fluid"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+equation
+  //
+  // Assertations
+  //
+  assert(no_components <= 1,
+    "The liquid volume model can only handel pure fluids (i.e., with one component)!",
+    level = AssertionLevel.error);
+
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  v = 1 / rho
+    "Specific volume";
+  rho = Medium.density(state=state)
+    "Density";
+
+  //
+  // Mass balance
+  //
+  dm_dtau = mc_flow
+    "Overall mass balance";
+
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if incompressibleLiquid then
+        dm_dtau = -geometry.V * rho * fluidProperties.beta * der(T)
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = geometry.V * rho * (
+          fluidProperties.kappa *der(p) - fluidProperties.beta * der(T))
+          "Transient overall mass balance";
+
+      end if;
+
+    else
+      if incompressibleLiquid then
+        dm_dtau = -geometry.V * rho * fluidProperties.beta * (
+          fluidProperties.my * der(p) +
+          1 / fluidProperties.cp * der(h))
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = geometry.V * rho * ((fluidProperties.kappa -
+          fluidProperties.beta * fluidProperties.my) * der(p) -
+          fluidProperties.beta / fluidProperties.cp * der(h))
+          "Transient overall mass balance";
+
+      end if;
+    end if;
+  end if;
+
+  mc_flow = sum(cfp_xMinus.m_flow) + sum(cfp_xPlus.m_flow)
+    "Sum of all convective mass flow rates across boundaries";
+
+  //
+  // Energy balance
+  //
+  dU_dtau = Hb_flow + Qb_flow
+    "Energy balane";
+
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if neglectTermVp then
+        dU_dtau = u * dm_dtau + m * (
+          v * (1 - T * fluidProperties.beta) * der(p) +
+          fluidProperties.cp * der(T))
+          "Transient energy balance";
+
+      else
+        if incompressibleLiquid then
+          dU_dtau = u * dm_dtau + m * (
+            -v * T * fluidProperties.beta * der(p) +
+            (fluidProperties.cp - p * v * fluidProperties.beta) * der(T))
+            "Transient energy balance";
+
+        else
+          dU_dtau = u * dm_dtau + m * (
+            v * (p * fluidProperties.kappa - T * fluidProperties.beta) * der(p) +
+            (fluidProperties.cp - p * v * fluidProperties.beta) * der(T))
+            "Transient energy balance";
+
+        end if;
+      end if;
+
+    else
+      if neglectTermVp then
+        dU_dtau = u * dm_dtau + m * der(h)
+          "Transient energy balance";
+
+      else
+        if incompressibleLiquid then
+          dU_dtau = u * dm_dtau + m * (
+            (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h) -
+            v * (p * fluidProperties.beta * fluidProperties.my + 1) * der(p))
+            "Transient energy balance";
+
+        else
+          dU_dtau = u * dm_dtau + m * (
+            (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h) +
+            v * (p * (fluidProperties.kappa - fluidProperties.beta *
+            fluidProperties.my) - 1) * der(p))
+            "Transient energy balance";
+
+        end if;
+      end if;
+    end if;
+  end if;
+
+  if avoid_events then
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* noEvent(actualStream(cfp_xMinus.h_outflow))) +
+      sum(cfp_xPlus.m_flow .* noEvent(actualStream(cfp_xPlus.h_outflow)))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  else
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* actualStream(cfp_xMinus.h_outflow)) +
+      sum(cfp_xPlus.m_flow .* actualStream(cfp_xPlus.h_outflow))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  end if;
+
+  Qb_flow = Q_flow_xMinus + Q_flow_xPlus +
+    Q_flow_yMinus + Q_flow_yPlus +
+    Q_flow_zMinus + Q_flow_zPlus
+    "Sum of all heat flow rates across boundaries";
+
+  //
+  // Summary record
+  //
+  fluidProperties.cp = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  fluidProperties.lambda = if calculateAdditionalProperties then
+    Medium.thermalConductivity(state=state) else 0
+    "Thermal conductivity";
+  fluidProperties.eta = if calculateAdditionalProperties then
+    Medium.dynamicViscosity(state=state) else 0
+    "Dynamic viscosity";
+
+  fluidProperties.beta = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  fluidProperties.kappa = if (not incompressibleLiquid and
+    (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp))) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  fluidProperties.my = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)))) then
+    v / fluidProperties.cp * (fluidProperties.beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  fluidProperties.Pr = if calculateAdditionalProperties then
+    fluidProperties.eta * fluidProperties.cp / fluidProperties.lambda else 0
+    "Prandtl number";
+
+  fluidProperties.m_flow_sorption = 0
+    "Total mass flow rate at port 'sorption'";
+
+  fluidProperties.mc_flow_yMinus = 0
+    "Total convective mass flow rate at port '-dy/2'";
+  fluidProperties.mc_flow_yPlus = 0
+    "Total convective mass flow rate at port '+dy/2'";
+  fluidProperties.mc_flow_zMinus = 0
+    "Total convective mass flow rate at port '-dz/2'";
+  fluidProperties.mc_flow_zPlus = 0
+    "Total convective mass flow rate at port '+dz/2'";
+
+  fluidProperties.md_flow_xMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dx/2'";
+  fluidProperties.md_flow_xPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dx/2'";
+  fluidProperties.md_flow_yMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dy/2'";
+  fluidProperties.md_flow_yPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dy/2'";
+  fluidProperties.md_flow_zMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dz/2'";
+  fluidProperties.md_flow_zPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a liquid volume, applying a lumped modeling approach. Depending 
+on the volume setup, this model may have up to six heat ports (i.e., two for each 
+spatial direction of a cartesian coordinate system). Furthermore, this model has
+convective fluid ports in y-direction, following the 'connectorSizing' principle. 
+These ports allow for the combination of several fluid volumes to create a spatially 
+distributed model.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equations are the momentum, mass, and energy balance. According to
+the staggered grid approach, the momentum balance is not solved within the volume but 
+at the volume's boundaries via so-called 
+<a href=\"Modelica://SorpLib.Components.Fittings\">flow models</a>. Hennce, no pressure 
+losses occur within the volume:
+</p>
+<pre>
+    p = cfp_xMinus.p;
+</pre>
+<pre>
+    p = cfp_xPlus.p;
+</pre>
+
+<p>
+Regarding the mass and energy balances, either steady-state or tansient balnaces
+can be selected. When using the pressure <i>p</i> and temperature <i>T</i> as  
+independent states, the mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * &rho; * [&kappa; * (dp/d&tau;) - &beta; * (dT/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * &kappa; - T * &beta;) * (dp/d&tau;) + (c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+When using the pressure <i>p</i> and specific enthalpy <i>h</i> as independent 
+states, the mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * &rho; * [(&kappa; - &beta; * &mu;) * (dp/d&tau;) - &beta; / c<sub>p</sub> * (dh/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * (&kappa; - &beta; * &mu;) - 1) * (dp/d&tau;) + (1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+Herein, <i>(dm/d&tau;)</i> is the derivative of the mass w.r.t. time, <i>(dU/d&tau;)</i> 
+is the derivative of the internal energy w.r.t. time, <i>(d&rho;/d&tau;)</i> is the 
+derivative of the density w.r.t. time, <i>(du/d&tau;)</i> is the derivative of the specific 
+internal energy w.r.t.time, <i>(dp/d&tau;)</i> is the derivative of the pressure w.r.t. 
+time, <i>(dT/d&tau;)</i> is the derivative of the temperature w.r.t. time, <i>(dh/d&tau;)</i> 
+is the derivative of the specific enthalpy w.r.t. time,  <i>V</i> is the volume, <i>m</i> is 
+the mass, <i>v</i> is the specific volume, <i>&rho;</i> is the density, <i>&kappa;</i> is 
+the isothermal compressibility, <i>&beta;</i> is the isobaric expansion coefficient, <i>&mu;</i> 
+is the Joule-Thomson coefficient, <i>c<sub>p</sub></i> is the specific heat capacity at 
+constant pressure,<i>m<sub>c,flow</sub></i> is the sum of the convective mass flow rates, 
+<i>H<sub>b,flow</sub></i> is the sum of the enthalpy flow rates, and <i>Q<sub>b,flow</sub></i> 
+is the sum of the heat flow rates.
+</p>
+
+<h4>Main equations for an ideal liquid</h4>
+<p>
+The liquid is incompressible when using the fluid property model of an ideal liquid.
+In this case, the isothermal compressibility <i>&kappa;</i> is zero (see option 
+'incompressibleLiquid'), and the mass and energy balances can be simplified. When using 
+the pressure <i>p</i> and temperature <i>T</i> as independent states, the mass balance 
+reads now as
+</p>
+<pre>
+    (dm/d&tau;) = -V * &rho; * &beta; * (dT/d&tau;) = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance reads now as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * [-v * T * &beta; * (dp/d&tau;) + (c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+When using the pressure <i>p</i> and specific enthalpy <i>h</i> as independent states, 
+the mass balance reads now as
+</p>
+<pre>
+    (dm/d&tau;) = -V * &rho; * &beta; * [&mu; * (dp/d&tau;) + 1/c<sub>p</sub> * (dh/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance reads now as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * [-v * (p * &beta; * &mu; + 1) * (dp/d&tau;) + (1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to model the heat transfer fluid of a a pipe or heat
+exchanger. In this context, the liquid is often modelled as an ideal liquid.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>incompressibleLiquid</i>:
+  Defines if the medium is incompressible and the partial derivative of specific 
+  volume w.r.t. pressure at constant temperature is constant, thus leading to
+  simplified governing equations.
+  </li>
+  <li>
+  <i>neglectTermVp</i>:
+  Defines if the term 'p*V' is neglected to calculate specific internal energy.
+  </li>
+  <li>
+  <i>calculateAdditionalProperties</i>:
+  Defines if additional properties like transport properties shall be calculated.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has two dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> and temperature <i>T</i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i> and specific enthalpy <i>h</i>.
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid property model is a single state model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 7, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LiquidVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasMixtureVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasMixtureVolume.mo
new file mode 100644
index 0000000..93a5edb
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasMixtureVolume.mo
@@ -0,0 +1,235 @@
+within SorpLib.Basics.Volumes.FluidVolumes.Tester;
+model Test_GasMixtureVolume "Tester for gas mixture volume"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture
+    "Medium model of the ideal gas mixture"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of liquid models
+  //
+  SorpLib.Basics.Volumes.FluidVolumes.GasMixtureVolume
+    gas_pTX_transientMassBalance_transientEnergyBalance(
+    no_adsorptivs=2,
+    ind_adsorptivs={3,4},
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    p_initial=25000,
+    T_initial=293.15,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_independentMassBalances=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Gas-mixture volume with p, T, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,-10},{-40,10}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.GasMixtureVolume
+    gas_phX_transientMassBalance_transientEnergyBalance(
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    no_adsorptivs=2,
+    ind_adsorptivs={3,4},
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    p_initial=25000,
+    h_initial=295427,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_independentMassBalances=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Gas-mixture volume with p, h, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{40,-10},{60,10}})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium) "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-72,-10},{-52,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    outlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=1e-3,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-28,-10},{-48,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance_ads1(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=-1e-6,
+    T_fixed=393.15,
+      redeclare package Medium = Media.IdealGases.CO2)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-76,-12},{-56,8}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance_ads2(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=-1e-5,
+    T_fixed=393.15,
+    redeclare package Medium = Media.IdealGases.H2O)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-80,-14},{-60,6}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{28,-10},{48,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    outlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=1e-3,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{72,-10},{52,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_phX_transientMassBalance_transientEnergyBalance_ads1(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=-1e-6,
+    T_fixed=393.15,
+      redeclare package Medium = Media.IdealGases.CO2)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{24,-12},{44,8}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_phX_transientMassBalance_transientEnergyBalance_ads2(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=-1e-5,
+    T_fixed=393.15,
+      redeclare package Medium = Media.IdealGases.H2O)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{20,-14},{40,6}})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-40,-12})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={60,-12})));
+
+equation
+  //
+  // Connections
+  //
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{-62,0},{-60,0},{-60,1.8},{-54.2,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,0},{-40,0},{-40,1.8},{-42.2,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,0},{40,0},{40,1.8},{45.8,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,0},{60,0},{60,1.8},{57.8,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance_ads1.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.fp_sorption[1])
+    annotation (Line(
+      points={{-66,-2},{-64,-2},{-64,-10},{-51.6,-10},{-51.6,-7.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance_ads2.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.fp_sorption[2])
+    annotation (Line(
+      points={{-70,-4},{-68,-4},{-68,-12},{-51.6,-12},{-51.6,-7.4}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance_ads1.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.fp_sorption[1])
+    annotation (Line(
+      points={{34,-2},{36,-2},{36,-10},{48.4,-10},{48.4,-7.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance_ads2.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.fp_sorption[2])
+    annotation (Line(
+      points={{30,-4},{32,-4},{32,-12},{48.4,-12},{48.4,-7.4}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(heatSource_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-40,-12},{-40,-8},{-50,-8},{-50,-6}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{60,-12},{60,-8},{50,-8},{50,-6}},
+      color={238,46,47},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=25), Documentation(info="<html>
+<p>
+This model checks the gas mixture volume model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 25 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 12, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasMixtureVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasVaporMixtureVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasVaporMixtureVolume.mo
new file mode 100644
index 0000000..0054251
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasVaporMixtureVolume.mo
@@ -0,0 +1,307 @@
+within SorpLib.Basics.Volumes.FluidVolumes.Tester;
+model Test_GasVaporMixtureVolume "Tester for gas-vapor-mixture volume"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture
+    "Medium model of the ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of liquid models
+  //
+  SorpLib.Basics.Volumes.FluidVolumes.GasVaporMixtureVolume
+    gas_pTX_transientMassBalance_transientEnergyBalance(
+    no_adsorptivs=2,
+    ind_adsorptivs={1,3},
+    idealGasVaporMixture=false,
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    p_initial=15000,
+    T_initial=293.15,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_independentMassBalances=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Gas-mixture volume with p, T, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,-10},{-40,10}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.GasVaporMixtureVolume
+    gas_phX_transientMassBalance_transientEnergyBalance(
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    no_adsorptivs=2,
+    ind_adsorptivs={1,3},
+    idealGasVaporMixture=false,
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    p_initial=15000,
+    h_initial=20223.1,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_independentMassBalances=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Gas-mixture volume with p, h, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{40,-10},{60,10}})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_m_N2_flow(
+    amplitude=1e-5,
+    f=1/5)
+    "Input signal for mass flow rate of N2"
+    annotation (Placement(transformation(extent={{-100,60},{-80,80}})));
+  Modelica.Blocks.Sources.Sine input_m_CO2_flow(
+    amplitude=1e-8,
+    f=1/5)
+    "Input signal for mass flow rate of CO2"
+    annotation (Placement(transformation(extent={{-100,20},{-80,40}})));
+  Modelica.Blocks.Sources.Ramp input_m_flow(
+    height=-1e-4,
+    duration=15,
+    offset=-1e-3,
+    startTime=10)
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{100,10},{80,30}})));
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=40,
+    f=1/5,
+    offset=273.15 + 50)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,50},{80,70}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    use_mFlowInput=true,
+      m_flow_fixed=-0.001,
+    use_TInput=true,
+    T_fixed=323.15,
+    X_fixed={0.6,0.1,0.1,0.2},
+      redeclare package Medium = Medium) "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-72,-10},{-52,10}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource
+    outlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=1e-3,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-28,-10},{-48,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance_ads1(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    m_flow_fixed=-1e-6,
+    T_fixed=393.15,
+      redeclare package Medium = Media.IdealGases.N2)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-82,-12},{-62,8}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance_ads2(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    m_flow_fixed=-1e-5,
+    T_fixed=393.15,
+    redeclare package Medium = Media.IdealGases.CO2)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-86,-14},{-66,6}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource
+    inlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    boundaryTypeStreamMassFractions=SorpLib.Choices.BoundaryFluidStreamMassFractions.MassFractions,
+    use_mFlowInput=true,
+      m_flow_fixed=-0.001,
+    use_TInput=true,
+    T_fixed=323.15,
+    X_fixed={0.6,0.1,0.1,0.2},
+      redeclare package Medium = Medium)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{28,-10},{48,10}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource
+    outlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=1e-3,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{72,-10},{52,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_phX_transientMassBalance_transientEnergyBalance_ads1(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    m_flow_fixed=-1e-6,
+    T_fixed=393.15,
+      redeclare package Medium = Media.IdealGases.N2)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{18,-12},{38,8}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_phX_transientMassBalance_transientEnergyBalance_ads2(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    m_flow_fixed=-1e-5,
+    T_fixed=393.15,
+      redeclare package Medium = Media.IdealGases.CO2)
+    "Inlet for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{14,-14},{34,6}})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  Modelica.Blocks.Sources.Sine input_Q_flow(amplitude=25, f=1/5)
+    "Input signal for heat flow rate"
+    annotation (Placement(transformation(extent={{-100,-40},{-80,-20}})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=true,
+      Q_flow_fixed=-25)
+    "Heat source for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-40,-12})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=true,
+      Q_flow_fixed=-25)
+    "Heat source for Gas-mixture volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={60,-12})));
+
+equation
+  //
+  // Connections
+  //
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{-62,0},{-60,0},{-60,1.8},{-54.2,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,0},{-40,0},{-40,1.8},{-42.2,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,0},{40,0},{40,1.8},{45.8,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,0},{60,0},{60,1.8},{57.8,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance_ads1.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.fp_sorption[1])
+    annotation (Line(
+      points={{-72,-2},{-70,-2},{-70,-10},{-51.6,-10},{-51.6,-7.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance_ads2.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.fp_sorption[2])
+    annotation (Line(
+      points={{-76,-4},{-74,-4},{-74,-12},{-51.6,-12},{-51.6,-7.4}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance_ads1.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.fp_sorption[1])
+    annotation (Line(
+      points={{28,-2},{30,-2},{30,-10},{48.4,-10},{48.4,-7.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance_ads2.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.fp_sorption[2])
+    annotation (Line(
+      points={{24,-4},{26,-4},{26,-12},{48.4,-12},{48.4,-7.4}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(heatSource_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-40,-12},{-40,-8},{-50,-8},{-50,-6}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{60,-12},{60,-8},{50,-8},{50,-6}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_Q_flow.y,
+    heatSource_pTX_transientMassBalance_transientEnergyBalance.Q_flow_input)
+    annotation (Line(points={{-79,-30},{-35,-30},{-35,-13}}, color={0,0,127}));
+  connect(input_Q_flow.y,
+    heatSource_phX_transientMassBalance_transientEnergyBalance.Q_flow_input)
+    annotation (Line(points={{-79,-30},{65,-30},{65,-13}}, color={0,0,127}));
+  connect(input_m_N2_flow.y,
+    inlet_pTX_transientMassBalance_transientEnergyBalance_ads1.m_flow_input)
+    annotation (Line(points={{-79,70},{-73.2,70},{-73.2,0}}, color={0,0,127}));
+  connect(input_m_N2_flow.y,
+    inlet_phX_transientMassBalance_transientEnergyBalance_ads1.m_flow_input)
+    annotation (Line(points={{-79,70},{26.8,70},{26.8,0}}, color={0,0,127}));
+  connect(input_m_CO2_flow.y,
+    inlet_pTX_transientMassBalance_transientEnergyBalance_ads2.m_flow_input)
+    annotation (Line(points={{-79,30},{-77.2,30},{-77.2,-2}}, color={0,0,127}));
+  connect(input_m_CO2_flow.y,
+    inlet_phX_transientMassBalance_transientEnergyBalance_ads2.m_flow_input)
+    annotation (Line(points={{-79,30},{22.8,30},{22.8,-2}}, color={0,0,127}));
+  connect(input_m_flow.y, inlet_phX_transientMassBalance_transientEnergyBalance.m_flow_input)
+    annotation (Line(points={{79,20},{36.8,20},{36.8,2}}, color={0,0,127}));
+  connect(input_m_flow.y, inlet_pTX_transientMassBalance_transientEnergyBalance.m_flow_input)
+    annotation (Line(points={{79,20},{-63.2,20},{-63.2,2}}, color={0,0,127}));
+  connect(input_T.y, inlet_phX_transientMassBalance_transientEnergyBalance.T_input)
+    annotation (Line(points={{79,60},{34,60},{34,-2},{36.8,-2}}, color={0,0,127}));
+  connect(input_T.y, inlet_pTX_transientMassBalance_transientEnergyBalance.T_input)
+    annotation (Line(points={{79,60},{-66,60},{-66,-2},{-63.2,-2}}, color={0,0,127}));
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=25,
+      Tolerance=1e-06),     Documentation(info="<html>
+<p>
+This model checks the gas-vapor-mixture volume model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 25 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 13, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasVaporMixtureVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasVolume.mo
new file mode 100644
index 0000000..01d9bf4
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_GasVolume.mo
@@ -0,0 +1,429 @@
+within SorpLib.Basics.Volumes.FluidVolumes.Tester;
+model Test_GasVolume "Tester for gas volume"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = SorpLib.Media.IdealGases.N2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium model of the ideal gas"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of gas models
+  //
+  SorpLib.Basics.Volumes.FluidVolumes.GasVolume
+    gas_pTX_transientMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    p_initial=1000,
+    T_initial=293.15,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Gas volume with p, T, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,40},{-40,60}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.GasVolume
+    gas_pTX_steadyStateMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Gas volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,-10},{-40,10}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.GasVolume
+    gas_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Gas volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, and steady-state mass balance with free 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,-60},{-40,-40}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.GasVolume
+    gas_phX_transientMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    p_initial=1000,
+    h_initial=304300.38,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Gas volume with p, h, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{40,40},{60,60}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.GasVolume
+    gas_phX_steadyStateMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    h_initial=304300.38,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Gas volume with p, h, and X as independent states, steady-state mass 
+    balance with free initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{40,-10},{60,10}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.GasVolume
+    gas_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    h_initial=360495.72,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Gas volume with p, h, and X as independent states, steady-state mass 
+    balance with free initial values, and steady-state mass balance with free 
+    initial values"
+    annotation (Placement(transformation(extent={{40,-60},{60,-40}})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium) "Inlet for gas volume"
+    annotation (Placement(transformation(extent={{-72,40},{-52,60}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    outlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=1e-3,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for gas volume"
+    annotation (Placement(transformation(extent={{-28,40},{-48,60}})));
+  Sources.Fluids.GasSource sorption_pTX_transientMassBalance_transientEnergyBalance(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=-0.00001,
+    T_fixed=423.15,
+    redeclare package Medium = Medium) "Sorption inlet for gas volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={-60,38})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for gas volume"
+    annotation (Placement(transformation(extent={{-72,-10},{-52,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    outlet_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=10000,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for gas volume"
+    annotation (Placement(transformation(extent={{-28,-10},{-48,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for gas volume"
+    annotation (Placement(transformation(extent={{-72,-60},{-52,-40}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    outlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=10000,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for gas volume"
+    annotation (Placement(transformation(extent={{-28,-60},{-48,-40}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for gas volume"
+    annotation (Placement(transformation(extent={{28,40},{48,60}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    outlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for gas volume"
+    annotation (Placement(transformation(extent={{72,40},{52,60}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    sorption_phX_transientMassBalance_transientEnergyBalance(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=-0.00001,
+    T_fixed=423.15,
+    redeclare package Medium = Medium)
+    "Sorption inlet for gas volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={40,38})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for gas volume"
+    annotation (Placement(transformation(extent={{28,-10},{48,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    outlet_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=10000,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for gas volume"
+    annotation (Placement(transformation(extent={{72,-10},{52,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource
+    inlet_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for gas volume"
+    annotation (Placement(transformation(extent={{28,-60},{48,-40}})));
+  SorpLib.Basics.Sources.Fluids.GasSource
+    outlet_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=10000,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for gas volume"
+    annotation (Placement(transformation(extent={{72,-60},{52,-40}})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for gas volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-40,38})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for gas volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-40,-12})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for gas volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-40,-62})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for gas volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={60,38})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for gas volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={60,-12})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for gas volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={60,-62})));
+
+equation
+  //
+  // Connections
+  //
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{-62,50},{-60,50},{-60,51.8},{-54.2,51.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,50},{-40,50},{-40,51.8},{-42.2,51.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(gas_pTX_steadyStateMassBalance_transientEnergyBalance.cfp_xMinus[1],
+    inlet_pTX_steadyStateMassBalance_transientEnergyBalance.port) annotation (
+      Line(
+      points={{-54.2,1.8},{-60,1.8},{-60,0},{-62,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_pTX_steadyStateMassBalance_transientEnergyBalance.port,
+    gas_pTX_steadyStateMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,0},{-40,0},{-40,1.8},{-42.2,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(gas_pTX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xMinus[1],
+    inlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port) annotation (
+     Line(
+      points={{-54.2,-48.2},{-60,-48.2},{-60,-50},{-62,-50}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    gas_pTX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,-50},{-40,-50},{-40,-48.2},{-42.2,-48.2}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,50},{40,50},{40,51.8},{45.8,51.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,50},{60,50},{60,51.8},{57.8,51.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    gas_phX_steadyStateMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,0},{40,0},{40,1.8},{45.8,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    gas_phX_steadyStateMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,0},{60,0},{60,1.8},{57.8,1.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(inlet_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    gas_phX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,-50},{40,-50},{40,-48.2},{45.8,-48.2}},
+      color={244,125,35},
+      thickness=1));
+  connect(outlet_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    gas_phX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,-50},{60,-50},{60,-48.2},{57.8,-48.2}},
+      color={244,125,35},
+      thickness=1));
+  connect(sorption_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.fp_sorption)
+    annotation (Line(
+      points={{-60,38},{-60,42.4},{-51.6,42.4}},
+      color={244,125,35},
+      thickness=1));
+  connect(sorption_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.fp_sorption)
+    annotation (Line(
+      points={{40,38},{40,42.4},{48.4,42.4}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(heatSource_pTX_transientMassBalance_transientEnergyBalance.port,
+    gas_pTX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-40,38},{-40,42},{-50,42},{-50,44}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_steadyStateMassBalance_transientEnergyBalance.port,
+    gas_pTX_steadyStateMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-40,-12},{-40,-8},{-50,-8},{-50,-6}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    gas_pTX_steadyStateMassBalance_steadyStateEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-40,-62},{-40,-58},{-50,-58},{-50,-56}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    gas_phX_steadyStateMassBalance_steadyStateEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{60,-62},{60,-58},{50,-58},{50,-56}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    gas_phX_steadyStateMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{60,-12},{60,-8},{50,-8},{50,-6}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_transientMassBalance_transientEnergyBalance.port,
+    gas_phX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{60,38},{60,42},{50,42},{50,44}},
+      color={238,46,47},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=25), Documentation(info="<html>
+<p>
+This model checks the gas volume model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 25 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 11, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_LiquidVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_LiquidVolume.mo
new file mode 100644
index 0000000..bba85fa
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_LiquidVolume.mo
@@ -0,0 +1,769 @@
+within SorpLib.Basics.Volumes.FluidVolumes.Tester;
+model Test_LiquidVolume "Tester for liquid volume"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of liquid models
+  //
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_pTX_transientMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,70},{-40,90}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_pTX_steadyStateMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,40},{-40,60}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, and steady-state mass balance with free 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,10},{-40,30}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_pTX_transientMassBalance_transientEnergyBalance_woVp(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    neglectTermVp=true,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, transient mass 
+    balance with fixed initial values, transient mass balance with fixed 
+    initial values, and assumption that u = h"
+    annotation (Placement(transformation(extent={{-62,-30},{-42,-10}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_pTX_steadyStateMassBalance_transientEnergyBalance_woVp(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    neglectTermVp=true,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, transient mass balance with fixed 
+    initial values, and assumption that u = h"
+    annotation (Placement(transformation(extent={{-62,-60},{-42,-40}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    neglectTermVp=true,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, steady-state mass balance with free 
+    initial values, and assumption that u = h"
+    annotation (Placement(transformation(extent={{-62,-90},{-42,-70}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_phX_transientMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=84011.8,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, h, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{40,70},{60,90}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_phX_steadyStateMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=84011.8,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, h, and X as independent states, steady-state mass 
+    balance with free initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{40,40},{60,60}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=84011.8,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, h, and X as independent states, steady-state mass 
+    balance with free initial values, and steady-state mass balance with free 
+    initial values"
+    annotation (Placement(transformation(extent={{40,10},{60,30}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_phX_transientMassBalance_transientEnergyBalance_woVp(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=84011.8,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    neglectTermVp=true,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, transient mass 
+    balance with fixed initial values, transient mass balance with fixed 
+    initial values, and assumption that u = h"
+    annotation (Placement(transformation(extent={{40,-30},{60,-10}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_phX_steadyStateMassBalance_transientEnergyBalance_woVp(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=84011.8,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    neglectTermVp=true,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, transient mass balance with fixed 
+    initial values, and assumption that u = h"
+    annotation (Placement(transformation(extent={{40,-60},{60,-40}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume
+    liquid_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=84011.8,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    neglectTermVp=true,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "Liquid volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, steady-state mass balance with free 
+    initial values, and assumption that u = h"
+    annotation (Placement(transformation(extent={{40,-90},{60,-70}})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{-72,70},{-52,90}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{-28,70},{-48,90}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{-72,40},{-52,60}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      p_fixed=1e5,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{-28,40},{-48,60}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{-72,10},{-52,30}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      p_fixed=1e5,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{-28,10},{-48,30}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_pTX_transientMassBalance_transientEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{-74,-30},{-54,-10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_pTX_transientMassBalance_transientEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{-30,-30},{-50,-10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_pTX_steadyStateMassBalance_transientEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{-74,-60},{-54,-40}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_pTX_steadyStateMassBalance_transientEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      p_fixed=100000,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{-30,-60},{-50,-40}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{-74,-90},{-54,-70}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      p_fixed=100000,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{-30,-90},{-50,-70}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{28,70},{48,90}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{72,70},{52,90}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{28,40},{48,60}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      p_fixed=1e5,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{72,40},{52,60}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{28,10},{48,30}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      p_fixed=1e5,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{72,10},{52,30}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_phX_transientMassBalance_transientEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{28,-30},{48,-10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_phX_transientMassBalance_transientEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{72,-30},{52,-10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_phX_steadyStateMassBalance_transientEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{28,-60},{48,-40}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_phX_steadyStateMassBalance_transientEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      p_fixed=100000,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{72,-60},{52,-40}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    inlet_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for liquid volume"
+    annotation (Placement(transformation(extent={{28,-90},{48,-70}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource
+    outlet_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      p_fixed=100000,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for liquid volume"
+    annotation (Placement(transformation(extent={{72,-90},{52,-70}})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-50,68})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-50,38})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-50,8})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_transientMassBalance_transientEnergyBalance_woVp(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume" annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={-52,-32})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_steadyStateMassBalance_transientEnergyBalance_woVp(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume" annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={-52,-62})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume" annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={-52,-92})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={50,68})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={50,38})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={50,8})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_transientMassBalance_transientEnergyBalance_woVp(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={50,-32})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_steadyStateMassBalance_transientEnergyBalance_woVp(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={50,-62})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for liquid volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={50,-92})));
+
+equation
+  //
+  // Connections
+  //
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    liquid_pTX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{-62,80},{-60,80},{-60,81.8},{-54.2,81.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    liquid_pTX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,80},{-40,80},{-40,81.8},{-42.2,81.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(liquid_pTX_steadyStateMassBalance_transientEnergyBalance.cfp_xMinus[1],
+    inlet_pTX_steadyStateMassBalance_transientEnergyBalance.port) annotation (
+      Line(
+      points={{-54.2,51.8},{-60,51.8},{-60,50},{-62,50}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_pTX_steadyStateMassBalance_transientEnergyBalance.port,
+    liquid_pTX_steadyStateMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,50},{-40,50},{-40,51.8},{-42.2,51.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(liquid_pTX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xMinus[1],
+    inlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port) annotation (
+     Line(
+      points={{-54.2,21.8},{-60,21.8},{-60,20},{-62,20}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    liquid_pTX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,20},{-40,20},{-40,21.8},{-42.2,21.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance_woVp.port,
+    liquid_pTX_transientMassBalance_transientEnergyBalance_woVp.cfp_xMinus[1])
+    annotation (Line(
+      points={{-64,-20},{-62,-20},{-62,-18.2},{-56.2,-18.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_pTX_transientMassBalance_transientEnergyBalance_woVp.port,
+    liquid_pTX_transientMassBalance_transientEnergyBalance_woVp.cfp_xPlus[1])
+    annotation (Line(
+      points={{-40,-20},{-42,-20},{-42,-18.2},{-44.2,-18.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(liquid_pTX_steadyStateMassBalance_transientEnergyBalance_woVp.cfp_xMinus[1],
+    inlet_pTX_steadyStateMassBalance_transientEnergyBalance_woVp.port)
+    annotation (Line(
+      points={{-56.2,-48.2},{-62,-48.2},{-62,-50},{-64,-50}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_pTX_steadyStateMassBalance_transientEnergyBalance_woVp.port,
+    liquid_pTX_steadyStateMassBalance_transientEnergyBalance_woVp.cfp_xPlus[1])
+    annotation (Line(
+      points={{-40,-50},{-42,-50},{-42,-48.2},{-44.2,-48.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(liquid_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.cfp_xMinus[1],
+    inlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.port)
+    annotation (Line(
+      points={{-56.2,-78.2},{-62,-78.2},{-62,-80},{-64,-80}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.port,
+    liquid_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.cfp_xPlus[1])
+    annotation (Line(
+      points={{-40,-80},{-42,-80},{-42,-78.2},{-44.2,-78.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance.port,
+    liquid_phX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,80},{40,80},{40,81.8},{45.8,81.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_phX_transientMassBalance_transientEnergyBalance.port,
+    liquid_phX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,80},{60,80},{60,81.8},{57.8,81.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(inlet_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    liquid_phX_steadyStateMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,50},{40,50},{40,51.8},{45.8,51.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    liquid_phX_steadyStateMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,50},{60,50},{60,51.8},{57.8,51.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(inlet_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    liquid_phX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,20},{40,20},{40,21.8},{45.8,21.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    liquid_phX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,20},{60,20},{60,21.8},{57.8,21.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance_woVp.port,
+    liquid_phX_transientMassBalance_transientEnergyBalance_woVp.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,-20},{40,-20},{40,-18.2},{45.8,-18.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_phX_transientMassBalance_transientEnergyBalance_woVp.port,
+    liquid_phX_transientMassBalance_transientEnergyBalance_woVp.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,-20},{60,-20},{60,-18.2},{57.8,-18.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(inlet_phX_steadyStateMassBalance_transientEnergyBalance_woVp.port,
+    liquid_phX_steadyStateMassBalance_transientEnergyBalance_woVp.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,-50},{40,-50},{40,-48.2},{45.8,-48.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_phX_steadyStateMassBalance_transientEnergyBalance_woVp.port,
+    liquid_phX_steadyStateMassBalance_transientEnergyBalance_woVp.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,-50},{60,-50},{60,-48.2},{57.8,-48.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(inlet_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.port,
+    liquid_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,-80},{40,-80},{40,-78.2},{45.8,-78.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.port,
+    liquid_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,-80},{60,-80},{60,-78.2},{57.8,-78.2}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(heatSource_pTX_transientMassBalance_transientEnergyBalance.port,
+    liquid_pTX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-50,68},{-50,74}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_steadyStateMassBalance_transientEnergyBalance.port,
+    liquid_pTX_steadyStateMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-50,38},{-50,38},{-50,44}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    liquid_pTX_steadyStateMassBalance_steadyStateEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-50,8},{-50,14}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_transientMassBalance_transientEnergyBalance_woVp.port,
+    liquid_pTX_transientMassBalance_transientEnergyBalance_woVp.hp_yMinus)
+    annotation (Line(
+      points={{-52,-32},{-52,-26}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_steadyStateMassBalance_transientEnergyBalance_woVp.port,
+    liquid_pTX_steadyStateMassBalance_transientEnergyBalance_woVp.hp_yMinus)
+    annotation (Line(
+      points={{-52,-62},{-52,-56}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.port,
+    liquid_pTX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.hp_yMinus)
+    annotation (Line(
+      points={{-52,-92},{-52,-86}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    liquid_phX_steadyStateMassBalance_steadyStateEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{50,8},{50,14}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    liquid_phX_steadyStateMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{50,38},{50,44}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_transientMassBalance_transientEnergyBalance.port,
+    liquid_phX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{50,68},{50,74},{50,74}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_transientMassBalance_transientEnergyBalance_woVp.port,
+    liquid_phX_transientMassBalance_transientEnergyBalance_woVp.hp_yMinus)
+    annotation (Line(
+      points={{50,-32},{50,-26},{50,-26}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_steadyStateMassBalance_transientEnergyBalance_woVp.port,
+    liquid_phX_steadyStateMassBalance_transientEnergyBalance_woVp.hp_yMinus)
+    annotation (Line(
+      points={{50,-62},{50,-56}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.port,
+    liquid_phX_steadyStateMassBalance_steadyStateEnergyBalance_woVp.hp_yMinus)
+    annotation (Line(
+      points={{50,-92},{50,-86}},
+      color={238,46,47},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=25), Documentation(info="<html>
+<p>
+This model checks the liquid volume model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 25 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 7, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_VLEVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_VLEVolume.mo
new file mode 100644
index 0000000..68e04fa
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/Tester/Test_VLEVolume.mo
@@ -0,0 +1,431 @@
+within SorpLib.Basics.Volumes.FluidVolumes.Tester;
+model Test_VLEVolume "Tester for VLE volume"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the VLE liquid"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of VLE models
+  //
+  SorpLib.Basics.Volumes.FluidVolumes.VLEVolume
+    vle_pTX_transientMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    p_initial=1000,
+    T_initial=293.15,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "VLE volume with p, T, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,40},{-40,60}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.VLEVolume
+    vle_pTX_steadyStateMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "VLE volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,-10},{-40,10}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.VLEVolume
+    vle_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    T_initial=293.15,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "VLE volume with p, T, and X as independent states, steady-state mass 
+    balance with free initial values, and steady-state mass balance with free 
+    initial values"
+    annotation (Placement(transformation(extent={{-60,-60},{-40,-40}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.VLEVolume
+    vle_phX_transientMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    p_initial=1000,
+    h_initial=2538185.5,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium) "VLE volume with p, h, and X as independent states, transient mass 
+    balance with fixed initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{40,40},{60,60}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.VLEVolume
+    vle_phX_steadyStateMassBalance_transientEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    h_initial=83927.11,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "VLE volume with p, h, and X as independent states, steady-state mass 
+    balance with free initial values, and transient mass balance with fixed 
+    initial values"
+    annotation (Placement(transformation(extent={{40,-10},{60,10}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.VLEVolume
+    vle_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=2616993.5,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium) "VLE volume with p, h, and X as independent states, steady-state mass 
+    balance with free initial values, and steady-state mass balance with free 
+    initial values"
+    annotation (Placement(transformation(extent={{40,-60},{60,-40}})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  SorpLib.Basics.Sources.Fluids.VLESource
+    inlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium) "Inlet for VLE volume"
+    annotation (Placement(transformation(extent={{-72,40},{-52,60}})));
+  SorpLib.Basics.Sources.Fluids.VLESource
+    outlet_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=1e-3,
+    T_fixed=323.15,
+      redeclare package Medium = Medium) "Outlet for VLE volume"
+    annotation (Placement(transformation(extent={{-28,40},{-48,60}})));
+  Sources.Fluids.VLESource sorption_pTX_transientMassBalance_transientEnergyBalance(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=-0.000001,
+    T_fixed=423.15,
+    redeclare package Medium = Medium) "Sorption inlet for VLE volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={-60,38})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource
+    inlet_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for VLE volume"
+    annotation (Placement(transformation(extent={{-72,-10},{-52,10}})));
+  SorpLib.Basics.Sources.Fluids.VLESource
+    outlet_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=10000,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for VLE volume"
+    annotation (Placement(transformation(extent={{-28,-10},{-48,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource
+    inlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for VLE volume"
+    annotation (Placement(transformation(extent={{-72,-60},{-52,-40}})));
+  SorpLib.Basics.Sources.Fluids.VLESource
+    outlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=10000,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for VLE volume"
+    annotation (Placement(transformation(extent={{-28,-60},{-48,-40}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource
+    inlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for VLE volume"
+    annotation (Placement(transformation(extent={{28,40},{48,60}})));
+  SorpLib.Basics.Sources.Fluids.VLESource
+    outlet_phX_transientMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for VLE volume"
+    annotation (Placement(transformation(extent={{72,40},{52,60}})));
+  SorpLib.Basics.Sources.Fluids.VLESource
+    sorption_phX_transientMassBalance_transientEnergyBalance(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    m_flow_fixed=-0.000001,
+    T_fixed=423.15,
+    redeclare package Medium = Medium)
+    "Sorption inlet for VLE volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={40,38})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource
+    inlet_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for VLE volume"
+    annotation (Placement(transformation(extent={{28,-10},{48,10}})));
+  SorpLib.Basics.Sources.Fluids.VLESource
+    outlet_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=10000,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for VLE volume"
+    annotation (Placement(transformation(extent={{72,-10},{52,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource
+    inlet_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+      m_flow_fixed=-0.001,
+      T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Inlet for VLE volume"
+    annotation (Placement(transformation(extent={{28,-60},{48,-40}})));
+  SorpLib.Basics.Sources.Fluids.VLESource
+    outlet_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+      boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=10000,
+    T_fixed=323.15,
+      redeclare package Medium = Medium)
+    "Outlet for VLE volume"
+    annotation (Placement(transformation(extent={{72,-60},{52,-40}})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25) "Heat source for VLE volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-40,38})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for VLE volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-40,-12})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_pTX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for VLE volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={-40,-62})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_transientMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for VLE volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={60,38})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_steadyStateMassBalance_transientEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for VLE volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={60,-12})));
+  SorpLib.Basics.Sources.Thermal.HeatSource
+    heatSource_phX_steadyStateMassBalance_steadyStateEnergyBalance(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+      Q_flow_fixed=-25)
+    "Heat source for VLE volume"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}}, rotation=90,
+                origin={60,-62})));
+
+equation
+  //
+  // Connections
+  //
+  connect(inlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    vle_pTX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{-62,50},{-60,50},{-60,51.8},{-54.2,51.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(outlet_pTX_transientMassBalance_transientEnergyBalance.port,
+    vle_pTX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,50},{-40,50},{-40,51.8},{-42.2,51.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(vle_pTX_steadyStateMassBalance_transientEnergyBalance.cfp_xMinus[1],
+    inlet_pTX_steadyStateMassBalance_transientEnergyBalance.port) annotation (
+      Line(
+      points={{-54.2,1.8},{-60,1.8},{-60,0},{-62,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(outlet_pTX_steadyStateMassBalance_transientEnergyBalance.port,
+    vle_pTX_steadyStateMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,0},{-40,0},{-40,1.8},{-42.2,1.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(vle_pTX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xMinus[1],
+    inlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port) annotation (
+     Line(
+      points={{-54.2,-48.2},{-60,-48.2},{-60,-50},{-62,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(outlet_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    vle_pTX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{-38,-50},{-40,-50},{-40,-48.2},{-42.2,-48.2}},
+      color={0,140,72},
+      thickness=1));
+  connect(inlet_phX_transientMassBalance_transientEnergyBalance.port,
+    vle_phX_transientMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,50},{40,50},{40,51.8},{45.8,51.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(outlet_phX_transientMassBalance_transientEnergyBalance.port,
+    vle_phX_transientMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,50},{60,50},{60,51.8},{57.8,51.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(inlet_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    vle_phX_steadyStateMassBalance_transientEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,0},{40,0},{40,1.8},{45.8,1.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(outlet_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    vle_phX_steadyStateMassBalance_transientEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,0},{60,0},{60,1.8},{57.8,1.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(inlet_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    vle_phX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xMinus[1])
+    annotation (Line(
+      points={{38,-50},{40,-50},{40,-48.2},{45.8,-48.2}},
+      color={0,140,72},
+      thickness=1));
+  connect(outlet_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    vle_phX_steadyStateMassBalance_steadyStateEnergyBalance.cfp_xPlus[1])
+    annotation (Line(
+      points={{62,-50},{60,-50},{60,-48.2},{57.8,-48.2}},
+      color={0,140,72},
+      thickness=1));
+  connect(sorption_pTX_transientMassBalance_transientEnergyBalance.port,
+    vle_pTX_transientMassBalance_transientEnergyBalance.fp_sorption)
+    annotation (Line(
+      points={{-60,38},{-60,42.4},{-51.6,42.4}},
+      color={0,140,72},
+      thickness=1));
+  connect(sorption_phX_transientMassBalance_transientEnergyBalance.port,
+    vle_phX_transientMassBalance_transientEnergyBalance.fp_sorption)
+    annotation (Line(
+      points={{40,38},{40,42.4},{48.4,42.4}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(heatSource_pTX_transientMassBalance_transientEnergyBalance.port,
+    vle_pTX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-40,38},{-40,42},{-50,42},{-50,44}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_steadyStateMassBalance_transientEnergyBalance.port,
+    vle_pTX_steadyStateMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-40,-12},{-40,-8},{-50,-8},{-50,-6}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_pTX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    vle_pTX_steadyStateMassBalance_steadyStateEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{-40,-62},{-40,-58},{-50,-58},{-50,-56}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_steadyStateMassBalance_steadyStateEnergyBalance.port,
+    vle_phX_steadyStateMassBalance_steadyStateEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{60,-62},{60,-58},{50,-58},{50,-56}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_steadyStateMassBalance_transientEnergyBalance.port,
+    vle_phX_steadyStateMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{60,-12},{60,-8},{50,-8},{50,-6}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_phX_transientMassBalance_transientEnergyBalance.port,
+    vle_phX_transientMassBalance_transientEnergyBalance.hp_yMinus)
+    annotation (Line(
+      points={{60,38},{60,42},{50,42},{50,44}},
+      color={238,46,47},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=25), Documentation(info="<html>
+<p>
+This model checks the VLE volume model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 25 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 8, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_VLEVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/Tester/package.mo b/SorpLib/Basics/Volumes/FluidVolumes/Tester/package.mo
new file mode 100644
index 0000000..3f3637c
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Volumes.FluidVolumes;
+package Tester "Models to test and varify models of fluid volumes"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented fluid volumes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/Tester/package.order b/SorpLib/Basics/Volumes/FluidVolumes/Tester/package.order
new file mode 100644
index 0000000..3722cda
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/Tester/package.order
@@ -0,0 +1,5 @@
+Test_LiquidVolume
+Test_GasVolume
+Test_GasMixtureVolume
+Test_GasVaporMixtureVolume
+Test_VLEVolume
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/VLEVolume.mo b/SorpLib/Basics/Volumes/FluidVolumes/VLEVolume.mo
new file mode 100644
index 0000000..c4e375b
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/VLEVolume.mo
@@ -0,0 +1,444 @@
+within SorpLib.Basics.Volumes.FluidVolumes;
+model VLEVolume
+  "Homogenous volume of a real fluid (i.e., with a two-phase regime)"
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialFluidVolume(
+    final no_components = Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final neglectTermVp = false,
+    redeclare final connector FluidPortsIn =
+      SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in,
+    redeclare final connector FluidPortsOut =
+      SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    useHeatPorts=true,
+    useHeatPortsY=true,
+    h_initial=
+      Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=Medium.reference_X),
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with a two-phase regime)"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.MassFlowRate ms_flow_initial = 1e-4
+    "Start value for sorption mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_sorption
+    "Sorption heat port"
+    annotation (Placement(transformation(extent={{10,-50},{22,-38}}),
+                iconTransformation(extent={{10,-50},{22,-38}})));
+
+  FluidPortsIn fp_sorption(
+    final no_components=no_components,
+    m_flow(start=ms_flow_initial))
+    "Sorption fluid port"
+    annotation (Placement(transformation(extent={{-20,-80},{-12,-72}}),
+                iconTransformation(extent={{-20,-80},{-12,-72}})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.MassFlowRate ms_flow
+    "Sum of all sorption mass flow rates across boundaries";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+equation
+  //
+  // Assertations
+  //
+  assert(no_components <= 1,
+    "The VLE volume model can only handel pure fluids (i.e., with one component)!",
+    level = AssertionLevel.error);
+
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  v = 1 / rho
+    "Specific volume";
+  rho = Medium.density(state=state)
+    "Density";
+
+  //
+  // Momentum balance
+  //
+  fp_sorption.p = p
+    "Total pressure at the port (i.e., homogenous volume)";
+
+  //
+  // Mass balance
+  //
+  dm_dtau = mc_flow + ms_flow
+    "Overall mass balance";
+
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dm_dtau = geometry.V * rho *
+        (fluidProperties.kappa *der(p) - fluidProperties.beta * der(T))
+        "Transient overall mass balance";
+
+    else
+      dm_dtau = geometry.V * rho * ((fluidProperties.kappa -
+        fluidProperties.beta * fluidProperties.my) * der(p) -
+        fluidProperties.beta / fluidProperties.cp * der(h))
+        "Transient overall mass balance";
+
+    end if;
+  end if;
+
+  mc_flow = sum(cfp_xMinus.m_flow) + sum(cfp_xPlus.m_flow)
+    "Sum of all convective mass flow rates across boundaries";
+  ms_flow = fp_sorption.m_flow
+    "Sum of all sorption mass flow rates across boundaries";
+
+  //
+  // Energy balance
+  //
+  dU_dtau = Hb_flow + Qb_flow
+    "Energy balane";
+
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dU_dtau = u * dm_dtau + m * (
+        v * (p * fluidProperties.kappa - T * fluidProperties.beta) * der(p) +
+        (fluidProperties.cp - p * v * fluidProperties.beta) * der(T))
+        "Transient energy balance";
+
+    else
+      dU_dtau = u * dm_dtau + m * (
+        (1 - p * v * fluidProperties.beta / fluidProperties.cp) * der(h) +
+        v * (p * (fluidProperties.kappa - fluidProperties.beta *
+        fluidProperties.my) - 1) * der(p))
+        "Transient energy balance";
+
+    end if;
+  end if;
+
+  if avoid_events then
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* noEvent(actualStream(cfp_xMinus.h_outflow))) +
+      sum(cfp_xPlus.m_flow .* noEvent(actualStream(cfp_xPlus.h_outflow))) +
+      fp_sorption.m_flow * noEvent(actualStream(fp_sorption.h_outflow))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  else
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* actualStream(cfp_xMinus.h_outflow)) +
+      sum(cfp_xPlus.m_flow .* actualStream(cfp_xPlus.h_outflow)) +
+      fp_sorption.m_flow * actualStream(fp_sorption.h_outflow)
+      "Sum of all enthalpy flow rates across boundaries";
+
+  end if;
+
+  Qb_flow = Q_flow_xMinus + Q_flow_xPlus +
+    Q_flow_yMinus + Q_flow_yPlus +
+    Q_flow_zMinus + Q_flow_zPlus +
+    hp_sorption.Q_flow
+    "Sum of all heat flow rates across boundaries";
+
+  fp_sorption.h_outflow = h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  hp_sorption.T = T
+    "Temperature at sorption heat port";
+
+  //
+  // Summary record
+  //
+  fluidProperties.cp = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  fluidProperties.lambda = if calculateAdditionalProperties then
+    Medium.thermalConductivity(state=state) else 0
+    "Thermal conductivity";
+  fluidProperties.eta = if calculateAdditionalProperties then
+    Medium.dynamicViscosity(state=state) else 0
+    "Dynamic viscosity";
+
+  fluidProperties.beta = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  fluidProperties.kappa = if (calculateAdditionalProperties or
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  fluidProperties.my = if (calculateAdditionalProperties or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)))) then
+    v / fluidProperties.cp * (fluidProperties.beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  fluidProperties.Pr = if calculateAdditionalProperties then
+    fluidProperties.eta * fluidProperties.cp / fluidProperties.lambda else 0
+    "Prandtl number";
+
+  fluidProperties.m_flow_sorption = ms_flow
+    "Total mass flow rate at port 'sorption'";
+
+  fluidProperties.mc_flow_yMinus = 0
+    "Convective mass flow rate at port '-dy/2'";
+  fluidProperties.mc_flow_yPlus = 0
+    "Convective mass flow rate at port '+dy/2'";
+  fluidProperties.mc_flow_zMinus = 0
+    "Convective mass flow rate at port '-dz/2'";
+  fluidProperties.mc_flow_zPlus = 0
+    "Convective mass flow rate at port '+dz/2'";
+
+  fluidProperties.md_flow_xMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dx/2'";
+  fluidProperties.md_flow_xPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dx/2'";
+  fluidProperties.md_flow_yMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dy/2'";
+  fluidProperties.md_flow_yPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dy/2'";
+  fluidProperties.md_flow_zMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dz/2'";
+  fluidProperties.md_flow_zPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a VLE volume, applying a lumped modeling approach. Depending 
+on the volume setup, this model may have up to seven heat ports (i.e., two for each 
+spatial direction of a cartesian coordinate system and one for a adsorbate volume).
+Furthermore, this model has convective fluid ports in y-direction, following the 
+'connectorSizing' principle, and a sorption fluid port. These ports allow for the 
+combination of several fluid volumes to create a spatially distributed model.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equations are the momentum, mass, and energy balance. According to
+the staggered grid approach, the momentum balance is not solved within the volume but 
+at the volume's boundaries via so-called 
+<a href=\"Modelica://SorpLib.Components.Fittings\">flow models</a>. Hennce, no pressure 
+losses occur within the volume:
+</p>
+<pre>
+    p = cfp_xMinus.p;
+</pre>
+<pre>
+    p = cfp_xPlus.p;
+</pre>
+<pre>
+    p = fp_sorption.p;
+</pre>
+
+<p>
+Regarding the mass and energy balances, either steady-state or tansient balnaces
+can be selected. When using the pressure <i>p</i> and temperature <i>T</i> as  
+independent states, the mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * &rho; * [&kappa; * (dp/d&tau;) - &beta; * (dT/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * &kappa; - T * &beta;) * (dp/d&tau;) + (c<sub>p</sub> - p * v * &beta;) * (dT/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+When using the pressure <i>p</i> and specific enthalpy <i>h</i> as independent 
+states, the mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = V * &rho; * [(&kappa; - &beta; * &mu;) * (dp/d&tau;) - &beta; / c<sub>p</sub> * (dh/d&tau;)] = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [v * (p * (&kappa; - &beta; * &mu;) - 1) * (dp/d&tau;) + (1 - p * v * &beta; / c<sub>p</sub>) * (dh/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+Herein, <i>(dm/d&tau;)</i> is the derivative of the mass w.r.t. time, <i>(dU/d&tau;)</i> 
+is the derivative of the internal energy w.r.t. time, <i>(d&rho;/d&tau;)</i> is the 
+derivative of the density w.r.t. time, <i>(du/d&tau;)</i> is the derivative of the specific 
+internal energy w.r.t.time, <i>(dp/d&tau;)</i> is the derivative of the pressure w.r.t. 
+time, <i>(dT/d&tau;)</i> is the derivative of the temperature w.r.t. time, <i>(dh/d&tau;)</i> 
+is the derivative of the specific enthalpy w.r.t. time,  <i>V</i> is the volume, <i>m</i> is 
+the mass, <i>v</i> is the specific volume, <i>&rho;</i> is the density, <i>&kappa;</i> is 
+the isothermal compressibility, <i>&beta;</i> is the isobaric expansion coefficient, <i>&mu;</i> 
+is the Joule-Thomson coefficient, <i>c<sub>p</sub></i> is the specific heat capacity at 
+constant pressure,<i>m<sub>c,flow</sub></i> is the sum of the convective mass flow rates, 
+<i>H<sub>b,flow</sub></i> is the sum of the enthalpy flow rates, and <i>Q<sub>b,flow</sub></i> 
+is the sum of the heat flow rates.
+</p>
+
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to model the adsorptive at vapor phase within
+adsorber modules.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>calculateAdditionalProperties</i>:
+  Defines if additional properties like transport properties shall be calculated.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has two dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> and temperature <i>T</i>, or
+  </li>
+  <li>
+  pressure <i>p</i> and specific enthalpy <i>h</i> (recommended).
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid property model is a single state model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 8, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end VLEVolume;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/package.mo b/SorpLib/Basics/Volumes/FluidVolumes/package.mo
new file mode 100644
index 0000000..6fb9c62
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics.Volumes;
+package FluidVolumes "Package containing finte volume models of fluids"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains finite volume models of fluids. This package calculates 
+fluid properties based on the open-source Modelica Standard Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end FluidVolumes;
diff --git a/SorpLib/Basics/Volumes/FluidVolumes/package.order b/SorpLib/Basics/Volumes/FluidVolumes/package.order
new file mode 100644
index 0000000..fc9cb2b
--- /dev/null
+++ b/SorpLib/Basics/Volumes/FluidVolumes/package.order
@@ -0,0 +1,6 @@
+LiquidVolume
+GasVolume
+GasMixtureVolume
+GasVaporMixtureVolume
+VLEVolume
+Tester
diff --git a/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/PhaseSeparatorVolume.mo b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/PhaseSeparatorVolume.mo
new file mode 100644
index 0000000..68f65c8
--- /dev/null
+++ b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/PhaseSeparatorVolume.mo
@@ -0,0 +1,279 @@
+within SorpLib.Basics.Volumes.PhaseSeparatorVolumes;
+model PhaseSeparatorVolume
+  "Homogenous phase separator of a real fluid (i.e., with a two-phase regime)"
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialPhaseSeparatorVolume(
+    final no_components = Medium.nX,
+    useHeatPorts=true,
+    useHeatPortsY=true,
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with a two-phase regime)"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+  Medium.SaturationProperties stateSaturation
+    "Thermodynamic saturation state required to calculate medium properties";
+
+equation
+  //
+  // Calculation of properties
+  //
+  state = Medium.setState_dTX(d=rho, T=T, X=Medium.reference_X)
+    "Thermodynamic state required to calculate medium properties";
+  stateSaturation = Medium.setSat_T(T=T)
+    "Thermodynamic saturation state required to calculate medium properties";
+
+  p = Medium.saturationPressure_sat(sat=stateSaturation)
+    "Pressure";
+
+  rho_liq = Medium.bubbleDensity(sat=stateSaturation)
+    "Density at saturated liquid line";
+  rho_vap = Medium.dewDensity(sat=stateSaturation)
+    "Density at saturated vapor line";
+  h_liq = Medium.bubbleEnthalpy(sat=stateSaturation)
+    "Specific enthalpy at saturated liquid line";
+  h_vap = Medium.dewEnthalpy(sat=stateSaturation)
+    "Specific enthalpy at saturated vapor line";
+
+  //
+  // Mass balance
+  //
+  dm_dtau = mc_flow
+    "Overall mass balance";
+
+  mc_flow = sum(cfp_xMinus.m_flow) + sum(cfp_xPlus.m_flow)
+    "Sum of all convective mass flow rates across boundaries";
+
+  //
+  // Energy balance
+  //
+  dU_dtau = Hb_flow + Qb_flow
+    "Energy balane";
+
+  if avoid_events then
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* noEvent(actualStream(cfp_xMinus.h_outflow))) +
+      sum(cfp_xPlus.m_flow .* noEvent(actualStream(cfp_xPlus.h_outflow)))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  else
+    Hb_flow =
+      sum(cfp_xMinus.m_flow .* actualStream(cfp_xMinus.h_outflow)) +
+      sum(cfp_xPlus.m_flow .* actualStream(cfp_xPlus.h_outflow))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  end if;
+
+  Qb_flow = Q_flow_xMinus + Q_flow_xPlus +
+    Q_flow_yMinus + Q_flow_yPlus +
+    Q_flow_zMinus + Q_flow_zPlus
+    "Sum of all heat flow rates across boundaries";
+
+  //
+  // Summary record
+  //
+  phaseSepratorProperties.cp = if calculateAdditionalProperties then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  phaseSepratorProperties.cv =
+    Medium.specificHeatCapacityCv(state=state)
+    "Specific heat capacity";
+  phaseSepratorProperties.lambda = if calculateAdditionalProperties then
+    Medium.thermalConductivity(state=state) else 0
+    "Thermal conductivity";
+  phaseSepratorProperties.eta = if calculateAdditionalProperties then
+    Medium.dynamicViscosity(state=state) else 0
+    "Dynamic viscosity";
+
+  phaseSepratorProperties.beta = if calculateAdditionalProperties then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  phaseSepratorProperties.kappa = if calculateAdditionalProperties then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  phaseSepratorProperties.my = if calculateAdditionalProperties then
+    v / phaseSepratorProperties.cp * (phaseSepratorProperties.beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  phaseSepratorProperties.mc_flow_yMinus = 0
+    "Convective mass flow rate at port '-dy/2'";
+  phaseSepratorProperties.mc_flow_yPlus = 0
+    "Convective mass flow rate at port '+dy/2'";
+  phaseSepratorProperties.mc_flow_zMinus = 0
+    "Convective mass flow rate at port '-dz/2'";
+  phaseSepratorProperties.mc_flow_zPlus = 0
+    "Convective mass flow rate at port '+dz/2'";
+
+  phaseSepratorProperties.md_flow_xMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dx/2'";
+  phaseSepratorProperties.md_flow_xPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dx/2'";
+  phaseSepratorProperties.md_flow_yMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dy/2'";
+  phaseSepratorProperties.md_flow_yPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dy/2'";
+  phaseSepratorProperties.md_flow_zMinus = zeros(no_components)
+    "Diffusive mass flow rate at port '-dz/2'";
+  phaseSepratorProperties.md_flow_zPlus = zeros(no_components)
+    "Diffusive mass flow rate at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a phase separator volume, applying a lumped modeling approach. 
+Depending on the volume setup, this model may have up to six heat ports (i.e., two 
+for each spatial direction of a cartesian coordinate system). Furthermore, this model 
+has convective fluid ports in y-direction, following the 'connectorSizing' principle.
+The fluid port at position 'cfp_xMinus' is used as liquid fluid port, meaning that the
+outflowing fluid is set at saturated liquid state. In contrast, the fluid port at 
+position 'cfp_XPlus' is used as vapor fluid port, meaning that the outflowing fluid is 
+set to saturated vapor state.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equations are the momentum, mass, and energy balance. According to
+the staggered grid approach, the momentum balance is not solved within the volume but 
+at the volume's boundaries via so-called 
+<a href=\"Modelica://SorpLib.Components.Fittings\">flow models</a>. Hennce, no pressure 
+losses occur within the volume:
+</p>
+<pre>
+    p = cfp_xMinus.p;
+</pre>
+<pre>
+    p = cfp_xPlus.p;
+</pre>
+
+<p>
+Regarding the mass and energy balances, either steady-state or tansient balnaces
+can be selected. The mass balance is defined as
+</p>
+<pre>
+    (dm/d&tau;) = V * (d&rho;/d&tau;) = &sum; m<sub>c,flow</sub>;
+</pre>
+<p>
+and the energy balance is defined as
+</p>
+<pre>
+    (dU/d&tau;) = u * (dm/d&tau;) + m * (du/d&tau;) = u * (dm/d&tau;) + m * [c<sub>v</sub> * (dT/d&tau;) + 1/&rho;<sup>2</sup> * (-p + (h<sub>vap</sub> - h<sub>liq</sub>) / (1/&rho;<sub>vap</sub> - 1/&rho;<sub>liq</sub>)) (d&rho;/d&tau;)] = &sum; H<sub>b,flow</sub> + &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+Herein, <i>(dm/d&tau;)</i> is the derivative of the mass w.r.t. time, <i>(dU/d&tau;)</i> 
+is the derivative of the internal energy w.r.t. time, <i>(du/d&tau;)</i> is the derivative 
+of the specific internal energy w.r.t.time, <i>(dT/d&tau;)</i> is the derivative of the 
+temperature w.r.t. time, <i>(d&rho;/d&tau;)</i> is the derivative of the density w.r.t. 
+time, <i>V</i> is the volume, <i>m</i> is the mass, <i>p</i> ist the pressure, <i>&rho;</i> 
+is the density, <i>&rho;<sub>liq</sub></i> is the density at the saturated liquid line, 
+<i>&rho;<sub>vap</sub></i> is the density at the saturated vapor line, <i>h<sub>liq</sub></i> 
+is the specific enthalpy at the saturated liquid line, <i>h<sub>vap</sub></i> is the specific
+enthalpy at the saturated vapor line, <i>u</i> is the specific internal energy, <i>c<sub>v</sub></i> 
+is the specific heat capacity at constant volume,<i>m<sub>c,flow</sub></i> is the sum of the 
+convective mass flow rates, <i>H<sub>b,flow</sub></i> is the sum of the enthalpy flow rates, 
+and <i>Q<sub>b,flow</sub></i> is the sum of the heat flow rates.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Mechanical, thermal, and chemical equilibrium between the liquid and vapor phase
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used as ideal phase saperator to model an evaporator od condenser.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <i>calculateAdditionalProperties</i>:
+  Defines if additional properties like transport properties shall be calculated.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>useStateLimiter</i>:
+  Defines if specific enthalpy of vapor or liquid is limited at ports (i.e., vapor port is 
+  slightly overheated and liquid port is slightly supercooled) to increase numerical stability.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has two dynamic states:
+</p>
+<ul>
+  <li>
+  Temperature <i>T</i> and density <i>&rho;</i>.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Tummescheit, H (2002). Design and Implementation of Object-Oriented Model Libraries using Modelica. PhD Thesis. URL: https://lucris.lub.lu.se/ws/files/4779081/8571901.pdf.
+  </li>
+  <li>
+  Gr&auml;ber, M. and Kirches, C. and Bock, H.G. and Schl&ouml;der, J.P. and Tegethoff, W. and K&ouml;hler, J. (2011). Determining the optimum cyclic operation of adsorption chillers by a direct method for periodic optimal control. International Journal of Refrigeration, 34(4):902-913. DOI: https://doi.org/10.1016/j.ijrefrig.2010.12.021.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 14, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 13, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PhaseSeparatorVolume;
diff --git a/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/Test_PhaseSeparator.mo b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/Test_PhaseSeparator.mo
new file mode 100644
index 0000000..7c361c5
--- /dev/null
+++ b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/Test_PhaseSeparator.mo
@@ -0,0 +1,153 @@
+within SorpLib.Basics.Volumes.PhaseSeparatorVolumes.Tester;
+model Test_PhaseSeparator "Tester for phase separator volume"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the VLE liquid"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of VLE models
+  //
+  SorpLib.Basics.Volumes.PhaseSeparatorVolumes.PhaseSeparatorVolume phaseSeparator(
+    T_initial=293.15,
+    rho_initial=500,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    calculateAdditionalProperties=true,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium,
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1) "Model of a phase seperator volume" annotation (
+      Placement(transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={0,0})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_liquidPort(
+    amplitude=-0.0001,
+    rising=250,
+    width=400,
+    falling=250,
+    period=950,
+    startTime=50)
+    "Input for liquid port boundary"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={-30,-70})));
+  Modelica.Blocks.Sources.Ramp input_vaporPort(
+    height=0.0001,
+    duration=250,
+    startTime=500)
+    "Input for vapor Port"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={-30,70})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource liquidInlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    m_flow_fixed=-0.001,
+    h_fixed=0.5e6,
+    redeclare package Medium = Medium)
+    "Liquid inlet for phase seprator volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=90,
+                origin={0,-40})));
+  SorpLib.Basics.Sources.Fluids.VLESource VaporInlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    m_flow_fixed=1e-3,
+    h_fixed=1e-6,
+    redeclare package Medium = Medium)
+    "Vapor inlet for phase separator"
+    annotation (Placement(transformation(
+                extent={{10,-10},{-10,10}},
+                rotation=90,
+                origin={0,40})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  Modelica.Blocks.Sources.Ramp input_heatFlow(
+    height=-350,
+    duration=250,
+    startTime=250)
+    "Input for heat flow"
+    annotation (Placement(transformation(
+                extent={{10,-10},{-10,10}},
+                rotation=0,
+                origin={70,0})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource heatSource(
+    boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=true,
+    Q_flow_fixed=-25)
+    "Heat source for phase seprator volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=180,
+                origin={40,0})));
+
+equation
+  //
+  // Connections
+  //
+  connect(liquidInlet.port, phaseSeparator.cfp_xMinus[1]) annotation (Line(
+      points={{0,-40},{0,-8.4},{-3.6,-8.4}},
+      color={0,140,72},
+      thickness=1));
+  connect(VaporInlet.port, phaseSeparator.cfp_xPlus[1]) annotation (Line(
+      points={{0,40},{0,15.6},{-3.6,15.6}},
+      color={0,140,72},
+      thickness=1));
+  connect(heatSource.port, phaseSeparator.hp_yMinus) annotation (Line(
+      points={{40,0},{12,0}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_liquidPort.y, liquidInlet.m_flow_input)
+    annotation (Line(points={{-19,-70},{-2,-70},{-2,-41.2}}, color={0,0,127}));
+  connect(input_vaporPort.y, VaporInlet.m_flow_input)
+    annotation (Line(points={{-19,70},{-2,70},{-2,41.2}}, color={0,0,127}));
+  connect(input_heatFlow.y, heatSource.Q_flow_input)
+    annotation (Line(points={{59,0},{50,0},{50,5},{41,5}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=1000), Documentation(info="<html>
+<p>
+This model checks the model of the phase separator volume.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 1000 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 14, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 13, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_PhaseSeparator;
diff --git a/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/package.mo b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/package.mo
new file mode 100644
index 0000000..b0ff8b3
--- /dev/null
+++ b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Volumes.PhaseSeparatorVolumes;
+package Tester "Models to test and varify models of phase separators"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented phase separators.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/package.order b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/package.order
new file mode 100644
index 0000000..a00cf22
--- /dev/null
+++ b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/Tester/package.order
@@ -0,0 +1 @@
+Test_PhaseSeparator
diff --git a/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/package.mo b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/package.mo
new file mode 100644
index 0000000..112c24c
--- /dev/null
+++ b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Basics.Volumes;
+package PhaseSeparatorVolumes "Package containing finte volume models of phase separators"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains finite volume models of phase separators. This package 
+calculates fluid properties based on the open-source Modelica Standard Library 
+(MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PhaseSeparatorVolumes;
diff --git a/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/package.order b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/package.order
new file mode 100644
index 0000000..d86df73
--- /dev/null
+++ b/SorpLib/Basics/Volumes/PhaseSeparatorVolumes/package.order
@@ -0,0 +1,2 @@
+PhaseSeparatorVolume
+Tester
diff --git a/SorpLib/Basics/Volumes/Records/AdsorbateVolumeProperties.mo b/SorpLib/Basics/Volumes/Records/AdsorbateVolumeProperties.mo
new file mode 100644
index 0000000..89b8e12
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Records/AdsorbateVolumeProperties.mo
@@ -0,0 +1,86 @@
+within SorpLib.Basics.Volumes.Records;
+record AdsorbateVolumeProperties
+  "This record summarizes important thermodynamic properties of an adsorbate volume"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters
+  //
+  parameter Integer no_adsorptivs = 1
+    "Number of adsorptivs (i.e., components that can be adsorbed/desorbed)"
+    annotation (Dialog(tab="General", group="Media"));
+
+  //
+  // Definition of state properties
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T
+    "Temperature";
+  SorpLib.Units.Uptake x
+    "Loading";
+  SorpLib.Units.Uptake[no_adsorptivs] x_i
+    "Loading of each component";
+
+  //
+  // Definition of additional properties
+  //
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity of the adsorpt";
+  Modelica.Units.SI.SpecificEnthalpy dh_ads
+    "Specific enthalpy of adsorption";
+
+  //
+  // Definition of flow-specific variables
+  //
+  Modelica.Units.SI.MassFlowRate m_flow_sorption
+    "Total mass flow rate at port 'sorption'";
+
+  Modelica.Units.SI.MassFlowRate ma_flow_xMinus
+    "Adsorbate mass flow rate at port '-dx/2'";
+  Modelica.Units.SI.MassFlowRate ma_flow_xPlus
+    "Adsorbate mass flow rate at port '+dx/2'";
+
+  Modelica.Units.SI.MassFlowRate ma_flow_yMinus
+    "Adsorbate mass flow rate at port '-dy/2'";
+  Modelica.Units.SI.MassFlowRate ma_flow_yPlus
+    "Adsorbate mass flow rate at port '+dy/2'";
+
+  Modelica.Units.SI.MassFlowRate ma_flow_zMinus
+    "Adsorbate mass flow rate at port '-dz/2'";
+  Modelica.Units.SI.MassFlowRate ma_flow_zPlus
+    "Adsorbate mass flow rate at port '+dz/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_adsorptivs] md_flow_xMinus
+    "Diffusive mass flow rates at port '-dx/2'";
+  Modelica.Units.SI.MassFlowRate[no_adsorptivs] md_flow_xPlus
+    "Diffusive mass flow rates at port '+dx/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_adsorptivs] md_flow_yMinus
+    "Diffusive mass flow rates at port '-dy/2'";
+  Modelica.Units.SI.MassFlowRate[no_adsorptivs] md_flow_yPlus
+    "Diffusive mass flow rates at port '+dy/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_adsorptivs] md_flow_zMinus
+    "Diffusive mass flow rates at port '-dz/2'";
+  Modelica.Units.SI.MassFlowRate[no_adsorptivs] md_flow_zPlus
+    "Diffusive mass flow rates at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains important thermodynamic properties of an adsorbate volume.
+These properties may be required to calculate heat transfer or mass transfer 
+phenomena.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorbateVolumeProperties;
diff --git a/SorpLib/Basics/Volumes/Records/FluidVolumeProperties.mo b/SorpLib/Basics/Volumes/Records/FluidVolumeProperties.mo
new file mode 100644
index 0000000..5fe92d3
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Records/FluidVolumeProperties.mo
@@ -0,0 +1,99 @@
+within SorpLib.Basics.Volumes.Records;
+record FluidVolumeProperties
+  "This record summarizes important thermodynamic properties of a fluid volume"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Media"));
+
+  //
+  // Definition of state properties
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+
+  //
+  // Definition of additional properties
+  //
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity at constant pressure";
+  Modelica.Units.SI.ThermalConductivity lambda
+    "Thermal conductivity";
+  Modelica.Units.SI.DynamicViscosity eta
+    "Dynamic viscosity";
+
+  Modelica.Media.Common.IsobaricVolumeExpansionCoefficient beta
+    "Isobaric expnasion coefficient";
+  Modelica.Media.Common.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Media.Common.JouleThomsonCoefficient my
+    "Joule-Thomson coefficient";
+
+  Modelica.Units.SI.PrandtlNumber Pr
+    "Prandtl number";
+
+  //
+  // Definition of flow-specific variables
+  //
+  Modelica.Units.SI.MassFlowRate m_flow_sorption
+    "Total mass flow rate at port 'sorption'";
+
+  Modelica.Units.SI.MassFlowRate mc_flow_xMinus
+    "Total convective mass flow rate at port '-dx/2'";
+  Modelica.Units.SI.MassFlowRate mc_flow_xPlus
+    "Total convective mass flow rate at port '+dx/2'";
+
+  Modelica.Units.SI.MassFlowRate mc_flow_yMinus
+    "Total convective mass flow rate at port '-dy/2'";
+  Modelica.Units.SI.MassFlowRate mc_flow_yPlus
+    "Total convective mass flow rate at port '+dy/2'";
+
+  Modelica.Units.SI.MassFlowRate mc_flow_zMinus
+    "Total convective mass flow rate at port '-dz/2'";
+  Modelica.Units.SI.MassFlowRate mc_flow_zPlus
+    "Total convective mass flow rate at port '+dz/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_xMinus
+    "Diffusive mass flow rates at port '-dx/2'";
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_xPlus
+    "Diffusive mass flow rates at port '+dx/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_yMinus
+    "Diffusive mass flow rates at port '-dy/2'";
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_yPlus
+    "Diffusive mass flow rates at port '+dy/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_zMinus
+    "Diffusive mass flow rates at port '-dz/2'";
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_zPlus
+    "Diffusive mass flow rates at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains important thermodynamic properties of a fluid volume. These
+properties may be required to calculate heat transfer or mass transfer phenomena.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 7, 2023, by Mirko Engelpracht:<br/>
+  Update due to major restructering of finite volume cells.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end FluidVolumeProperties;
diff --git a/SorpLib/Basics/Volumes/Records/PhaseSeparatorGeometry.mo b/SorpLib/Basics/Volumes/Records/PhaseSeparatorGeometry.mo
new file mode 100644
index 0000000..30ac63e
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Records/PhaseSeparatorGeometry.mo
@@ -0,0 +1,28 @@
+within SorpLib.Basics.Volumes.Records;
+record PhaseSeparatorGeometry
+  "This record defines the geometry of a phase separator volume"
+  extends SorpLib.Basics.Volumes.Records.VolumeGeometry;
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Area A_base = A_yz
+    "Base area used to calculate relative filling level"
+    annotation (Dialog(tab="General", group="Geometry - Area"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains parameters defining the geometry of a phase separator volume.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PhaseSeparatorGeometry;
diff --git a/SorpLib/Basics/Volumes/Records/PhaseSeparatorProperties.mo b/SorpLib/Basics/Volumes/Records/PhaseSeparatorProperties.mo
new file mode 100644
index 0000000..7d02dcc
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Records/PhaseSeparatorProperties.mo
@@ -0,0 +1,103 @@
+within SorpLib.Basics.Volumes.Records;
+record PhaseSeparatorProperties
+  "This record summarizes important thermodynamic properties of a phase separator volume"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Media"));
+
+  //
+  // Definition of state properties
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+
+  //
+  // Definition of additional properties
+  //
+  Modelica.Units.SI.Length l_liq
+    "Height of liquid phase";
+  Real l_liq_rel(unit="1")
+    "Relative height of liquid phase";
+
+  //
+  // Definition of additional properties
+  //
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity at constant pressure";
+  Modelica.Units.SI.SpecificHeatCapacity cv
+    "Specific heat capacity at constant volume";
+  Modelica.Units.SI.ThermalConductivity lambda
+    "Thermal conductivity";
+  Modelica.Units.SI.DynamicViscosity eta
+    "Dynamic viscosity";
+
+  Modelica.Media.Common.IsobaricVolumeExpansionCoefficient beta
+    "Isobaric expnasion coefficient";
+  Modelica.Media.Common.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Media.Common.JouleThomsonCoefficient my
+    "Joule-Thomson coefficient";
+
+  Modelica.Units.SI.PrandtlNumber Pr
+    "Prandtl number";
+
+  //
+  // Definition of flow-specific variables
+  //
+  Modelica.Units.SI.MassFlowRate mc_flow_xMinus
+    "Total convective mass flow rate at port '-dx/2'";
+  Modelica.Units.SI.MassFlowRate mc_flow_xPlus
+    "Total convective mass flow rate at port '+dx/2'";
+
+  Modelica.Units.SI.MassFlowRate mc_flow_yMinus
+    "Total convective mass flow rate at port '-dy/2'";
+  Modelica.Units.SI.MassFlowRate mc_flow_yPlus
+    "Total convective mass flow rate at port '+dy/2'";
+
+  Modelica.Units.SI.MassFlowRate mc_flow_zMinus
+    "Total convective mass flow rate at port '-dz/2'";
+  Modelica.Units.SI.MassFlowRate mc_flow_zPlus
+    "Total convective mass flow rate at port '+dz/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_xMinus
+    "Diffusive mass flow rates at port '-dx/2'";
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_xPlus
+    "Diffusive mass flow rates at port '+dx/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_yMinus
+    "Diffusive mass flow rates at port '-dy/2'";
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_yPlus
+    "Diffusive mass flow rates at port '+dy/2'";
+
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_zMinus
+    "Diffusive mass flow rates at port '-dz/2'";
+  Modelica.Units.SI.MassFlowRate[no_components] md_flow_zPlus
+    "Diffusive mass flow rates at port '+dz/2'";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains important thermodynamic properties of a phase seprator 
+volume. These properties may be required to calculate heat transfer or mass 
+transfer phenomena.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PhaseSeparatorProperties;
diff --git a/SorpLib/Basics/Volumes/Records/SolidVolumeProperties.mo b/SorpLib/Basics/Volumes/Records/SolidVolumeProperties.mo
new file mode 100644
index 0000000..14895ef
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Records/SolidVolumeProperties.mo
@@ -0,0 +1,44 @@
+within SorpLib.Basics.Volumes.Records;
+record SolidVolumeProperties
+  "This record summarizes important thermodynamic properties of a solide volume"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of state properties
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+
+  //
+  // Definition of additional properties
+  //
+  Modelica.Units.SI.SpecificHeatCapacity c
+    "Specific heat capacity";
+  Modelica.Units.SI.ThermalConductivity lambda
+    "Thermal conductivity";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains important thermodynamic properties of a solid volume. These
+properties may be required to calculate heat transfer phenomena.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 6, 2023, by Mirko Engelpracht:<br/>
+  Update due to major restructering of finite volume cells.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SolidVolumeProperties;
diff --git a/SorpLib/Basics/Volumes/Records/VolumeGeometry.mo b/SorpLib/Basics/Volumes/Records/VolumeGeometry.mo
new file mode 100644
index 0000000..11ec4d8
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Records/VolumeGeometry.mo
@@ -0,0 +1,52 @@
+within SorpLib.Basics.Volumes.Records;
+record VolumeGeometry
+  "This record defines the geometry of a finite volume"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Length dx = 0.1
+    "Length in x direction"
+    annotation (Dialog(tab="General", group="Geometry - Length"));
+  parameter Modelica.Units.SI.Length dy = 0.1
+    "Length in y direction"
+    annotation (Dialog(tab="General", group="Geometry - Length"));
+  parameter Modelica.Units.SI.Length dz = 0.1
+    "Length in z direction"
+    annotation (Dialog(tab="General", group="Geometry - Length"));
+
+  parameter Modelica.Units.SI.Area A_xy = dx * dy
+    "Cross-sectional area of x-y direction"
+    annotation (Dialog(tab="General", group="Geometry - Area"));
+  parameter Modelica.Units.SI.Area A_xz = dx * dz
+    "Cross-sectional area of x-z direction"
+    annotation (Dialog(tab="General", group="Geometry - Area"));
+  parameter Modelica.Units.SI.Area A_yz = dy * dz
+    "Cross-sectional area of y-z direction"
+    annotation (Dialog(tab="General", group="Geometry - Area"));
+
+  parameter Modelica.Units.SI.Volume V = dx * dy * dz
+    "Volume"
+    annotation (Dialog(tab="General", group="Geometry - Volume"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains parameters defining the geometry of a finite volume.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 6, 2023, by Mirko Engelpracht:<br/>
+  Update due to major restructering of finite volume cells.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end VolumeGeometry;
diff --git a/SorpLib/Basics/Volumes/Records/package.mo b/SorpLib/Basics/Volumes/Records/package.mo
new file mode 100644
index 0000000..ae3a581
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Records/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Basics.Volumes;
+package Records "Records describing geometry and summarizing properties of finite volumes"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records. These records are used to cluster 
+parameters and variables to tidy up the model implementation.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Basics/Volumes/Records/package.order b/SorpLib/Basics/Volumes/Records/package.order
new file mode 100644
index 0000000..b591023
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Records/package.order
@@ -0,0 +1,6 @@
+AdsorbateVolumeProperties
+FluidVolumeProperties
+PhaseSeparatorGeometry
+PhaseSeparatorProperties
+SolidVolumeProperties
+VolumeGeometry
diff --git a/SorpLib/Basics/Volumes/SolidVolumes/SolidVolume.mo b/SorpLib/Basics/Volumes/SolidVolumes/SolidVolume.mo
new file mode 100644
index 0000000..d1651aa
--- /dev/null
+++ b/SorpLib/Basics/Volumes/SolidVolumes/SolidVolume.mo
@@ -0,0 +1,291 @@
+within SorpLib.Basics.Volumes.SolidVolumes;
+model SolidVolume "Homogenous solid volume"
+
+  //
+  // Definition of models
+  //
+  replaceable Media.Solids.MetalsAndMetalAlloys.Aluminium solidMedium
+    constrainedby Media.Solids.BaseClasses.PartialSolid(
+      final calcCaloricProperties=true,
+      final approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+      final p=p,
+      final T=T)
+    "Medium model calculating solid properties"
+    annotation (Dialog(tab="General", group="Media"),
+                choicesAllMatching=true,
+                Placement(transformation(extent={{-8,-8},{12,12}})));
+
+  //
+  // Definition of parameters regarding calculation setup
+  //
+  parameter SorpLib.Choices.IndependentVariablesVolume independentStateVariables=
+    SorpLib.Choices.IndependentVariablesVolume.pTX
+    "Independent state variables"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.Temperature T_initial = 298.15
+    "Initial value of temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=(independentStateVariables==
+                  SorpLib.Choices.IndependentVariablesVolume.pTX)));
+  parameter Modelica.Units.SI.SpecificEnthalpy h_initial = 0
+    "Initial value of specific enthalpy"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=(independentStateVariables==
+                  SorpLib.Choices.IndependentVariablesVolume.phX)));
+
+  extends SorpLib.Basics.Volumes.BaseClasses.PartialVolume(
+    final useHeatPorts=true,
+    useHeatPortsX = true);
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Temperature T(
+    start=T_initial,
+    stateSelect= if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then StateSelect.prefer
+      else StateSelect.avoid)
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+  Modelica.Units.SI.Density rho
+    "Density";
+
+  Modelica.Units.SI.SpecificEnthalpy h(
+    start=h_initial,
+    stateSelect= if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.phX then StateSelect.prefer
+      else StateSelect.avoid)
+    "Specific enthalpy";
+  Modelica.Units.SI.SpecificInternalEnergy u
+    "Specific internal energy";
+
+  Modelica.Units.SI.Mass m
+    "Mass";
+
+  Modelica.Units.SI.InternalEnergy U
+    "Internal energy";
+  Real dU_dtau(final unit="W")
+    "Derivative of internal energy w.r.t. time";
+  Modelica.Units.SI.HeatFlowRate Qb_flow
+    "Sum of all heat flow rates across boundaries";
+
+  SorpLib.Basics.Volumes.Records.SolidVolumeProperties solidProperties
+    "Properties of solid volume often required for calculation of heat transfer";
+
+initial equation
+  if type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      T = T_initial
+        "Fixed initial value";
+
+    else
+      h = h_initial
+        "Fixed initial value";
+
+    end if;
+
+  elseif type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      der(T) = 0
+        "Steady-state initial value";
+
+    else
+      der(h) = 0
+        "Steady-state initial value";
+
+    end if;
+  end if;
+
+equation
+  //
+  // Assertations
+  //
+  assert(useHeatPortsX or useHeatPortsY or useHeatPortsZ,
+    "Must use heat ports at least in one direction (e.g., x, y, or z)!",
+    level = AssertionLevel.error);
+
+  //
+  // Property calculation
+  //
+  v = solidMedium.state_variables.v
+    "Specific volume";
+  rho = 1 / v
+    "Density";
+
+  h = solidMedium.state_variables.h
+    "Specific enthalpy";
+  u = solidMedium.state_variables.u
+    "Specific internal energy";
+
+  //
+  // Mass balance
+  //
+  m = geometry.V / v
+    "Mass";
+
+  //
+  // Energy balance
+  //
+  U = m * u
+    "Internal energy";
+
+  dU_dtau = Qb_flow
+  "Energy balance";
+
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dU_dtau = m * solidMedium.additional_variables.c * der(T)
+        "Transient energy balance with p and T as independent states";
+
+    else
+      dU_dtau = m *der(h)
+        "Transient energy balance with p and h as independent states";
+
+    end if;
+  end if;
+
+  Qb_flow = Q_flow_xMinus + Q_flow_xPlus + Q_flow_yMinus + Q_flow_yPlus +
+    Q_flow_zMinus + Q_flow_zPlus
+    "Sum of all heat flow rates across boundaries";
+
+  T_heatPorts = T
+    "Required for conditional component";
+
+  //
+  // Summary record
+  //
+  solidProperties.p = p
+    "Pressure";
+  solidProperties.T = T
+    "Temperature";
+  solidProperties.v = v
+    "Specific volume";
+
+  solidProperties.c = solidMedium.additional_variables.c
+    "Specific heat capacity";
+  solidProperties.lambda = solidMedium.additional_variables.lambda
+    "Thermal conductivity";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a solid volume, applying a lumped modeling approach. Depending on
+the volume setup, this model may have up to six heat ports (i.e., two for each spatial
+direction of a cartesian coordinate system). These heat ports allow for the combination 
+of several solid volumes via appropriate heat transfer models to create a spatially 
+distributed model.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The most important equation is the energy balance. When using the temperature <i>T</i> as
+an independent state, the energy balance is defined as
+</p>
+<pre>
+    m * c  * (dT/d&tau;) = &sum; Q<sub>b,flow</sub>;
+</pre>
+<p>
+When using the specific enthalpy <i>h</i> as an independent state, the energy balance is 
+defined as
+</p>
+<pre>
+    m * (dh/d&tau;) = &sum; Q<sub>b,flow</sub>;
+</pre>
+
+<p>
+Herein, <i>m</i> is the volume mass, <i>T</i> is the temperature, <i>h</i> is the 
+specific enthalpy, <i>c</i> is the specific heat capacity, and <i>Q<sub>b,flow</sub></i> 
+is the sum of the heat flow rates over the volume boundaries.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Incompressible medium (i.e., constant specific volume <i>v</i>)
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used as wall model to represent the thermal capacity of a
+metal. Thus, e.g., walls of pipes, fins of heat exchangers, or casings of components
+are modeled.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useHeatPorts</i>:
+  Defines if heat ports in the spatial direction <i>i</i> are required.
+  </li>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables of the model.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+This model has one dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Temperature <i>T</i> (recommended to avoid non-linear equations), or
+  </li>
+  <li>
+  specific enthalpy <i>h</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 6, 2023, by Mirko Engelpracht:<br/>
+  Major revisions due to restructering finite volumes.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  Revisions (e.g., object-oriented approach) after restructering of the library.
+  </li>
+  <li>
+  November 23, 2017, by Andrej Gibelhaus:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end SolidVolume;
diff --git a/SorpLib/Basics/Volumes/SolidVolumes/Tester/Test_SolidVolume.mo b/SorpLib/Basics/Volumes/SolidVolumes/Tester/Test_SolidVolume.mo
new file mode 100644
index 0000000..c43fe3f
--- /dev/null
+++ b/SorpLib/Basics/Volumes/SolidVolumes/Tester/Test_SolidVolume.mo
@@ -0,0 +1,221 @@
+within SorpLib.Basics.Volumes.SolidVolumes.Tester;
+model Test_SolidVolume "Tester for solid"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable model Solid =
+      SorpLib.Media.Solids.MetalsAndMetalAlloys.Aluminium
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Solid medium"
+    annotation (Dialog(tab="General", group="Media"));
+
+  parameter Modelica.Units.SI.Pressure p_initial = 0
+    "Initial pressure"
+    annotation (Dialog(tab="General", group="Start Values"));
+  parameter Modelica.Units.SI.Temperature T_initial = 273.15
+    "Initial temperature"
+    annotation (Dialog(tab="General", group="Start Values"));
+
+  //
+  // Definition of solid models
+  //
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume solid_transientFreeInitial_x(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial)
+    "Solid with transient energy balance but free start values and heat ports in 
+    x direction"
+    annotation (Placement(transformation(extent={{-40,60},{-20,80}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume solid_transientFreeInitial_xy(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final useHeatPortsY=true,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial)
+    "Solid with transient energy balance but free start values and heat ports in 
+    x and y directions"
+    annotation (Placement(transformation(extent={{-10,60},{10,80}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume
+    solid_transientFreeInitial_xyz(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final useHeatPortsY=true,
+    final useHeatPortsZ=true,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial)
+    "Solid with transient energy balance but free start values and heat ports in 
+    x, y, and z directions"
+    annotation (Placement(transformation(extent={{20,60},{40,80}})));
+
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume solid_transientFixed_x(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial)
+    "Solid with transient energy balance but fixed start values and heat ports in 
+    x direction"
+    annotation (Placement(transformation(extent={{-40,20},{-20,40}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume solid_transientFixed_xy(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final useHeatPortsY=true,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial)
+    "Solid with transient energy balance but fixed start values and heat ports in 
+    x and y directions"
+    annotation (Placement(transformation(extent={{-10,20},{10,40}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume solid_transientFixed_xyz(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final useHeatPortsY=true,
+    final useHeatPortsZ=true,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial)
+    "Solid with transient energy balance but fixed start values and heat ports in 
+    x, y, and z directions"
+    annotation (Placement(transformation(extent={{20,20},{40,40}})));
+
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume
+    solid_transientFreeInitial_boundaries_x(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial)
+    "Solid with transient energy balance but free start values and heat ports in 
+    x direction connected to thermal boundaries"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume
+    solid_transientFixedInitial_boundaries_x(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial)
+    "Solid with transient energy balance but fixed start values and heat ports in 
+    x direction connected to thermal boundaries"
+    annotation (Placement(transformation(extent={{-10,-60},{10,-40}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume
+    solid_steadyStateFreeInitial_boundaries_x(
+    redeclare final Solid solidMedium,
+    final p=p,
+    final T_initial=T_initial,
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial)
+    "Solid with steady-state energy balance but free start values and heat ports 
+    in x direction connected to thermal boundaries"
+    annotation (Placement(transformation(extent={{-10,-90},{10,-70}})));
+
+  //
+  // Definition of boundaries
+  //
+protected
+  Sources.Thermal.HeatSource heatSource_transientFixedInitial_xMinus(
+      boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate, use_QFlowInput=
+       true) "Heat source for heat ports '-dx/2'"
+    annotation (Placement(transformation(extent={{-60,-60},{-40,-40}})));
+  Sources.Thermal.HeatSource heatSource_transientFreeInitial_xMinus(
+    boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=true)
+    "Heat source for heat ports '-dx/2'"
+    annotation (Placement(transformation(extent={{-60,-30},{-40,-10}})));
+  Sources.Thermal.HeatSource heatSource_steadyStateFreeInitial_xMinus(
+    boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput= true)
+    "Heat source for heat ports '-dx/2'"
+    annotation (Placement(transformation(extent={{-60,-90},{-40,-70}})));
+  Sources.Thermal.HeatSource heatSource_steadyStateFreeInitial_xPlus(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true)
+    "Heat source for heat ports '+dx/2'"
+    annotation (Placement(transformation(extent={{50,-90},{30,-70}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Ramp input_QFlowVar(
+    height=10000,
+    duration=25,
+    offset=-5000,
+    startTime=0) "Ramp to simulate input signal of heat flow rate" annotation (
+      Placement(transformation(extent={{-90,-60},{-70,-40}})),  HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_TVar(
+    height=200,
+    duration=25,
+    offset=173.15,
+    startTime=0) "Ramp to simulate input signal of temperature" annotation (
+      Placement(transformation(extent={{90,-60},{70,-40}})),  HideResult=true);
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p(start=p_initial, fixed=true)
+    "Pressure";
+
+equation
+  //
+  // Change of state variables
+  //
+  der(p) = (10e5 - p_initial) / 25
+    "Pressure";
+
+  //
+  // Connections
+  //
+  connect(heatSource_transientFreeInitial_xMinus.port,
+    solid_transientFreeInitial_boundaries_x.hp_xMinus) annotation (Line(
+      points={{-50,-20},{-6,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_transientFixedInitial_xMinus.port,
+    solid_transientFixedInitial_boundaries_x.hp_xMinus) annotation (Line(
+      points={{-50,-50},{-6,-50}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatSource_steadyStateFreeInitial_xMinus.port,
+    solid_steadyStateFreeInitial_boundaries_x.hp_xMinus) annotation (Line(
+      points={{-50,-80},{-6,-80}},
+      color={238,46,47},
+      thickness=1));
+  connect(solid_steadyStateFreeInitial_boundaries_x.hp_xPlus,
+    heatSource_steadyStateFreeInitial_xPlus.port) annotation (Line(
+      points={{6,-80},{40,-80}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_TVar.y, heatSource_steadyStateFreeInitial_xPlus.T_input)
+    annotation (Line(points={{69,-50},{60,-50},{60,-74.8},{41,-74.8}}, color={0,
+          0,127}));
+  connect(input_QFlowVar.y, heatSource_transientFreeInitial_xMinus.Q_flow_input)
+    annotation (Line(points={{-69,-50},{-60,-50},{-60,-25},{-51,-25}}, color={0,
+          0,127}));
+  connect(input_QFlowVar.y, heatSource_transientFixedInitial_xMinus.Q_flow_input)
+    annotation (Line(points={{-69,-50},{-60,-50},{-60,-55},{-51,-55}}, color={0,
+          0,127}));
+  connect(input_QFlowVar.y, heatSource_steadyStateFreeInitial_xMinus.Q_flow_input)
+    annotation (Line(points={{-69,-50},{-60,-50},{-60,-85},{-51,-85}}, color={0,
+          0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=25), Documentation(info="<html>
+<p>
+This model checks the solid volume model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 25 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 6, 2023, by Mirko Engelpracht:<br/>
+  Added documentation.
+  </li>
+  <li>
+  January 12, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_SolidVolume;
diff --git a/SorpLib/Basics/Volumes/SolidVolumes/Tester/package.mo b/SorpLib/Basics/Volumes/SolidVolumes/Tester/package.mo
new file mode 100644
index 0000000..2b5778e
--- /dev/null
+++ b/SorpLib/Basics/Volumes/SolidVolumes/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Volumes.SolidVolumes;
+package Tester "Models to test and varify models of solid volumes"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented solid volumes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Basics/Volumes/SolidVolumes/Tester/package.order b/SorpLib/Basics/Volumes/SolidVolumes/Tester/package.order
new file mode 100644
index 0000000..d9d7d13
--- /dev/null
+++ b/SorpLib/Basics/Volumes/SolidVolumes/Tester/package.order
@@ -0,0 +1 @@
+Test_SolidVolume
diff --git a/SorpLib/Basics/Volumes/SolidVolumes/package.mo b/SorpLib/Basics/Volumes/SolidVolumes/package.mo
new file mode 100644
index 0000000..a7710a6
--- /dev/null
+++ b/SorpLib/Basics/Volumes/SolidVolumes/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Volumes;
+package SolidVolumes "Package containing finte volume models of solids"
+extends Modelica.Icons.VariantsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains finite volume models of solids.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end SolidVolumes;
diff --git a/SorpLib/Basics/Volumes/SolidVolumes/package.order b/SorpLib/Basics/Volumes/SolidVolumes/package.order
new file mode 100644
index 0000000..8641ba6
--- /dev/null
+++ b/SorpLib/Basics/Volumes/SolidVolumes/package.order
@@ -0,0 +1,2 @@
+SolidVolume
+Tester
diff --git a/SorpLib/Basics/Volumes/Utilities/mapSorptionFluidPorts.mo b/SorpLib/Basics/Volumes/Utilities/mapSorptionFluidPorts.mo
new file mode 100644
index 0000000..1bb61a2
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Utilities/mapSorptionFluidPorts.mo
@@ -0,0 +1,75 @@
+within SorpLib.Basics.Volumes.Utilities;
+function mapSorptionFluidPorts
+  "Maps sorption fluid ports to the component array of a mixture fluid"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Integer no_components
+    "Number of components"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Integer[:] ind_adsorptivs
+    "Indeces of adsorptivs in the ideal gas mixture"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Integer[no_components] mappedFluidPorts
+    "Mapped fluid ports"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Integer fp_ind = 1
+    "Actual index of fluid port";
+
+algorithm
+  //
+  // Loop through components and check if they are adsorptives
+  //
+  mappedFluidPorts := zeros(no_components)
+    "Mapped fluid ports";
+
+  for ind_comp in 1:no_components loop
+    for ind_ads in ind_adsorptivs loop
+      if ind_comp == ind_ads then
+        mappedFluidPorts[ind_comp] :=fp_ind
+          "Map sorption fluid port index";
+        fp_ind :=fp_ind + 1
+          "Actual index of fluid port";
+        break;
+
+      end if;
+    end for;
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function maps the indices of sorption fluid ports to a component array of a
+mixture fluid in the following way:
+</p>
+<ul>
+  <li>
+  0 if current component of the component array cannot be adsorbed/desorbed.
+  </li>
+  <li>
+  Index of sorption fluid port if current component of the component array can be 
+  adsorbed/desorbed.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 11, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end mapSorptionFluidPorts;
diff --git a/SorpLib/Basics/Volumes/Utilities/package.mo b/SorpLib/Basics/Volumes/Utilities/package.mo
new file mode 100644
index 0000000..29af562
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Utilities/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Basics.Volumes;
+package Utilities "Package containing utility functions and models for modelling finite volumes"
+  extends Modelica.Icons.UtilitiesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains utility functions and models required to model finite volumes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Utilities;
diff --git a/SorpLib/Basics/Volumes/Utilities/package.order b/SorpLib/Basics/Volumes/Utilities/package.order
new file mode 100644
index 0000000..4cf6a39
--- /dev/null
+++ b/SorpLib/Basics/Volumes/Utilities/package.order
@@ -0,0 +1 @@
+mapSorptionFluidPorts
diff --git a/SorpLib/Basics/Volumes/package.mo b/SorpLib/Basics/Volumes/package.mo
new file mode 100644
index 0000000..e0ce69e
--- /dev/null
+++ b/SorpLib/Basics/Volumes/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Basics;
+package Volumes "Finite volumes used to aggregate complex models"
+extends SorpLib.Icons.VolumesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package provides finite volume models of solids, fluids, phase separators,
+and adsorbates. These models calculate thermodynamic properties as homogenous 
+properties within the volume. Thus, these models serve as the basis for aggregating 
+complex  models discretized in several spatial directions via an upwind finite 
+volume approach.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Volumes;
diff --git a/SorpLib/Basics/Volumes/package.order b/SorpLib/Basics/Volumes/package.order
new file mode 100644
index 0000000..86020b4
--- /dev/null
+++ b/SorpLib/Basics/Volumes/package.order
@@ -0,0 +1,7 @@
+BaseClasses
+Records
+AdsorbateVolumes
+FluidVolumes
+PhaseSeparatorVolumes
+SolidVolumes
+Utilities
diff --git a/SorpLib/Basics/package.mo b/SorpLib/Basics/package.mo
new file mode 100644
index 0000000..a8a5f9c
--- /dev/null
+++ b/SorpLib/Basics/package.mo
@@ -0,0 +1,34 @@
+within SorpLib;
+package Basics "Library containing basic modeles used to aggregate advanced models"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains basic models required to aggregate advanced models:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Basics.Interfaces\">Interfaces</a>: 
+  Thermal and fluid connectors that serve as interfaces between models.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Basics.Sources\">Sources</a>: 
+  Thermal and fluid sources that define potential, flow, and stream variables
+  at connectors.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Basics.Volumes\">Volumes</a>: 
+  Finite volume models with (transient) mass and energy balances. These finite
+  volume models cover adsorbates, fluids, solids, and phase separators and can
+  be used to create spatial distributed models.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Basics;
diff --git a/SorpLib/Basics/package.order b/SorpLib/Basics/package.order
new file mode 100644
index 0000000..68a915b
--- /dev/null
+++ b/SorpLib/Basics/package.order
@@ -0,0 +1,3 @@
+Interfaces
+Sources
+Volumes
diff --git a/SorpLib/Choices/BalanceEquations.mo b/SorpLib/Choices/BalanceEquations.mo
new file mode 100644
index 0000000..25eff0c
--- /dev/null
+++ b/SorpLib/Choices/BalanceEquations.mo
@@ -0,0 +1,11 @@
+within SorpLib.Choices;
+type BalanceEquations = enumeration(
+    TransientFreeInitial
+      "Transient balance equation - free initial state values",
+    TransientFixedInitial
+      "Transient balance equation - fixed initial state values",
+    TransientSteadyStateInitial
+      "Transient balance equation - steady-state initial state values",
+    SteadyStateFreeInitial
+       "Steady-state balance equation - free initial state values")
+  "Enumeration defining balance equations";
diff --git a/SorpLib/Choices/BoundaryFluidPotentialFlow.mo b/SorpLib/Choices/BoundaryFluidPotentialFlow.mo
new file mode 100644
index 0000000..bd5129c
--- /dev/null
+++ b/SorpLib/Choices/BoundaryFluidPotentialFlow.mo
@@ -0,0 +1,6 @@
+within SorpLib.Choices;
+type BoundaryFluidPotentialFlow = enumeration(
+    Pressure "Prescribed pressure at fluid boundary",
+    MassFlowRate "Prescribed mass flow rate at fluid boundary",
+    VolumeFlowRate "Prescribed volume flow rate at fluid boundary")
+  "Enumeration defining prescribed potential or flow variable of a fluid boundary";
diff --git a/SorpLib/Choices/BoundaryFluidStreamEnthalpy.mo b/SorpLib/Choices/BoundaryFluidStreamEnthalpy.mo
new file mode 100644
index 0000000..8b02456
--- /dev/null
+++ b/SorpLib/Choices/BoundaryFluidStreamEnthalpy.mo
@@ -0,0 +1,5 @@
+within SorpLib.Choices;
+type BoundaryFluidStreamEnthalpy = enumeration(
+    SpecificEnthalpy "Prescribed specific enthalpy at fluid boundary",
+    Temperature "Prescribed temperature at fluid boundary")
+  "Enumeration defining prescribed stream variable (specific enthalpy) of a fluid boundary";
diff --git a/SorpLib/Choices/BoundaryFluidStreamMassFractions.mo b/SorpLib/Choices/BoundaryFluidStreamMassFractions.mo
new file mode 100644
index 0000000..ea4091a
--- /dev/null
+++ b/SorpLib/Choices/BoundaryFluidStreamMassFractions.mo
@@ -0,0 +1,5 @@
+within SorpLib.Choices;
+type BoundaryFluidStreamMassFractions = enumeration(
+    MassFractions "Prescribed mass fractions",
+    DryMassFractionsPhi "Prescribed mass fractions of dry air components and relative humidity")
+  "Enumeration defining prescribed stream variable (mass fractions) of a fluid boundary";
diff --git a/SorpLib/Choices/BoundaryThermal.mo b/SorpLib/Choices/BoundaryThermal.mo
new file mode 100644
index 0000000..4a2cf6e
--- /dev/null
+++ b/SorpLib/Choices/BoundaryThermal.mo
@@ -0,0 +1,5 @@
+within SorpLib.Choices;
+type BoundaryThermal = enumeration(
+    Temperature "Prescribed temperature at thermal boundary",
+    HeatFlowRate "Prescribed heat flow rate at thermal boundary")
+  "Enumeration defining prescribed variable of a thermal boundary";
diff --git a/SorpLib/Choices/ChangingConstantVariableOfDiagram.mo b/SorpLib/Choices/ChangingConstantVariableOfDiagram.mo
new file mode 100644
index 0000000..d95be46
--- /dev/null
+++ b/SorpLib/Choices/ChangingConstantVariableOfDiagram.mo
@@ -0,0 +1,6 @@
+within SorpLib.Choices;
+type ChangingConstantVariableOfDiagram = enumeration(
+    Manual "Manual input",
+    Linespace "Linearly distributed values",
+    Logspace "Logarithmicaly distributed values")
+  "Enumeration defining the changing type (i.e., manuel, linespace, logspace) of the constant variable of a fluid property diagram";
diff --git a/SorpLib/Choices/DiagramTypePureComponentWorkingPair.mo b/SorpLib/Choices/DiagramTypePureComponentWorkingPair.mo
new file mode 100644
index 0000000..11b513c
--- /dev/null
+++ b/SorpLib/Choices/DiagramTypePureComponentWorkingPair.mo
@@ -0,0 +1,6 @@
+within SorpLib.Choices;
+type DiagramTypePureComponentWorkingPair = enumeration(
+    Isotherms "Isotherms: T = const, p = variable",
+    Isosters "Isosters: x = const, T = variable",
+    Isobars "Isobars: p = const, T = variable")
+  "Enumeration defining the diagram type (i.e., isotherms, isosters, or isobars) of a pure component working pair";
diff --git a/SorpLib/Choices/GeneralizedFunctionApproach.mo b/SorpLib/Choices/GeneralizedFunctionApproach.mo
new file mode 100644
index 0000000..fc66d17
--- /dev/null
+++ b/SorpLib/Choices/GeneralizedFunctionApproach.mo
@@ -0,0 +1,7 @@
+within SorpLib.Choices;
+type GeneralizedFunctionApproach = enumeration(
+    PolynomialFunctionTemperature "Polynomial function using temperature",
+    PolynomialFunctionReducedTemperature "Polynomial function using reduced temperature",
+    ExponentialFunctionTemperature "Exponential function using temperature",
+    ExponentialFunctionReducedTemperature "Exponential function using reduced temperature")
+  "Enumeration defining the approach used within the generalized function for calculating fluid property data";
diff --git a/SorpLib/Choices/IASTAlgorithm.mo b/SorpLib/Choices/IASTAlgorithm.mo
new file mode 100644
index 0000000..7cfd191
--- /dev/null
+++ b/SorpLib/Choices/IASTAlgorithm.mo
@@ -0,0 +1,6 @@
+within SorpLib.Choices;
+type IASTAlgorithm = enumeration(
+    NewtonRaphson "Standard 'Newton-Raphson' algorithm",
+    NestedLoop "'Nested loop' algorithm",
+    FastIAST "'Fast IAST' algorithm")
+  "Enumeration defining the algorithm solving the IAST (i.e., x_i = f(p,y,T))";
diff --git a/SorpLib/Choices/IndependentVariablesMultiComponentWorkingPair.mo b/SorpLib/Choices/IndependentVariablesMultiComponentWorkingPair.mo
new file mode 100644
index 0000000..fcff072
--- /dev/null
+++ b/SorpLib/Choices/IndependentVariablesMultiComponentWorkingPair.mo
@@ -0,0 +1,5 @@
+within SorpLib.Choices;
+type IndependentVariablesMultiComponentWorkingPair = enumeration(
+    pyT "Pressure, independent mole fractions of gas/vapor phase, and temperature",
+    xT "Uptakes and temperature")
+  "Enumeration defining the independent variables of a multi-component working pair";
diff --git a/SorpLib/Choices/IndependentVariablesPureComponentWorkingPair.mo b/SorpLib/Choices/IndependentVariablesPureComponentWorkingPair.mo
new file mode 100644
index 0000000..482f2f3
--- /dev/null
+++ b/SorpLib/Choices/IndependentVariablesPureComponentWorkingPair.mo
@@ -0,0 +1,5 @@
+within SorpLib.Choices;
+type IndependentVariablesPureComponentWorkingPair = enumeration(
+    pT "Pressure and temperature",
+    xT "Uptake and temperature")
+  "Enumeration defining the independent variables of a pure component working pair";
diff --git a/SorpLib/Choices/IndependentVariablesVolume.mo b/SorpLib/Choices/IndependentVariablesVolume.mo
new file mode 100644
index 0000000..7a50814
--- /dev/null
+++ b/SorpLib/Choices/IndependentVariablesVolume.mo
@@ -0,0 +1,5 @@
+within SorpLib.Choices;
+type IndependentVariablesVolume = enumeration(
+    pTX "Pressure, temperature, and independent mass fractions",
+    phX "Pressure, specific enthalpy, and independent mass fractions")
+  "Enumeration defining the independent variables of a finite volume";
diff --git a/SorpLib/Choices/InterpolationApproach.mo b/SorpLib/Choices/InterpolationApproach.mo
new file mode 100644
index 0000000..5e0d83d
--- /dev/null
+++ b/SorpLib/Choices/InterpolationApproach.mo
@@ -0,0 +1,5 @@
+within SorpLib.Choices;
+type InterpolationApproach = enumeration(
+    Linear "Linear interpolation without extrapolation",
+    CubicSplines "Cubic spline interpolation without extrapolation")
+  "Enumeration defining the interpolation approach for calculations";
diff --git a/SorpLib/Choices/IsobaricExpansionCoefficientAdsorpt.mo b/SorpLib/Choices/IsobaricExpansionCoefficientAdsorpt.mo
new file mode 100644
index 0000000..e40ee39
--- /dev/null
+++ b/SorpLib/Choices/IsobaricExpansionCoefficientAdsorpt.mo
@@ -0,0 +1,7 @@
+within SorpLib.Choices;
+type IsobaricExpansionCoefficientAdsorpt = enumeration(
+    Constant "Constant value",
+    BoilingCurve "Boiling point curve as function of temperature",
+    GeneralizedFunction "Generalized function often used for fluid property data calculation",
+    Interpolation "Table-based interpolation as function of temperature")
+  "Enumeration defining the calculation approach for the isobaric expansion coefficient of the adsorpt phase";
diff --git a/SorpLib/Choices/MassFlowRateHeatTranferCorrelation.mo b/SorpLib/Choices/MassFlowRateHeatTranferCorrelation.mo
new file mode 100644
index 0000000..054bdbd
--- /dev/null
+++ b/SorpLib/Choices/MassFlowRateHeatTranferCorrelation.mo
@@ -0,0 +1,10 @@
+within SorpLib.Choices;
+type MassFlowRateHeatTranferCorrelation = enumeration(
+    PortXMinus
+      "Mass flow rate at design inlet",
+    PortXPlus
+      "Mass flow rate at design outlet",
+    Average
+      "Average absolute mass flow rate")
+  "Enumeration defining the mass flow rate used for calculating generic heat transfer 
+  correlations";
diff --git a/SorpLib/Choices/MassTransferFluidProperties.mo b/SorpLib/Choices/MassTransferFluidProperties.mo
new file mode 100644
index 0000000..cb7a9a1
--- /dev/null
+++ b/SorpLib/Choices/MassTransferFluidProperties.mo
@@ -0,0 +1,11 @@
+within SorpLib.Choices;
+type MassTransferFluidProperties = enumeration(
+    PortAInlet
+      "Instreaming fluid properties ar port a",
+    PortBInlet
+      "Instreaming fluid properties ar port b",
+    ActualInlet
+      "Fluid properties at actual inlet",
+    AverageInstreaming
+      "Average fluid properties using instreaming fluid properties")
+  "Enumeration defining fluid property calculation for mass transfers";
diff --git a/SorpLib/Choices/PrescripedFanVariable.mo b/SorpLib/Choices/PrescripedFanVariable.mo
new file mode 100644
index 0000000..c30a30b
--- /dev/null
+++ b/SorpLib/Choices/PrescripedFanVariable.mo
@@ -0,0 +1,7 @@
+within SorpLib.Choices;
+type PrescripedFanVariable = enumeration(
+    m_flow
+      "Mass flow rate",
+    V_flow
+      "Volume flow rate")
+  "Enumeration defining the variable that is prescribed by a fan";
diff --git a/SorpLib/Choices/PrescripedPumpVariable.mo b/SorpLib/Choices/PrescripedPumpVariable.mo
new file mode 100644
index 0000000..9368d18
--- /dev/null
+++ b/SorpLib/Choices/PrescripedPumpVariable.mo
@@ -0,0 +1,7 @@
+within SorpLib.Choices;
+type PrescripedPumpVariable = enumeration(
+    m_flow
+      "Mass flow rate",
+    V_flow
+      "Volume flow rate")
+  "Enumeration defining the variable that is prescribed by a pump";
diff --git a/SorpLib/Choices/ResistorFluidProperties.mo b/SorpLib/Choices/ResistorFluidProperties.mo
new file mode 100644
index 0000000..d1f76ac
--- /dev/null
+++ b/SorpLib/Choices/ResistorFluidProperties.mo
@@ -0,0 +1,15 @@
+within SorpLib.Choices;
+type ResistorFluidProperties = enumeration(
+    Constant
+      "Constant fluid properties",
+    PortAInlet
+      "Instreaming fluid properties ar port a",
+    PortBInlet
+      "Instreaming fluid properties ar port b",
+    ActualInlet
+      "Fluid properties at actual inlet",
+    AverageInstreaming
+      "Average fluid properties using instreaming fluid properties",
+    Detailed
+      "Correct fluid properties, also depending on the flow direction")
+  "Enumeration defining fluid property calculation for hydraulic resistors";
diff --git a/SorpLib/Choices/SorptionEnthalpy.mo b/SorpLib/Choices/SorptionEnthalpy.mo
new file mode 100644
index 0000000..d94cbf6
--- /dev/null
+++ b/SorpLib/Choices/SorptionEnthalpy.mo
@@ -0,0 +1,7 @@
+within SorpLib.Choices;
+type SorptionEnthalpy = enumeration(
+    Constant "Constant sorption enthalpy",
+    Formal "Definition according to thermodynamic derivation",
+    ClausiusClapeyron "Definition according to Clausius Clapeyron assumptions",
+    Dubinin "Definition according to the model of Dubinin")
+  "Enumeration defining the calculation approach for the sorption enthalpy";
diff --git a/SorpLib/Choices/SpecificHeatCapacityAdsorpt.mo b/SorpLib/Choices/SpecificHeatCapacityAdsorpt.mo
new file mode 100644
index 0000000..56dd3ac
--- /dev/null
+++ b/SorpLib/Choices/SpecificHeatCapacityAdsorpt.mo
@@ -0,0 +1,10 @@
+within SorpLib.Choices;
+type SpecificHeatCapacityAdsorpt = enumeration(
+    Constant "Constant value",
+    BoilingCurve "Boiling point curve as function of temperature",
+    GeneralizedFunction "Generalized function often used for fluid property data calculation",
+    Interpolation "Table-based interpolation as function of temperature",
+    WaltonLeVan "Derivation according to Walton and LeVan (2005)",
+    ChakrabortyElAl "Derivation according to Chakraborty et al. (2009)",
+    SchwambergerSchmidt "Derivation according to Schwamberger and Schmidt (2013)")
+  "Enumeration defining the calculation approach for the specific heat capacity of the adsorpt phase";
diff --git a/SorpLib/Choices/SpecificHeatCapacitySolid.mo b/SorpLib/Choices/SpecificHeatCapacitySolid.mo
new file mode 100644
index 0000000..d6ac37c
--- /dev/null
+++ b/SorpLib/Choices/SpecificHeatCapacitySolid.mo
@@ -0,0 +1,6 @@
+within SorpLib.Choices;
+type SpecificHeatCapacitySolid = enumeration(
+    Constant "Constant value",
+    GeneralizedFunction "Generalized function often used for fluid property data calculation",
+    Interpolation "Table-based interpolation as function of temperature")
+  "Enumeration defining the calculation approach for the specific heat capacity of a solid";
diff --git a/SorpLib/Choices/SpecificVolumeAdsorpt.mo b/SorpLib/Choices/SpecificVolumeAdsorpt.mo
new file mode 100644
index 0000000..43e4061
--- /dev/null
+++ b/SorpLib/Choices/SpecificVolumeAdsorpt.mo
@@ -0,0 +1,7 @@
+within SorpLib.Choices;
+type SpecificVolumeAdsorpt = enumeration(
+    Constant "Constant value",
+    BoilingCurve "Boiling point curve as function of temperature",
+    GeneralizedFunction "Generalized function often used for fluid property data calculation",
+    Interpolation "Table-based interpolation as function of temperature")
+  "Enumeration defining the calculation approach for the specific volume of the adsorpt phase";
diff --git a/SorpLib/Choices/SpecificVolumeSolid.mo b/SorpLib/Choices/SpecificVolumeSolid.mo
new file mode 100644
index 0000000..9981a8e
--- /dev/null
+++ b/SorpLib/Choices/SpecificVolumeSolid.mo
@@ -0,0 +1,6 @@
+within SorpLib.Choices;
+type SpecificVolumeSolid = enumeration(
+    Constant "Constant value",
+    GeneralizedFunction "Generalized function often used for fluid property data calculation",
+    Interpolation "Table-based interpolation as function of temperature")
+  "Enumeration defining the calculation approach for the specific volume of a solid";
diff --git a/SorpLib/Choices/TemperatureHeatTranferCorrelation.mo b/SorpLib/Choices/TemperatureHeatTranferCorrelation.mo
new file mode 100644
index 0000000..5bea75f
--- /dev/null
+++ b/SorpLib/Choices/TemperatureHeatTranferCorrelation.mo
@@ -0,0 +1,12 @@
+within SorpLib.Choices;
+type TemperatureHeatTranferCorrelation = enumeration(
+    PortA
+      "Average temperature at port a",
+    PortB
+      "Average temperature at port b",
+    Average
+      "Average temperature of ports a and b",
+    Difference
+      "Average temperature difference between ports a and b")
+  "Enumeration defining the temperature used for calculating generic heat transfer 
+  correlations";
diff --git a/SorpLib/Choices/ThermalConductivitySolid.mo b/SorpLib/Choices/ThermalConductivitySolid.mo
new file mode 100644
index 0000000..a89591b
--- /dev/null
+++ b/SorpLib/Choices/ThermalConductivitySolid.mo
@@ -0,0 +1,6 @@
+within SorpLib.Choices;
+type ThermalConductivitySolid = enumeration(
+    Constant "Constant value",
+    GeneralizedFunction "Generalized function often used for fluid property data calculation",
+    Interpolation "Table-based interpolation as function of temperature")
+  "Enumeration defining the calculation approach for the thermal conductivity of a solid";
diff --git a/SorpLib/Choices/package.mo b/SorpLib/Choices/package.mo
new file mode 100644
index 0000000..0a8808f
--- /dev/null
+++ b/SorpLib/Choices/package.mo
@@ -0,0 +1,17 @@
+within SorpLib;
+package Choices "Library containing type definitions representing choices"
+extends Modelica.Icons.TypesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains definitions of types representing enumeration used within the Modelica library SorpLib.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Choices;
diff --git a/SorpLib/Choices/package.order b/SorpLib/Choices/package.order
new file mode 100644
index 0000000..f3e17b5
--- /dev/null
+++ b/SorpLib/Choices/package.order
@@ -0,0 +1,26 @@
+IASTAlgorithm
+GeneralizedFunctionApproach
+InterpolationApproach
+SpecificVolumeSolid
+SpecificHeatCapacitySolid
+ThermalConductivitySolid
+SorptionEnthalpy
+SpecificHeatCapacityAdsorpt
+SpecificVolumeAdsorpt
+IsobaricExpansionCoefficientAdsorpt
+IndependentVariablesVolume
+IndependentVariablesPureComponentWorkingPair
+IndependentVariablesMultiComponentWorkingPair
+ChangingConstantVariableOfDiagram
+DiagramTypePureComponentWorkingPair
+BoundaryThermal
+BoundaryFluidPotentialFlow
+BoundaryFluidStreamEnthalpy
+BoundaryFluidStreamMassFractions
+BalanceEquations
+ResistorFluidProperties
+PrescripedPumpVariable
+PrescripedFanVariable
+TemperatureHeatTranferCorrelation
+MassFlowRateHeatTranferCorrelation
+MassTransferFluidProperties
diff --git a/SorpLib/Components/AdsorberColumns/package.mo b/SorpLib/Components/AdsorberColumns/package.mo
new file mode 100644
index 0000000..fa000ea
--- /dev/null
+++ b/SorpLib/Components/AdsorberColumns/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components;
+package AdsorberColumns "Adsorbers columns used in open sorption systems"
+  extends SorpLib.Icons.AdsorberColumnsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED!
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end AdsorberColumns;
diff --git a/SorpLib/Components/AdsorberColumns/package.order b/SorpLib/Components/AdsorberColumns/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Components/Cells/Adsorbent/Adsorbent.mo b/SorpLib/Components/Cells/Adsorbent/Adsorbent.mo
deleted file mode 100644
index 9dbfadf..0000000
--- a/SorpLib/Components/Cells/Adsorbent/Adsorbent.mo
+++ /dev/null
@@ -1,213 +0,0 @@
-within SorpLib.Components.Cells.Adsorbent;
-model Adsorbent
-
-  /*********************** SIM ***********************************/
-  parameter TILMedia.VLEFluidTypes.BaseVLEFluid vleFluidType=sim.vleFluidType1
-    "VLE fluid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.vleFluidType1 "VLE fluid 1 as defined in SIM",
-      choice=sim.vleFluidType2 "VLE fluid 2 as defined in SIM",
-      choice=sim.vleFluidType3 "VLE fluid 3 as defined in SIM"));
-protected
-  outer TIL.SystemInformationManager sim "System information manager";
-
-  TIL.Internals.SimPort simPort;
-
-  /********************* Connectors *************************************/
-public
-  TIL.Connectors.VLEFluidPort vlePortA(final vleFluidType=vleFluidType, final
-      h_limit=-1e6) annotation (Placement(transformation(extent={{-82,-10},{-62,
-            10}}, rotation=0), iconTransformation(extent={{-82,-10},{-62,10}})));
-  TIL.Connectors.VLEFluidPort vlePortB(final vleFluidType=vleFluidType, final
-      h_limit=-1e6) annotation (Placement(transformation(extent={{62,-10},{82,
-            10}},
-          rotation=0), iconTransformation(extent={{62,-10},{82,10}})));
-  TIL.Connectors.HeatPort heatPortA annotation (Placement(transformation(extent={{-10,-70},
-            {10,-50}},         rotation=0), iconTransformation(extent={{-10,-70},
-            {10,-50}})));
-  TIL.Connectors.HeatPort heatPortB annotation (Placement(transformation(extent=
-           {{-10,50},{10,70}}), iconTransformation(extent={{-10,50},{10,70}})));
-
-  /********************* AdsorbentAdsorbate ****************************************/
-
-  replaceable model AdsorbentAdsorbateModel =
-      SorpLib.Media.AdsorbentAdsorbate.Zeolite13XWaterNunez
-    constrainedby
-    SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater
-    "Adsorbent / Adsorbate model" annotation (choicesAllMatching=true, Dialog(
-        group="Adsorbent / Adsorbate"));
-
-  AdsorbentAdsorbateModel adsorbentAdsorbate(final x=x, final T=T) "Sorbent"
-    annotation (Placement(transformation(extent={{-10,20},{10,40}})));
-
-  Real x(unit="kg/kg") "Loading of adsorbent";
-  Modelica.SIunits.Temperature T "Temperature of adsorbent/adsorbate";
-  Modelica.SIunits.Pressure p "Equilibrium pressure of adsorbate";
-
-  /********************* VLE Fluid ************************************/
-
-  Modelica.SIunits.Mass massVLEFluid;
-
-  TILMedia.VLEFluid_dT adsorbate(
-    final vleFluidType=vleFluidType,
-    d=adsorbate.VLE.d_v,
-    T=adsorbentAdsorbate.T)
-    annotation (Placement(transformation(extent={{-10,-34},{10,-14}})));
-
-  /********************* Parameters ************************************/
-  parameter Modelica.SIunits.Mass massAdsorbent "Mass of dry adsorbent"
-    annotation (Dialog(group="Parameters"));
-
-  /********************* Initialization ********************************/
-  parameter Modelica.SIunits.Temperature TInitial(start=298.15)
-    annotation (Dialog(group="Initial Values", tab="Start and Initialization"));
-  parameter Real xInitial(unit="kg/kg",start=0.2) annotation (Dialog(
-      enable=initial_x,
-      group="Initial Values",
-      tab="Start and Initialization"));
-  parameter Modelica.SIunits.Pressure pInitial=100 annotation (Dialog(
-      enable=not initial_x,
-      group="Initial Values",
-      tab="Start and Initialization"));
-  parameter Boolean initial_x=true "if true then xInital else pInitial"
-    annotation (Dialog(group="Initial Values", tab="Start and Initialization"),
-      choices(choice=true "Use loading (x) as initilization parameter", choice=false
-        "Use pressure (p) as initilization parameter"));
-
-  /*******************Summary**********************/
-public
-  inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-
-  parameter Boolean generateEventsAtFlowReversal=false "If true, tranport propertie are calculated in the gas object" annotation(Evaluate=true, Dialog(tab="Advanced", group="Event-Handling"));
-
-
-protected
-  record Summary
-    extends TIL.Internals.ClassTypes.Record;
-
-    Modelica.SIunits.MassFlowRate m_flow_A if include;
-    Modelica.SIunits.MassFlowRate m_flow_B if include;
-    Modelica.SIunits.Pressure p_A if include;
-    Modelica.SIunits.Pressure p_B if include;
-    Modelica.SIunits.SpecificEnthalpy h_A_outflow if include;
-    Modelica.SIunits.SpecificEnthalpy h_B_outflow if include;
-    Modelica.SIunits.Pressure p if include;
-    Real x if include;
-    Modelica.SIunits.Temperature T if include;
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-
-  end Summary;
-
-  replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    m_flow_A=vlePortA.m_flow,
-    m_flow_B=vlePortB.m_flow,
-    p_A=vlePortA.p,
-    p_B=vlePortB.p,
-    h_A_outflow=vlePortA.h_outflow,
-    h_B_outflow=vlePortB.h_outflow,
-    p=adsorbentAdsorbate.p,
-    x=x,
-    T=T) annotation (Placement(transformation(extent={{66,-88},{86,-68}},
-          rotation=0)));
-
-initial equation
-  T = TInitial;
-
-  if initial_x then
-    x = xInitial;
-  else
-    p = pInitial;
-  end if;
-
-equation
-  assert(vleFluidType.concatVLEFluidName == adsorbentAdsorbate.vleFluidType.concatVLEFluidName,
-    "VLE Fluid in SIM doesn't match adsorbate.");
-
-  // simport setup
-  connect(sim.fluidPort[vleFluidType.ID], simPort.vleFluidPort);
-  simPort.vleFluidMass = massVLEFluid;
-  simPort.vleFluidVolume =massVLEFluid/adsorbate.VLE.d_l;
-
-  adsorbentAdsorbate.p = p;
-
-  // Momentum balance
-
-  vlePortA.p = p;
-  vlePortB.p = p;
-
-  // Mass balance
-  massAdsorbent*der(x) = vlePortA.m_flow + vlePortB.m_flow;
-  massVLEFluid = x*massAdsorbent;
-
-  // Energy balance
-  if (generateEventsAtFlowReversal) then
-     massAdsorbent*adsorbentAdsorbate.dudT_x*der(T) =
-      vlePortA.m_flow*actualStream(vlePortA.h_outflow) -
-      vlePortA.m_flow*adsorbentAdsorbate.u_ads +
-      vlePortB.m_flow*actualStream(vlePortB.h_outflow) -
-      vlePortB.m_flow*adsorbentAdsorbate.u_ads +
-      heatPortA.Q_flow + heatPortB.Q_flow;
-  else
-    massAdsorbent*adsorbentAdsorbate.dudT_x*der(T) =
-      vlePortA.m_flow*noEvent(actualStream(vlePortA.h_outflow)) -
-      vlePortA.m_flow*adsorbentAdsorbate.u_ads +
-      vlePortB.m_flow*noEvent(actualStream(vlePortB.h_outflow)) -
-      vlePortB.m_flow*adsorbentAdsorbate.u_ads +
-      heatPortA.Q_flow + heatPortB.Q_flow;
-  end if;
-
-  // Fluid ports
-  vlePortA.h_outflow =adsorbate.h;
-  vlePortB.h_outflow =adsorbate.h;
-
-  heatPortA.T = T;
-  heatPortB.T = T;
-
-  annotation (
-    Icon(graphics={Bitmap(
-          extent={{-100,100},{100,-100}},
-          imageSource="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",
-          fileName="modelica://SorpLib/Resources/Images/Adsorbent.png")}),
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100,
-            100}})),
-    Documentation(info="<html>
-<p>This model is a cell model combining adsorbent and adsorbate. This cell model consists of an energy and a mass balance, combined with equilibrium data for the adsorbent/adsorbate working pair (<a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan\">SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater</a>). </p>
-<p>For a cell, a lumped model approach is used with equal temperature of adsorbent/adsorbate. By combining more cells with a finite volume approach, a distributed adsorbent model can be built, with a spatial loading and temperature distribution. To create a full adsorber, this adsorbent cell model can be connected to some kind of heat exchanger model. </p>
-<p><b>Main equations</b> </p>
-<p>The main equations are an energy and a mass balance.</p>
-<p>Mass balance: </p>
-<p align=\"center\"><i>dx/dt</i> = 1 / <i>m</i><sub>sor</sub> * (<i><code>&#7745;</code></i><sub>ad,in</sub> - <i><code>&#7745;</code></i><sub>ad,out</sub>) </p>
-<p>where <i>x</i> is the loading of the adsorbent defined as <i>x = m</i><sub>ad</sub> / <i>m</i><sub>sor</sub>. <i>m</i><sub>sor</sub> is the mass of dry adsorbent and <i>m</i><sub>ad</sub> is the mass of adsorbate. </p>
-<p>Energy balance: </p>
-<p align=\"center\">(<i>c</i><sub>sor</sub> + <i>x</i> <i>c</i><sub>ad</sub>) <i>dT/dt</i> + <i>u</i><sub>ad</sub> <i>dx/dt</i> = 1 / <i>m</i><sub>sor</sub> * (<i><code>&#7745;</code></i><sub>ad,in</sub> * <i>h</i><sub>in</sub> - <i><code>&#7745;</code></i><sub>ad,out</sub> * <i>h</i><sub>out</sub> + <code>&sum;</code> <i>Q</i> ) </p>
-<p>where <i>c</i> is the specific heat capacity, <i>u</i><sub>ad</sub> is the specific internal energy of the adsorbate at the current loading and temperature, <i>h</i> is the specific enthalpy of the incoming and outflowing adsorbate stream, and <i>Q</i> is the heat flow.</p>
-<p>The specific enthalpy of the incoming adsorbate stream is determined by the component, where the adsorbate is coming from (normally the evaporator). The specific enthalpy of the outflowing stream is set the saturation enthalpy of adsorbate in vapour state. </p>
-<p><b>Assumptions and limitations</b> </p>
-<p>The model uses the following main assumptions: </p>
-<ul>
-<li>All adsorbate is in adsorbed state. </li>
-<li>Adsorbent and adsorbate have the same temperature. </li>
-<li>Enthalpy of outflowing stream is set the saturation enthalpy of adsorbate in vapour state</li>
-<li>Note: the pressure at the VLE ports is set to the equilibrium pressure of the equilibrium model. --&GT; A mass transfer model has to be connected to the adsorbent model. </li>
-</ul>
-<p><b>Typical use and important parameters</b> </p>
-<p>The adsorbent cell model is at the heart of all adsorption models: closed adsorber (adsorption heat pumps and chiller) and open adsorber (desiccant). </p>
-<p><b>Dynamics</b> </p>
-<p>The adsorbent model has two differential states: the loading <i>x</i> and the temperature <i>T</i>. </p>
-<p><b>References</b> </p>
-<ul>
-<li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257. </li>
-</ul>
-<p><b>Author Information</b> </p>
-<ul>
-<li>November 18, 2017, by Uwe Bau:<br>Tidy up implementation and enhance documentation for publication of library.<br></li>
-</ul>
-</html>"));
-end Adsorbent;
diff --git a/SorpLib/Components/Cells/Adsorbent/Testers/TestAdsorbent.mo b/SorpLib/Components/Cells/Adsorbent/Testers/TestAdsorbent.mo
deleted file mode 100644
index 54c4b2a..0000000
--- a/SorpLib/Components/Cells/Adsorbent/Testers/TestAdsorbent.mo
+++ /dev/null
@@ -1,125 +0,0 @@
-within SorpLib.Components.Cells.Adsorbent.Testers;
-model TestAdsorbent
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(use_massFlowRateInput=
-       true) annotation (Placement(transformation(extent={{-34,-10},{-26,10}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    hFixed=2538000,
-    pFixed(displayUnit="kPa") = 0,
-    m_flowFixed=0,
-    boundaryType="m_flow") annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=180,
-        origin={32,0})));
-  Adsorbent adsorbent(
-    vleFluidType=sim.vleFluidType1,
-    redeclare model AdsorbentAdsorbateModel =
-        Media.AdsorbentAdsorbate.AQSOAZ02WaterGoldsworthy,
-    massAdsorbent=5,
-    xInitial=0.25,
-    initial_x=true,
-    pInitial(displayUnit="kPa") = 100,
-    TInitial=298.15)
-    annotation (Placement(transformation(extent={{-11,-12},{11,12}})));
-
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary_Losses1(
-    Q_flowFixed=0,
-    boundaryType="T",
-    TFixed=453.15) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={0,42})));
-
-  Modelica.Blocks.Sources.Step stepVLEBoundary1(
-    height=-0.003,
-    offset=0.003,
-    startTime=200)
-    annotation (Placement(transformation(extent={{-55,-3},{-45,7}})));
-  HeatTransfer.HeatTransfer heatTransfer(redeclare model HeatTransfer =
-        HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (constantAlphaA=100),
-      n=1) annotation (Placement(transformation(
-        extent={{-8,-4},{8,4}},
-        rotation=90,
-        origin={0,26})));
-equation
-  connect(adsorbent.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{7.92,0},{7.92,0},{32,0}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vleBoundary1.port, adsorbent.vlePortA) annotation (Line(
-      points={{-30,0},{-30,0},{-7.92,0}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vleBoundary1.m_flow_in, stepVLEBoundary1.y)
-    annotation (Line(points={{-34,2},{-44.5,2}}, color={0,0,127}));
-  connect(heatBoundary_Losses1.heatPort, heatTransfer.heatPortB[1]) annotation (
-     Line(
-      points={{0,42},{0,38},{0,34}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer.heatPortA, adsorbent.heatPortB) annotation (Line(
-      points={{0,18},{0,7.2}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
-            100,100}})),
-    experiment(StopTime=1000),
-    __Dymola_experimentSetupOutput,
-    Documentation(info="<html>
-  <p>
-    This model is a cell model combining adsorbent and adsorbate. This cell model consists of an energy and a mass balance, combined with equilibrium data for the adsorbent/adsorbate working pair 
-    (<a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan\">SorpLib.Media.SorbentWater.Partial.PartialSorbentWater</a>). <br>
-    For a cell, a lumped model approach is used with equal temperature of adsorbent/adsorbate.
-    By combining more cells with a finite volume approach, a distributed adsorbent model can be built, with a spatial loading and temperature distribution. 
-    To create a full adsorber, this adsorbent cell model can be connected to some kind of heat exchanger model.
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    The main equations are an energy and a mass balance.<br>
-    Mass balance:
-    <p align=\"center\">
-      <i><code>x&#775;</code></i> = 1 / <i>m</i><sub>sor</sub> * (<i><code>m&#775;</code></i><sub>ad,in</sub> - <i><code>m&#775;</code></i><sub>ad,out</sub>)
-    </p>
-    where <i>x</i> is the loading of the adsorbent defined as <i>x = m</i><sub>ad</sub> / <i>m</i><sub>sor</sub>. <i>m</i><sub>sor</sub> is the mass of dry adsorbent and <i>m</i><sub>ad</sub> is the mass of adsorbate. <br>
-    Energy balance:
-    <p align=\"center\">
-      (<i>c</i><sub>sor</sub> + <i>x</i> <i>c</i><sub>ad</sub>) <i><code>T&#775;</code></i> + <i>u</i><sub>ad</sub> <i><code>x&#775;</code></i> = 
-      1 / <i>m</i><sub>sor</sub> * (<i><code>m&#775;</code></i><sub>ad,in</sub> * <i>h</i><sub>in</sub> - <i><code>m&#775;</code></i><sub>ad,out</sub> * <i>h</i><sub>out</sub> + <code>&sum;</code> <i>Q</i> )
-    </p>
-    where <i>c</i> is the specific heat capacity, <i>u</i><sub>ad</sub> is the specific internal energy of the adsorbate at the current loading and temperature, 
-    <i>h</i> is the specific enthalpy of the incoming and outflowing adsorbate strem, and <i>Q</i> is the heat flow. <br>
-    The specific enthalpy of the incoming adsorbate stream is determined by the component, where the adsorbate is coming from (normally the evaporator).
-    The specific enthalpy of the outflowing enthalpy is set the saturation enthalpy of adsorbate in vapour state.
-  </p>
-  <h4>Assumptions and limitations</h4>
-  <p>
-    The model uses the following main assumptions:
-    <ul>
-      <li>All adsorbate is in adsorbed state.</li>
-      <li>Adsorbent and adsorbate have the same temperature.</li>
-      <li>Note: the pressure at the VLE ports is set to the equilibrium pressure of the equilibrium model. --> A mass transfer model has to be connected to the adsorbent model.
-    </ul>
-  </p>
-  <h4>Typical use and important parameters</h4>
-  <p>
-    The adsorbent cell model is at the heart of all adsorption models: closed adsorber (adsorption heat pumps and chiller) and open adsorber (desiccant).
-  </p>
-  <h4>Dynamics</h4>
-  <p>
-    The adsorbent model has two differential states: the loading <i>x</i> and the temperature <T>.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>
-        November 18, 2017, by Uwe Bau:<br>
-        Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end TestAdsorbent;
diff --git a/SorpLib/Components/Cells/Adsorbent/Testers/package.mo b/SorpLib/Components/Cells/Adsorbent/Testers/package.mo
deleted file mode 100644
index 33178e9..0000000
--- a/SorpLib/Components/Cells/Adsorbent/Testers/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.Cells.Adsorbent;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-end Testers;
diff --git a/SorpLib/Components/Cells/Adsorbent/Testers/package.order b/SorpLib/Components/Cells/Adsorbent/Testers/package.order
deleted file mode 100644
index 7b23783..0000000
--- a/SorpLib/Components/Cells/Adsorbent/Testers/package.order
+++ /dev/null
@@ -1 +0,0 @@
-TestAdsorbent
diff --git a/SorpLib/Components/Cells/Adsorbent/package.mo b/SorpLib/Components/Cells/Adsorbent/package.mo
deleted file mode 100644
index 6223a36..0000000
--- a/SorpLib/Components/Cells/Adsorbent/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.Cells;
-package Adsorbent
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-end Adsorbent;
diff --git a/SorpLib/Components/Cells/Adsorbent/package.order b/SorpLib/Components/Cells/Adsorbent/package.order
deleted file mode 100644
index 4a6fffe..0000000
--- a/SorpLib/Components/Cells/Adsorbent/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-Adsorbent
-Testers
diff --git a/SorpLib/Components/Cells/Gas/Gas.mo b/SorpLib/Components/Cells/Gas/Gas.mo
deleted file mode 100644
index a114a31..0000000
--- a/SorpLib/Components/Cells/Gas/Gas.mo
+++ /dev/null
@@ -1,343 +0,0 @@
-within SorpLib.Components.Cells.Gas;
-model Gas
-
-  /*********************** SIM ***********************************/
-
-  inner parameter TILMedia.GasTypes.BaseGas gasType=sim.gasType1 "Gas type"
-    annotation (Dialog(tab="SIM", group="SIM"), choices(choice=sim.gasType1
-        "Gas 1 as defined in SIM", choice=sim.gasType2
-        "Gas 2 as defined in SIM", choice=sim.gasType3
-        "Gas 3 as defined in SIM"));
-  parameter TILMedia.VLEFluidTypes.BaseVLEFluid vleFluidType=sim.vleFluidType1
-    "VLE fluid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.vleFluidType1 "VLE Fluid 1 as defined in SIM",
-      choice=sim.vleFluidType2 "VLE Fluid 2 as defined in SIM",
-      choice=sim.vleFluidType3 "VLE Fluid 3 as defined in SIM"));
-
-protected
-  outer TIL.SystemInformationManager sim "System information manager";
-
-  TIL.Internals.SimPort simPort;
-
-  /********************* Connectors *****************************/
-
-public
-  TIL.Connectors.GasPort gasPortA(m_flow(final start=m_flowStart), final
-      gasType=gasType) annotation (Placement(transformation(extent={{-110,
-            -10},{-90,10}},       rotation=0), iconTransformation(extent={{-110,
-            -10},{-90,10}})));
-  TIL.Connectors.GasPort gasPortB(m_flow(final start=-m_flowStart), final
-      gasType=gasType) annotation (Placement(transformation(extent={{90,-10},
-            {110,10}},      rotation=0), iconTransformation(extent={{88,-10},{108,
-            10}})));
-
-  TIL.Connectors.VLEFluidPort vlePort(final vleFluidType=vleFluidType,
-    final h_limit=-1e6) annotation (Placement(transformation(
-          extent={{-70,-110},{-50,-90}}),
-                                        iconTransformation(extent={{-70,-110},{-50,
-            -90}})));
-
-  TIL.Connectors.HeatPort heatPortA annotation (
-      Placement(transformation(extent={{-10,-110},{10,-90}}),iconTransformation(
-          extent={{-10,-110},{10,-90}})));
-  TIL.Connectors.HeatPort heatPortB annotation (Placement(
-        transformation(extent={{-10,90},{10,110}}), iconTransformation(extent={{-10,90},
-            {10,110}})));
-
-   /************************ Gas *************************/
-
-   TILMedia.Gas_ph gas(
-     final gasType=gasType,
-     final p=p,
-     final h=h,
-     final xi=xi,
-     final computeTransportProperties = pressureDropModel.computeTransportProperties or computeTransportProperties) "Gas properties"
-     annotation (Placement(transformation(extent={{30,-12},{50,8}},rotation=0)));
-
-   TILMedia.VLEFluid_pT vaporVLE_outflow(
-    final vleFluidType=vleFluidType,
-    final p=gas.p_i[1],
-    final T=gas.T) "Conversion of enthalpy from gas to vle fluid"
-    annotation (Placement(transformation(extent={{-50,-80},{-30,-60}})));
-
-   TILMedia.VLEFluid_ph vaporVLE_instream(
-    final vleFluidType=vleFluidType,
-    final p=vlePort.p,
-    final h=inStream(vlePort.h_outflow)) "Calculation of temperature of instream vapor"
-    annotation (Placement(transformation(extent={{-90,-80},{-70,-60}})));
-
-   TILMedia.Gas_pT vaporGas_instream(
-    final gasType=gasType,
-    final p=p,
-    final T=vaporVLE_instream.T) "Conversion of enthalpy from vle fluid to gas"
-    annotation (Placement(transformation(extent={{-70,-52},{-50,-32}})));
-
-   Modelica.SIunits.Pressure p(final start=pInitial, fixed=fixedInitialPressure)
-    "Pressure in gas cell";
-
-   Modelica.SIunits.SpecificEnthalpy h(final start=hInitial) "Specific enthalpy of gas";
-
-   Modelica.SIunits.MassFraction xi[gasType.nc - 1](final start=xiInitial)
-    "Composition of gas";
-
-   Modelica.SIunits.SpecificEnthalpy h_vaporGas "Specific enthalpy vle fluid";
-
-   Modelica.SIunits.Mass massGas;
-
-   Real drhodt(unit="kg/(m3.s)") "Derivative of density by time";
-
-   inner TILMedia.Internals.PropertyRecord properties(
-    final d=gas.d,
-    final h=gas.h,
-    final p=gas.p,
-    final s=gas.s,
-    final T=gas.T,
-    final cp=gas.cp,
-    final transp=gas.transp);
-
-   /************************ Pressure drop *************************/
-
-   replaceable model PressureDropModel =
-    PressureDropCorrelations.Partial.PartialPressureDrop
-    constrainedby PressureDropCorrelations.Partial.PartialPressureDrop "Pressure drop model"
-    annotation (choices(choice(redeclare model
-                PressureDropModel =
-            SorpLib.Components.Cells.Gas.PressureDropCorrelations.ZeroPressureDrop),
-            choice(redeclare model PressureDropModel =
-            SorpLib.Components.Cells.Gas.PressureDropCorrelations.ConstantResistanceCoefficient)), Dialog(group="Pressure drop model"));
-
-   PressureDropModel pressureDropModel "Pressure drop"
-    annotation (Placement(transformation(extent={{-30,-10},{-10,10}})));
-
-   inner Modelica.SIunits.MassFlowRate mdotHydraulic
-    "Hydraulic mass flow rate";
-
-   /****************** Geometry *******************/
-
-   inner parameter Geometry.CellGeometry cellGeometry "cell geometry" annotation (Dialog(group="Geometry"));
-
-   /********************* Initialization ********************************/
-
-   parameter Modelica.SIunits.Temperature TInitial
-    "Initial temperature of gas" annotation (Dialog(group="Initial Values", tab="Start and Initialization"));
-   parameter Modelica.SIunits.MassFraction[gasType.nc - 1] xiInitial=gasType.defaultMixingRatio[1:end - 1]/sum(gasType.defaultMixingRatio)
-    "Initial composition of gas" annotation (Dialog(group="Initial Values", tab="Start and Initialization"));
-   parameter Modelica.SIunits.Pressure pInitial
-    "Initial pressure in gas cell" annotation (Dialog(group="Initial Values", tab="Start and Initialization"));
-   final parameter Modelica.SIunits.SpecificEnthalpy hInitial=
-      TILMedia.GasFunctions.specificEnthalpy_pTxi(
-      gasType,
-      pInitial,
-      TInitial,
-      xiInitial);
-   parameter Boolean fixedInitialPressure=true
-    "If true, initial pressure is fixed" annotation (Dialog(group="Initial Values", tab="Start and Initialization"));
-   parameter Modelica.SIunits.MassFlowRate m_flowStart=0.2
-    "Start mass flow rate for iteration" annotation (Dialog(group="Start Values", tab="Start and Initialization"));
-
-  /*******************Summary**********************/
-
-   inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-
-   parameter Boolean generateEventsAtFlowReversal=false "If true, events are generated at flow reversal" annotation(Evaluate=true, Dialog(tab="Advanced", group="Event-Handling"));
-
-   parameter Boolean computeTransportProperties=false "If true, tranport properties are calculated in the gas object" annotation(Dialog(tab="Advanced", group="Transport properties"));
-
-   parameter String HydraulicMassFlowPosition="gas port B" "Position of hydraulic mass flow of gas cell" annotation(Evaluate=true, Dialog(tab="Advanced", group="Hydraulic mass flow position"),
-    choices(
-    choice="gas port A" "hydraulic mass flow at gas port A",
-    choice="gas port B" "hydraulic mass flow at gas port B"));
-
-protected
-  record Summary
-    extends TIL.Internals.ClassTypes.Record;
-
-    Modelica.SIunits.MassFlowRate m_flow_A if include;
-    Modelica.SIunits.MassFlowRate m_flow_B if include;
-    Modelica.SIunits.MassFlowRate m_flow_vle if include;
-    Modelica.SIunits.SpecificEnthalpy h_A if include;
-    Modelica.SIunits.SpecificEnthalpy h_B if include;
-    Modelica.SIunits.SpecificEnthalpy h_vle if include;
-    Modelica.SIunits.Pressure p_A if include;
-    Modelica.SIunits.Pressure p_B if include;
-    Modelica.SIunits.Pressure p_vle if include;
-    Modelica.SIunits.Temperature T if include;
-    Modelica.SIunits.Pressure p if include;
-    Modelica.SIunits.MassFraction xi[gasType.nc-1] if include;
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-    outer parameter TILMedia.GasTypes.BaseGas gasType;
-
-  end Summary;
-
-  replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    m_flow_A=gasPortA.m_flow,
-    m_flow_B=gasPortB.m_flow,
-    m_flow_vle=vlePort.m_flow,
-    h_A=noEvent(actualStream(gasPortA.h_outflow)),
-    h_B=noEvent(actualStream(gasPortB.h_outflow)),
-    h_vle=noEvent(actualStream(vlePort.h_outflow)),
-    p_A=gasPortA.p,
-    p_B=gasPortB.p,
-    p_vle=vlePort.p,
-    T=gas.T,
-    p=p,
-    xi=xi)
-     annotation (Placement(transformation(extent={{66,-88},{86,-68}},
-          rotation=0)));
-
-initial equation
-
-  h=hInitial;
-
-  xi=xiInitial;
-
-equation
-
-  // simport setup
-  connect(sim.fluidPort[vleFluidType.ID], simPort.vleFluidPort);
-  simPort.vleFluidMass = massGas*xi[1];
-  simPort.vleFluidVolume = cellGeometry.volume;
-
-  massGas=cellGeometry.volume*gas.d;
-
-  // Fluid ports
-  gasPortA.h_outflow=h;
-  gasPortB.h_outflow=h;
-
-  gasPortA.xi_outflow=xi;
-  gasPortB.xi_outflow=xi;
-
-  vlePort.h_outflow=vaporVLE_outflow.h;
-
-  heatPortA.T=gas.T;
-  heatPortB.T=gas.T;
-
-  vlePort.p=gas.p_i[1];
-
-  p=(gasPortA.p+gasPortB.p)/2;
-
-  if HydraulicMassFlowPosition=="gas port A" then
-    mdotHydraulic=-gasPortA.m_flow;
-  else
-    mdotHydraulic=gasPortB.m_flow;
-  end if;
-
-  // Momentum balance
-  gasPortB.p-gasPortA.p=pressureDropModel.pressureDrop;
-
-  // Mass balance
-  cellGeometry.volume*drhodt=gasPortA.m_flow+gasPortB.m_flow+vlePort.m_flow
-    "Moist gas mass balance";
-
-  drhodt=gas.drhodh_pxi*der(h)+gas.drhodp_hxi*der(p)+gas.drhodxi_ph*der(xi);
-
-  if (generateEventsAtFlowReversal) then
-    massGas*der(xi) =
-      gasPortA.m_flow*actualStream(gasPortA.xi_outflow) - gasPortA.m_flow*xi +
-      gasPortB.m_flow*actualStream(gasPortB.xi_outflow) - gasPortB.m_flow*xi +
-      vlePort.m_flow*cat(1,{1},zeros(gasType.nc-2)) - vlePort.m_flow*cat(1,{xi[1]},zeros(gasType.nc-2))
-      "Vapor mass balance";
-
-    // Energy balance
-    massGas*der(h) =
-      gasPortA.m_flow*actualStream(gasPortA.h_outflow) - gasPortA.m_flow*h +
-      gasPortB.m_flow*actualStream(gasPortB.h_outflow) - gasPortB.m_flow*h +
-      vlePort.m_flow*h_vaporGas - vlePort.m_flow*h +
-      cellGeometry.volume*der(p) + heatPortA.Q_flow + heatPortB.Q_flow;
-
-    h_vaporGas=Modelica.Fluid.Utilities.regStep(vlePort.m_flow, vaporGas_instream.h, gas.h_i[1], 1e-6);
-  else
-    massGas*der(xi) =
-      gasPortA.m_flow*noEvent(actualStream(gasPortA.xi_outflow)) - gasPortA.m_flow*xi +
-      gasPortB.m_flow*noEvent(actualStream(gasPortB.xi_outflow)) - gasPortB.m_flow*xi +
-      vlePort.m_flow*cat(1,{1},zeros(gasType.nc-2)) - vlePort.m_flow*cat(1,{xi[1]},zeros(gasType.nc-2))
-      "Vapor mass balance";
-
-    // Energy balance
-    massGas*der(h) =
-      gasPortA.m_flow*noEvent(actualStream(gasPortA.h_outflow)) - gasPortA.m_flow*h +
-      gasPortB.m_flow*noEvent(actualStream(gasPortB.h_outflow)) - gasPortB.m_flow*h +
-      vlePort.m_flow*h_vaporGas - vlePort.m_flow*h +
-      cellGeometry.volume*der(p) + heatPortA.Q_flow + heatPortB.Q_flow;
-
-    h_vaporGas=noEvent(Modelica.Fluid.Utilities.regStep(vlePort.m_flow, vaporGas_instream.h, gas.h_i[1], 1e-6));
-  end if;
-
-annotation (Icon(coordinateSystem(extent={{-100,-100},{100,100}},
-          preserveAspectRatio=false),
-                 graphics={Bitmap(
-          extent={{-100,100},{100,-100}},
-          imageSource=
-              "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOjnJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABhElEQVR42u3UsQ3AMAhFQZPJ2JzRSEvhynKkFHcd7dcTawEAcFvMo6oswpnMjIh9WN1tIM6/1AjrMQdfEBbCQlgIC4SFsBAWCAthISwQFsJCWCAshIWwQFgIC2GBsBAWwgJhISyEBcJCWAgLhIWwEBYIC2EhLBAWwkJYICyEhbBAWAgLYYGwEBbCAmEhLIQFwkJYCAuEhbAQFggLYSEsEBbCQlggLISFsEBYCAthgbAQFsICYSEshAXCQlgIC4SFsBAWCAthISwQFsJCWCAshIWwEBYIC2EhLBAWwkJYICyEhbBAWAgLYYGwEBbCAmEhLIQFwkJYCAuEhbAQFggLYSEsEBbCQlggLISFsEBYCAthgbAQFsICYSEshAXCQlgIC4SFsBAWCAthISwQFsJCWCAshIWwQFgIC2GBsBAWwgJhISyEBcJCWAgLhIWwEBYIC2EhLBAWwkJYICyEhbBAWAgLYSEsEyAshIWwQFgIC2GBsBAWwgJhISyEBcJCWAgLAAD4qReb+Qd/FUGUbAAAAABJRU5ErkJggg==",
-          fileName="modelica://TIL/Images/CellUni.png"),
-                                   Text(
-          extent={{-80,40},{80,-40}},
-          lineColor={0,0,0},
-          fillColor={255,255,255},
-          fillPattern=FillPattern.Solid,
-          textString="Gas")}),
-                        Diagram(coordinateSystem(extent={{-100,-100},{100,100}},
-          preserveAspectRatio=false)),
-    Documentation(info="<html>
-  <p>
-    This model represents an ideal gas cell, which may contain a pure gas or a gas mixture with a condensing component such as moist air. For a cell, a lumped model approach is used with an uniform enthalpy, pressure and composition within the cell. By combining more cells with a finite volume approach, a distributed gas channel can be built, with a spatial enthalpy, pressure and composition distribution. The model has five ports: two gas ports to exchange gas, a VLE port to add/remove the condensing component, and two heat ports to exchange heat with connected components. <br>
-    
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    <p>Mass balance: </p>
-    <p align=\"center\"><i>V</i> <i>d<code>&rho;</code>/dt</i> = <i><code>&#7745;</code></i><sub>gas,in</sub> + <i><code>&#7745;</code></i><sub>gas,out</sub> + <i><code>&#7745;</code></i><sub>VLE</sub> </p>
-    <p>where <i>V</i> is the volume, <i>&rho;</i> is the density of the gas, and <i><code>&#7745;</code></i><sub>gas,in</sub>, <i><code>&#7745;</code></i><sub>gas,out</sub> and <i><code>&#7745;</code></i><sub>VLE</sub> are the mass flow rates at the gas ports and at the vle port.</p>
-    <p>The derivative <i>d<code>&rho;</code>/dt</i> can be expressed by the total differential: </p>
-    <p align=\"center\"><i>d<code>&rho;</code>/dt</i> = <i>d<code>&rho;</code>/dh</i> <i>dh/dt</i> + <i>d<code>&rho;</code>/dp</i> <i>dp/dt</i> + <i>d<code>&rho;</code>/dxi</i> <i>dxi/dt</i> </p>
-    <p>where <i>h</i> is the specific enthalpy, <i>p</i> is the pressure, and <i>xi</i> is the mass fraction of the condensing component in the gas cell. </p>
-    <p align=\"center\"> <i>V <code>&rho;</code></i>  <i>dxi/dt</i> = <i><code>&#7745;</code></i><sub>gas,in</sub> (<i>xi</i><sub>gas,in</sub> - <i>xi</i>) - <i><code>&#7745;</code></i><sub>gas,out</sub> (<i>xi</i><sub>gas,out</sub> - <i>xi</i>) + <i><code>&#7745;</code></i><sub>vle</sub> (1 - <i>xi</i>) </p>    
-    <p>Energy balance: </p>
-    <p align=\"center\"> <i>V <code>&rho;</code></i>  <i>dh/dt</i> = <i><code>&#7745;</code></i><sub>gas,in</sub> (<i>h</i><sub>gas,in</sub> - <i>h</i>) - <i><code>&#7745;</code></i><sub>gas,out</sub> (<i>h</i><sub>gas,out</sub> - <i>h</i>) + <i><code>&#7745;</code></i><sub>vle</sub> (<i>h</i><sub>vle</sub> - <i>h</i>) + <i>V</i> <i>dp/dt</i> + <code>&sum;</code> <i>Q</i> </p>
-    <p>where <i>h</i><sub>gas,in</sub>, <i>h</i><sub>gas,out</sub>, and <i>h</i><sub>vle</sub> are the specific enthalpies of incoming/outflowing streams. </p>
-    <p>Momentum balance: </p>
-    <p align=\"center\"> <i>p</i><sub>in</sub> - <i>p</i><sub>out</sub> = <i><code>&Delta;</code>p</i> </p>
-    <p align=\"center\"> <i>p</i> = (<i>p</i><sub>in</sub> + <i>p</i><sub>out</sub>) / 2 </p>
-    <p>where <i>p</i><sub>in</sub>, and <i>p</i><sub>out</sub> are the pressures at the gas ports. <i><code>&Delta;</code>p</i> is the pressure drop, which is calculated by an internal selectable pressure drop model. </p>
-    The pressure at the vle port is set equal to the partial pressure of the condensing component in the gas mixture. To consider different reference states fot the specific enthalpies of gas and vle models the specific enthalpies are converted into each other using temperature and pressure.
-  </p>
-
-  <h4>Assumptions and limitations</h4>
-
-  <p>
-    The model uses the following main assumptions:
-    <ul>
-      <li>The gas / gas mixtrue within the cell is ideally mixed with a uniform enthalpy, pressure and composition.</li>
-      <li>For the calculations of the gas properties, the ideal gas law is assumed.</li>
-      <li>For the simple pressure drop models, such as zero pressure drop and constant pressure drop, there is no correlation between mass flow rate and pressure drop. Thus, a mass flow rate has to be given by a connected model, e.g. by a mass flow boundary.</li>
-    </ul>
-  </p>
-
-  <h4>Typical use and important parameters</h4>
-  <p>
-    <p>For open adsorption systems the gas cell represents the moist air. </p>
-
-    <p>With the parameter hydraulicMassFlowPosition in the advanced settings, the position of the hydraulic mass flow rate can be chosen for pressure drop calculations. For numerical reasons the hydraulic mass flow rate should be chosen at the opposite port of the mass flow boundary. If two mass flow boundaries or two pressure boundaries are used, both options work. </p>
-  </p>
-  <h4>Dynamics</h4>
-  <p>
-    The model has three states: the specific enthalpy <i>h</i>, the pressure <i>p</i> and the mass fraction of the condensing component <i>xi</i>.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>November 23, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end Gas;
diff --git a/SorpLib/Components/Cells/Gas/Geometry/CellGeometry.mo b/SorpLib/Components/Cells/Gas/Geometry/CellGeometry.mo
deleted file mode 100644
index 3b8da0f..0000000
--- a/SorpLib/Components/Cells/Gas/Geometry/CellGeometry.mo
+++ /dev/null
@@ -1,28 +0,0 @@
-within SorpLib.Components.Cells.Gas.Geometry;
-record CellGeometry
-  extends SorpLib.Internals.ClassTypes.Record;
-
-  parameter Modelica.SIunits.Length length( start=1) "Length of cell";
-
-  parameter Modelica.SIunits.Diameter hydraulicDiameter(start = 1) "Hydraulic diameter of cell";
-
-  parameter Modelica.SIunits.Area flowCrossSection(start = 1) "Cross-sectional area of cell";
-
-  parameter Real psi(final unit="1", start=1, min=0, max=1) "Void percentage gas channel (1 = free channel)";
-
-  final parameter Modelica.SIunits.Volume volume = flowCrossSection*length*psi "volume of cell";
-
-  annotation (Documentation(info="<html>
-  <p>
-  This record containes all information necessary to describe a gas cell. <br>  
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-    <li>December 12, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end CellGeometry;
diff --git a/SorpLib/Components/Cells/Gas/Geometry/package.mo b/SorpLib/Components/Cells/Gas/Geometry/package.mo
deleted file mode 100644
index b810365..0000000
--- a/SorpLib/Components/Cells/Gas/Geometry/package.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Components.Cells.Gas;
-package Geometry
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-
-
-
-annotation (Documentation(info="<html>
-</html>"));
-end Geometry;
diff --git a/SorpLib/Components/Cells/Gas/Geometry/package.order b/SorpLib/Components/Cells/Gas/Geometry/package.order
deleted file mode 100644
index bf1521e..0000000
--- a/SorpLib/Components/Cells/Gas/Geometry/package.order
+++ /dev/null
@@ -1 +0,0 @@
-CellGeometry
diff --git a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/ConstantResistanceCoefficient.mo b/SorpLib/Components/Cells/Gas/PressureDropCorrelations/ConstantResistanceCoefficient.mo
deleted file mode 100644
index 89d5dbf..0000000
--- a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/ConstantResistanceCoefficient.mo
+++ /dev/null
@@ -1,43 +0,0 @@
-within SorpLib.Components.Cells.Gas.PressureDropCorrelations;
-model ConstantResistanceCoefficient
-  "Pressure drop correlation with constant resistance coefficient"
-  extends Partial.PartialPressureDrop(
-      final computeTransportProperties=true);
-
-  outer parameter Geometry.CellGeometry cellGeometry "cell geometry";
-
-  outer TILMedia.Internals.PropertyRecord properties "Fluid property record";
-
-  outer Modelica.SIunits.MassFlowRate mdotHydraulic
-    "Hydraulic mass flow rate";
-
-  parameter Real f(final unit="1")=2 "Resistance coefficient";
-
-equation
-  pressureDrop=(cellGeometry.length/cellGeometry.hydraulicDiameter)/(2*properties.d*cellGeometry.flowCrossSection^2)*f*TIL.Utilities.Numerics.squareFunction(mdotHydraulic);
-  annotation (Documentation(info="<html>
-<p>
-  This model calculates the pressure drop with a constant resistance coefficient according to the VDI Wärmeatlas (2013). The sign of the pressure drop is automatically determined by the sign of the hydraulic mass flow rate. The hydraulic mass flow rate is defined as outer variable and thus taken from the overlying model level. The fluid properties record is also defined as outer object and taken from the overlying model level. 
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i><code>&Delta;</code>p</i> = sgn(<i><code>&#7745;</code></i><sub>hydraulic</sub>) <i>L</i> / <i>D</i> <i>f</i> / (2 <i><code>&rho;</code></i> <i>A</i><sup>2</sup>) <i><code>&#7745;</code></i><sub>hydraulic</sub><sup>2</sup> </p>
-<p>where <i><code>&Delta;</code>p</i> is the pressure drop, <i><code>&#7745;</code></i><sub>hydraulic</sub> is the hydraulic mass flow rate, <i>L</i> is the hydraulic length, <i>D</i> is the hydraulic diameter, <i>f</i> is the resistance coefficient, <i><code>&rho;</code></i> is the fluid density and <i>A</i> is the cross sectional area. </p>
-</p>
-
-<h4>References</h4>
-<ul>
-<li>VDI e.V., VDI Wärmeatlas 11., bearbeitete und erweiterte Auflage, Chapter L1, Darmstadt: Springer Berlin Heidelberg, 2011. </li>
-</ul>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 28, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ConstantResistanceCoefficient;
diff --git a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/PartialPressureDrop.mo b/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/PartialPressureDrop.mo
deleted file mode 100644
index 6c289eb..0000000
--- a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/PartialPressureDrop.mo
+++ /dev/null
@@ -1,29 +0,0 @@
-within SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial;
-partial model PartialPressureDrop
-
-  Modelica.SIunits.Pressure pressureDrop;
-
-  parameter Boolean computeTransportProperties;
-
-  annotation (Icon(graphics={Bitmap(extent={{-100,-100},{100,100}},
-          imageSource=
-              "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",
-          fileName=
-              "modelica://SorpLib/Resources/Images/DeltaP.png")}),
-      Documentation(info="<html>
-<p>
-  This partial model is the basis for the pressure drop correlation models. <br>
-</p>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 28, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-
-end PartialPressureDrop;
diff --git a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/package.mo b/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/package.mo
deleted file mode 100644
index 7c8a3e9..0000000
--- a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.Cells.Gas.PressureDropCorrelations;
-package Partial
-    extends SorpLib.Internals.ClassTypes.PartialPackage;
-
-end Partial;
diff --git a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/package.order b/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/package.order
deleted file mode 100644
index 1b8a13e..0000000
--- a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/Partial/package.order
+++ /dev/null
@@ -1 +0,0 @@
-PartialPressureDrop
diff --git a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/ZeroPressureDrop.mo b/SorpLib/Components/Cells/Gas/PressureDropCorrelations/ZeroPressureDrop.mo
deleted file mode 100644
index 72f3320..0000000
--- a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/ZeroPressureDrop.mo
+++ /dev/null
@@ -1,34 +0,0 @@
-within SorpLib.Components.Cells.Gas.PressureDropCorrelations;
-model ZeroPressureDrop "Pressure drop = 0 Pa"
-  extends Partial.PartialPressureDrop(
-      final computeTransportProperties=false);
-
-equation
-  pressureDrop=0;
-  annotation (Documentation(info="<html>
-<p>
-  This model sets the pressure drop to zero.
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i><code>&Delta;</code>p</i> = 0 </p>
-<p>where <i><code>&Delta;</code>p</i> is the pressure drop. </p>
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    The model uses the following main assumptions:
-    <ul>
-      <li>In this simple pressure drop model, there is no correlation between mass flow rate and pressure drop. Thus, a mass flow rate has to be given by another model, e.g. by a mass flow boundary.</li>
-    </ul>
-  </p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 28, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ZeroPressureDrop;
diff --git a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/package.mo b/SorpLib/Components/Cells/Gas/PressureDropCorrelations/package.mo
deleted file mode 100644
index a1e6d45..0000000
--- a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.Cells.Gas;
-package PressureDropCorrelations
-  extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-
-end PressureDropCorrelations;
diff --git a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/package.order b/SorpLib/Components/Cells/Gas/PressureDropCorrelations/package.order
deleted file mode 100644
index f549a87..0000000
--- a/SorpLib/Components/Cells/Gas/PressureDropCorrelations/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-ZeroPressureDrop
-ConstantResistanceCoefficient
-Partial
diff --git a/SorpLib/Components/Cells/Gas/Testers/TestGas.mo b/SorpLib/Components/Cells/Gas/Testers/TestGas.mo
deleted file mode 100644
index 79fa0d7..0000000
--- a/SorpLib/Components/Cells/Gas/Testers/TestGas.mo
+++ /dev/null
@@ -1,133 +0,0 @@
-within SorpLib.Components.Cells.Gas.Testers;
-model TestGas
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.GasTypes.TILMedia_MoistAir gasType1, redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-
-  Gas gas1(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{-80,-10},{-60,10}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.00002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={-76,-30})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.0002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={-6,-30})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary3(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.0002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={64,-30})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary1(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={-70,26})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary2(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={0,28})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary3(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={70,26})));
-  Gas gas2(
-      cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
-  Gas gas3(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (
-        f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{60,-10},{80,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryB(
-    boundaryType="p",
-    TFixed=303.15,
-    pFixed=1500000)
-    annotation (Placement(transformation(extent={{96,-10},{104,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryA(m_flowFixed=-2, TFixed=
-        303.15)
-    annotation (Placement(transformation(extent={{-104,-10},{-96,10}})));
-equation
-  connect(gas1.vlePort, vleBoundary1.port) annotation (Line(
-      points={{-76,-10},{-76,-10},{-76,-30}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas1.heatPortB, heatBoundary1.heatPort) annotation (Line(
-      points={{-70,10},{-70,10},{-70,26}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatBoundary2.heatPort, gas2.heatPortB) annotation (Line(
-      points={{0,28},{0,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vleBoundary2.port, gas2.vlePort) annotation (Line(
-      points={{-6,-30},{-6,-30},{-6,-10}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas3.gasPortA, gas2.gasPortB) annotation (Line(
-      points={{60,0},{34,0},{9.8,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(heatBoundary3.heatPort, gas3.heatPortB) annotation (Line(
-      points={{70,26},{70,26},{70,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vleBoundary3.port, gas3.vlePort) annotation (Line(
-      points={{64,-30},{64,-30},{64,-10}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas1.gasPortB, gas2.gasPortA) annotation (Line(
-      points={{-60.2,0},{-36,0},{-10,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gas1.gasPortA, gasBoundaryA.port) annotation (Line(
-      points={{-80,0},{-90,0},{-100,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gas3.gasPortB, gasBoundaryB.port) annotation (Line(
-      points={{79.8,0},{90,0},{100,0}},
-      color={255,153,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-            -100},{100,100}})), experiment(StopTime=100));
-end TestGas;
diff --git a/SorpLib/Components/Cells/Gas/Testers/TestGas2.mo b/SorpLib/Components/Cells/Gas/Testers/TestGas2.mo
deleted file mode 100644
index bd6620c..0000000
--- a/SorpLib/Components/Cells/Gas/Testers/TestGas2.mo
+++ /dev/null
@@ -1,133 +0,0 @@
-within SorpLib.Components.Cells.Gas.Testers;
-model TestGas2
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.GasTypes.TILMedia_MoistAir gasType1, redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-
-  Gas gas1(
-    fixedInitialPressure=false,
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{-80,-10},{-60,10}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.00002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={-76,-30})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.0002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={-6,-30})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary3(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.0002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={64,-30})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary1(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={-70,26})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary2(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={0,28})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary3(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={70,26})));
-  Gas gas2(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
-  Gas gas3(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{60,-10},{80,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryB(boundaryType="p", pFixed=
-        1000000)
-    annotation (Placement(transformation(extent={{96,-10},{104,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryA(
-    boundaryType="p",
-    TFixed=303.15,
-    pFixed=1500000)
-    annotation (Placement(transformation(extent={{-104,-10},{-96,10}})));
-equation
-  connect(gas1.vlePort, vleBoundary1.port) annotation (Line(
-      points={{-76,-10},{-76,-10},{-76,-30}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas1.heatPortB, heatBoundary1.heatPort) annotation (Line(
-      points={{-70,10},{-70,10},{-70,26}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatBoundary2.heatPort, gas2.heatPortB) annotation (Line(
-      points={{0,28},{0,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vleBoundary2.port, gas2.vlePort) annotation (Line(
-      points={{-6,-30},{-6,-30},{-6,-10}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas3.gasPortA, gas2.gasPortB) annotation (Line(
-      points={{60,0},{34,0},{9.8,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(heatBoundary3.heatPort, gas3.heatPortB) annotation (Line(
-      points={{70,26},{70,26},{70,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vleBoundary3.port, gas3.vlePort) annotation (Line(
-      points={{64,-30},{64,-30},{64,-10}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas1.gasPortB, gas2.gasPortA) annotation (Line(
-      points={{-60.2,0},{-36,0},{-10,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gas3.gasPortB, gasBoundaryB.port) annotation (Line(
-      points={{79.8,0},{90,0},{100,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gas1.gasPortA, gasBoundaryA.port) annotation (Line(
-      points={{-80,0},{-100,0}},
-      color={255,153,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-            -100},{100,100}})), experiment(StopTime=100));
-end TestGas2;
diff --git a/SorpLib/Components/Cells/Gas/Testers/TestGas3.mo b/SorpLib/Components/Cells/Gas/Testers/TestGas3.mo
deleted file mode 100644
index bb49a29..0000000
--- a/SorpLib/Components/Cells/Gas/Testers/TestGas3.mo
+++ /dev/null
@@ -1,135 +0,0 @@
-within SorpLib.Components.Cells.Gas.Testers;
-model TestGas3
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.GasTypes.TILMedia_MoistAir gasType1, redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-
-  Gas gas(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000,
-    HydraulicMassFlowPosition="gas port A")
-    annotation (Placement(transformation(extent={{-80,-10},{-60,10}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.00002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={-76,-30})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.0002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={-6,-30})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary3(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    m_flowFixed=-0.0002,
-    TFixed=303.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={64,-30})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary1(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={-70,26})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary2(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={0,28})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary3(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={70,26})));
-  Gas gas2(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000,
-    HydraulicMassFlowPosition="gas port A")
-    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
-  Gas gas3(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000,
-    HydraulicMassFlowPosition="gas port A")
-    annotation (Placement(transformation(extent={{60,-10},{80,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryA(
-    boundaryType="p",
-    TFixed=303.15,
-    pFixed=1000000)
-    annotation (Placement(transformation(extent={{-104,-10},{-96,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryB(m_flowFixed=-2, TFixed=
-        303.15)
-    annotation (Placement(transformation(extent={{96,-10},{104,10}})));
-equation
-  connect(gas.vlePort, vleBoundary1.port) annotation (Line(
-      points={{-76,-10},{-76,-10},{-76,-30}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas.heatPortB, heatBoundary1.heatPort) annotation (Line(
-      points={{-70,10},{-70,10},{-70,26}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatBoundary2.heatPort, gas2.heatPortB) annotation (Line(
-      points={{0,28},{0,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vleBoundary2.port, gas2.vlePort) annotation (Line(
-      points={{-6,-30},{-6,-30},{-6,-10}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas3.gasPortA, gas2.gasPortB) annotation (Line(
-      points={{60,0},{34,0},{9.8,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(heatBoundary3.heatPort, gas3.heatPortB) annotation (Line(
-      points={{70,26},{70,26},{70,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vleBoundary3.port, gas3.vlePort) annotation (Line(
-      points={{64,-30},{64,-30},{64,-10}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas.gasPortB, gas2.gasPortA) annotation (Line(
-      points={{-60.2,0},{-36,0},{-10,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gas.gasPortA, gasBoundaryA.port) annotation (Line(
-      points={{-80,0},{-90,0},{-100,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gas3.gasPortB, gasBoundaryB.port) annotation (Line(
-      points={{79.8,0},{90,0},{100,0}},
-      color={255,153,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-            -100},{100,100}})), experiment(StopTime=100));
-end TestGas3;
diff --git a/SorpLib/Components/Cells/Gas/Testers/TestGas4.mo b/SorpLib/Components/Cells/Gas/Testers/TestGas4.mo
deleted file mode 100644
index 5d0e688..0000000
--- a/SorpLib/Components/Cells/Gas/Testers/TestGas4.mo
+++ /dev/null
@@ -1,130 +0,0 @@
-within SorpLib.Components.Cells.Gas.Testers;
-model TestGas4
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.GasTypes.TILMedia_MoistAir gasType1, redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-
-  Gas gas(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{-80,-10},{-60,10}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    TFixed=303.15,
-    m_flowFixed=0) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={-76,-30})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    TFixed=303.15,
-    m_flowFixed=0) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={-6,-30})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary3(
-    boundaryType="m_flow",
-    streamVariablesInputType="T",
-    TFixed=303.15,
-    m_flowFixed=0) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={64,-30})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary1(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={-70,26})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary2(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={0,28})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary3(boundaryType="Q_flow",
-      Q_flowFixed=-30) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={70,26})));
-  Gas gas2(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
-  Gas gas3(
-    cellGeometry(
-      length=0.2,
-      hydraulicDiameter=0.02,
-      flowCrossSection=0.000314,
-      psi=1),
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.ConstantResistanceCoefficient (f=0.016),
-    TInitial=303.15,
-    pInitial=1000000)
-    annotation (Placement(transformation(extent={{60,-10},{80,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryB(m_flowFixed=2, TFixed=
-        303.15)
-    annotation (Placement(transformation(extent={{96,-10},{104,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryA(m_flowFixed=-2, TFixed=
-        303.15)
-    annotation (Placement(transformation(extent={{-104,-10},{-96,10}})));
-equation
-  connect(gas.vlePort, vleBoundary1.port) annotation (Line(
-      points={{-76,-10},{-76,-10},{-76,-30}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas.heatPortB, heatBoundary1.heatPort) annotation (Line(
-      points={{-70,10},{-70,10},{-70,26}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatBoundary2.heatPort, gas2.heatPortB) annotation (Line(
-      points={{0,28},{0,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vleBoundary2.port, gas2.vlePort) annotation (Line(
-      points={{-6,-30},{-6,-30},{-6,-10}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas3.gasPortA, gas2.gasPortB) annotation (Line(
-      points={{60,0},{34,0},{9.8,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(heatBoundary3.heatPort, gas3.heatPortB) annotation (Line(
-      points={{70,26},{70,26},{70,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vleBoundary3.port, gas3.vlePort) annotation (Line(
-      points={{64,-30},{64,-30},{64,-10}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(gas.gasPortB, gas2.gasPortA) annotation (Line(
-      points={{-60.2,0},{-36,0},{-10,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gas3.gasPortB, gasBoundaryB.port) annotation (Line(
-      points={{79.8,0},{90,0},{100,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gas.gasPortA, gasBoundaryA.port) annotation (Line(
-      points={{-80,0},{-90,0},{-100,0}},
-      color={255,153,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-            -100},{100,100}})), experiment(StopTime=100));
-end TestGas4;
diff --git a/SorpLib/Components/Cells/Gas/Testers/package.mo b/SorpLib/Components/Cells/Gas/Testers/package.mo
deleted file mode 100644
index c346db7..0000000
--- a/SorpLib/Components/Cells/Gas/Testers/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.Cells.Gas;
-package Testers
-  extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-
-
-end Testers;
diff --git a/SorpLib/Components/Cells/Gas/Testers/package.order b/SorpLib/Components/Cells/Gas/Testers/package.order
deleted file mode 100644
index fb98d43..0000000
--- a/SorpLib/Components/Cells/Gas/Testers/package.order
+++ /dev/null
@@ -1,4 +0,0 @@
-TestGas
-TestGas2
-TestGas3
-TestGas4
diff --git a/SorpLib/Components/Cells/Gas/package.mo b/SorpLib/Components/Cells/Gas/package.mo
deleted file mode 100644
index 43c6b99..0000000
--- a/SorpLib/Components/Cells/Gas/package.mo
+++ /dev/null
@@ -1,7 +0,0 @@
-within SorpLib.Components.Cells;
-package Gas
-  extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-
-end Gas;
diff --git a/SorpLib/Components/Cells/Gas/package.order b/SorpLib/Components/Cells/Gas/package.order
deleted file mode 100644
index a019f1a..0000000
--- a/SorpLib/Components/Cells/Gas/package.order
+++ /dev/null
@@ -1,4 +0,0 @@
-Gas
-PressureDropCorrelations
-Geometry
-Testers
diff --git a/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/TestVLEPhaseSeparator.mo b/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/TestVLEPhaseSeparator.mo
deleted file mode 100644
index 2ffb8cb..0000000
--- a/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/TestVLEPhaseSeparator.mo
+++ /dev/null
@@ -1,90 +0,0 @@
-within SorpLib.Components.Cells.VLEPhaseSeparator.Testers;
-model TestVLEPhaseSeparator
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  VLEPhaseSeparator vlePhaseSeparator(
-    dInitial=600,
-    vleFluidType=sim.vleFluidType1,
-    volume(displayUnit="l") = 0.005,
-    area=0.03,
-    includeDefaultSummary=true,
-    n=2,
-    k=1,
-    TInitial=298.15) annotation (Placement(transformation(
-        extent={{5,8},{-5,-8}},
-        rotation=180,
-        origin={0,0})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary1(
-    boundaryType="Q_flow",
-    use_heatFlowRateInput=false,
-    Q_flowFixed=-2200,
-    TFixed=323.15)
-    annotation (Placement(transformation(extent={{30,-6},{22,6}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{4,-10},{-4,10}},
-        rotation=90,
-        origin={-14,28})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=false,
-    m_flowFixed=-0.001) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={0,-20})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary3(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{4,-10},{-4,10}},
-        rotation=90,
-        origin={12,28})));
-  Modelica.Blocks.Sources.Step stepVLEBounday2(
-    height=-0.001,
-    offset=0.001,
-    startTime=50) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={-16,48})));
-  Modelica.Blocks.Sources.Step stepVLEBounday3(height=0.001, startTime=100)
-    annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={10,48})));
-equation
-  connect(heatBoundary1.heatPort, vlePhaseSeparator.heatPort) annotation (Line(
-      points={{26,0},{18,0},{18,-8.88178e-016},{5,-8.88178e-016}},
-      color={204,0,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-
-  connect(vleBoundary2.m_flow_in, stepVLEBounday2.y)
-    annotation (Line(points={{-16,32},{-16,32},{-16,41.4}}, color={0,0,127}));
-  connect(stepVLEBounday3.y, vleBoundary3.m_flow_in)
-    annotation (Line(points={{10,41.4},{10,36.7},{10,32}}, color={0,0,127}));
-  connect(vlePhaseSeparator.vleVapourPort[1], vleBoundary2.port) annotation (
-      Line(
-      points={{8.88178e-016,7.33333},{8.88178e-016,14},{-14,14},{-14,28}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vlePhaseSeparator.vleVapourPort[2], vleBoundary3.port) annotation (
-      Line(
-      points={{8.88178e-016,8.66667},{0,8.66667},{0,14},{12,14},{12,28}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vlePhaseSeparator.vleLiquidPort[1], vleBoundary1.port) annotation (
-      Line(
-      points={{-9.99201e-016,-8},{0,-8},{0,-20}},
-      color={153,204,0},
-      thickness=0.5));
-  annotation (
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
-            100,100}})),
-    experiment(StopTime=500, Tolerance=1e-005),
-    __Dymola_experimentSetupOutput(events=false));
-end TestVLEPhaseSeparator;
diff --git a/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/package.mo b/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/package.mo
deleted file mode 100644
index fc620d5..0000000
--- a/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.Cells.VLEPhaseSeparator;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-end Testers;
diff --git a/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/package.order b/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/package.order
deleted file mode 100644
index a0d62bb..0000000
--- a/SorpLib/Components/Cells/VLEPhaseSeparator/Testers/package.order
+++ /dev/null
@@ -1 +0,0 @@
-TestVLEPhaseSeparator
diff --git a/SorpLib/Components/Cells/VLEPhaseSeparator/VLEPhaseSeparator.mo b/SorpLib/Components/Cells/VLEPhaseSeparator/VLEPhaseSeparator.mo
deleted file mode 100644
index d9ed5a9..0000000
--- a/SorpLib/Components/Cells/VLEPhaseSeparator/VLEPhaseSeparator.mo
+++ /dev/null
@@ -1,237 +0,0 @@
-within SorpLib.Components.Cells.VLEPhaseSeparator;
-model VLEPhaseSeparator
-
-  /*********************** SIM ***********************************/
-
-  parameter TILMedia.VLEFluidTypes.BaseVLEFluid vleFluidType=sim.vleFluidType1
-    "VLE fluid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.vleFluidType1 "VLE fluid 1 as defined in SIM",
-      choice=sim.vleFluidType2 "VLE fluid 2 as defined in SIM",
-      choice=sim.vleFluidType3 "VLE fluid 3 as defined in SIM"));
-
-protected
-  outer TIL.SystemInformationManager sim "System information manager";
-
-  TIL.Internals.SimPort simPort;
-
-  /********************** Connectors **************************/
-
-public
-  TIL.Connectors.VLEFluidPort vleVapourPort[n](each final vleFluidType=
-        vleFluidType) "VLE Vapor ports" annotation (Placement(transformation(
-          extent={{-10,50},{10,70}}, rotation=0), iconTransformation(extent={{-10,
-            50},{10,70}})));
-
-  TIL.Connectors.VLEFluidPort vleLiquidPort[k](each final vleFluidType=
-        vleFluidType) "VLE Liquid port" annotation (Placement(transformation(
-          extent={{-10,-70},{10,-50}}, rotation=0), iconTransformation(extent={
-            {-10,-70},{10,-50}})));
-
-  parameter Integer n=0
-    "Number of vapour ports, parameter is necessary for automatic increasing of ports"
-    annotation (Dialog(connectorSizing=true));
-
-  parameter Integer k=0
-    "Number of liquid ports, parameter is necessary for automatic increasing of ports"
-    annotation (Dialog(connectorSizing=true));
-
-public
-  TIL.Connectors.HeatPort heatPort annotation (Placement(transformation(extent=
-            {{30,-10},{50,10}}), iconTransformation(extent={{30,-10},{50,10}})));
-
-  /*********************** VLEFluid ***************************/
-
-  TILMedia.VLEFluid_dT vleFluid(
-    T=T,
-    d=d,
-    final vleFluidType=vleFluidType,
-    computeTransportProperties=false,
-    computeSurfaceTension=false) "VLEFluid in mixing volume" annotation (
-      Placement(transformation(extent={{-10,-10},{10,10}}, rotation=0)));
-
-  Modelica.SIunits.Density d(start=dInitial, fixed=true) "VLE fluid density";
-
-  Modelica.SIunits.Temperature T(start=TInitial, fixed=true)
-    "VLE fluid temperature";
-
-  Modelica.SIunits.SpecificEnergy u "VLE specific internal energy";
-
-  Modelica.SIunits.InternalEnergy U "VLE internal energy";
-
-  Real dudrho "derivative of internal energy u wrt to density rho";
-
-  Modelica.SIunits.Length l "height of liquid level";
-
-  Real l_relative "relative height of liquid level";
-
-  Real X "Vapour mass fraction";
-
-  Modelica.SIunits.Mass mass "VLE fluid mass";
-
-  /******************** Parameters ********************/
-
-  parameter Modelica.SIunits.Volume volume "fluid volume";
-  parameter Modelica.SIunits.Area area "base area";
-  final parameter Modelica.SIunits.Length height=volume/area
-    "height of VLE phase seperator";
-
-  /********************* Initialization ********************************/
-
-  parameter Modelica.SIunits.Density dInitial "Initial value for VLE density"
-    annotation (Dialog(group="Initial Values", tab="Start and Initialization"));
-
-  parameter Modelica.SIunits.Temperature TInitial
-    "Initial value for VLE temperature"
-    annotation (Dialog(group="Initial Values", tab="Start and Initialization"));
-
-  /*******************Summary**********************/
-public
-  inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-
-  parameter Boolean generateEventsAtFlowReversal=false "If true, events are generated at flow reversal" annotation(Evaluate=true, Dialog(tab="Advanced", group="Event-Handling"));
-
-protected
-  record Summary
-    extends TIL.Internals.ClassTypes.Record;
-
-    Modelica.SIunits.Pressure p_VLE if include;
-    Modelica.SIunits.Temperature T_VLE if include;
-    Modelica.SIunits.Mass mass_VLE if include;
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-
-  end Summary;
-
-  replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    p_VLE=vleFluid.p,
-    T_VLE=vleFluid.T,
-    mass_VLE=mass) annotation (Placement(transformation(extent={{66,-88},{86,-68}},
-          rotation=0)));
-
-equation
-  //assert(T > 273.15, "Evaporator temperature must be above 0 °C"); Assert operator may be added for simulations with water
-
-  // simport setup
-  connect(sim.fluidPort[vleFluidType.ID], simPort.vleFluidPort);
-
-  simPort.vleFluidMass = mass;
-  simPort.vleFluidVolume = volume;
-
-  mass = volume*d "Mass in cv";
-  u = vleFluid.h - vleFluid.p/vleFluid.d "specific internal energy";
-  U = mass*u;
-
-  X = (vleFluid.VLE.d_l - d)/d*vleFluid.VLE.d_v/(vleFluid.VLE.d_l - vleFluid.VLE.d_v);
-  l = (1 - X)*mass/(vleFluid.VLE.d_l*area);
-  l_relative = l/height;
-
-  // Momentum balances
-  for i in 1:n loop
-    vleFluid.p = vleVapourPort[i].p;
-    // vapour port: vapour enthalpy + 10 J/kg --> slightly overheated --> higher stability in valve models
-    vleVapourPort[i].h_outflow = vleFluid.VLE.h_v + 10;
-    vleVapourPort[i].h_limit = -1e6;
-    //no limiter used
-  end for;
-
-  for i in 1:k loop
-    vleFluid.p = vleLiquidPort[i].p;
-    // liquid port: liquid enthalpy - 10 J/kg --> slightly subcooled --> higher stability in valve models
-    vleLiquidPort[i].h_outflow = vleFluid.VLE.h_l - 10;
-    vleLiquidPort[i].h_limit = -1e6;
-    //no limiter used
-  end for;
-
-  // Calculation of du/drho using the Brdigeman table and the equation of Cl.-Clayperon
-  dudrho = 1/d^2*(-vleFluid.p + (vleFluid.VLE.h_v - vleFluid.VLE.h_l)/(1/
-    vleFluid.VLE.d_v - 1/vleFluid.VLE.d_l));
-
-  if (generateEventsAtFlowReversal) then
-    u*volume*der(d) + mass*vleFluid.cv*der(T) + mass*dudrho*der(d) = sum(
-      vleVapourPort.m_flow .* actualStream(vleVapourPort.h_outflow)) + sum(
-      vleLiquidPort.m_flow .* actualStream(vleLiquidPort.h_outflow)) + heatPort.Q_flow
-      "Energy balance";
-  else
-    u*volume*der(d) + mass*vleFluid.cv*der(T) + mass*dudrho*der(d) = sum(
-      vleVapourPort.m_flow .* noEvent(actualStream(vleVapourPort.h_outflow))) + sum(
-      vleLiquidPort.m_flow .* noEvent(actualStream(vleLiquidPort.h_outflow))) + heatPort.Q_flow
-      "Energy balance";
-  end if;
-
-  volume*der(d) = sum(vleVapourPort[:].m_flow) + sum(vleLiquidPort[:].m_flow)
-    "Mass balance";
-
-  heatPort.T = T;
-
-  annotation (
-    defaultComponentName="simpleEvapCond",
-    Icon(coordinateSystem(preserveAspectRatio=true, extent={{-40,-60},{40,60}}),
-        graphics={Bitmap(
-          extent={{-44,-62},{44,60}},
-          imageSource=
-              "iVBORw0KGgoAAAANSUhEUgAAAPAAAAFuCAMAAAH/l1WxAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAByUExURZvI76rU9QAAADh/w5HB6qDN8myl2nux4WKe1nGq3VeW0bDY+L7j/kyOzb/k/zN7wbXd+ihzvYG15Cl0vQAAAHeu34a65lKSz7rg/S12v0iLyz2DxpbF7QAAAKXR84u96AAAAAAAAAAAAGei2Fya1EKGyPNjzFIAAAAjdFJOU///y///////////////////////x///////////NP//PP9ElpbsfAAAAAlwSFlzAAAXEQAAFxEByibzPwAAA3ZJREFUeF7t3dmKHDkURVE5PZTnsTxPFS77/3/RweWiJxFGCuoIH+311BBcNofuzrazOtPl+3akbC+P8LiJx01le3akbB+OlO33kbK9OlK2N0d43MTjpjt+fKjkv0xtPG7icdNW8qW3bSv50tu2lXzpbdtKvvS2bSX/eW/jcROPm+748fEvaw5x3InjThx3WvS4DNuPnwzbj78M24/zRXgAx5047sRxJ447nTy+zjcNRvzjfYhD1/z3uQ/HnTjuxHEnjjtx3InjTose59vxA/bj/D38gP043+kfsB/nGwAD9uP8IcKA/TjfPRiwH+fPJwbsx/kr7wEcd+K4E8edOO7EcSeOO3HcieNO/+/xCaeOz9jD+fscKcIyhGUIyxCWISxDWIawDGEZwjKEZQjLEJaZG/40QYR/TBDhBxNE+GqCCN9OEOGPE0T46wQRfjdBhPPtZynCMoRlCMsQliEsQ1iGsAxhGcIyhGUIyxCWISxDWCbCc5z6roQTbuYt5gdeGoRlCMsQliEsQ1iGsAxhGcIyhGUIyxCWISxDWIawDGEZwjKEZQjLEJYhLENYhrAMYRnCMouG89PXUhHOL0GXinB+7FsqwvnN7VIRzs+bS0U4v25eKsL5QXepCOd35EtFOD9hLxXh/GJ/qQjnR/ulIpx/GoFUhPM7BaQinH+EglSE88sMpCKc/8uzFGEZwjKEZQjLEJYhLENYhrAMYRnCMoRlCMsQliEsQ1iGsAxhGcIyhGUIyxCWISxDWIawDGEZwjKEZQjLLBqeY1b4MuvrZ2e5TPtbPEsMzs/F2GOwOwa7Y7A7BrtjsDsGu2OwOwa7Y7A7BrtjsDsGu2OwOwa7Y7A7BrtjsDsGu2OwOwa7Y7A7BrtjsDsGu2OwOwa7Y7A7BrtjsDsGu2OwOwa7Y7A7BrtjsDsGu2Owu3UHP19EHfx6EXXwvUXUwQ8XUQd/W0Qd/HMRdfDbRdTB7xdRBz9aRB38eBF18NNF1MEvFlEH/1lEHXx/EXXw50XUwfllxPYY7I7B7hjsjsHuGOyOwe4Y7I7B7hjsjsHuGOyOwe4Y7I7B7hjsjsHuGOyOwe4Y7I7B7hjsjsHuGOyOwe4Y7I7B7hjsjsHuGOyOwe4Y7I7B7hjsjsHuGOyOwe4Y7I7B7hjsjsHuGOyOwe4Y7G7dwSspN5f8qyVcfv0FM01fniGVbusAAAAASUVORK5CYII=",
-          fileName=
-              "modelica://SorpLib/Resources/Images/EvpCond.png")}),
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-40,-60},{40,
-            60}})),
-    Documentation(info="<html>
-  <p>
-    This model represents an ideal vapour liquid equilibrium (VLE) phase separator. The model has three ports: a VLE vapour port, a VLE liquid port, and a heat port. <br>
-    
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    <p>Mass balance: </p>
-    <p align=\"center\"><i>V</i> <i>d<code>&rho;</code>/dt</i> = <code>&sum;</code> <i><code>&#7745;</code></i> </p>
-    <p>where <i>V</i> is the volume, <i>&rho;</i> is the density of the VLE fluid, and <i><code>&#7745;</code></i> are the mass flow rates at the VLE vapour ports, and the VLE liquid ports.</p>
-    <p>Energy balance: </p>
-    <p align=\"center\"><i>V u</i> <i>d<code>&rho;</code>/dt</i> + <i>m</i> <i>c</i><sub>v</sub> <i>dT/dt</i> + <i>m du/d<code>&rho;</code> d<code>&rho;</code>/dt</i> = 
-    <code>&sum;</code> <i><code>&#7745;</code> h </i> + <code>&sum;</code> <i>Q</i> </p>
-    <p>where <i>c</i><sub>v</sub> is the specific heat capacity at constant volume, <i>u</i> is the specific internal energy at the current density and temperature, <i>h</i> is the specific enthalpy of the incoming and outflowing VLE streams, and <i>Q</i> is the heat flow.</p>
-    <p>The partial derivative <i>du/d<code>&rho;</code></i> can be expressed as:</p>
-    <p align=\"center\"><i>du/d<code>&rho;</code></i> = 1/<i><code>&rho;</code></i><sup>2</sup> <i>( -p + T dpdT )</i> </p>
-    <p>where <i>dpdT</i> can be substituted with the equation of Clausius-Clayperon: <i>dpdT = (h<sup>v</sup> - h<sup>l</sup>) / (T (v<sup>v</sup> - v<sup>l</sup>)</i>. <br>
-    For more information see Gräber (2011) and Tummescheit (2002). <br></p>
-    The VLE phase seperator has two VLE ports, a liquid and a vapour VLE port. At the liquid VLE port, the specific enthalpy of the leaving fluid is slightly subccoled, at the vapour VLE port, the specific enthalpy of the leaving fluid is slightly superheated.
-  </p>
-  <h4>Assumptions and limitations</h4>
-
-  <p>
-    The model uses the following main assumptions:
-    <ul>
-      <li>Liquid and vapour phase are in chemical equilibrium --> same pressure and temperature</li>
-    </ul>
-  </p>
-  <h4>Typical use and important parameters</h4>
-  <p>
-    For adsorption systems, the VLE phase separator is a core part of the the evaporator/condenser component.
-  </p>
-  <h4>Dynamics</h4>
-  <p>
-    The model has two states: the temperature <i>T</i> and the density <i><code>&rho;</code></i>.
-  </p>
-  <h4>References</h4>
-  <p>
-    <ul>
-      <li>Tummescheit, H. Design and Implementation of Object-Oriented Model Libraries using Modelica. PhD Thesis. Lund, 2002.</li>
-      <li>Gräber, M.; Kirches, C.; Bock, H.G.; Schlöder, J.P.; Tegethoff, W.; Köhler, J. Determining the optimum cyclic operation of adsorption chillers by a direct method for periodic optimal control. Int. J. Refrig., 2011, 34(4), 902-913.</li>
-    </ul>
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>November 22, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>
-"));
-end VLEPhaseSeparator;
diff --git a/SorpLib/Components/Cells/VLEPhaseSeparator/package.mo b/SorpLib/Components/Cells/VLEPhaseSeparator/package.mo
deleted file mode 100644
index 6c6f663..0000000
--- a/SorpLib/Components/Cells/VLEPhaseSeparator/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.Cells;
-package VLEPhaseSeparator
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-end VLEPhaseSeparator;
diff --git a/SorpLib/Components/Cells/VLEPhaseSeparator/package.order b/SorpLib/Components/Cells/VLEPhaseSeparator/package.order
deleted file mode 100644
index 47b6b56..0000000
--- a/SorpLib/Components/Cells/VLEPhaseSeparator/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-VLEPhaseSeparator
-Testers
diff --git a/SorpLib/Components/Cells/Wall/Testers/TestWall.mo b/SorpLib/Components/Cells/Wall/Testers/TestWall.mo
deleted file mode 100644
index 9d011ec..0000000
--- a/SorpLib/Components/Cells/Wall/Testers/TestWall.mo
+++ /dev/null
@@ -1,43 +0,0 @@
-within SorpLib.Components.Cells.Wall.Testers;
-model TestWall
-
-  Wall wall(
-    redeclare model WallMaterial = TILMedia.SolidTypes.TILMedia_Steel,
-    volume=0.1,
-    TInitial=333.15)
-    annotation (Placement(transformation(extent={{-8,-6},{8,6}})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary2(
-    Q_flowFixed=5000,
-    boundaryType="T",
-    TFixed=298.15) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={0,40})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary1(boundaryType="Q_flow",
-      Q_flowFixed=-8000) annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={0,-20})));
-  HeatTransfer.HeatTransfer heatTransfer(redeclare model HeatTransfer =
-        HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (constantAlphaA=500))
-    annotation (Placement(transformation(
-        extent={{-8,-4},{8,4}},
-        rotation=90,
-        origin={0,22})));
-equation
-  connect(heatBoundary1.heatPort, wall.heatPortA) annotation (Line(
-      points={{0,-20},{0,-6}},
-      color={204,0,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(heatTransfer.heatPortA, wall.heatPortB) annotation (Line(
-      points={{0,14},{0,5.7}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatBoundary2.heatPort, heatTransfer.heatPortB[1]) annotation (Line(
-      points={{0,40},{0,35},{0,30}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-            -100},{100,100}})), experiment(StopTime=1000));
-end TestWall;
diff --git a/SorpLib/Components/Cells/Wall/Testers/package.mo b/SorpLib/Components/Cells/Wall/Testers/package.mo
deleted file mode 100644
index 0e04418..0000000
--- a/SorpLib/Components/Cells/Wall/Testers/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.Cells.Wall;
-package Testers
-  extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-end Testers;
diff --git a/SorpLib/Components/Cells/Wall/Testers/package.order b/SorpLib/Components/Cells/Wall/Testers/package.order
deleted file mode 100644
index 0017d6d..0000000
--- a/SorpLib/Components/Cells/Wall/Testers/package.order
+++ /dev/null
@@ -1 +0,0 @@
-TestWall
diff --git a/SorpLib/Components/Cells/Wall/Wall.mo b/SorpLib/Components/Cells/Wall/Wall.mo
deleted file mode 100644
index 433249c..0000000
--- a/SorpLib/Components/Cells/Wall/Wall.mo
+++ /dev/null
@@ -1,108 +0,0 @@
-within SorpLib.Components.Cells.Wall;
-model Wall
-
-   /********************* Connectors ****************************************/
-
-  TIL.Connectors.HeatPort heatPortA
-    annotation (Placement(transformation(extent={{-10,-50},{10,-30}}),
-        iconTransformation(extent={{-10,-50},{10,-30}})));
-  TIL.Connectors.HeatPort heatPortB
-    annotation (Placement(transformation(extent={{-10,28},{10,48}}),
-        iconTransformation(extent={{-10,28},{10,48}})));
-  TIL.Connectors.HeatPort heatPortC
-    annotation (Placement(transformation(extent={{68,-10},{88,10}}),
-        iconTransformation(extent={{68,-10},{88,10}})));
-  TIL.Connectors.HeatPort heatPortD
-    annotation (Placement(transformation(extent={{-88,-10},{-68,10}}),
-        iconTransformation(extent={{-88,-10},{-68,10}})));
-
-  /********************* Solid ****************************************/
-
-  replaceable model WallMaterial = TILMedia.SolidTypes.BaseSolid constrainedby
-    TILMedia.SolidTypes.BaseSolid "Wall material" annotation (choicesAllMatching=true, Dialog(
-        group="Solid type"));
-
-  TILMedia.Solid wallMaterial(T=T,
-    redeclare model SolidType=WallMaterial) "Wall material properties" annotation (Placement(
-        transformation(extent={{-10,-12},{10,8}},  rotation=0)));
-
-  Modelica.SIunits.Temperature T "Temperature of wall material";
-
-  /********************* Parameters ****************************************/
-
-  parameter Modelica.SIunits.Volume volume "Volume of wall cell";
-
-  final parameter Modelica.SIunits.Mass mass=wallMaterial.d*volume
-    "Mass of wall cell";
-
-  /********************* Initialization ********************************/
-
-  parameter Modelica.SIunits.Temperature TInitial "Initial Temperature" annotation (Dialog(group="Initial Values", tab="Start and Initialization"));
-
-initial equation
-
-  T=TInitial;
-
-equation
-
-  // Heat ports
-  heatPortA.T=T;
-  heatPortB.T=T;
-  heatPortC.T=T;
-  heatPortD.T=T;
-
-  // Energy balance
-  mass*wallMaterial.cp*der(T) =heatPortA.Q_flow + heatPortB.Q_flow +
-    heatPortA.Q_flow + heatPortB.Q_flow;
-
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false,extent={{-80,-40},
-            {80,40}}), graphics={Bitmap(extent={{-95,40},{94,-42}},
-            fileName=
-              "modelica://SorpLib/Resources/Images/Wall.png")}),
-                               Diagram(coordinateSystem(preserveAspectRatio=
-            true, extent={{-80,-40},{80,40}}), graphics),
-    Documentation(info="<html>
-  <p>
-    This model represents a wall cell. For a cell, a lumped model approach is used with an uniform Temperatur. By combining more cells with a finite volume approach, a distributed model can be built, with a spatial and temperature distribution. The model has four heat ports to exchange heat with connected components. <br>
-    
-  </p>
-  <h4>Main equations</h4>
-  <p>    
-    <p>Energy balance: </p>
-    <p align=\"center\"> <i>m</i> <i>c</i> <i>dT/dt</i> = <code>&sum;</code> <i>Q</i> </p>
-    <p>where <i>m</i> is the mass, <i>c</i> is the specific heat capacity, <i>T</i> is the temperature and <i>Q</i> is the heat flow. </p>
-    The temperature at each heat port is set equal to the wall temperature <i>T</i>.
-  </p>
-
-  <h4>Assumptions and limitations</h4>
-
-  <p>
-    The model uses the following main assumptions:
-    <ul>
-      <li>The wall cell has a uniform temperature --> heat conduction is not considered</li>
-    </ul>
-  </p>
-
-  <h4>Typical use and important parameters</h4>
-  <p>
-    In heat exchangers the wall cell represents the thermal capacity of the metal mass. 
-  </p>
-  <h4>Dynamics</h4>
-  <p>
-    The model has one state: the temperature <i>T</i>.
-  </p>
-  <h4>References</h4>
-  <p>
-    <ul>
-    </ul>
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>November 23, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end Wall;
diff --git a/SorpLib/Components/Cells/Wall/package.mo b/SorpLib/Components/Cells/Wall/package.mo
deleted file mode 100644
index ed4dc65..0000000
--- a/SorpLib/Components/Cells/Wall/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.Cells;
-package Wall
-  extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-end Wall;
diff --git a/SorpLib/Components/Cells/package.mo b/SorpLib/Components/Cells/package.mo
deleted file mode 100644
index 71803c3..0000000
--- a/SorpLib/Components/Cells/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components;
-package Cells
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-
-
-end Cells;
diff --git a/SorpLib/Components/Cells/package.order b/SorpLib/Components/Cells/package.order
deleted file mode 100644
index ada36aa..0000000
--- a/SorpLib/Components/Cells/package.order
+++ /dev/null
@@ -1,4 +0,0 @@
-Adsorbent
-Gas
-Wall
-VLEPhaseSeparator
diff --git a/SorpLib/Components/ClosedAdsorber/Adsorber.mo b/SorpLib/Components/ClosedAdsorber/Adsorber.mo
deleted file mode 100644
index cbc651e..0000000
--- a/SorpLib/Components/ClosedAdsorber/Adsorber.mo
+++ /dev/null
@@ -1,338 +0,0 @@
-within SorpLib.Components.ClosedAdsorber;
-model Adsorber
-  "adsorber model including adsorbent, tube heat exchanger, and casing (optional) "
-  /********************************** SIM ***********************************/
-  parameter TILMedia.VLEFluidTypes.BaseVLEFluid vleFluidType=sim.vleFluidType1
-    "VLE fluid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.vleFluidType1 "VLE fluid 1 as defined in SIM",
-      choice=sim.vleFluidType2 "VLE fluid 2 as defined in SIM",
-      choice=sim.vleFluidType3 "VLE fluid 3 as defined in SIM"));
-
-  parameter TILMedia.LiquidTypes.BaseLiquid liquidType=sim.liquidType1
-    "Liquid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.liquidType1 "Liquid 1 as defined in SIM",
-      choice=sim.liquidType2 "Liquid 2 as defined in SIM",
-      choice=sim.liquidType3 "Liquid 3 as defined in SIM"));
-
-protected
-  outer TIL.SystemInformationManager sim "System information manager";
-  TIL.Internals.SimPort simPort;
-
-  /*************************** Connectors *************************************/
-public
-  TIL.Connectors.VLEFluidPort vlePortA(final vleFluidType=vleFluidType)
-    "VLE Port A" annotation (Placement(transformation(extent={{-4,17},{16,37}},
-          rotation=0), iconTransformation(extent={{-4,17},{16,37}})));
-  TIL.Connectors.VLEFluidPort vlePortB(final vleFluidType=vleFluidType)
-    "VLE Port B" annotation (Placement(transformation(extent={{-4,-55},{16,-35}},
-          rotation=0), iconTransformation(extent={{-4,-55},{16,-35}})));
-
-  TIL.Connectors.LiquidPort liquidPortA(liquidType=liquidType) "Liquid PortA"
-    annotation (Placement(transformation(extent={{65,-41},{85,-21}}),
-        iconTransformation(extent={{65,-41},{85,-21}})));
-  TIL.Connectors.LiquidPort liquidPortB(liquidType=liquidType) "Liquid Port B"
-    annotation (Placement(transformation(extent={{65,0},{85,20}}),
-        iconTransformation(extent={{65,0},{85,20}})));
-
-  TIL.Connectors.HeatPort heatPort if (enableHeatPort and enableCasing)
-    annotation (Placement(transformation(extent={{-69,-20},{-49,0}},
-                                                                   rotation=0),
-        iconTransformation(extent={{-69,-20},{-49,0}})));
-
-  /******************** Components ***************************/
-
-  /***************************** Adsorbent ***********************************/
-
-public
-  Cells.Adsorbent.Adsorbent adsorbent(
-    vleFluidType=vleFluidType,
-    massAdsorbent=massAdsorbent,
-    includeDefaultSummary=includeDefaultSummary,
-    xInitial=xInitial,
-    TInitial=TInitial,
-    pInitial=pInitial,
-    initial_x=initial_x,
-    redeclare final model AdsorbentAdsorbateModel = AdsorbentAdsorbateModel,
-    generateEventsAtFlowReversal=generateEventsAtFlowReversal) annotation (
-      Placement(transformation(
-        extent={{-10,-10},{10,10}},
-        rotation=270,
-        origin={6,-10})));
-
-  /*********************** Heat exchanger ***********************************/
-
-  TIL.LiquidComponents.Tubes.Tube heatexchanger(
-    enableHeatPorts=true,
-    initLiquid="linearTemperatureDistribution",
-    liquidType=liquidType,
-    steadyStateContinuity=true,
-    nCells=nCells,
-    redeclare model WallHeatConductionModel =
-      TIL.LiquidComponents.Tubes.TransportPhenomena.WallHeatTransfer.GeometryBasedConduction,
-    redeclare parameter TubeGeometry tubeGeometry,
-    redeclare model TubeSideHeatTransferModel = TubeSideHeatTransferModel,
-    redeclare model PressureDropModel = PressureDropModel,
-    redeclare model WallMaterial = WallMaterial_hx,
-    TInitialWall(displayUnit="degC") = hx_TInitialWall,
-    TInitialLiquid_CellN=hx_TInitialCelln,
-    includeDefaultSummary=includeDefaultSummary,
-    TInitialLiquid_Cell1=hx_TInitialCell1) annotation (Placement(transformation(
-        extent={{8,2},{-8,-2}},
-        rotation=270,
-        origin={51,-9.5})));
-
-  /******************************** Casing ***********************************/
-
-  TIL.OtherComponents.Thermal.HeatCapacitor casing(
-    solidMass=massCasing,
-    TInitial=TInitialCasing,
-    inputType="m, solid",
-    redeclare model WallMaterial = WallMaterial_casing) if enableCasing annotation (Placement(
-        transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=180,
-        origin={-38,-4})));
-
-  /********************* General Parameters ************************************/
-
-  inner parameter Boolean enableCasing=true "true, if casing is modeled"
-    annotation (Dialog(group="Casing"));
-
-  inner parameter Boolean enableHeatPort=true
-    "true, if heat port to environment is enabled"
-    annotation (Dialog(enable=enableCasing, group="Casing"));
-
-  /********************* Parameters Heat Exchanger*****************************/
-
-  replaceable model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Steel
-    constrainedby TILMedia.SolidTypes.BaseSolid
-    "Wall material of heat exchanger" annotation (choicesAllMatching=true,
-      Dialog(group="Heat Exchanger"));
-
-   inner replaceable record TubeGeometry =
-      SorpLib.Components.ClosedAdsorber.Geometry.TubeGeometry constrainedby
-    SorpLib.Components.ClosedAdsorber.Geometry.TubeGeometry
-    "Geometry of tube" annotation (choicesAllMatching=true, Dialog(group="Heat Exchanger"));
-
-  inner parameter TubeGeometry adsorberTubeGeometry "Geometry of adsorber tube";
-
-  parameter Integer nCells(min=1) = 1
-    "Number of cells of heat exchanger (Discretization level of HX)"
-    annotation (Dialog(group="Heat Exchanger"));
-
-  /********************* Parameters Adsorbent*****************************/
-
-  parameter Modelica.SIunits.Mass massAdsorbent=5 "Mass of dry sorbent"
-    annotation (Dialog(group="Adsorbent / Adsorbate"));
-  parameter Modelica.SIunits.Mass massCasing=2 "Mass of Container"
-    annotation (Dialog(group="Casing", enable=enableCasing));
-  replaceable model WallMaterial_casing = TILMedia.SolidTypes.TILMedia_Steel
-    constrainedby TILMedia.SolidTypes.BaseSolid "Wall material of casing"
-    annotation (choicesAllMatching=true, Dialog(enable=enableCasing, group="Casing"));
-
-  /*********************** Adorbent Adsorbate Model *************************/
-  replaceable model AdsorbentAdsorbateModel =
-      SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater
-    constrainedby
-    SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater
-    " Water-Sorbent Model" annotation (
-    Placement(transformation(extent={{-32,-70},{-12,-50}})),
-    choicesAllMatching=true,
-    Dialog(group="Adsorbent / Adsorbate"));
-
-  /*********************** Heat transfer models ****************************/
-
-  HeatTransfer.HeatTransfer heatTransfer_1_n_HX(n=nCells, redeclare model
-      HeatTransfer = HeatTransferModel_HX) annotation (Placement(transformation(
-        extent={{-6.25,-3.25},{6.25,3.25}},
-        rotation=0,
-        origin={30.25,-9.75})));
-
-  HeatTransfer.HeatTransfer heatTransfer_inner(redeclare model HeatTransfer =
-        HeatTransferModel_InternalCoupling) if      enableCasing annotation (
-      Placement(transformation(
-        extent={{-6,-3},{6,3}},
-        rotation=180,
-        origin={-21,-10})));
-
-  replaceable model HeatTransferModel_HX =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "Adsorber heat transfer model between adsorber and heat exchanger wall"
-    annotation (
-    extend=[10,20; -10,40],
-    Dialog(group="Heat Transfer"),
-    choices(choice(redeclare model
-                HeatTransferModel_HX =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha),
-            choice(redeclare model HeatTransferModel_HX =
-          SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA),
-            choice(redeclare model HeatTransferModel_HX =
-          SorpLib.Components.ClosedAdsorber.RecordsTransportCoefficients.HeatTransfer.HeatTransferSilicaGel_Lanzerath2015),
-             choice(redeclare model HeatTransferModel_HX =
-          SorpLib.Components.ClosedAdsorber.RecordsTransportCoefficients.HeatTransfer.HeatTransferZeolith13X_Lanzerath2015)));
-
-  replaceable model HeatTransferModel_InternalCoupling =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "Adsorber heat transfer model for connection between adsorbent and casing"
-    annotation (
-    extend=[10,20; -10,40],
-    choices(choice(redeclare model
-                HeatTransferModel_InternalCoupling =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha),
-            choice(redeclare model HeatTransferModel_InternalCoupling =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA)),
-    Dialog(group="Casing", enable=enableCasing));
-
-  replaceable model TubeSideHeatTransferModel =
-      TIL.LiquidComponents.Tubes.TransportPhenomena.HeatTransfer.PartialHeatTransfer
-    constrainedby
-    TIL.LiquidComponents.Tubes.TransportPhenomena.HeatTransfer.PartialHeatTransfer
-    "Tube side heat transfer model" annotation (
-    extend=[10,20; -10,40],
-    choicesAllMatching=true,
-    Dialog(group="Heat Transfer"));
-
-  /*********************** Pressure drop ****************************/
-
-  replaceable model PressureDropModel =
-      TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop
-    constrainedby
-    TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.PartialPressureDrop
-    "Pressure drop model" annotation (
-    choicesAllMatching=true,
-    Dialog(group="Heat Exchanger"),
-    Placement(transformation(extent={{-10,20},{10,40}}, rotation=0)));
-
-  /*******************Summary**********************/
-public
-  inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-
-protected
-  record Summary
-    extends TIL.Internals.ClassTypes.Record;
-
-    Modelica.SIunits.Temperature T_liq_A if include;
-    Modelica.SIunits.Temperature T_liq_B if include;
-    Modelica.SIunits.Temperature T_cas if (include and enableCasing);
-    Modelica.SIunits.Pressure p_ad if include;
-    Real x_ad if include;
-    Modelica.SIunits.Temperature T_ad if include;
-    Modelica.SIunits.EnthalpyFlowRate DeltaH_flow_liq if include;
-    Modelica.SIunits.HeatFlowRate Q_flow_liq_ad if include;
-    Modelica.SIunits.HeatFlowRate Q_flow_ad_cas if (include and enableCasing);
-    Modelica.SIunits.HeatFlowRate Q_flow_cas_amb if (include and enableHeatPort);
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-    outer parameter Boolean enableCasing;
-    outer parameter Boolean enableHeatPort;
-
-  end Summary;
-
-  replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    T_liq_A=heatexchanger.summary.T_liq_A,
-    T_liq_B=heatexchanger.summary.T_liq_B,
-    T_cas=casing.T,
-    p_ad=adsorbent.adsorbentAdsorbate.p,
-    x_ad=adsorbent.x,
-    T_ad=adsorbent.T,
-    DeltaH_flow_liq = heatexchanger.portA.m_flow*(heatexchanger.summary.h_liq_A-heatexchanger.summary.h_liq_B),
-    Q_flow_liq_ad = -heatexchanger.summary.Q_flow_liq,
-    Q_flow_ad_cas = heatTransfer_inner.heatPortA.Q_flow,
-    Q_flow_cas_amb = heatPort.Q_flow) annotation (Placement(transformation(extent={{-59,-59},
-            {-39,-39}},rotation=0)));
-
-  /*************************  Advanced  ******************************/
-
-  parameter Boolean generateEventsAtFlowReversal=false
-    "If true, tranport propertie are calculated in the gas object"
-    annotation (Evaluate=true, Dialog(tab="Advanced", group="Event-Handling"));
-
-  /********************* Initialization ********************************/
-  parameter Modelica.SIunits.Temperature TInitial=343.15
-    annotation (Dialog(group="Sorbent / Sorbate", tab="Initialization"));
-  parameter Boolean initial_x=true "if true then xInital else pInitial"
-    annotation (Dialog(group="Sorbent / Sorbate", tab="Initialization"));
-  parameter Real xInitial=0.2 annotation (Dialog(
-      enable=initial_x,
-      group="Sorbent / Sorbate",
-      tab="Initialization"));
-  parameter Modelica.SIunits.Pressure pInitial=10e2 annotation (Dialog(
-      enable=not initial_x,
-      group="Sorbent / Sorbate",
-      tab="Initialization"));
-
-  parameter Modelica.SIunits.Temperature hx_TInitialCell1=288.15
-    "Initial Temperature of heat exchanger fluid in cell 1"
-    annotation (Dialog(tab="Initialization", group="Heat Exchanger"));
-  parameter Modelica.SIunits.Temperature hx_TInitialCelln=298.15
-    "Initial Temperature of heat exchanger fluid in cell n"
-    annotation (Dialog(tab="Initialization", group="Heat Exchanger"));
-  parameter Modelica.SIunits.Temperature hx_TInitialWall=293.15
-    "Initial Temperature of heat exchanger wall"
-    annotation (Dialog(tab="Initialization", group="Heat Exchanger"));
-
-  parameter Modelica.SIunits.Temperature TInitialCasing=343.15
-    annotation (Dialog(group="Casing", tab="Initialization"));
-
-equation
-
-  connect(heatTransfer_1_n_HX.heatPortB, heatexchanger.heatPort) annotation (
-      Line(
-      points={{36.5,-9.75},{49,-9.75},{49,-9.5}},
-      color={204,0,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(adsorbent.vlePortA, vlePortA) annotation (Line(
-      points={{6,-2.8},{6,27}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(adsorbent.vlePortB, vlePortB) annotation (Line(
-      points={{6,-17.2},{6,-45}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(liquidPortA, heatexchanger.portA) annotation (Line(
-      points={{75,-31},{51,-31},{51,-17.5}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(heatexchanger.portB, liquidPortB) annotation (Line(
-      points={{51,-1.5},{51,-1.5},{51,10},{75,10}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(adsorbent.heatPortB, heatTransfer_1_n_HX.heatPortA) annotation (Line(
-      points={{12,-10},{13,-10},{13,-9.75},{24,-9.75}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer_inner.heatPortB[1], casing.heatPort) annotation (Line(
-      points={{-27,-10},{-38,-10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(casing.heatPort, heatPort) annotation (Line(
-      points={{-38,-10},{-38,-10},{-59,-10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer_inner.heatPortA, adsorbent.heatPortA) annotation (Line(
-      points={{-15,-10},{-15,-10},{0,-10}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(
-        preserveAspectRatio=true,
-        grid={1,1},
-        extent={{-60,-60},{70,40}})), Icon(coordinateSystem(preserveAspectRatio=
-           true, grid={1,1}, extent={{-60,-60},{70,40}}), graphics={Bitmap(
-          extent={{-57,-59},{77,41}},
-          imageSource="iVBORw0KGgoAAAANSUhEUgAAAiIAAAGLCAYAAAD6T/mRAAAAAXNSR0ICQMB9xQAAAAlwSFlzAAAXEgAAFxIBZ5/SUgAAABl0RVh0U29mdHdhcmUATWljcm9zb2Z0IE9mZmljZX/tNXEAACOXSURBVHja7d0tcFXJuoDhJZGRyEhkJDISGYmMREbGwGEUx41EIrkOiUDsjEIikZGpW1fkuqg53NVr9tzJwM6w9/rp7q/Xc6reOlVMCP3fb/fqr7vruu7bfX755ZcOAADURavz9Q8ZA1rHgNbuwAwYy4gIoPOCiADGMiICEBEiAhjLiAig84KIAMay/UXE4AYAQP3iTUQAAAARISIAABARIgIAAIgIEQEAgIgQEQAAQESICAAARISIAAAAIkJEAAAgIkQEAAAQESICAAARISIAAICIqGwAAIgIEQEAAEQEAAAQESICAAARISIAAICIEBEAAIgIEQEAAESEiAAAQESICAAAICJEBAAAIkJEAAAAESEiAAAQESICAACICBEBAICIEBEAAEBEiAgAAESEiAAAACICAACICBEBAABEBAAAEBEiAgAAESEiAACAiBARAACICBEBAABEhIgAAEBEiAgAACAiRAQAACJCRAAAABEhIgAAEBEiAgAAiAgRAQCAiBARAABARIgIAABEhIgAAAAiAgAAiAgRAQCAiBARAABARIgIAABEhIgAAAAiQkQAACAiRAQAABARIgIAABEhIgAAgIgQEQAAiAgRAQAARISIAABARIgIAAAgIkQEAAAiQkQAAAARAQAARISIAAAAIgIAAIgIEQEAgIgQEQAAQESICAAARISIAAAAIkJEAAAgIkQEAAAQESICAAARISIAAICIEBEAAIgIEQEAAESEiAAAQESICAAAICJEBAAAIkJEAAAAEQEAAESEiDTCt0/do2+b7nnP6/9cdZv7/P5b96b/8/P+Zx7LawXp33THPRd9Wt/+Le1X3bv+zy97Tpppl43ndU11Kd9tlw0RwaRG3zfw99+uum/7kDpE/3eeyWuR9J/2afq8Z9qv+59/EbhdNp3XNdVl5HznXLREbxNEBKM6WN+Rfu0b9N2+E/MPk3SQHZLoeU3/dp+GDyPT/iXS6rL1vK6pLiPnO+eipZU2QURwcCcbGvCIhv9dJ7jpf9dTeV00/SfD6mda2u/633MWoF02ndc11WXUfOde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",
-          fileName="modelica://SorpLib/Resources/Images/ClosedAdsorber.png")}));
-end Adsorber;
diff --git a/SorpLib/Components/ClosedAdsorber/Geometry/Adsorber_Finned_Tubes_Alu.mo b/SorpLib/Components/ClosedAdsorber/Geometry/Adsorber_Finned_Tubes_Alu.mo
deleted file mode 100644
index ee79202..0000000
--- a/SorpLib/Components/ClosedAdsorber/Geometry/Adsorber_Finned_Tubes_Alu.mo
+++ /dev/null
@@ -1,14 +0,0 @@
-within SorpLib.Components.ClosedAdsorber.Geometry;
-record Adsorber_Finned_Tubes_Alu
-  "Finned tube Alu used for dissertation Lanzerath and mobile adsorption project"
-  extends TubeGeometry(
-    final innerDiameter=0.01285,
-    final wallThickness=0.004005,
-    length=7.355,
-    final nParallelTubes=1,
-    final crossSectionType=TIL.Internals.CrossSectionType.Circular,
-    final innerCrossSectionalAreaNonCircular=0,
-    final outerCrossSectionalAreaNonCircular=0,
-    final innerPerimeterNonCircular=0);
-
-end Adsorber_Finned_Tubes_Alu;
diff --git a/SorpLib/Components/ClosedAdsorber/Geometry/TubeGeometry.mo b/SorpLib/Components/ClosedAdsorber/Geometry/TubeGeometry.mo
deleted file mode 100644
index b49296c..0000000
--- a/SorpLib/Components/ClosedAdsorber/Geometry/TubeGeometry.mo
+++ /dev/null
@@ -1,56 +0,0 @@
-within SorpLib.Components.ClosedAdsorber.Geometry;
-record TubeGeometry "Geometry record for a tube"
-  extends SorpLib.Internals.ClassTypes.Record;
-
-  parameter Modelica.SIunits.Diameter innerDiameter=0.01
-    "Inner diameter of circular tube" annotation (Dialog(group="Geometry",
-        enable=(crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-  parameter Modelica.SIunits.Length wallThickness=0.0005 "Wall thickness"
-    annotation (Dialog(group="Geometry", enable=(crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-  parameter Modelica.SIunits.Length length=1 "|Geometry|Length";
-
-  parameter Integer nParallelTubes(min=1) = 1
-    "|Geometry|Number of parallel Tubes";
-
-  parameter TIL.Internals.CrossSectionType crossSectionType=TIL.Internals.CrossSectionType.Circular
-    "|Geometry|Tube Cross Section Type";
-
-  parameter Modelica.SIunits.Area innerCrossSectionalAreaNonCircular=0
-    "Inner cross sectional area of one non-circular tube" annotation (Dialog(
-        group="Geometry", enable=not (crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-
-  parameter Modelica.SIunits.Area outerCrossSectionalAreaNonCircular=0
-    "Outer cross sectional area of one non-circular tube" annotation (Dialog(
-        group="Geometry", enable=not (crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-
-  parameter Modelica.SIunits.Length innerPerimeterNonCircular=0
-    "Perimeter of one non-circular tube" annotation (Dialog(group="Geometry",
-        enable=not (crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-
-  final parameter Modelica.SIunits.Diameter outerDiameter=innerDiameter + 2*
-      wallThickness;
-  final parameter Modelica.SIunits.Area innerCrossSectionalArea=if
-      tubeIsCircular then Modelica.Constants.pi*innerDiameter*innerDiameter/4.0
-      *nParallelTubes else innerCrossSectionalAreaNonCircular*nParallelTubes
-    "Inner cross-sectional area";
-  final parameter Modelica.SIunits.Area outerCrossSectionalArea=if
-      tubeIsCircular then Modelica.Constants.pi*outerDiameter*outerDiameter/4.0
-      *nParallelTubes else outerCrossSectionalAreaNonCircular*nParallelTubes
-    "Outer cross-sectional area";
-  final parameter Modelica.SIunits.Area hydraulicCrossSectionalArea=if
-      tubeIsCircular then Modelica.Constants.pi*innerDiameter*innerDiameter/4.0
-       else innerCrossSectionalAreaNonCircular "Hydraulic cross sectional area";
-  final parameter Modelica.SIunits.Diameter hydraulicDiameter=if tubeIsCircular
-       then innerDiameter else 4*innerCrossSectionalAreaNonCircular/
-      innerPerimeterNonCircular "Hydraulic diameter";
-  final parameter Modelica.SIunits.Volume innerVolume=innerCrossSectionalArea*
-      length "Inner volume";
-  final parameter Modelica.SIunits.Volume outerVolume=outerCrossSectionalArea*
-      length "Outer volume";
-  final parameter Modelica.SIunits.Area innerHeatTransferArea=if tubeIsCircular
-       then Modelica.Constants.pi*innerDiameter*length*nParallelTubes else
-      innerPerimeterNonCircular*length*nParallelTubes;
-  final parameter Boolean tubeIsCircular=(crossSectionType == TIL.Internals.CrossSectionType.Circular)
-    "true, if tube's cross section is circular";
-
-end TubeGeometry;
diff --git a/SorpLib/Components/ClosedAdsorber/Geometry/package.mo b/SorpLib/Components/ClosedAdsorber/Geometry/package.mo
deleted file mode 100644
index 96a51a7..0000000
--- a/SorpLib/Components/ClosedAdsorber/Geometry/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.ClosedAdsorber;
-package Geometry
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-end Geometry;
diff --git a/SorpLib/Components/ClosedAdsorber/Geometry/package.order b/SorpLib/Components/ClosedAdsorber/Geometry/package.order
deleted file mode 100644
index ca85bb4..0000000
--- a/SorpLib/Components/ClosedAdsorber/Geometry/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-TubeGeometry
-Adsorber_Finned_Tubes_Alu
diff --git a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/HeatTransferSilicaGel_Lanzerath2015.mo b/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/HeatTransferSilicaGel_Lanzerath2015.mo
deleted file mode 100644
index efedc1f..0000000
--- a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/HeatTransferSilicaGel_Lanzerath2015.mo
+++ /dev/null
@@ -1,28 +0,0 @@
-within SorpLib.Components.ClosedAdsorber.RecordsTransportCoefficients.HeatTransfer;
-model HeatTransferSilicaGel_Lanzerath2015
-  "Heat transfer coefficient heat exchanger to adsorbent (Silica gel) (Lanzerath2015)"
-  extends SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha(final constantAlpha=686.7, final heatTransferArea=Modelica.Constants.pi*0.02086*adsorberTubeGeometry.length);
-
-  outer parameter SorpLib.Components.ClosedAdsorber.Geometry.TubeGeometry adsorberTubeGeometry;
-
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    Documentation(info="<html>
-<p>
-  The heat transfer coefficient in this record was determined by Lanzerath et. al. (2015) for silica gel 123 particles.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end HeatTransferSilicaGel_Lanzerath2015;
diff --git a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/HeatTransferZeolith13X_Lanzerath2015.mo b/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/HeatTransferZeolith13X_Lanzerath2015.mo
deleted file mode 100644
index b6f20cf..0000000
--- a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/HeatTransferZeolith13X_Lanzerath2015.mo
+++ /dev/null
@@ -1,28 +0,0 @@
-within SorpLib.Components.ClosedAdsorber.RecordsTransportCoefficients.HeatTransfer;
-model HeatTransferZeolith13X_Lanzerath2015
-  "Heat transfer coefficient heat exchanger to adsorbent (Zeolite13X) (Lanzerath2015)"
-  extends SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha(final constantAlpha=294.6, final heatTransferArea=Modelica.Constants.pi*0.02086*adsorberTubeGeometry.length);
-
-  outer parameter SorpLib.Components.ClosedAdsorber.Geometry.TubeGeometry adsorberTubeGeometry;
-
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    Documentation(info="<html>
-<p>
-  The heat transfer coefficient in this record was determined by Lanzerath et. al. (2015) for zeolite 13 X particles.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end HeatTransferZeolith13X_Lanzerath2015;
diff --git a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/package.mo b/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/package.mo
deleted file mode 100644
index 6e41626..0000000
--- a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.ClosedAdsorber.RecordsTransportCoefficients;
-package HeatTransfer
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-end HeatTransfer;
diff --git a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/package.order b/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/package.order
deleted file mode 100644
index 14a2e44..0000000
--- a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/HeatTransfer/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-HeatTransferSilicaGel_Lanzerath2015
-HeatTransferZeolith13X_Lanzerath2015
diff --git a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/package.mo b/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/package.mo
deleted file mode 100644
index 9c840d9..0000000
--- a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.ClosedAdsorber;
-package RecordsTransportCoefficients
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-end RecordsTransportCoefficients;
diff --git a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/package.order b/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/package.order
deleted file mode 100644
index 2dc6ac8..0000000
--- a/SorpLib/Components/ClosedAdsorber/RecordsTransportCoefficients/package.order
+++ /dev/null
@@ -1 +0,0 @@
-HeatTransfer
diff --git a/SorpLib/Components/ClosedAdsorber/Testers/TestAdsorber1.mo b/SorpLib/Components/ClosedAdsorber/Testers/TestAdsorber1.mo
deleted file mode 100644
index 2cd0549..0000000
--- a/SorpLib/Components/ClosedAdsorber/Testers/TestAdsorber1.mo
+++ /dev/null
@@ -1,96 +0,0 @@
-within SorpLib.Components.ClosedAdsorber.Testers;
-model TestAdsorber1
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1, redeclare
-      TILMedia.LiquidTypes.TILMedia_Water liquidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  Adsorber adsorber(
-    enableHeatPort=false,
-    xInitial=0.10,
-    initial_x=true,
-    redeclare model HeatTransferModel_InternalCoupling =
-        SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA,
-    enableCasing=false,
-    redeclare model AdsorbentAdsorbateModel =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Aluminum,
-    nCells=10,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    includeDefaultSummary=true,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ConstantZeta
-        (zeta=1, massFlowLimit=0.001),
-    redeclare record TubeGeometry = Geometry.Adsorber_Finned_Tubes_Alu,
-    redeclare model HeatTransferModel_HX =
-        RecordsTransportCoefficients.HeatTransfer.HeatTransferSilicaGel_Lanzerath2015,
-    TInitial=303.15,
-    hx_TInitialCell1=293.15,
-    hx_TInitialCelln=293.15,
-    hx_TInitialWall=293.15)
-    annotation (Placement(transformation(extent={{-10,-8},{10,8}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundaryA(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=270,
-        origin={0,20})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_vapour(
-    height=-0.001,
-    offset=0.001,
-    startTime=50) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={2,38})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_liquid(
-    height=0.001,
-    offset=-0.001,
-    startTime=100) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=90,
-        origin={-2,-36})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundaryB(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true,
-    hFixed=2.5e6) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={0,-20})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryB(boundaryType="p")
-    annotation (Placement(transformation(extent={{36,6},{44,26}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryA(m_flowFixed=-0.1, TFixed=
-        313.15)
-    annotation (Placement(transformation(extent={{36,-24},{44,-4}})));
-equation
-  connect(adsorber.vlePortA, vleBoundaryA.port) annotation (Line(
-      points={{0.153846,5.92},{0.153846,11.46},{0,11.46},{0,20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(adsorber.vlePortB, vleBoundaryB.port) annotation (Line(
-      points={{0.153846,-5.6},{0.153846,-12.05},{0,-12.05},{0,-20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vleBoundaryB.m_flow_in, stepVLEBounday_liquid.y)
-    annotation (Line(points={{-2,-24},{-2,-29.4}}, color={0,0,127}));
-  connect(stepVLEBounday_vapour.y, vleBoundaryA.m_flow_in)
-    annotation (Line(points={{2,31.4},{2,24}}, color={0,0,127}));
-  connect(liquidBoundaryB.port, adsorber.liquidPortB) annotation (Line(
-      points={{40,16},{20,16},{20,3.2},{10.7692,3.2}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(liquidBoundaryA.port, adsorber.liquidPortA) annotation (Line(
-      points={{40,-14},{20,-14},{20,-3.36},{10.7692,-3.36}},
-      color={0,170,238},
-      thickness=0.5));
-  annotation (
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
-            100,100}})),
-    experiment(StopTime=500, Interval=1),
-    __Dymola_experimentSetupOutput);
-end TestAdsorber1;
diff --git a/SorpLib/Components/ClosedAdsorber/Testers/TestAdsorber2.mo b/SorpLib/Components/ClosedAdsorber/Testers/TestAdsorber2.mo
deleted file mode 100644
index 819d8da..0000000
--- a/SorpLib/Components/ClosedAdsorber/Testers/TestAdsorber2.mo
+++ /dev/null
@@ -1,107 +0,0 @@
-within SorpLib.Components.ClosedAdsorber.Testers;
-model TestAdsorber2
-  import SorpLib;
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1, redeclare
-      TILMedia.LiquidTypes.TILMedia_Water liquidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  Adsorber adsorber(
-    xInitial=0.10,
-    redeclare record TubeGeometry =
-        SorpLib.Components.ClosedAdsorber.Geometry.Adsorber_Finned_Tubes_Alu,
-    initial_x=true,
-    redeclare model AdsorbentAdsorbateModel =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Aluminum,
-    nCells=10,
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    includeDefaultSummary=true,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ConstantZeta
-        (zeta=1, massFlowLimit=0.001),
-    enableCasing=true,
-    enableHeatPort=true,
-    redeclare model HeatTransferModel_InternalCoupling =
-        HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (constantAlphaA=50),
-    redeclare model HeatTransferModel_HX =
-        SorpLib.Components.ClosedAdsorber.RecordsTransportCoefficients.HeatTransfer.HeatTransferSilicaGel_Lanzerath2015,
-    TInitial=576.3,
-    hx_TInitialCell1=566.3,
-    hx_TInitialCelln=566.3,
-    hx_TInitialWall=566.3)
-    annotation (Placement(transformation(extent={{-10,-8},{10,8}})));
-
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryA(m_flowFixed=-0.1, TFixed=
-        313.15)
-    annotation (Placement(transformation(extent={{36,-24},{44,-4}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundaryA(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=270,
-        origin={0,20})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_vapour(
-    height=-0.001,
-    offset=0.001,
-    startTime=50) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={2,38})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_liquid(
-    height=0.001,
-    offset=-0.001,
-    startTime=100) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=90,
-        origin={-2,-36})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundaryB(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true,
-    hFixed=2.5e6) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={0,-20})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryB(boundaryType="p")
-    annotation (Placement(transformation(extent={{36,6},{44,26}})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary(boundaryType="Q_flow",
-      Q_flowFixed=100)
-    annotation (Placement(transformation(extent={{-4,-6},{4,6}},
-        rotation=180,
-        origin={-24,0})));
-equation
-  connect(adsorber.vlePortA, vleBoundaryA.port) annotation (Line(
-      points={{0.153846,5.92},{0.153846,11.46},{0,11.46},{0,20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(liquidBoundaryA.port, adsorber.liquidPortA) annotation (Line(
-      points={{40,-14},{20,-14},{20,-3.36},{10.7692,-3.36}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(adsorber.vlePortB, vleBoundaryB.port) annotation (Line(
-      points={{0.153846,-5.6},{0.153846,-12.05},{0,-12.05},{0,-20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vleBoundaryB.m_flow_in, stepVLEBounday_liquid.y)
-    annotation (Line(points={{-2,-24},{-2,-29.4}}, color={0,0,127}));
-  connect(stepVLEBounday_vapour.y, vleBoundaryA.m_flow_in)
-    annotation (Line(points={{2,31.4},{2,24}}, color={0,0,127}));
-  connect(adsorber.liquidPortB, liquidBoundaryB.port) annotation (Line(
-      points={{10.7692,3.2},{10.7692,3.2},{20,3.2},{20,16},{40,16}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(adsorber.heatPort, heatBoundary.heatPort) annotation (Line(
-      points={{-9.84615,-4.44089e-016},{-9.84615,0.46},{-24,0.46},{-24,0}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
-            100,100}})),
-    experiment(StopTime=500, Interval=1),
-    __Dymola_experimentSetupOutput);
-end TestAdsorber2;
diff --git a/SorpLib/Components/ClosedAdsorber/Testers/package.mo b/SorpLib/Components/ClosedAdsorber/Testers/package.mo
deleted file mode 100644
index 12b147b..0000000
--- a/SorpLib/Components/ClosedAdsorber/Testers/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.ClosedAdsorber;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-end Testers;
diff --git a/SorpLib/Components/ClosedAdsorber/Testers/package.order b/SorpLib/Components/ClosedAdsorber/Testers/package.order
deleted file mode 100644
index 8e26024..0000000
--- a/SorpLib/Components/ClosedAdsorber/Testers/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-TestAdsorber1
-TestAdsorber2
diff --git a/SorpLib/Components/ClosedAdsorber/package.mo b/SorpLib/Components/ClosedAdsorber/package.mo
deleted file mode 100644
index 3f79a63..0000000
--- a/SorpLib/Components/ClosedAdsorber/package.mo
+++ /dev/null
@@ -1,7 +0,0 @@
-within SorpLib.Components;
-package ClosedAdsorber "Model of a closed adsorber: combining adsorbent and heat exchanger"
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-
-end ClosedAdsorber;
diff --git a/SorpLib/Components/ClosedAdsorber/package.order b/SorpLib/Components/ClosedAdsorber/package.order
deleted file mode 100644
index 69b0711..0000000
--- a/SorpLib/Components/ClosedAdsorber/package.order
+++ /dev/null
@@ -1,4 +0,0 @@
-Adsorber
-Geometry
-RecordsTransportCoefficients
-Testers
diff --git a/SorpLib/Components/EvpCond/EvpCond.mo b/SorpLib/Components/EvpCond/EvpCond.mo
deleted file mode 100644
index 792d4a5..0000000
--- a/SorpLib/Components/EvpCond/EvpCond.mo
+++ /dev/null
@@ -1,321 +0,0 @@
-within SorpLib.Components.EvpCond;
-model EvpCond
-  "evaporator/condenser model including VLE separator, tube heat exchanger, and casing (optional) "
-
-  /*********************** SIM ***********************************/
-
-  parameter TILMedia.VLEFluidTypes.BaseVLEFluid vleFluidType=sim.vleFluidType1
-    "VLE fluid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.vleFluidType1 "VLE fluid 1 as defined in SIM",
-      choice=sim.vleFluidType2 "VLE fluid 2 as defined in SIM",
-      choice=sim.vleFluidType3 "VLE fluid 3 as defined in SIM"));
-
-  parameter TILMedia.LiquidTypes.BaseLiquid liquidType=sim.liquidType1
-    "Liquid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.liquidType1 "Liquid 1 as defined in SIM",
-      choice=sim.liquidType2 "Liquid 2 as defined in SIM",
-      choice=sim.liquidType3 "Liquid 3 as defined in SIM"));
-
-protected
-  outer TIL.SystemInformationManager sim "System information manager";
-
-  TIL.Internals.SimPort simPort;
-
-  /********************** Connectors **************************/
-public
-  TIL.Connectors.VLEFluidPort vlePort_vapour[nports](each final vleFluidType=
-        vleFluidType) "VLE port (vapour)" annotation (Placement(transformation(
-          extent={{-10,28},{10,48}}, rotation=0), iconTransformation(extent={{-10,
-            28},{10,48}})));
-
-  TIL.Connectors.VLEFluidPort vlePort_liquid[kports](each final vleFluidType=
-        vleFluidType) "VLE port (liquid)" annotation (Placement(transformation(
-          extent={{-10,-48},{10,-28}}, rotation=0), iconTransformation(extent={{
-            -10,-48},{10,-28}})));
-  TIL.Connectors.LiquidPort liquidPortA(final liquidType=liquidType)
-    "Liquid portA" annotation (Placement(transformation(extent={{-110,-20},{-90,
-            0}}, rotation=0), iconTransformation(extent={{-110,-20},{-90,0}})));
-  TIL.Connectors.LiquidPort liquidPortB(final liquidType=liquidType)
-    "Liquid portB" annotation (Placement(transformation(extent={{90,-20},{110,0}},
-          rotation=0), iconTransformation(extent={{90,-20},{110,0}})));
-
-  TIL.Connectors.HeatPort heatPort if (enableHeatPort and enableCasing)
-    "Heat Port ambient" annotation (Placement(transformation(extent={{56,26},{76,
-            46}}, rotation=0), iconTransformation(extent={{56,26},{76,46}})));
-
-  /******************** Components ***************************/
-
-  /*********************** VLE volume ***********************************/
-public
-  Cells.VLEPhaseSeparator.VLEPhaseSeparator volume(
-    vleFluidType=vleFluidType,
-    n=nports,
-    volume(displayUnit="l") = freeVolume,
-    area=basearea,
-    dInitial=dInitial,
-    TInitial=TInitial,
-    k=kports) annotation (Placement(transformation(
-        extent={{-6.50003,-9.5},{6.50001,9.5}},
-        rotation=0,
-        origin={0,10})));
-
-  /*********************** Heat exchanger ***********************************/
-
-  TIL.LiquidComponents.Tubes.Tube heatexchanger(
-    enableHeatPorts=true,
-    steadyStateContinuity=true,
-    initLiquid="linearTemperatureDistribution",
-    redeclare model WallHeatConductionModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.WallHeatTransfer.GeometryBasedConduction,
-    liquidType=liquidType,
-    redeclare model TubeSideHeatTransferModel =
-        TubeSideHeatTransferModel,
-    TInitialLiquid_CellN=hx_TInitialCelln,
-    TInitialLiquid_Cell1=hx_TInitialCell1,
-    TInitialWall=hx_TInitialWall,
-    redeclare parameter TubeGeometry tubeGeometry,
-    redeclare model PressureDropModel = PressureDropModel,
-    redeclare model WallMaterial = WallMaterial_hx,
-    nCells=nCells)                                  annotation (Placement(
-        transformation(
-        extent={{-8,-2},{8,2}},
-        rotation=0,
-        origin={34,-22})));
-
-  /*********************** Casing ***********************************/
-
-  TIL.OtherComponents.Thermal.HeatCapacitor casing(
-    solidMass=massCasing,
-    TInitial=TInitialCasing,
-    inputType="m, solid",
-    redeclare model WallMaterial = WallMaterial_casing) if enableCasing annotation (Placement(
-        transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=90,
-        origin={72,20})));
-
-  /*********************** Heat Transfer ***********************************/
-
-  HeatTransfer.HeatTransfer heatTransfer_tube_VLE(redeclare model HeatTransfer =
-        VLESideHeatTransferModel, n=nCells) annotation (Placement(
-        transformation(
-        extent={{6,3},{-6,-3}},
-        rotation=90,
-        origin={34,-5})));
-
-  HeatTransfer.HeatTransfer heatTransfer_inner(redeclare model HeatTransfer =
-        HeatTransferModel_InternalCoupling, n=1) if
-                                               enableCasing annotation (
-      Placement(transformation(
-        extent={{-6,-3},{6,3}},
-        rotation=0,
-        origin={51,20})));
-
-  /********************* General Parameters ************************************/
-
-  inner parameter Boolean enableCasing=true "true, if casing is modeled"
-    annotation (Dialog(group="Casing"),choices(choice = true
-        "Casing is modelled",                                                      choice = false
-        "Casing is neglected"));
-
-  inner parameter Boolean enableHeatPort=true
-    "true, if heat port to environment is enabled"
-    annotation (Dialog(enable=enableCasing, group="Casing"));
-
-  /******************** Parameters Geometry ********************/
-
-  parameter Integer nports=0 "Number of connected adsorber units"
-    annotation (Dialog(connectorSizing=true));
-
-  parameter Integer kports=0 "Number of connected adsorber units"
-    annotation (Dialog(connectorSizing=true));
-
-  parameter Integer nCells=10 "number of hx discretization";
-
-  replaceable record TubeGeometry =
-      SorpLib.Components.EvpCond.Geometry.TubeGeometry constrainedby
-    SorpLib.Components.EvpCond.Geometry.TubeGeometry
-    "Geometry of tube" annotation (choicesAllMatching=true, Dialog(group=
-          "Geometry"));
-
-  parameter Modelica.SIunits.Volume freeVolume=0.001 "free fluid volume"
-    annotation (Dialog(group="Geometry"));
-
-  parameter Modelica.SIunits.Area basearea=heatexchanger.tubeGeometry.length
-      *heatexchanger.tubeGeometry.outerDiameter "base area of vle volume"
-    annotation (Dialog(group="Geometry"));
-
-  replaceable model WallMaterial_hx =
-      TILMedia.SolidTypes.TILMedia_Steel
-    constrainedby TILMedia.SolidTypes.BaseSolid
-    "Wall material of heat exchanger" annotation (choicesAllMatching=true,
-      Dialog(group="Geometry"));
-
-  parameter Modelica.SIunits.Mass massCasing=2 "Mass of Container"
-    annotation (Dialog(group="Casing", enable=enableCasing));
-  replaceable model WallMaterial_casing =
-      TILMedia.SolidTypes.TILMedia_Steel
-    constrainedby TILMedia.SolidTypes.BaseSolid "Wall material of casing"
-    annotation (choicesAllMatching=true, Dialog(enable=enableCasing, group=
-          "Casing"));
-
-  /*********************** Heat transfer models ****************************/
-
-  replaceable model VLESideHeatTransferModel =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "VLE side Heat Transfer Model" annotation (Placement(transformation(extent=
-            {{-32,-70},{-12,-50}})), choicesAllMatching=true);
-
-  replaceable model HeatTransferModel_InternalCoupling =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "Internal heat transfer model for connection between VLE fluid and casing"
-    annotation (
-    extend=[10,20; -10,40],
-    choicesAllMatching=true,
-    Dialog(group="Casing", enable=enableCasing));
-
-  replaceable model TubeSideHeatTransferModel =
-      SorpLib.Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate
-    constrainedby
-    TIL.LiquidComponents.Tubes.TransportPhenomena.HeatTransfer.PartialHeatTransfer
-    "Tube side heat transfer model" annotation (extend=[10,20; -10,40],
-      choicesAllMatching=true);
-
-  /*********************** Pressure drop ****************************/
-
-  replaceable model PressureDropModel =
-      TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop
-    constrainedby
-    TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.PartialPressureDrop
-    "Pressure drop model" annotation (
-    choicesAllMatching=true,
-    Dialog(group="Pressure drop"),
-    Placement(transformation(extent={{-10,20},{10,40}}, rotation=0)));
-
-  /*******************Summary**********************/
-public
-  inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-
-protected
-  record Summary
-    extends TIL.Internals.ClassTypes.Record;
-
-    Modelica.SIunits.Temperature T_liq_A if include;
-    Modelica.SIunits.Temperature T_liq_B if include;
-    Modelica.SIunits.Temperature T_cas if (include and enableCasing);
-    Modelica.SIunits.Pressure p_VLE if include;
-    Modelica.SIunits.Density d_VLE if include;
-    Modelica.SIunits.Temperature T_VLE if include;
-    Modelica.SIunits.EnthalpyFlowRate DeltaH_flow_liq if include;
-    Modelica.SIunits.HeatFlowRate Q_flow_liq_VLE if include;
-    Modelica.SIunits.HeatFlowRate Q_flow_VLE_cas if (include and enableCasing);
-    Modelica.SIunits.HeatFlowRate Q_flow_cas_amb if (include and enableHeatPort);
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-    outer parameter Boolean enableCasing;
-    outer parameter Boolean enableHeatPort;
-
-  end Summary;
-
-  replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    T_liq_A=heatexchanger.summary.T_liq_A,
-    T_liq_B=heatexchanger.summary.T_liq_B,
-    T_cas=casing.T,
-    p_VLE=volume.vleFluid.p,
-    d_VLE=volume.d,
-    T_VLE=volume.T,
-    DeltaH_flow_liq = heatexchanger.portA.m_flow*(heatexchanger.summary.h_liq_A-heatexchanger.summary.h_liq_B),
-    Q_flow_liq_VLE = -heatexchanger.summary.Q_flow_liq,
-    Q_flow_VLE_cas = heatTransfer_inner.heatPortA.Q_flow,
-    Q_flow_cas_amb = heatPort.Q_flow) annotation (Placement(transformation(extent={{-98,18},
-            {-78,38}}, rotation=0)));
-
-  /*************************  Advanced  ******************************/
-
-  parameter Boolean generateEventsAtFlowReversal=false
-    "If true, tranport propertie are calculated in the gas object"
-    annotation (Evaluate=true, Dialog(tab="Advanced", group="Event-Handling"));
-
-  /******************** Initialization ********************/
-
-  parameter Modelica.SIunits.Density dInitial(
-    min=0,
-    max=1000) = 100 "Initial value for VLE density in free volume"
-    annotation (Dialog(tab="Initialization", group="VLE volume"));
-  parameter Modelica.SIunits.Temperature TInitial(min=273.15) = 300
-    "Initial value for VLE temperature in free volume"
-    annotation (Dialog(tab="Initialization", group="VLE volume"));
-
-  parameter Modelica.SIunits.Temperature hx_TInitialCell1=288.15
-    "Initial Temperature of heat exchanger fluid in cell 1"
-    annotation (Dialog(tab="Initialization", group="Heat Exchanger"));
-  parameter Modelica.SIunits.Temperature hx_TInitialCelln=298.15
-    "Initial Temperature of heat exchanger fluid in cell n"
-    annotation (Dialog(tab="Initialization", group="Heat Exchanger"));
-  parameter Modelica.SIunits.Temperature hx_TInitialWall(min=273.15) = 300
-    "Initial value for heat exchanger temperature"
-    annotation (Dialog(tab="Initialization", group="heat exchanger"));
-
-  parameter Modelica.SIunits.Temperature TInitialCasing=343.15
-    annotation (Dialog(group="Casing", tab="Initialization"));
-
-equation
-
-  connect(volume.heatPort, heatTransfer_inner.heatPortA) annotation (Line(
-      points={{6.50001,10},{34,10},{34,20},{45,20}},
-      color={204,0,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(volume.heatPort, heatTransfer_tube_VLE.heatPortA) annotation (Line(
-      points={{6.50001,10},{34,10},{34,1}},
-      color={204,0,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(vlePort_vapour, volume.vleVapourPort) annotation (Line(
-      points={{0,38},{0,19.5},{-1e-005,19.5}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(volume.vleLiquidPort, vlePort_liquid) annotation (Line(
-      points={{-1e-005,0.5},{-1e-005,-20},{0,-20},{0,-38}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(liquidPortA, heatexchanger.portA) annotation (Line(
-      points={{-100,-10},{-70,-10},{-70,-22},{26,-22}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(heatexchanger.portB, liquidPortB) annotation (Line(
-      points={{42,-22},{70,-22},{70,-10},{100,-10}},
-      color={0,170,238},
-      thickness=0.5));
-  connect(heatTransfer_inner.heatPortB[1], casing.heatPort) annotation (Line(
-      points={{57,20},{66,20}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer_tube_VLE.heatPortB, heatexchanger.heatPort) annotation (
-      Line(
-      points={{34,-11},{34,-11},{34,-20}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(casing.heatPort, heatPort) annotation (Line(
-      points={{66,20},{66,36}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, grid={1,1}, extent={{-100,-40},
-            {100,40}})),                Icon(coordinateSystem(
-          preserveAspectRatio=true, extent={{-100,-40},{100,40}}), graphics={
-          Bitmap(extent={{-100,-58},{100,58}}, fileName=
-          "modelica://SorpLib/Resources/Images/Evaporator.png")}));
-end EvpCond;
diff --git a/SorpLib/Components/EvpCond/Geometry/CondLanzerath2014.mo b/SorpLib/Components/EvpCond/Geometry/CondLanzerath2014.mo
deleted file mode 100644
index f33e0eb..0000000
--- a/SorpLib/Components/EvpCond/Geometry/CondLanzerath2014.mo
+++ /dev/null
@@ -1,34 +0,0 @@
-within SorpLib.Components.EvpCond.Geometry;
-record CondLanzerath2014
-  "Condenser used in dissertation of Lanzerath (2014 & 2015)"
-  extends TubeGeometry(
-    final innerDiameter=0.008,
-    final wallThickness=0.001,
-    length=4.55,
-    final nParallelTubes=1,
-    final crossSectionType=TIL.Internals.CrossSectionType.Circular,
-    final innerCrossSectionalAreaNonCircular=0,
-    final outerCrossSectionalAreaNonCircular=0,
-    final innerPerimeterNonCircular=0);
-
-  annotation (Documentation(info="<html>
-  <p>
-    This record containes the information on the condenser used by Lanzerath (2014 & 2015).<br>     
-  </p>
-  <h4>References</h4>
-  <p>
-    <ul>
-      <li>Lanzerath, F. Modellgestützte Entwicklung von Adsorptionswärmepumpen (in German). Aachen: Mainz, 2014. Aachener Beiträge zur Technischen Thermodynamik. 3. ISBN 9783861304722.</li>
-      <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-    </ul>
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 07, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end CondLanzerath2014;
diff --git a/SorpLib/Components/EvpCond/Geometry/EvpLanzerath2014.mo b/SorpLib/Components/EvpCond/Geometry/EvpLanzerath2014.mo
deleted file mode 100644
index 31eeee4..0000000
--- a/SorpLib/Components/EvpCond/Geometry/EvpLanzerath2014.mo
+++ /dev/null
@@ -1,35 +0,0 @@
-within SorpLib.Components.EvpCond.Geometry;
-record EvpLanzerath2014
-  "Evaporator used in dissertation of Lanzerath (2014 & 2015)"
-  extends TubeGeometry(
-    final innerDiameter=0.01467,
-    final wallThickness=0.0015025,
-    length=2.3,
-    final nParallelTubes=1,
-    final crossSectionType=TIL.Internals.CrossSectionType.Circular,
-    final innerCrossSectionalAreaNonCircular=0,
-    final outerCrossSectionalAreaNonCircular=0,
-    final innerPerimeterNonCircular=0);
-
-  annotation (Documentation(info="<html>
-  <p>
-    This record containes the information on the evaporator used by Lanzerath (2014 & 2015).<br>     
-  </p>
-  <h4>References</h4>
-  <p>
-    <ul>
-      <li>Lanzerath, F. Modellgestützte Entwicklung von Adsorptionswärmepumpen (in German). Aachen: Mainz, 2014. Aachener Beiträge zur Technischen Thermodynamik. 3. ISBN 9783861304722.</li>
-      <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-    </ul>
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 07, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>
-"));
-end EvpLanzerath2014;
diff --git a/SorpLib/Components/EvpCond/Geometry/TubeGeometry.mo b/SorpLib/Components/EvpCond/Geometry/TubeGeometry.mo
deleted file mode 100644
index 2fff312..0000000
--- a/SorpLib/Components/EvpCond/Geometry/TubeGeometry.mo
+++ /dev/null
@@ -1,70 +0,0 @@
-within SorpLib.Components.EvpCond.Geometry;
-record TubeGeometry "Geometry record for a tube"
-  extends SorpLib.Internals.ClassTypes.Record;
-
-  parameter Modelica.SIunits.Diameter innerDiameter=0.01
-    "Inner diameter of circular tube" annotation (Dialog(group="Geometry",
-        enable=(crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-  parameter Modelica.SIunits.Length wallThickness=0.0005 "Wall thickness"
-    annotation (Dialog(group="Geometry", enable=(crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-  parameter Modelica.SIunits.Length length=1 "|Geometry|Length";
-
-  parameter Integer nParallelTubes(min=1) = 1
-    "|Geometry|Number of parallel Tubes";
-
-  parameter TIL.Internals.CrossSectionType crossSectionType=TIL.Internals.CrossSectionType.Circular
-    "|Geometry|Tube Cross Section Type";
-
-  parameter Modelica.SIunits.Area innerCrossSectionalAreaNonCircular=0
-    "Inner cross sectional area of one non-circular tube" annotation (Dialog(
-        group="Geometry", enable=not (crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-
-  parameter Modelica.SIunits.Area outerCrossSectionalAreaNonCircular=0
-    "Outer cross sectional area of one non-circular tube" annotation (Dialog(
-        group="Geometry", enable=not (crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-
-  parameter Modelica.SIunits.Length innerPerimeterNonCircular=0
-    "Perimeter of one non-circular tube" annotation (Dialog(group="Geometry",
-        enable=not (crossSectionType == TIL.Internals.CrossSectionType.Circular)));
-
-  final parameter Modelica.SIunits.Diameter outerDiameter=innerDiameter + 2*
-      wallThickness;
-  final parameter Modelica.SIunits.Area innerCrossSectionalArea=if
-      tubeIsCircular then Modelica.Constants.pi*innerDiameter*innerDiameter/4.0
-      *nParallelTubes else innerCrossSectionalAreaNonCircular*nParallelTubes
-    "Inner cross-sectional area";
-  final parameter Modelica.SIunits.Area outerCrossSectionalArea=if
-      tubeIsCircular then Modelica.Constants.pi*outerDiameter*outerDiameter/4.0
-      *nParallelTubes else outerCrossSectionalAreaNonCircular*nParallelTubes
-    "Outer cross-sectional area";
-  final parameter Modelica.SIunits.Area hydraulicCrossSectionalArea=if
-      tubeIsCircular then Modelica.Constants.pi*innerDiameter*innerDiameter/4.0
-       else innerCrossSectionalAreaNonCircular "Hydraulic cross sectional area";
-  final parameter Modelica.SIunits.Diameter hydraulicDiameter=if tubeIsCircular
-       then innerDiameter else 4*innerCrossSectionalAreaNonCircular/
-      innerPerimeterNonCircular "Hydraulic diameter";
-  final parameter Modelica.SIunits.Volume innerVolume=innerCrossSectionalArea*
-      length "Inner volume";
-  final parameter Modelica.SIunits.Volume outerVolume=outerCrossSectionalArea*
-      length "Outer volume";
-  final parameter Modelica.SIunits.Area innerHeatTransferArea=if tubeIsCircular
-       then Modelica.Constants.pi*innerDiameter*length*nParallelTubes else
-      innerPerimeterNonCircular*length*nParallelTubes;
-  final parameter Boolean tubeIsCircular=(crossSectionType == TIL.Internals.CrossSectionType.Circular)
-    "true, if tube's cross section is circular";
-
-  annotation (Documentation(info="<html>
-  <p>
-    This record containes all information necessary to describe a liquid tube. <br>  
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 07, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>
-"));
-end TubeGeometry;
diff --git a/SorpLib/Components/EvpCond/Geometry/package.mo b/SorpLib/Components/EvpCond/Geometry/package.mo
deleted file mode 100644
index 5f03358..0000000
--- a/SorpLib/Components/EvpCond/Geometry/package.mo
+++ /dev/null
@@ -1,7 +0,0 @@
-within SorpLib.Components.EvpCond;
-package Geometry
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-
-end Geometry;
diff --git a/SorpLib/Components/EvpCond/Geometry/package.order b/SorpLib/Components/EvpCond/Geometry/package.order
deleted file mode 100644
index 9dea20e..0000000
--- a/SorpLib/Components/EvpCond/Geometry/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-TubeGeometry
-EvpLanzerath2014
-CondLanzerath2014
diff --git a/SorpLib/Components/EvpCond/Testers/TestEvpCond1.mo b/SorpLib/Components/EvpCond/Testers/TestEvpCond1.mo
deleted file mode 100644
index 89f55b5..0000000
--- a/SorpLib/Components/EvpCond/Testers/TestEvpCond1.mo
+++ /dev/null
@@ -1,92 +0,0 @@
-within SorpLib.Components.EvpCond.Testers;
-model TestEvpCond1
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1, redeclare
-      TILMedia.LiquidTypes.TILMedia_Water liquidType1)
-    annotation (Placement(transformation(extent={{50,64},{70,84}})));
-  EvpCond evpCond(
-    freeVolume(displayUnit="l") = 0.002,
-    dInitial=300,
-    nports=1,
-    kports=1,
-    nCells=10,
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    redeclare model VLESideHeatTransferModel =
-        HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (constantAlphaA=100),
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Copper,
-    enableCasing=false,
-    redeclare record TubeGeometry = Geometry.EvpLanzerath2014,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    enableHeatPort=false,
-    TInitial=298.15,
-    hx_TInitialWall=298.15)
-    annotation (Placement(transformation(extent={{-12,-4},{12,6}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary_vapour(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=270,
-        origin={0,20})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryA(m_flowFixed=-0.1,
-      TFixed=313.15)
-    annotation (Placement(transformation(extent={{-44,-10},{-36,10}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryB(boundaryType="p")
-    annotation (Placement(transformation(extent={{36,-10},{44,10}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary_liquid(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={0,-20})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_vapour(
-    height=-0.001,
-    offset=0.001,
-    startTime=50) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={2,38})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_liquid(
-    height=0.001,
-    offset=-0.001,
-    startTime=100) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=90,
-        origin={-2,-36})));
-equation
-
-  connect(liquidBoundaryA.port, evpCond.liquidPortA) annotation (Line(
-      points={{-40,0},{-18,0},{-18,-0.25},{-12,-0.25}},
-      color={0,170,238},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(evpCond.liquidPortB, liquidBoundaryB.port) annotation (Line(
-      points={{12,-0.25},{26,-0.25},{26,0},{40,0}},
-      color={0,170,238},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(vleBoundary_vapour.port, evpCond.vlePort_vapour[1]) annotation (Line(
-      points={{0,20},{0,20},{0,5.75}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vleBoundary_liquid.port, evpCond.vlePort_liquid[1]) annotation (Line(
-      points={{0,-20},{0,-16},{0,-3.75}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(stepVLEBounday_vapour.y, vleBoundary_vapour.m_flow_in)
-    annotation (Line(points={{2,31.4},{2,27.7},{2,24}}, color={0,0,127}));
-  connect(vleBoundary_liquid.m_flow_in, stepVLEBounday_liquid.y)
-    annotation (Line(points={{-2,-24},{-2,-29.4}}, color={0,0,127}));
-  annotation (
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
-            100,100}})),
-    experiment(StopTime=500, Tolerance=1e-005),
-    __Dymola_experimentSetupOutput(events=false));
-end TestEvpCond1;
diff --git a/SorpLib/Components/EvpCond/Testers/TestEvpCond2.mo b/SorpLib/Components/EvpCond/Testers/TestEvpCond2.mo
deleted file mode 100644
index ebb6260..0000000
--- a/SorpLib/Components/EvpCond/Testers/TestEvpCond2.mo
+++ /dev/null
@@ -1,97 +0,0 @@
-within SorpLib.Components.EvpCond.Testers;
-model TestEvpCond2
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1, redeclare
-      TILMedia.LiquidTypes.TILMedia_Water liquidType1)
-    annotation (Placement(transformation(extent={{50,64},{70,84}})));
-  EvpCond evpCond(
-    freeVolume(displayUnit="l") = 0.002,
-    dInitial=300,
-    nports=1,
-    kports=1,
-    nCells=10,
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    enableCasing=true,
-    redeclare model VLESideHeatTransferModel =
-        HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (constantAlphaA=100),
-    redeclare model WallMaterial_casing =
-        TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model HeatTransferModel_InternalCoupling =
-        HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (constantAlphaA=5),
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Copper,
-    massCasing=2,
-    redeclare record TubeGeometry = Geometry.EvpLanzerath2014,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    enableHeatPort=false,
-    TInitial=298.15,
-    hx_TInitialWall=298.15)
-    annotation (Placement(transformation(extent={{-12,-4},{12,6}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary_vapour(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=270,
-        origin={0,20})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryA(m_flowFixed=-0.1,
-      TFixed=313.15)
-    annotation (Placement(transformation(extent={{-44,-10},{-36,10}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryB(boundaryType="p")
-    annotation (Placement(transformation(extent={{36,-10},{44,10}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary_liquid(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={0,-20})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_vapour(
-    height=-0.001,
-    offset=0.001,
-    startTime=50) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={2,38})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_liquid(
-    height=0.001,
-    offset=-0.001,
-    startTime=100) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=90,
-        origin={-2,-36})));
-equation
-
-  connect(liquidBoundaryA.port, evpCond.liquidPortA) annotation (Line(
-      points={{-40,0},{-18,0},{-18,-0.25},{-12,-0.25}},
-      color={0,170,238},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(evpCond.liquidPortB, liquidBoundaryB.port) annotation (Line(
-      points={{12,-0.25},{26,-0.25},{26,0},{40,0}},
-      color={0,170,238},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(vleBoundary_vapour.port, evpCond.vlePort_vapour[1]) annotation (Line(
-      points={{0,20},{0,20},{0,5.75}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vleBoundary_liquid.port, evpCond.vlePort_liquid[1]) annotation (Line(
-      points={{0,-20},{0,-16},{0,-3.75}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(stepVLEBounday_vapour.y, vleBoundary_vapour.m_flow_in)
-    annotation (Line(points={{2,31.4},{2,27.7},{2,24}}, color={0,0,127}));
-  connect(vleBoundary_liquid.m_flow_in, stepVLEBounday_liquid.y)
-    annotation (Line(points={{-2,-24},{-2,-29.4}}, color={0,0,127}));
-  annotation (
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
-            100,100}})),
-    experiment(StopTime=500, Tolerance=1e-005),
-    __Dymola_experimentSetupOutput(events=false));
-end TestEvpCond2;
diff --git a/SorpLib/Components/EvpCond/Testers/TestEvpCond3.mo b/SorpLib/Components/EvpCond/Testers/TestEvpCond3.mo
deleted file mode 100644
index 4def28e..0000000
--- a/SorpLib/Components/EvpCond/Testers/TestEvpCond3.mo
+++ /dev/null
@@ -1,126 +0,0 @@
-within SorpLib.Components.EvpCond.Testers;
-model TestEvpCond3
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1, redeclare
-      TILMedia.LiquidTypes.TILMedia_Water liquidType1)
-    annotation (Placement(transformation(extent={{50,64},{70,84}})));
-  EvpCond evpCond(
-    freeVolume(displayUnit="l") = 0.002,
-    dInitial=300,
-    nports=2,
-    kports=1,
-    nCells=10,
-    redeclare model TubeSideHeatTransferModel =
-        Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube.SiederTate,
-    enableCasing=true,
-    redeclare model VLESideHeatTransferModel =
-        HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (constantAlphaA=100),
-    redeclare model WallMaterial_casing =
-        TILMedia.SolidTypes.TILMedia_Steel,
-    redeclare model HeatTransferModel_InternalCoupling =
-        HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (constantAlphaA=5),
-    vleFluidType=sim.vleFluidType1,
-    liquidType=sim.liquidType1,
-    redeclare model WallMaterial_hx = TILMedia.SolidTypes.TILMedia_Copper,
-    massCasing=2,
-    redeclare record TubeGeometry = Geometry.EvpLanzerath2014,
-    redeclare model PressureDropModel =
-        TIL.LiquidComponents.Tubes.TransportPhenomena.PressureDrop.ZeroPressureDrop,
-    enableHeatPort=true,
-    TInitial=298.15,
-    hx_TInitialWall=298.15)
-    annotation (Placement(transformation(extent={{-12,-4},{12,6}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary_vapour1(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=270,
-        origin={-16,20})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryA(m_flowFixed=-0.1,
-      TFixed=313.15)
-    annotation (Placement(transformation(extent={{-44,-10},{-36,10}})));
-  TIL.LiquidComponents.Boundaries.Boundary liquidBoundaryB(boundaryType="p")
-    annotation (Placement(transformation(extent={{36,-10},{44,10}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary_liquid(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={0,-20})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_vapour2(
-    startTime=50,
-    height=-0.0005,
-    offset=0.0005) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={-14,36})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_liquid(
-    height=0.001,
-    offset=-0.001,
-    startTime=100) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=90,
-        origin={-2,-36})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary(boundaryType="Q_flow",
-      Q_flowFixed=100)
-    annotation (Placement(transformation(extent={{-4,-6},{4,6}},
-        rotation=90,
-        origin={22,20})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary_vapour2(
-    pFixed(displayUnit="kPa") = 15000,
-    boundaryType="m_flow",
-    use_massFlowRateInput=true) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=270,
-        origin={4,20})));
-  Modelica.Blocks.Sources.Step stepVLEBounday_vapour1(
-    height=-0.0005,
-    offset=0.0005,
-    startTime=150) annotation (Placement(transformation(
-        extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={6,36})));
-equation
-
-  connect(liquidBoundaryA.port, evpCond.liquidPortA) annotation (Line(
-      points={{-40,0},{-18,0},{-18,-0.25},{-12,-0.25}},
-      color={0,170,238},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(evpCond.liquidPortB, liquidBoundaryB.port) annotation (Line(
-      points={{12,-0.25},{26,-0.25},{26,0},{40,0}},
-      color={0,170,238},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(vleBoundary_vapour1.port, evpCond.vlePort_vapour[1]) annotation (Line(
-      points={{-16,20},{-16,20},{-16,16},{-16,10},{0,10},{0,5.125}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vleBoundary_liquid.port, evpCond.vlePort_liquid[1]) annotation (Line(
-      points={{0,-20},{0,-16},{0,-3.75}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(stepVLEBounday_vapour2.y, vleBoundary_vapour1.m_flow_in)
-    annotation (Line(points={{-14,29.4},{-14,24}}, color={0,0,127}));
-  connect(vleBoundary_liquid.m_flow_in, stepVLEBounday_liquid.y)
-    annotation (Line(points={{-2,-24},{-2,-29.4}}, color={0,0,127}));
-  connect(evpCond.heatPort, heatBoundary.heatPort) annotation (Line(
-      points={{7.92,5.5},{7.92,12.75},{22,12.75},{22,20}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(stepVLEBounday_vapour1.y, vleBoundary_vapour2.m_flow_in)
-    annotation (Line(points={{6,29.4},{6,26.7},{6,24}}, color={0,0,127}));
-  connect(vleBoundary_vapour2.port, evpCond.vlePort_vapour[2]) annotation (Line(
-      points={{4,20},{4,20},{4,10},{0,10},{0,6},{0,6.375}},
-      color={153,204,0},
-      thickness=0.5));
-  annotation (
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{
-            100,100}})),
-    experiment(StopTime=500, Tolerance=1e-005),
-    __Dymola_experimentSetupOutput(events=false));
-end TestEvpCond3;
diff --git a/SorpLib/Components/EvpCond/Testers/package.mo b/SorpLib/Components/EvpCond/Testers/package.mo
deleted file mode 100644
index 04d1e54..0000000
--- a/SorpLib/Components/EvpCond/Testers/package.mo
+++ /dev/null
@@ -1,7 +0,0 @@
-within SorpLib.Components.EvpCond;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-
-end Testers;
diff --git a/SorpLib/Components/EvpCond/Testers/package.order b/SorpLib/Components/EvpCond/Testers/package.order
deleted file mode 100644
index 9898f98..0000000
--- a/SorpLib/Components/EvpCond/Testers/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-TestEvpCond1
-TestEvpCond2
-TestEvpCond3
diff --git a/SorpLib/Components/EvpCond/package.mo b/SorpLib/Components/EvpCond/package.mo
deleted file mode 100644
index db6eba5..0000000
--- a/SorpLib/Components/EvpCond/package.mo
+++ /dev/null
@@ -1,7 +0,0 @@
-within SorpLib.Components;
-package EvpCond
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-
-end EvpCond;
diff --git a/SorpLib/Components/EvpCond/package.order b/SorpLib/Components/EvpCond/package.order
deleted file mode 100644
index c152373..0000000
--- a/SorpLib/Components/EvpCond/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-EvpCond
-Geometry
-Testers
diff --git a/SorpLib/Components/Fans/AffinityFan.mo b/SorpLib/Components/Fans/AffinityFan.mo
new file mode 100644
index 0000000..3d53f57
--- /dev/null
+++ b/SorpLib/Components/Fans/AffinityFan.mo
@@ -0,0 +1,133 @@
+within SorpLib.Components.Fans;
+model AffinityFan "Model of a fan based on affinity laws"
+  extends BaseClasses.PartialAffinityFan(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculation of fluid properties
+  //
+  rho = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1, inStream(port_a.Xi_outflow), {1-sum(inStream(port_a.Xi_outflow))}))
+    "Instreaming density";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The affinity fan can be used to prescribe the mass or volume flow rate in hydraulic
+components, such as tubes or heat exchangers. The model assumes a non-constant fan
+efficiency that depends on the volume flow rate. Changes compared to a nominal operating
+point are considered by affinity laws.
+
+<h4>Main equations</h4>
+<p>
+The model calculates the hydraulic, shaft, and drive power transmitted to the fluid
+or required to drive the fan. The hydraulic power <i>P<sub>hydraulic</sub></i> 
+transmitted to the fluid is defined as:
+</p>
+<pre>
+    P<sub>hydraulic</sub> = m&#x307; / &rho;<sub>in</sub> * &Delta;p;
+</pre>
+<p>
+Herein, <i>m&#x307;</i> is the mass flow rate, <i>&rho;<sub>in</sub></i> describes the 
+fluid density at the inlet, and <i>&Delta;p = p<sub>b</sub> - p<sub>a</sub></i> is the 
+pressure difference between port b and a. The mass flow rate <i>m&#x307;</i> follows
+from the volume flow rate <i>V<sub>flow</sub></i> that depends on the rotational speed
+<i>n</i>, the nominal volume flow rate <i>V<sub>flow,ref</sub></i>, and the nominal
+rotational speed <i>n<sub>ref</sub></i>:
+</p>
+<pre>
+    V<sub>flow</sub> = m&#x307; / &rho;<sub>in</sub> = V<sub>flow,ref</sub> * n / n<sub>ref</sub>;
+</pre>
+<p>
+The shaft power <i>P<sub>shaft</sub></i> depends on the fan efficiency 
+<i>&eta;<sub>fan</sub></i> and is defined as:
+</p>
+<pre>
+    P<sub>shaft</sub> = P<sub>hydraulic</sub> / &eta;<sub>fan</sub>;
+</pre>
+<p>
+with
+</p>
+<pre>
+    &eta;<sub>fan</sub> = &eta;<sub>fan,ref</sub> * (1 - f<sub>loss</sub> * ((m&#x307; / &rho;<sub>in</sub>) / V<sub>flow,ref</sub> - 1) ^ 2);
+</pre>
+<p>
+Herein, <i>f<sub>loss</sub></i> is a loss factor describing the dependency on the volume 
+flow rate, <i>&eta;<sub>fan,ref</sub></i> is the efficiency at the nominal operating point, 
+and <i>V<sub>flow,ref</sub></i> is the nominal volume flow rate. The shaft power is completly 
+transmitted to the fluid, thus increasing the outflowing specific enthalpy of the fluid.
+<br/><br/>
+The drive power <i>P<sub>drive</sub></i> is required to drive the fan, depends on the
+drive efficienciy <i>&eta;<sub>drive</sub></i>, and is defined as:
+</p>
+<pre>
+    P<sub>drive</sub> = P<sub>shaft</sub> / &eta;<sub>drive</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No flow reversal
+  </li>
+  <li>
+  Affinity laws apply to describe changes in operating conditions
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The affinity fan is typically used to prescripe the mass or volume flow rate
+in hydraulic components, such as tubes or heat exchangers, if process controlelrs
+are investigated and the flow rate changes.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>assumeIsenthalpicFan</i>:
+  Defines if the hydraulic losses are considered in the energy balance.
+  </li>
+  <li>
+  <i>calculateDrivePower</i>:
+  Defines if the driving power is calculates within the model.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 11, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AffinityFan;
diff --git a/SorpLib/Components/Fans/BaseClasses/PartialAffinityFan.mo b/SorpLib/Components/Fans/BaseClasses/PartialAffinityFan.mo
new file mode 100644
index 0000000..addd4c0
--- /dev/null
+++ b/SorpLib/Components/Fans/BaseClasses/PartialAffinityFan.mo
@@ -0,0 +1,142 @@
+within SorpLib.Components.Fans.BaseClasses;
+partial model PartialAffinityFan
+  "Base model for all fans using affinity laws"
+  extends SorpLib.Components.Fans.BaseClasses.PartialFan;
+
+  //
+  // Definition of paramteres describring the fan's characteristics
+  //
+  parameter Modelica.Units.SI.Frequency n_ref = 50
+    "Nominal rotational speed"
+    annotation (Dialog(tab="General", group="Fan Characteristics - Nominal point"));
+  parameter Modelica.Units.SI.VolumeFlowRate V_flow_ref = 10/1000/60
+    "Nominal volume flow rate"
+    annotation (Dialog(tab="General", group="Fan Characteristics - Nominal point"));
+  parameter Modelica.Units.SI.Efficiency eta_fan_ref = 0.4
+    "Nominal fan efficiency"
+    annotation (Dialog(tab="General", group="Fan Characteristics - Nominal point"));
+  parameter Real f_loss = 0.3
+    "Loss factor describing the fan efficiency"
+    annotation (Dialog(tab="General", group="Fan Characteristics - Nominal point"));
+
+  //
+  // Definition of parameters describing the inputs
+  //
+  parameter Boolean use_nInput = false
+    "=true, if n is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Inputs"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Frequency n_fixed = 50
+    "Fixed rotational speed"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=not use_nInput));
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput n_input(final unit="1/s") if
+    use_nInput
+    "Input for rotational speed"
+    annotation (Placement(transformation(extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={0,-90}),
+      iconTransformation(extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,-80})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput n_internal(final unit="1/s")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of variables
+  //
+public
+  Modelica.Units.SI.Efficiency eta_fan
+    "Fan efficiency";
+
+equation
+  //
+  // Assertions
+  //
+  assert(n_internal >= 0,
+         "Rotational speed cannot be negative!",
+         level=AssertionLevel.error);
+
+  //
+  // Connectors
+  //
+  connect(n_internal, n_input);
+
+  if not use_nInput then
+    n_internal = n_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Mass balance
+  //
+  m_flow = V_flow * rho
+    "Mass flow rate at port a";
+  V_flow = V_flow_ref * (n_internal / n_ref)
+    "Volume flow rate at port a (affinity law)";
+
+  //
+  // Energy balance
+  //
+  if assumeIsenthalpicFan then
+    port_a.h_outflow = inStream(port_b.h_outflow)
+      "Stream variable: Trivial equation since no change of energy due to
+      forbidden flow revesal";
+    port_b.h_outflow = inStream(port_a.h_outflow) + (1/eta_fan - 1) * dp / rho
+      "Increase of specific enthalpy due to internal losses of the fan";
+
+  else
+    port_a.h_outflow = inStream(port_b.h_outflow)
+      "Stream variable: Trivial equation since no change of energy";
+    port_b.h_outflow = inStream(port_a.h_outflow)
+      "Stream variable: Trivial equation since no change of energy";
+
+  end if;
+
+  //
+  // Power calculations
+  //
+  eta_fan = eta_fan_ref * (1 - f_loss * (V_flow / V_flow_ref - 1) ^ 2)
+    "Efficiency ot the fan dependent on the volume flow rate";
+
+  P_shaft = P_hydraulic / eta_fan
+    "Shaft power consumption of fan";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all fans using affinity laws and volume-
+flow-dependent efficiencies. It defines fundamental parameters and variables required 
+by all affinity fans. Models that inherit properties from this partial model have 
+to redeclare the fluid ports. Moreover, the instreaming density must be calculated. 
+In this context, appropriate fluid property models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Instreaming density <i>rho</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 11, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialAffinityFan;
diff --git a/SorpLib/Components/Fans/BaseClasses/PartialFan.mo b/SorpLib/Components/Fans/BaseClasses/PartialFan.mo
new file mode 100644
index 0000000..cd891df
--- /dev/null
+++ b/SorpLib/Components/Fans/BaseClasses/PartialFan.mo
@@ -0,0 +1,197 @@
+within SorpLib.Components.Fans.BaseClasses;
+partial model PartialFan "Base model for all fans"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of paramteres describring the fan's characteristics
+  //
+  parameter Boolean assumeIsenthalpicFan = false
+    " = true, if internal losses do not influence the energy balance"
+    annotation (Dialog(tab="General", group="Fan Characteristics"));
+  parameter Boolean calculateDrivePower = true
+    " = true, if drive power is calcualted"
+    annotation (Dialog(tab="General", group="Fan Characteristics"));
+
+  parameter Modelica.Units.SI.Efficiency eta_drive = 0.9
+    "Efficiency of drive that is used to calculate drive power"
+    annotation (Dialog(tab="General", group="Fan Characteristics",
+                enable=calculateDrivePower));
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-90,-10},{-70,10}}),
+                iconTransformation(extent={{-90,-10},{-70,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{70,-10},{90,10}}),
+                iconTransformation(extent={{70,-10},{90,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Density rho
+    "Instreaming density";
+
+  Modelica.Units.SI.PressureDifference dp
+    "Pressure difference between port a and b";
+  Modelica.Units.SI.MassFlowRate m_flow
+    "Mass flow rate";
+  Modelica.Units.SI.VolumeFlowRate V_flow
+    "Volume flow rate";
+
+  Modelica.Units.SI.Power P_hydraulic
+    "Hydraulic power consumption of the fan";
+  Modelica.Units.SI.Power P_shaft
+    "Shaft power consumption of the fan";
+  Modelica.Units.SI.Power P_drive
+    "Drive power consumption of the fan";
+  Modelica.Units.SI.Power P_loss_internal
+    "Internal power losses of the fan (i.e., increase of outflowing specific 
+    enthalpy)";
+
+equation
+  //
+  // Assertions
+  //
+  assert(m_flow >= 0,
+         "Fan model cannot handle flow reversal!",
+         level=AssertionLevel.error);
+
+  //
+  // Momentum balance
+  //
+  dp = port_b.p - port_a.p
+    "Pressure difference between port b and a";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + port_b.m_flow
+    "Steady-state mass balance";
+
+  port_a.Xi_outflow = inStream(port_b.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+  port_b.Xi_outflow = inStream(port_a.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+
+  port_a.m_flow = m_flow
+    "Mass flow rate at port a";
+
+  //
+  // Power calculations
+  //
+  P_hydraulic = V_flow * dp
+    "Hydraulic power consumption of the fan";
+  P_drive = if calculateDrivePower then P_shaft / eta_drive else 0
+    "Drive power consumption of fan";
+  P_loss_internal = P_shaft - P_hydraulic
+    "Internal power losses of fan (i.e., increase outflowing specific enthalpy)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all fans. It defines fundamental 
+parameters and variables required by all fans. Models that inherit properties 
+from this partial model have to redeclare the fluid ports. Moreover, the mass
+and energy balances must be completed, and the power calculations must be added.
+In this context, appropriate fluid property models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Instreaming density <i>rho</i>.
+  </li>
+  <br/>
+  <li>
+  Mass flow rate <i>m_flow</i> at port a.
+  </li>
+  <li>
+  Volume flow rate <i>V_flow</i> at port a.
+  </li>
+  <br/>
+  <li>
+  Outflowing specific enthalpy <i>port_a.h_outflow</i> at port a.
+  </li>
+  <li>
+  Outflowing specific enthalpy <i>port_b.h_outflow</i> at port b.
+  </li>
+  <br/>
+  <li>
+  Shaft power <i>P_shaft</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 10, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Ellipse(
+          extent={{-80,-80},{80,80}},
+          lineColor={244,125,35},
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Sphere),
+        Polygon(
+          points={{-68,42},{-68,-42},{80,0},{-68,42}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Line(
+          points={{40,0},{-20,0}},
+          color={0,0,0},
+          arrow={Arrow.Filled,Arrow.None}),
+        Ellipse(
+          extent={{-64,-4},{-24,4}},
+          lineColor={0,0,0},
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-20,-4},{20,4}},
+          lineColor={0,0,0},
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid,
+          origin={-44,0},
+          rotation=90)}));
+end PartialFan;
diff --git a/SorpLib/Components/Fans/BaseClasses/PartialSimpleFan.mo b/SorpLib/Components/Fans/BaseClasses/PartialSimpleFan.mo
new file mode 100644
index 0000000..8e0cd89
--- /dev/null
+++ b/SorpLib/Components/Fans/BaseClasses/PartialSimpleFan.mo
@@ -0,0 +1,169 @@
+within SorpLib.Components.Fans.BaseClasses;
+partial model PartialSimpleFan
+  "Base model for all simple fans with constant efficiencies"
+  extends SorpLib.Components.Fans.BaseClasses.PartialFan(final
+      calculateDrivePower=true);
+
+  //
+  // Definition of paramteres describring the fan's characteristics
+  //
+  parameter Modelica.Units.SI.Efficiency eta_fan = 0.4
+    "Efficiency of fan that is used to calculate shaft power"
+    annotation (Dialog(tab="General", group="Fan Characteristics"));
+
+  //
+  // Definition of parameters describing the inputs
+  //
+  parameter SorpLib.Choices.PrescripedFanVariable prescribedInput=
+    SorpLib.Choices.PrescripedFanVariable.V_flow
+    "Prescribed input variable"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  parameter Boolean use_mFlowInput = false
+    "=true, if m_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=(prescribedInput ==
+                SorpLib.Choices.PrescripedFanVariable.m_flow)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_fixed = 0.1
+    "Fixed mass flow rate"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=(prescribedInput ==
+                SorpLib.Choices.PrescripedFanVariable.m_flow)
+                and not use_mFlowInput));
+
+  parameter Boolean use_VFlowInput = false
+    "=true, if V_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=(prescribedInput ==
+                SorpLib.Choices.PrescripedFanVariable.V_flow)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.VolumeFlowRate V_flow_fixed = 10/1000/60
+    "Fixed volume flow rate"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=(prescribedInput ==
+                SorpLib.Choices.PrescripedFanVariable.V_flow)
+                and not use_VFlowInput));
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput m_flow_input(final unit="kg/s") if
+    (prescribedInput == SorpLib.Choices.PrescripedFanVariable.m_flow and
+    use_mFlowInput)
+    "Input for mass flow rate"
+    annotation (Placement(transformation(extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={0,-90}),
+      iconTransformation(extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,-80})));
+
+  Modelica.Blocks.Interfaces.RealInput V_flow_input(final unit="m3/s") if
+    (prescribedInput == SorpLib.Choices.PrescripedFanVariable.V_flow and
+    use_VFlowInput)
+    "Input for volume flow rate"
+    annotation (Placement(transformation(extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={30,-90}),
+      iconTransformation(extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={30,-80})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput m_flow_internal(final unit="kg/s")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput V_flow_internal(final unit="m3/s")
+    "Needed for connecting to conditional connector";
+
+equation
+  //
+  // Connectors
+  //
+  connect(m_flow_internal, m_flow_input);
+  connect(V_flow_internal, V_flow_input);
+
+  if not use_mFlowInput then
+    m_flow_internal = m_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_VFlowInput then
+    V_flow_internal = V_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Mass balance
+  //
+  if prescribedInput == SorpLib.Choices.PrescripedFanVariable.m_flow then
+    m_flow = m_flow_internal
+      "Mass flow rate at port a";
+    V_flow = m_flow_internal / rho
+      "Volume flow rate at port a";
+
+  elseif prescribedInput == SorpLib.Choices.PrescripedFanVariable.V_flow then
+    m_flow = V_flow_internal * rho
+      "Mass flow rate at port a";
+    V_flow = V_flow_internal
+      "Volume flow rate at port a";
+
+  end if;
+
+  //
+  // Energy balance
+  //
+  if assumeIsenthalpicFan then
+    port_a.h_outflow = inStream(port_b.h_outflow)
+      "Stream variable: Trivial equation since no change of energy due to
+      forbidden flow revesal";
+    port_b.h_outflow = inStream(port_a.h_outflow) + (1/eta_fan - 1) * dp / rho
+      "Increase of specific enthalpy due to internal losses of the fan";
+
+  else
+    port_a.h_outflow = inStream(port_b.h_outflow)
+      "Stream variable: Trivial equation since no change of energy";
+    port_b.h_outflow = inStream(port_a.h_outflow)
+      "Stream variable: Trivial equation since no change of energy";
+
+  end if;
+
+  //
+  // Power calculations
+  //
+  P_shaft = P_hydraulic / eta_fan
+    "Shaft power consumption of fan";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all simple fans with constant efficiencies.
+It defines fundamental parameters and variables required by all simple fans. Models 
+that inherit properties from this partial model have to redeclare the fluid ports. 
+Moreover, the instreaming density must be calculated. In this context, appropriate 
+fluid property models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Instreaming density <i>rho</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 10, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialSimpleFan;
diff --git a/SorpLib/Components/Fans/BaseClasses/package.mo b/SorpLib/Components/Fans/BaseClasses/package.mo
new file mode 100644
index 0000000..e3c3fe9
--- /dev/null
+++ b/SorpLib/Components/Fans/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Fans;
+package BaseClasses "Base models and functions for all pumps"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial fan models, containing fundamental definitions for 
+pumps. The content of this package is only of interest when adding new fans to 
+the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/Fans/BaseClasses/package.order b/SorpLib/Components/Fans/BaseClasses/package.order
new file mode 100644
index 0000000..5ee395b
--- /dev/null
+++ b/SorpLib/Components/Fans/BaseClasses/package.order
@@ -0,0 +1,3 @@
+PartialFan
+PartialSimpleFan
+PartialAffinityFan
diff --git a/SorpLib/Components/Fans/SimpleFan.mo b/SorpLib/Components/Fans/SimpleFan.mo
new file mode 100644
index 0000000..5e009a8
--- /dev/null
+++ b/SorpLib/Components/Fans/SimpleFan.mo
@@ -0,0 +1,117 @@
+within SorpLib.Components.Fans;
+model SimpleFan "Model of a simple fan with constant efficiencies"
+  extends BaseClasses.PartialSimpleFan(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculation of fluid properties
+  //
+  rho = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1, inStream(port_a.Xi_outflow), {1-sum(inStream(port_a.Xi_outflow))}))
+    "Instreaming density";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The simple fan can be used to prescribe the mass or volume flow rate in hydraulic
+components, such as tubes or heat exchangers. The model assumes constant efficiencies
+and can be used for ideal gases, gas-mixtures, or gas-vapor mixtures.
+
+<h4>Main equations</h4>
+<p>
+The model calculates the hydraulic, shaft, and drive power transmitted to the fluid
+or required to drive the fan. The hydraulic power <i>P<sub>hydraulic</sub></i> 
+transmitted to the fluid is defined as:
+</p>
+<pre>
+    P<sub>hydraulic</sub> = m&#x307; / &rho;<sub>in</sub> * &Delta;p;
+</pre>
+<p>
+Herein, <i>m&#x307;</i> is the mass flow rate, <i>&rho;<sub>in</sub></i> describes the 
+fluid density at the inlet, and <i>&Delta;p = p<sub>b</sub> - p<sub>a</sub></i> is the 
+pressure difference between port b and a.
+<br/><br/>
+The shaft power <i>P<sub>shaft</sub></i> depends on the fan efficiency 
+<i>&eta;<sub>fan</sub></i> and is defined as:
+</p>
+<pre>
+    P<sub>shaft</sub> = P<sub>hydraulic</sub> / &eta;<sub>fan</sub>;
+</pre>
+<p>
+The shaft power is completly transmitted to the fluid, thus increasing the outflowing
+specific enthalpy of the fluid.
+<br/><br/>
+The drive power <i>P<sub>drive</sub></i> is required to drive the fan, depends on the
+drive efficienciy <i>&eta;<sub>drive</sub></i>, and is defined as:
+</p>
+<pre>
+    P<sub>drive</sub> = P<sub>shaft</sub> / &eta;<sub>drive</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No flow reversal
+  </li>
+  <li>
+  Constant efficiencies
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The simple fan is typically used to prescripe the mass or volume flow rate
+in hydraulic components, such as tubes or heat exchangers.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>prescribedInput</i>:
+  Defines the variable that is prescribed (i.e., mass flow rate or volume
+  flow rate).
+  </li>
+  <li>
+  <i>assumeIsenthalpicFan</i>:
+  Defines if the hydraulic losses are considered in the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 10, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SimpleFan;
diff --git a/SorpLib/Components/Fans/Tester/Test_AffinityFan.mo b/SorpLib/Components/Fans/Tester/Test_AffinityFan.mo
new file mode 100644
index 0000000..35ea49f
--- /dev/null
+++ b/SorpLib/Components/Fans/Tester/Test_AffinityFan.mo
@@ -0,0 +1,102 @@
+within SorpLib.Components.Fans.Tester;
+model Test_AffinityFan "Tester for the affinity fan"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fans.AffinityFan fan(use_nInput=true, redeclare final
+      package Medium = Medium) "Affinity fan"
+    annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
+
+  SorpLib.Components.Fittings.Resistors.GasTubeResistance pressureLoss(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.PortAInlet,
+    frictionPressureLoss=true,
+    fittingPressureLosss=false,
+    redeclare model PressureLossModel =
+        Fittings.PressureLossCorrelations.TubeInside.Blasius,
+    redeclare replaceable parameter Fittings.Records.GeometryTube geometry(l=5,
+        d_hyd_a=0.25) constrainedby
+      SorpLib.Components.Fittings.Records.GeometryTube,
+    redeclare final package Medium = Medium) "Pressure loss model"
+    annotation (Placement(transformation(extent={{20,-10},{40,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_n(
+    amplitude=50,
+    f=1/250,
+    offset=50)
+    "Input signal for the rotational speed"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, fan.port_a) annotation (Line(
+      points={{-60,0},{-38,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(pressureLoss.port_a, fan.port_b) annotation (Line(
+      points={{22,0},{-22,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, pressureLoss.port_b) annotation (Line(
+      points={{60,0},{38,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_n.y, fan.n_input)
+    annotation (Line(points={{-59,-30},{-30,-30},{-30,-8}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the affinity fan.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 11, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AffinityFan;
diff --git a/SorpLib/Components/Fans/Tester/Test_SimpleFan.mo b/SorpLib/Components/Fans/Tester/Test_SimpleFan.mo
new file mode 100644
index 0000000..ae63d5e
--- /dev/null
+++ b/SorpLib/Components/Fans/Tester/Test_SimpleFan.mo
@@ -0,0 +1,102 @@
+within SorpLib.Components.Fans.Tester;
+model Test_SimpleFan "Tester for the simple fan"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fans.SimpleFan fan(use_VFlowInput=true, redeclare final
+      package Medium = Medium) "Simple fan"
+    annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
+
+  SorpLib.Components.Fittings.Resistors.GasTubeResistance                       pressureLoss(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.PortAInlet,
+    frictionPressureLoss=true,
+    fittingPressureLosss=false,
+    redeclare model PressureLossModel =
+        Fittings.PressureLossCorrelations.TubeInside.Blasius,
+    redeclare replaceable parameter Fittings.Records.GeometryTube geometry(l=5,
+        d_hyd_a=0.25) constrainedby
+      SorpLib.Components.Fittings.Records.GeometryTube,
+    redeclare final package Medium = Medium) "Pressure loss model"
+    annotation (Placement(transformation(extent={{20,-10},{40,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_VFlow(
+    amplitude=100/1.2/60/60,
+    f=1/250,
+    offset=100/1.2/60/60)
+    "Input signal for volume flow rate"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, fan.port_a) annotation (Line(
+      points={{-60,0},{-38,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(pressureLoss.port_a, fan.port_b) annotation (Line(
+      points={{22,0},{-22,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, pressureLoss.port_b) annotation (Line(
+      points={{60,0},{38,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_VFlow.y, fan.V_flow_input)
+    annotation (Line(points={{-59,-30},{-27,-30},{-27,-8}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the simple fan.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 10, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_SimpleFan;
diff --git a/SorpLib/Components/Fans/Tester/package.mo b/SorpLib/Components/Fans/Tester/package.mo
new file mode 100644
index 0000000..5ef5541
--- /dev/null
+++ b/SorpLib/Components/Fans/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components.Fans;
+package Tester "Models to test and varify fan models"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented fans. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Fans/Tester/package.order b/SorpLib/Components/Fans/Tester/package.order
new file mode 100644
index 0000000..63eb6cd
--- /dev/null
+++ b/SorpLib/Components/Fans/Tester/package.order
@@ -0,0 +1,2 @@
+Test_SimpleFan
+Test_AffinityFan
diff --git a/SorpLib/Components/Fans/package.mo b/SorpLib/Components/Fans/package.mo
new file mode 100644
index 0000000..5d0208c
--- /dev/null
+++ b/SorpLib/Components/Fans/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components;
+package Fans "Fans to move fluids"
+  extends SorpLib.Icons.FansPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains fans. Ready-to-use models are based on the Modelica 
+Standard library (MSL). Fans are used to prescripe a mass or volume flow rate
+to a hydraulic fluid.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Fans;
diff --git a/SorpLib/Components/Fans/package.order b/SorpLib/Components/Fans/package.order
new file mode 100644
index 0000000..26d0d3c
--- /dev/null
+++ b/SorpLib/Components/Fans/package.order
@@ -0,0 +1,4 @@
+BaseClasses
+SimpleFan
+AffinityFan
+Tester
diff --git a/SorpLib/Components/Fittings/BaseClasses/PartialInertiaInducer.mo b/SorpLib/Components/Fittings/BaseClasses/PartialInertiaInducer.mo
new file mode 100644
index 0000000..692b559
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/PartialInertiaInducer.mo
@@ -0,0 +1,189 @@
+within SorpLib.Components.Fittings.BaseClasses;
+partial model PartialInertiaInducer
+  "Base model for all inertia inducers"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of setup parameters
+  //
+  parameter Modelica.Units.SI.Length f_momentum = 0.1
+    "Momentum factor describing acceleration of fluid mass"
+    annotation (Dialog(tab="General", group="Momentum Setup"));
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Integer initialisationType(min=1, max=3) = 3
+    "Initialisation type: Fixed, steady-state, or free"
+    annotation (Dialog(tab="Initialisation", group="Type"),
+                choices(
+                  choice=1 "Fixed",
+                  choice=2 "Steady-state",
+                  choice=3 "Free"));
+
+  parameter Modelica.Units.SI.MassFlowRate m_flow_initial = 0.01
+    "Initial value of mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}}),
+                iconTransformation(extent={{-70,-10},{-50,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid ports b"
+    annotation (Placement(transformation(extent={{50,-10},{70,10}}),
+                iconTransformation(extent={{50,-10},{70,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.PressureDifference dp
+    "Pressure difference between port a and b";
+
+  Modelica.Units.SI.MassFlowRate m_flow
+    "Mass flow rate";
+
+initial equation
+  if initialisationType==1 then
+    m_flow = m_flow_initial
+      "Fixed intial value";
+
+  elseif initialisationType==2 then
+    der(m_flow) = 0
+      "Steady-state initialisation";
+
+  end if;
+
+equation
+  //
+  // Momentum balance
+  //
+  dp = port_a.p - port_b.p
+    "Pressure difference between port a and b";
+  der(m_flow) = dp * f_momentum
+    "Mass flow rate";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + port_b.m_flow
+    "Steady-state mass balance";
+  port_a.m_flow = m_flow
+    "Mass flow rate at port a";
+
+  port_a.Xi_outflow = inStream(port_b.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+  port_b.Xi_outflow = inStream(port_a.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+
+  //
+  // Energy balance
+  //
+  port_a.h_outflow = inStream(port_b.h_outflow)
+    "Stream variable: Trivial equation since no change of energy";
+  port_b.h_outflow = inStream(port_a.h_outflow)
+    "Stream variable: Trivial equation since no change of energy";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all inertia inducers. It defines fundamental
+parameters and variables required by all inertia inducers. Models that inherit 
+properties from this partial model have to redeclare the fluid ports and to add a 
+medium model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Rectangle(
+          extent={{60,-50},{-60,50}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          lineThickness=1),
+        Ellipse(
+          extent={{-40,10},{-20,-10}},
+          lineColor={135,135,135},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{-18,2},{-14,-2}},
+          lineColor={135,135,135},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{-12,2},{-8,-2}},
+          lineColor={135,135,135},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{-6,2},{-2,-2}},
+          lineColor={135,135,135},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{2,2},{6,-2}},
+          lineColor={135,135,135},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{8,2},{12,-2}},
+          lineColor={135,135,135},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{14,2},{18,-2}},
+          lineColor={135,135,135},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{20,10},{40,-10}},
+          lineColor={135,135,135},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid),
+        Text(
+          extent={{-40,32},{40,10}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid,
+          textString="dṁ/dtau = ..."),
+        Line(
+          points={{-40,-16},{40,-16}},
+          color={0,0,0},
+          thickness=1,
+          arrow={Arrow.Open,Arrow.Open})}));
+end PartialInertiaInducer;
diff --git a/SorpLib/Components/Fittings/BaseClasses/PartialMultiPort.mo b/SorpLib/Components/Fittings/BaseClasses/PartialMultiPort.mo
new file mode 100644
index 0000000..9db8ff7
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/PartialMultiPort.mo
@@ -0,0 +1,145 @@
+within SorpLib.Components.Fittings.BaseClasses;
+partial model PartialMultiPort
+  "Base model for all multi port models (i.e., ideal splitter/junctions)"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of setup parameters
+  //
+  parameter Integer no_ports_b = 0
+    "Number of ports at position b"
+    annotation (Dialog(connectorSizing=true));
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}}),
+                iconTransformation(extent={{-70,-10},{-50,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort ports_b[no_ports_b]
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      each final no_components=no_components)
+    "Fluid ports b"
+    annotation (Placement(transformation(extent={{50,-10},{70,10}}),
+                iconTransformation(extent={{50,-10},{70,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Real denominator = Modelica.Constants.small +
+    sum({abs(ports_b[ind_b].m_flow) for ind_b in 1:no_ports_b})
+    "Denominator used to calculate mixing stream variables";
+
+equation
+  //
+  // Momentum balance
+  //
+  ports_b.p = fill(port_a.p, no_ports_b)
+    "No pressure loss";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + sum(ports_b.m_flow)
+    "Steady-state mass balance";
+
+  for ind_c in 1:no_components-1 loop
+    port_a.Xi_outflow[ind_c] =
+      (sum({abs(ports_b[ind_b].m_flow) * inStream(ports_b[ind_b].Xi_outflow[ind_c])
+        for ind_b in 1:no_ports_b}) + Modelica.Constants.small) / denominator
+      "Calculate ideal mixing stream variable for mass flow from port b to port a";
+  end for;
+
+  for ind_b in 1:no_ports_b loop
+    ports_b[ind_b].Xi_outflow = inStream(port_a.Xi_outflow)
+      "Expose stream variable of port due to splitting of mass flow from port a";
+  end for;
+
+  //
+  // Energy balance
+  //
+  port_a.h_outflow =
+    (sum({abs(ports_b[ind_b].m_flow) * inStream(ports_b[ind_b].h_outflow)
+      for ind_b in 1:no_ports_b}) + Modelica.Constants.small) / denominator
+    "Calculate ideal mixing stream variable for mass flow from port b to port a";
+
+  for ind_b in 1:no_ports_b loop
+    ports_b[ind_b].h_outflow = inStream(port_a.h_outflow)
+      "Expose stream variable of port due to splitting of mass flow from port a";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all multi port models. It defines fundamental
+parameters and variables required by all multi port models. Models that inherit 
+properties from this partial model have to redeclare the fluid ports and to add a 
+medium model.
+<br/><br/>
+This models is based on
+<a href=\"Modelica://Modelica.Fluid.Fittings.MultiPort\">Modelica.Fluid.Fittings.MultiPort</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 20, 2023, by Mirko Engelpracht:<br/>
+  Minor revisions (documentation).
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Rectangle(
+          extent={{-60,100},{60,-100}},
+          lineColor={0,0,0},
+          lineThickness=0.5,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Line(
+          points={{20,80},{40,80}},
+          color={0,0,0},
+          thickness=0.5),
+        Line(
+          points={{20,40},{40,40}},
+          color={0,0,0},
+          thickness=0.5),
+        Line(
+          points={{-40,0},{-20,0}},
+          color={0,0,0},
+          thickness=0.5),
+        Line(
+          points={{20,-80},{40,-80}},
+          color={0,0,0},
+          thickness=0.5),
+        Line(
+          points={{20,80},{-20,0},{20,-80}},
+          color={0,0,0},
+          thickness=0.5),
+        Line(
+          points={{20,0},{40,0}},
+          color={0,0,0},
+          thickness=0.5),
+        Line(
+          points={{20,-40},{40,-40}},
+          color={0,0,0},
+          thickness=0.5)}));
+end PartialMultiPort;
diff --git a/SorpLib/Components/Fittings/BaseClasses/PartialOpenAdsorberPressureLoss.mo b/SorpLib/Components/Fittings/BaseClasses/PartialOpenAdsorberPressureLoss.mo
new file mode 100644
index 0000000..5e97483
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/PartialOpenAdsorberPressureLoss.mo
@@ -0,0 +1,45 @@
+within SorpLib.Components.Fittings.BaseClasses;
+partial model PartialOpenAdsorberPressureLoss
+  "Base model for all pressure loss models of open adsorbers"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialPressureLoss(
+    final psi = geometry.psi,
+    redeclare replaceable parameter SorpLib.Components.Fittings.Records.GeometryOpenAdsorber geometry
+    constrainedby SorpLib.Components.Fittings.Records.GeometryOpenAdsorber);
+
+equation
+  //
+  // Calculate the hydraulic mass flow rate
+  //
+  m_flow_hyd = m_flow / geometry.no_hydraulicParallelFlows
+    "Hydraulic mass flow rate";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all pressure loss models applied in open
+adsorbers. It defines fundamental parameters and variables required by all pressure 
+loss models. Models that inherit properties from this partial model have to complete 
+the friction-based pressure loss correlation.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Friction factor <i>lambda_mean_dd</i> for design flow direction (i.e., a->b).
+  </li>
+  <li>
+  Friction factor <i>lambda_mean_rdd</i> for reverse design flow direction (i.e., 
+  a->b).
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialOpenAdsorberPressureLoss;
diff --git a/SorpLib/Components/Fittings/BaseClasses/PartialPressureLoss.mo b/SorpLib/Components/Fittings/BaseClasses/PartialPressureLoss.mo
new file mode 100644
index 0000000..f046798
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/PartialPressureLoss.mo
@@ -0,0 +1,1060 @@
+within SorpLib.Components.Fittings.BaseClasses;
+partial model PartialPressureLoss
+  "Base model for all pressure loss models"
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter SorpLib.Choices.ResistorFluidProperties positionFluidProperties=
+    SorpLib.Choices.ResistorFluidProperties.Detailed
+    "Position of fluid properties used for calculations"
+    annotation (Dialog(tab="General", group="Calculation Setup", enable=false),
+                Evaluate=true);
+  parameter Boolean requireTransportPropreties = true
+    "= true, if transport properties are required"
+    annotation (Dialog(tab="General", group="Calculation Setup", enable=false),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean dpFromMFlow = true
+    " = true, if static pressure loss is calculated from mass flow rate; otherwise,
+    mass flow rate is calculated from static pressure loss"
+    annotation (Dialog(tab="General", group="Calculation Setup", enable=false),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of parameters regarding the geometry
+  //
+  replaceable parameter SorpLib.Components.Fittings.Records.GeometryGenericReistance geometry
+    constrainedby SorpLib.Components.Fittings.Records.GeometryGenericReistance
+    "Resistor geometry"
+    annotation (Dialog(tab="General", group="Geometry", enable=false),
+                HideResult=true,
+                choicesAllMatching=true);
+
+  parameter Real psi(unit="1") = 1
+    "Void fraction of the resistance (i.e., psi = 1 - V_particle / V)"
+    annotation (Dialog(tab="General", group="Geometry", enable=false),
+                HideResult=true);
+  final parameter Modelica.Units.SI.Diameter d_hyd_mean=
+    (geometry.d_hyd_a + geometry.d_hyd_b) / 2
+    "Hydraulic diameter"
+    annotation (Dialog(tab="General", group="Geometry", enable=false),
+                HideResult=true);
+  final parameter Modelica.Units.SI.Area A_a=
+    Modelica.Constants.pi / 4 * geometry.d_hyd_a^2 * psi
+    "Cross-sectional area at port a"
+    annotation (Dialog(tab="General", group="Geometry", enable=false),
+                HideResult=true);
+  final parameter Modelica.Units.SI.Area A_b=
+    Modelica.Constants.pi / 4 * geometry.d_hyd_b^2 * psi
+    "Cross-sectional area at port b"
+    annotation (Dialog(tab="General", group="Geometry", enable=false),
+                HideResult=true);
+  final parameter Modelica.Units.SI.Area A_mean=
+    (A_a + A_b) / 2
+    "Average cross-sectional area"
+    annotation (Dialog(tab="General", group="Geometry", enable=false),
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding fluid properties
+  //
+  parameter SorpLib.Components.Fittings.Records.FluidProperties constantFluidProperties
+    "Constant fluid properties that might be used for pressure loss calculations"
+    annotation (Dialog(tab="General", group="Fluid Properties", enable=false));
+
+  //
+  // Definition of parameters regarding fittings
+  //
+  parameter Boolean flowDirectionDependentZeta = false
+    " = true, if loss factors differ with flow direction (e.g., sudden expansion)
+    and area and density at port a or b are used"
+    annotation (Dialog(tab="General", group="Fittings", enable=false),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Real[:] zeta_a(each unit="1") = {0}
+    "Loss factors due to fittings at port a"
+    annotation (Dialog(tab="General", group="Fittings", enable=false));
+  parameter Real[:] zeta_b(each unit="1") = zeta_a
+    "Loss factors due to fittings at port b"
+    annotation (Dialog(tab="General", group="Fittings", enable=false));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics", enable=false),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_small = 1e-4
+    "Regularization mass flow rate"
+    annotation (Dialog(tab="Advanced", group="Numerics", enable=false));
+
+  parameter Boolean showTotalPressures = false
+    "= true, if total pressures are calculated and shown"
+    annotation (Dialog(tab = "Advanced", group = "Diagnostics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean showVelocities = false
+    "= true, if fluid velocities at ports are calculated and shown"
+    annotation (Dialog(tab = "Advanced", group = "Diagnostics",
+                enable=geometry.frictionPressureLoss),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean showDarcyFrictionNumber = false
+    "= true, if Darcy friction number is calculated and shown"
+    annotation (Dialog(tab = "Advanced", group = "Diagnostics",
+                enable=geometry.frictionPressureLoss),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean showIndividualPressureLosses = false
+    "= true, if individual pressure loss contributions are calculated and shown"
+    annotation (Dialog(tab = "Advanced", group = "Diagnostics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MassFlowRate m_flow
+    "Mass flow rate"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  input SorpLib.Components.Fittings.Records.FluidProperties fluidProperties_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input SorpLib.Components.Fittings.Records.FluidProperties fluidProperties_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input SorpLib.Components.Fittings.Records.FluidProperties fluidProperties_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input SorpLib.Components.Fittings.Records.FluidProperties fluidProperties_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.PressureDifference dp_static
+    "Static pressure loss"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.MassFlowRate m_flow_hyd
+    "Hydraulic mass flow rate";
+
+  //
+  // Definition of protected veriables describing fluid properties
+  //
+protected
+  Modelica.Units.SI.Density rho_mean_dd
+    "Average density at port a for design flow direction (i.e., a->b)";
+  Modelica.Units.SI.ReynoldsNumber Re_mean_dd
+    "Average Reynolds number describing the flow regime for design flow 
+    direction (i.e., a->b)";
+
+  Modelica.Units.SI.Density rho_mean_rdd
+    "Average density at port a for reverse design flow direction (i.e., b->a)";
+  Modelica.Units.SI.ReynoldsNumber Re_mean_rdd
+    "Average Reynolds number describing the flow regime for reverse design flow 
+    direction (i.e., b->a)";
+
+  Real lambda_mean_dd(unit="1")
+    "Average Darcy friction number for design flow direction (a->b)";
+  Real lambda_mean_rdd(unit="1")
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  Modelica.Units.SI.PressureDifference dp_dyn_dd
+    "Dynamic pressure loss for design flow direction (a->b)";
+  Modelica.Units.SI.PressureDifference dp_geo_dd
+    "Geodetic pressure loss for design flow direction (a->b)";
+  Real f_fric_dd(unit="1/(kg.m)")
+    "Factor of friction-caused pressure loss for design flow direction (a->b)";
+  Real f_fit_dd(unit="1/(kg.m)")
+    "Factor of fitting-caused pressure loss for design flow direction (a->b)";
+
+  Modelica.Units.SI.PressureDifference dp_dyn_rdd
+    "Dynamic pressure loss for reverse design flow direction (b->a)";
+  Modelica.Units.SI.PressureDifference dp_geo_rdd
+    "Geodetic pressure loss for reverse design flow direction (b->a)";
+  Real f_fric_rdd(unit="1/(kg.m)")
+    "Factor of friction-caused pressure loss for reverse design flow direction 
+    (b->a)";
+  Real f_fit_rdd(unit="1/(kg.m)")
+    "Factor of fitting-caused pressure loss for reverse design flow direction 
+    (b->a)";
+
+  //
+  // Definition of variables required to calculate diagnostic variables
+  //
+  Modelica.Units.SI.Density rho_a
+    "Density at port a";
+  Modelica.Units.SI.Density rho_b
+    "Density at port b";
+
+  Modelica.Units.SI.DynamicViscosity eta_a
+    "Dynamic viscosity at port a";
+  Modelica.Units.SI.DynamicViscosity eta_b
+    "Dynamic viscosity at port b";
+
+  //
+  // Definition (and calculation) of diagnostic variables
+  //
+public
+  Modelica.Units.SI.Velocity w_a
+    "Hydraulic fluid velocity at port a";
+  Modelica.Units.SI.Velocity w_b
+    "Hydraulic fluid velocity at port b";
+  Modelica.Units.SI.Velocity w_mean
+    "Average hydraulic fluid velocity";
+
+  Modelica.Units.SI.ReynoldsNumber Re_a=
+    abs(m_flow_hyd) * geometry.d_hyd_a / (A_a * eta_a) if
+    showDarcyFrictionNumber
+    "Reynolds number describing the flow regime at port a";
+  Modelica.Units.SI.ReynoldsNumber Re_b=
+    abs(m_flow_hyd) * geometry.d_hyd_b / (A_b * eta_b) if
+    showDarcyFrictionNumber
+    "Reynolds number describing the flow regime at port b";
+  Modelica.Units.SI.ReynoldsNumber Re_mean=
+    abs(m_flow_hyd) * (geometry.d_hyd_a / (A_a * eta_a) +
+    geometry.d_hyd_b / (A_b * eta_b)) / 2 if
+    showDarcyFrictionNumber
+    "Average Reynolds number describing the flow regime";
+
+  Real lambda_mean(unit="1")=
+    SorpLib.Numerics.regStep(
+      x=m_flow_hyd,
+      y1=lambda_mean_dd,
+      y2=lambda_mean_rdd,
+      x_small=m_flow_small) if
+    showDarcyFrictionNumber
+    "Average darcy friction number";
+
+  Modelica.Units.SI.Pressure p_total_a=
+    fluidProperties_a.p + (w_a^2 / 2 +
+    Modelica.Constants.g_n * geometry.z_a) * rho_a if
+    showTotalPressures
+    "Total pressure at port a";
+  Modelica.Units.SI.Pressure p_total_b=
+    fluidProperties_b_ad.p + (w_b^2 / 2 +
+    Modelica.Constants.g_n * geometry.z_b) * rho_b if
+    showTotalPressures
+    "Total pressure at port b";
+  Modelica.Units.SI.PressureDifference dp_total=
+    fluidProperties_a.p + (w_a^2 / 2 +
+    Modelica.Constants.g_n * geometry.z_a) * rho_a -
+    fluidProperties_b_ad.p - (w_b^2 / 2 +
+    Modelica.Constants.g_n * geometry.z_b) * rho_b if
+    showTotalPressures
+    "Total pressure difference";
+
+  Modelica.Units.SI.PressureDifference dp_dyn=
+    1/2 * (rho_a * w_a^2 - rho_b * w_b^2) if
+    showIndividualPressureLosses
+    "Dynamic pressure difference between port a and b";
+  Modelica.Units.SI.PressureDifference dp_geo = Modelica.Constants.g_n *
+    (geometry.z_a * rho_a - geometry.z_b * rho_b) if
+    showIndividualPressureLosses
+    "Geodetic pressure difference between port a and b";
+  Modelica.Units.SI.PressureDifference dp_fric=
+    SorpLib.Numerics.regSquareWFactors(
+      x=m_flow_hyd,
+      delta_x=m_flow_small,
+      f_positive=1/(f_fric_dd+Modelica.Constants.small),
+      f_negative=1/(f_fric_rdd+Modelica.Constants.small)) if
+    showIndividualPressureLosses
+    "Pressure difference between port a and b due to friction";
+  Modelica.Units.SI.PressureDifference dp_fit=
+    SorpLib.Numerics.regSquareWFactors(
+      x=m_flow_hyd,
+      delta_x=m_flow_small,
+      f_positive=1/(f_fit_dd+Modelica.Constants.small),
+      f_negative=1/(f_fit_rdd+Modelica.Constants.small)) if
+    showIndividualPressureLosses
+    "Pressure difference between port a and b due to fittings";
+
+equation
+  //
+  // Assertations
+  //
+  if not geometry.dynamicPressureLoss then
+    assert(Modelica.Math.isEqual(
+      s1=geometry.d_hyd_a,
+      s2=geometry.d_hyd_b,
+      eps=Modelica.Constants.eps),
+      "Dynamic pressure loss is not considered: Hydraulic diameters must be " +
+      "equal to calculate sound results!",
+      level=AssertionLevel.error);
+  end if;
+
+  if not geometry.geodeticPressureLoss then
+    assert(Modelica.Math.isEqual(
+      s1=geometry.z_a,
+      s2=geometry.z_b,
+      eps=Modelica.Constants.eps),
+      "Geodetic pressure loss is not considered: Heights must be equal to " +
+      "calculate sound results!",
+      level=AssertionLevel.error);
+  end if;
+
+  //
+  // Calculate variables required to calculate diagnostic variables
+  //
+  if showVelocities or showTotalPressures or showIndividualPressureLosses then
+    if positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.Constant then
+      rho_a = constantFluidProperties.rho
+        "Density at port a";
+      rho_b = constantFluidProperties.rho
+        "Density at port b";
+
+      eta_a = constantFluidProperties.eta
+        "Dynamic viscosity at port a";
+      eta_b = constantFluidProperties.eta
+        "Dynamic viscosity at port b";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+      rho_a = fluidProperties_a.rho
+        "Density at port a";
+      rho_b = fluidProperties_a.rho
+        "Density at port b";
+
+      eta_a = fluidProperties_a.eta
+        "Dynamic viscosity at port a";
+      eta_b = fluidProperties_a.eta
+        "Dynamic viscosity at port b";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+      rho_a = fluidProperties_b_ad.rho
+        "Density at port a";
+      rho_b = fluidProperties_b_ad.rho
+        "Density at port b";
+
+      eta_a = fluidProperties_b_ad.eta
+        "Dynamic viscosity at port a";
+      eta_b = fluidProperties_b_ad.eta
+        "Dynamic viscosity at port b";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.ActualInlet then
+      if avoid_events then
+        rho_a = SorpLib.Numerics.regStep_noEvent(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.rho,
+          y2=fluidProperties_b_ad.rho,
+          x_small=m_flow_small)
+          "Density at port a";
+        rho_b = SorpLib.Numerics.regStep_noEvent(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.rho,
+          y2=fluidProperties_b_ad.rho,
+          x_small=m_flow_small)
+          "Density at port b";
+
+        eta_a = SorpLib.Numerics.regStep_noEvent(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.eta,
+          y2=fluidProperties_b_ad.eta,
+          x_small=m_flow_small)
+          "Dynamic viscosity at port a";
+        eta_b = SorpLib.Numerics.regStep_noEvent(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.eta,
+          y2=fluidProperties_b_ad.eta,
+          x_small=m_flow_small)
+          "Dynamic viscosity at port b";
+
+      else
+        rho_a = SorpLib.Numerics.regStep(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.rho,
+          y2=fluidProperties_b_ad.rho,
+          x_small=m_flow_small)
+          "Density at port a";
+        rho_b = SorpLib.Numerics.regStep(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.rho,
+          y2=fluidProperties_b_ad.rho,
+          x_small=m_flow_small)
+          "Density at port b";
+
+        eta_a = SorpLib.Numerics.regStep(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.eta,
+          y2=fluidProperties_b_ad.eta,
+          x_small=m_flow_small)
+          "Dynamic viscosity at port a";
+        eta_b = SorpLib.Numerics.regStep(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.eta,
+          y2=fluidProperties_b_ad.eta,
+          x_small=m_flow_small)
+          "Dynamic viscosity at port b";
+
+      end if;
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+      rho_a = (fluidProperties_a.rho + fluidProperties_b_ad.rho) / 2
+        "Density at port a";
+      rho_b = (fluidProperties_a.rho + fluidProperties_b_ad.rho) / 2
+        "Density at port b";
+
+      eta_a = (fluidProperties_a.eta + fluidProperties_b_ad.eta) / 2
+        "Dynamic viscosity at port a";
+      eta_b = (fluidProperties_a.eta + fluidProperties_b_ad.eta) / 2
+        "Dynamic viscosity at port b";
+
+    else
+      if avoid_events then
+        rho_a = SorpLib.Numerics.regStep_noEvent(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.rho,
+          y2=fluidProperties_a_ad.rho,
+          x_small=m_flow_small)
+          "Density at port a";
+        rho_b = SorpLib.Numerics.regStep_noEvent(
+          x=m_flow_hyd,
+          y1=fluidProperties_b.rho,
+          y2=fluidProperties_b_ad.rho,
+          x_small=m_flow_small)
+          "Density at port a";
+
+        eta_a = SorpLib.Numerics.regStep_noEvent(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.eta,
+          y2=fluidProperties_a_ad.eta,
+          x_small=m_flow_small)
+          "Dynamic viscosity at port a";
+        eta_b = SorpLib.Numerics.regStep_noEvent(
+          x=m_flow_hyd,
+          y1=fluidProperties_b.eta,
+          y2=fluidProperties_b_ad.eta,
+          x_small=m_flow_small)
+          "Dynamic viscosity at port a";
+
+      else
+        rho_a = SorpLib.Numerics.regStep(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.rho,
+          y2=fluidProperties_a_ad.rho,
+          x_small=m_flow_small)
+          "Density at port a";
+        rho_b = SorpLib.Numerics.regStep(
+          x=m_flow_hyd,
+          y1=fluidProperties_b.rho,
+          y2=fluidProperties_b_ad.rho,
+          x_small=m_flow_small)
+          "Density at port a";
+
+        eta_a = SorpLib.Numerics.regStep(
+          x=m_flow_hyd,
+          y1=fluidProperties_a.eta,
+          y2=fluidProperties_a_ad.eta,
+          x_small=m_flow_small)
+          "Dynamic viscosity at port a";
+        eta_b = SorpLib.Numerics.regStep(
+          x=m_flow_hyd,
+          y1=fluidProperties_b.eta,
+          y2=fluidProperties_b_ad.eta,
+          x_small=m_flow_small)
+          "Dynamic viscosity at port a";
+
+      end if;
+    end if;
+
+    w_a = m_flow_hyd / (A_a * rho_a)
+      "Hydraulic fluid velocity at port a";
+    w_b = m_flow_hyd / (A_b * rho_b)
+      "Hydraulic fluid velocity at port b";
+    w_mean = (w_a + w_b) / 2
+      "Average hydraulic fluid velocity";
+
+  else
+    rho_a = 0
+      "Density at port a";
+    rho_b = 0
+      "Density at port b";
+
+    eta_a = 0
+      "Dynamic viscosity at port a";
+    eta_b = 0
+      "Dynamic viscosity at port b";
+
+    w_a = 0
+      "Hydraulic fluid velocity at port a";
+    w_b = 0
+      "Hydraulic fluid velocity at port b";
+    w_mean = 0
+      "Average hydraulic fluid velocity";
+
+  end if;
+
+  //
+  // Calculate average properties for design flow direction (a->b)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    rho_mean_dd = constantFluidProperties.rho
+      "Average density for design flow direction (i.e., a->b)";
+    Re_mean_dd = abs(m_flow_hyd) / constantFluidProperties.eta *
+      (geometry.d_hyd_a / A_a + geometry.d_hyd_b / A_b) / 2
+      "Average Reynolds number describing the flow regime for design flow 
+      direction (i.e., a->b)";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    rho_mean_dd = fluidProperties_a.rho
+      "Average density for design flow direction (i.e., a->b)";
+    Re_mean_dd = abs(m_flow_hyd) / fluidProperties_a.eta *
+      (geometry.d_hyd_a / A_a + geometry.d_hyd_b / A_b) / 2
+      "Average Reynolds number describing the flow regime for design flow 
+      direction (i.e., a->b)";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    rho_mean_dd = fluidProperties_b_ad.rho
+      "Average density for design flow direction (i.e., a->b)";
+    Re_mean_dd = abs(m_flow_hyd) / fluidProperties_b_ad.eta *
+      (geometry.d_hyd_a / A_a + geometry.d_hyd_b / A_b) / 2
+      "Average Reynolds number describing the flow regime for design flow 
+      direction (i.e., a->b)";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet then
+    rho_mean_dd = fluidProperties_a.rho
+      "Average density for design flow direction (i.e., a->b)";
+    Re_mean_dd = abs(m_flow_hyd) / fluidProperties_a.eta *
+      (geometry.d_hyd_a / A_a + geometry.d_hyd_b / A_b) / 2
+      "Average Reynolds number describing the flow regime for design flow 
+      direction (i.e., a->b)";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    rho_mean_dd = (fluidProperties_a.rho + fluidProperties_b_ad.rho) / 2
+      "Average density for design flow direction (i.e., a->b)";
+    Re_mean_dd = abs(m_flow_hyd) /
+      ((fluidProperties_a.eta + fluidProperties_b_ad.eta) / 2) *
+      (geometry.d_hyd_a / A_a + geometry.d_hyd_b / A_b) / 2
+      "Average Reynolds number describing the flow regime for design flow 
+      direction (i.e., a->b)";
+
+  else
+    rho_mean_dd = (fluidProperties_a.rho + fluidProperties_b.rho) / 2
+      "Average density for design flow direction (i.e., a->b)";
+    Re_mean_dd = abs(m_flow_hyd) *
+      (geometry.d_hyd_a / (A_a * fluidProperties_a.eta) +
+       geometry.d_hyd_b / (A_b * fluidProperties_b.eta)) / 2
+      "Average Reynolds number describing the flow regime for design flow 
+      direction (i.e., a->b)";
+
+  end if;
+
+  //
+  // Calculate average properties for reverse design flow direction (b->a)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    rho_mean_rdd = rho_mean_dd
+      "Average density for reverse design flow direction (i.e., b->a)";
+    Re_mean_rdd = Re_mean_dd
+      "Average Reynolds number describing the flow regime for reverse flow 
+      design direction (i.e., b->a)";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    rho_mean_rdd = rho_mean_dd
+      "Average density for reverse design flow direction (i.e., b->a)";
+    Re_mean_rdd = Re_mean_dd
+      "Average Reynolds number describing the flow regime for reverse flow 
+      design direction (i.e., b->a)";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    rho_mean_rdd = rho_mean_dd
+      "Average density for reverse design flow direction (i.e., b->a)";
+    Re_mean_rdd = Re_mean_dd
+      "Average Reynolds number describing the flow regime for reverse flow 
+      design direction (i.e., b->a)";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet then
+    rho_mean_rdd = fluidProperties_b_ad.rho
+      "Average density for reverse design flow direction (i.e., b->a)";
+    Re_mean_rdd = abs(m_flow_hyd) / fluidProperties_b_ad.eta *
+      (geometry.d_hyd_a / A_a + geometry.d_hyd_b / A_b) / 2
+      "Average Reynolds number describing the flow regime for reverse flow 
+      design direction (i.e., b->a)";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    rho_mean_rdd = rho_mean_dd
+      "Average density for reverse design flow direction (i.e., b->a)";
+    Re_mean_rdd = Re_mean_dd
+      "Average Reynolds number describing the flow regime for reverse flow 
+      design direction (i.e., b->a)";
+
+  else
+    rho_mean_rdd = (fluidProperties_a_ad.rho + fluidProperties_b_ad.rho) / 2
+      "Average density for reverse design flow direction (i.e., b->a)";
+    Re_mean_rdd = abs(m_flow_hyd) *
+      (geometry.d_hyd_a / (A_a * fluidProperties_a_ad.eta) +
+       geometry.d_hyd_b / (A_b * fluidProperties_b_ad.eta)) / 2
+      "Average Reynolds number describing the flow regime for reverse flow 
+      design direction (i.e., b->a)";
+
+  end if;
+
+  //
+  // Calculate factors required for dynamic pressure loss
+  //
+  if geometry.dynamicPressureLoss then
+    if positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.Constant then
+      dp_dyn_dd = 1/2 * m_flow_hyd^2 * 1/constantFluidProperties.rho *
+        (1/A_b^2 - 1/A_a^2)
+        "Dynamic pressure loss for design flow direction (a->b)";
+      dp_dyn_rdd = dp_dyn_dd
+        "Dynamic pressure loss for reverse design flow direction (b->a)";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+      dp_dyn_dd = 1/2 * m_flow_hyd^2 * 1/fluidProperties_a.rho *
+        (1/A_b^2 - 1/A_a^2)
+        "Dynamic pressure loss for design flow direction (a->b)";
+      dp_dyn_rdd = dp_dyn_dd
+        "Dynamic pressure loss for reverse design flow direction (b->a)";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+      dp_dyn_dd = 1/2 * m_flow_hyd^2 * 1/fluidProperties_b_ad.rho *
+        (1/A_b^2 - 1/A_a^2)
+        "Dynamic pressure loss for design flow direction (a->b)";
+      dp_dyn_rdd = dp_dyn_dd
+        "Dynamic pressure loss for reverse design flow direction (b->a)";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.ActualInlet then
+      dp_dyn_dd = 1/2 * m_flow_hyd^2 * 1/fluidProperties_a.rho *
+        (1/A_b^2 - 1/A_a^2)
+        "Dynamic pressure loss for design flow direction (a->b)";
+      dp_dyn_rdd = 1/2 * m_flow_hyd^2 * 1/fluidProperties_b_ad.rho *
+        (1/A_b^2 - 1/A_a^2)
+        "Dynamic pressure loss for reverse design flow direction (b->a)";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+      dp_dyn_dd =  1 / (fluidProperties_a.rho + fluidProperties_b_ad.rho) *
+         m_flow_hyd^2 * (1/A_b^2 - 1/A_a^2)
+        "Dynamic pressure loss for design flow direction (a->b)";
+      dp_dyn_rdd = dp_dyn_dd
+        "Dynamic pressure loss for reverse design flow direction (b->a)";
+
+    else
+      dp_dyn_dd = 1/2 * m_flow_hyd^2 * (1 / (A_b^2 * fluidProperties_b.rho) -
+        1 / (A_a^2 * fluidProperties_a.rho))
+        "Dynamic pressure loss for design flow direction (a->b)";
+      dp_dyn_rdd = 1/2 * m_flow_hyd^2 * (1 / (A_b^2 * fluidProperties_b_ad.rho) -
+        1 / (A_a^2 * fluidProperties_a_ad.rho))
+        "Dynamic pressure loss for reverse design flow direction (b->a)";
+
+    end if;
+
+  else
+    dp_dyn_dd = 0
+      "Dynamic pressure loss for design flow direction (a->b)";
+    dp_dyn_rdd = 0
+      "Dynamic pressure loss for reverse design flow direction (b->a)";
+
+  end if;
+
+  //
+  // Calculate factors required for geodetic pressure loss
+  //
+  if geometry.geodeticPressureLoss then
+    if positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.Constant then
+      dp_geo_dd = Modelica.Constants.g_n * constantFluidProperties.rho *
+        (geometry.z_b - geometry.z_a)
+        "Geodetic pressure loss for design flow direction (a->b)";
+      dp_geo_rdd = dp_geo_dd
+        "Geodetic pressure loss for reverse design flow direction (b->a)";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+      dp_geo_dd = Modelica.Constants.g_n * fluidProperties_a.rho *
+        (geometry.z_b - geometry.z_a)
+        "Geodetic pressure loss for design flow direction (a->b)";
+      dp_geo_rdd = dp_geo_dd
+        "Geodetic pressure loss for reverse design flow direction (b->a)";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+      dp_geo_dd = Modelica.Constants.g_n * fluidProperties_b_ad.rho *
+        (geometry.z_b - geometry.z_a)
+        "Geodetic pressure loss for design flow direction (a->b)";
+      dp_geo_rdd = dp_geo_dd
+        "Geodetic pressure loss for reverse design flow direction (b->a)";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.ActualInlet then
+      dp_geo_dd = Modelica.Constants.g_n * fluidProperties_a.rho *
+        (geometry.z_b - geometry.z_a)
+        "Geodetic pressure loss for design flow direction (a->b)";
+      dp_geo_rdd = Modelica.Constants.g_n * fluidProperties_b_ad.rho *
+        (geometry.z_b - geometry.z_a)
+        "Geodetic pressure loss for reverse design flow direction (b->a)";
+
+    elseif positionFluidProperties==
+      SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+      dp_geo_dd = Modelica.Constants.g_n * (fluidProperties_a.rho +
+         fluidProperties_b_ad.rho) / 2 * (geometry.z_b - geometry.z_a)
+        "Geodetic pressure loss for design flow direction (a->b)";
+      dp_geo_rdd = dp_geo_dd
+        "Geodetic pressure loss for reverse design flow direction (b->a)";
+
+    else
+      dp_geo_dd = Modelica.Constants.g_n * (fluidProperties_b.rho *
+        geometry.z_b - fluidProperties_a.rho * geometry.z_a)
+        "Geodetic pressure loss for design flow direction (a->b)";
+      dp_geo_rdd = Modelica.Constants.g_n * (fluidProperties_b_ad.rho *
+        geometry.z_b - fluidProperties_a_ad.rho * geometry.z_a)
+        "Geodetic pressure loss for reverse design flow direction (b->a)";
+
+    end if;
+
+  else
+    dp_geo_dd = 0
+      "Geodetic pressure loss for design flow direction (a->b)";
+    dp_geo_rdd = 0
+      "Geodetic pressure loss for reverse design flow direction (b->a)";
+
+  end if;
+
+  //
+  // Calculate factors required for friction-caused pressure loss
+  //
+  if geometry.frictionPressureLoss then
+    f_fric_dd = 1/2 * 1 / (rho_mean_dd * A_mean^2) *
+      geometry.l / d_hyd_mean * lambda_mean_dd
+      "Factor of friction-caused pressure loss for design flow direction (a->b)";
+    f_fric_rdd = 1/2 * 1 / (rho_mean_rdd * A_mean^2) *
+      geometry.l / d_hyd_mean * lambda_mean_rdd
+      "Factor of friction-caused pressure loss for reverse design flow direction 
+      (b->a)";
+
+  else
+    f_fric_dd = 0
+      "Factor of friction-caused pressure loss for design flow direction (a->b)";
+    f_fric_rdd = 0
+      "Factor of friction-caused pressure loss for reverse design flow direction 
+      (b->a)";
+
+  end if;
+
+  //
+  // Calculate factors required for fitting-caused pressure loss
+  //
+  if geometry.fittingPressureLosss then
+    if flowDirectionDependentZeta then
+      if positionFluidProperties==
+        SorpLib.Choices.ResistorFluidProperties.Constant then
+        f_fit_dd = 1/2 * sum(zeta_a) / (constantFluidProperties.rho * A_a^2)
+          "Factor of fitting-caused pressure loss for design flow direction 
+          (a->b)";
+        f_fit_rdd = 1/2 * sum(zeta_b) / (constantFluidProperties.rho * A_b^2)
+          "Factor of fitting-caused pressure loss for reverse design flow 
+          direction (b->a)";
+
+      elseif positionFluidProperties==
+        SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+        f_fit_dd = 1/2 * sum(zeta_a) / (fluidProperties_a.rho * A_a^2)
+          "Factor of fitting-caused pressure loss for design flow direction 
+          (a->b)";
+        f_fit_rdd = 1/2 * sum(zeta_b) / (fluidProperties_a.rho * A_b^2)
+          "Factor of fitting-caused pressure loss for reverse design flow 
+          direction (b->a)";
+
+      elseif positionFluidProperties==
+        SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+        f_fit_dd = 1/2 * sum(zeta_a) / (fluidProperties_b_ad.rho * A_a^2)
+          "Factor of fitting-caused pressure loss for design flow direction 
+          (a->b)";
+        f_fit_rdd = 1/2 * sum(zeta_b) / (fluidProperties_b_ad.rho * A_b^2)
+          "Factor of fitting-caused pressure loss for reverse design flow 
+          direction (b->a)";
+
+      elseif positionFluidProperties==
+        SorpLib.Choices.ResistorFluidProperties.ActualInlet then
+        f_fit_dd = 1/2 * sum(zeta_a) / (fluidProperties_a.rho * A_a^2)
+          "Factor of fitting-caused pressure loss for design flow direction 
+          (a->b)";
+        f_fit_rdd = 1/2 * sum(zeta_b) / (fluidProperties_b_ad.rho * A_b^2)
+          "Factor of fitting-caused pressure loss for reverse design flow 
+          direction (b->a)";
+
+      elseif positionFluidProperties==
+        SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+        f_fit_dd = 1/2 * sum(zeta_a) / ((fluidProperties_a.rho +
+          fluidProperties_b_ad.rho) / 2 * A_a^2)
+          "Factor of fitting-caused pressure loss for design flow direction 
+          (a->b)";
+        f_fit_rdd = 1/2 * sum(zeta_b) / ((fluidProperties_a.rho +
+          fluidProperties_b_ad.rho) / 2 * A_b^2)
+          "Factor of fitting-caused pressure loss for reverse design flow 
+          direction (b->a)";
+
+      else
+        f_fit_dd = 1/2 * sum(zeta_a) / (fluidProperties_a.rho * A_a^2)
+          "Factor of fitting-caused pressure loss for design flow direction 
+          (a->b)";
+        f_fit_rdd = 1/2 * sum(zeta_b) / (fluidProperties_b_ad.rho * A_b^2)
+          "Factor of fitting-caused pressure loss for reverse design flow 
+          direction (b->a)";
+
+      end if;
+
+    else
+      f_fit_dd = 1/2 * ((sum(zeta_a) + sum(zeta_b)) / 2) /
+        (rho_mean_dd * A_mean^2)
+        "Factor of fitting-caused pressure loss for design flow direction (a->b)";
+      f_fit_rdd = 1/2 * ((sum(zeta_a) + sum(zeta_b)) / 2) /
+        (rho_mean_rdd * A_mean^2)
+        "Factor of fitting-caused pressure loss for reverse design flow direction 
+        (b->a)";
+
+    end if;
+
+  else
+    f_fit_dd = 0
+      "Factor of fitting-caused pressure loss for design flow direction (a->b)";
+    f_fit_rdd = 0
+      "Factor of fitting-caused pressure loss for reverse design flow direction 
+      (b->a)";
+
+  end if;
+
+  //
+  // Calculate pressure difference as function of mass flow rate or vice versa
+  //
+  if dpFromMFlow then
+    if avoid_events then
+      if (geometry.dynamicPressureLoss or geometry.geodeticPressureLoss) and
+        not (geometry.frictionPressureLoss or geometry.fittingPressureLosss) then
+        dp_static =
+          SorpLib.Numerics.regStep_noEvent(
+            x=m_flow_hyd,
+            y1=dp_dyn_dd + dp_geo_dd,
+            y2=dp_dyn_rdd + dp_geo_rdd,
+            x_small=m_flow_small)
+          "Static pressure difference between port a and b";
+
+      elseif not (geometry.dynamicPressureLoss or geometry.geodeticPressureLoss) and
+        (geometry.frictionPressureLoss or geometry.fittingPressureLosss) then
+        dp_static =
+          SorpLib.Numerics.regSquareWFactors_noEvent(
+            x=m_flow_hyd,
+            delta_x=m_flow_small,
+            f_positive=1 / (f_fric_dd + f_fit_dd + Modelica.Constants.small),
+            f_negative=1 / (f_fric_rdd + f_fit_rdd + Modelica.Constants.small))
+          "Static pressure difference between port a and b";
+
+      else
+        dp_static =
+          SorpLib.Numerics.regStep_noEvent(
+            x=m_flow_hyd,
+            y1=dp_dyn_dd + dp_geo_dd,
+            y2=dp_dyn_rdd + dp_geo_rdd,
+            x_small=m_flow_small) +
+          SorpLib.Numerics.regSquareWFactors_noEvent(
+            x=m_flow_hyd,
+            delta_x=m_flow_small,
+            f_positive=1 / (f_fric_dd + f_fit_dd + Modelica.Constants.small),
+            f_negative=1 / (f_fric_rdd + f_fit_rdd + Modelica.Constants.small))
+          "Static pressure difference between port a and b";
+
+      end if;
+
+    else
+      if (geometry.dynamicPressureLoss or geometry.geodeticPressureLoss) and
+        not (geometry.frictionPressureLoss or geometry.fittingPressureLosss) then
+        dp_static =
+          SorpLib.Numerics.regStep(
+            x=m_flow_hyd,
+            y1=dp_dyn_dd + dp_geo_dd,
+            y2=dp_dyn_rdd + dp_geo_rdd,
+            x_small=m_flow_small)
+          "Static pressure difference between port a and b";
+
+      elseif not (geometry.dynamicPressureLoss or geometry.geodeticPressureLoss) and
+        (geometry.frictionPressureLoss or geometry.fittingPressureLosss) then
+        dp_static =
+          SorpLib.Numerics.regSquareWFactors(
+            x=m_flow_hyd,
+            delta_x=m_flow_small,
+            f_positive=1 / (f_fric_dd + f_fit_dd + Modelica.Constants.small),
+            f_negative=1 / (f_fric_rdd + f_fit_rdd + Modelica.Constants.small))
+          "Static pressure difference between port a and b";
+
+      else
+        dp_static =
+          SorpLib.Numerics.regStep(
+            x=m_flow_hyd,
+            y1=dp_dyn_dd + dp_geo_dd,
+            y2=dp_dyn_rdd + dp_geo_rdd,
+            x_small=m_flow_small) +
+          SorpLib.Numerics.regSquareWFactors(
+            x=m_flow_hyd,
+            delta_x=m_flow_small,
+            f_positive=1 / (f_fric_dd + f_fit_dd + Modelica.Constants.small),
+            f_negative=1 / (f_fric_rdd + f_fit_rdd + Modelica.Constants.small))
+          "Static pressure difference between port a and b";
+
+      end if;
+    end if;
+
+  else
+    if avoid_events then
+      if (geometry.dynamicPressureLoss or geometry.geodeticPressureLoss) and
+        not (geometry.frictionPressureLoss or geometry.fittingPressureLosss) then
+        dp_static =
+          SorpLib.Numerics.regStep_noEvent(
+            x=m_flow_hyd,
+            y1=dp_dyn_dd + dp_geo_dd,
+            y2=dp_dyn_rdd + dp_geo_rdd,
+            x_small=m_flow_small)
+          "Static pressure difference between port a and b";
+
+      elseif not (geometry.dynamicPressureLoss or geometry.geodeticPressureLoss) and
+        (geometry.frictionPressureLoss or geometry.fittingPressureLosss) then
+        m_flow_hyd =
+          SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+            y=dp_static,
+            delta_x=m_flow_small,
+            f_positive=1 / (f_fric_dd + f_fit_dd + Modelica.Constants.small),
+            f_negative=1 / (f_fric_rdd + f_fit_rdd + Modelica.Constants.small))
+          "Hydraulic mass flow rate";
+
+      else
+        dp_static =
+          SorpLib.Numerics.regStep_noEvent(
+            x=m_flow_hyd,
+            y1=dp_dyn_dd + dp_geo_dd,
+            y2=dp_dyn_rdd + dp_geo_rdd,
+            x_small=m_flow_small) +
+          SorpLib.Numerics.regSquareWFactors_noEvent(
+            x=m_flow_hyd,
+            delta_x=m_flow_small,
+            f_positive=1 / (f_fric_dd + f_fit_dd + Modelica.Constants.small),
+            f_negative=1 / (f_fric_rdd + f_fit_rdd + Modelica.Constants.small))
+          "Static pressure difference between port a and b";
+
+      end if;
+
+    else
+      if (geometry.dynamicPressureLoss or geometry.geodeticPressureLoss) and
+        not (geometry.frictionPressureLoss or geometry.fittingPressureLosss) then
+        dp_static =
+          SorpLib.Numerics.regStep(
+            x=m_flow_hyd,
+            y1=dp_dyn_dd + dp_geo_dd,
+            y2=dp_dyn_rdd + dp_geo_rdd,
+            x_small=m_flow_small)
+          "Static pressure difference between port a and b";
+
+      elseif not (geometry.dynamicPressureLoss or geometry.geodeticPressureLoss) and
+        (geometry.frictionPressureLoss or geometry.fittingPressureLosss) then
+        m_flow_hyd =
+          SorpLib.Numerics.regSquareWFactors_inv(
+            y=dp_static,
+            delta_x=m_flow_small,
+            f_positive=1 / (f_fric_dd + f_fit_dd + Modelica.Constants.small),
+            f_negative=1 / (f_fric_rdd + f_fit_rdd + Modelica.Constants.small))
+          "Hydraulic mass flow rate";
+
+      else
+        dp_static =
+          SorpLib.Numerics.regStep(
+            x=m_flow_hyd,
+            y1=dp_dyn_dd + dp_geo_dd,
+            y2=dp_dyn_rdd + dp_geo_rdd,
+            x_small=m_flow_small) +
+          SorpLib.Numerics.regSquareWFactors(
+            x=m_flow_hyd,
+            delta_x=m_flow_small,
+            f_positive=1 / (f_fric_dd + f_fit_dd + Modelica.Constants.small),
+            f_negative=1 / (f_fric_rdd + f_fit_rdd + Modelica.Constants.small))
+          "Static pressure difference between port a and b";
+
+      end if;
+    end if;
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+          Ellipse(
+          extent={{-80,80},{80,-80}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={0,127,0},
+          fillPattern=FillPattern.Solid),
+        Text(
+          extent={{-60,60},{60,-60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid,
+          textString="ṁ 
+= 
+f(Δp, ...)")}), Diagram(coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the base model for all pressure loss models. It defines 
+fundamental parameters and variables required by all pressure loss models. Models 
+that inherit properties from this partial model have to complete the friction-
+based pressure loss correlation. Furthermore, the geometry record may be redeclared
+and constrained.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Hydraulic mass flow rate <i>m_flow_hyd</i>.
+  </li>
+  <li>
+  Friction factor <i>lambda_mean_dd</i> for design flow direction (i.e., a->b).
+  </li>
+  <li>
+  Friction factor <i>lambda_mean_rdd</i> for reverse design flow direction (i.e., 
+  a->b).
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialPressureLoss;
diff --git a/SorpLib/Components/Fittings/BaseClasses/PartialResistance.mo b/SorpLib/Components/Fittings/BaseClasses/PartialResistance.mo
new file mode 100644
index 0000000..9cb3f4b
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/PartialResistance.mo
@@ -0,0 +1,484 @@
+within SorpLib.Components.Fittings.BaseClasses;
+partial model PartialResistance
+  "Base model for all hydraulic resistors"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding calculation setup
+  //
+  parameter SorpLib.Choices.ResistorFluidProperties positionFluidProperties=
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet
+    "Position of fluid properties used for calculations"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean instreamingPropertiesByInput = false
+    " = true, if instreaming fluid properties are provied via inputs (i.e., 
+    fluidProperties_a and fluidProperties_b_ad) if already calculated"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  parameter Boolean dpFromMFlow = true
+    " = true, if static pressure loss is calculated from mass flow rate; otherwise,
+    mass flow rate is calculated from static pressure loss"
+    annotation (Dialog(tab="General", group="Calculation Setup",
+                enable= not dynamicPressureLoss and not geodeticPressureLoss and
+                  (frictionPressureLoss or fittingPressureLosss)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  parameter Boolean dynamicPressureLoss = false
+    " = true, if dynamic pressure loss shall be included (i.e., different
+    velocities at port a and b due to change of cross-sectional areas and 
+    densities)"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean geodeticPressureLoss = false
+    " = true, if geodetic pressure loss shall be included (i.e., different
+    heights at port a and b)"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean frictionPressureLoss = false
+    " = true, if pressure loss due to friction shall be included"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean fittingPressureLosss = true
+    " = true, if pressure losses due to fittings shall be included"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of parameters regarding the resistance characterisation
+  //
+  replaceable model PressureLossModel =
+    SorpLib.Components.Fittings.BaseClasses.PartialPressureLoss
+    constrainedby SorpLib.Components.Fittings.BaseClasses.PartialPressureLoss(
+      positionFluidProperties=positionFluidProperties,
+      dpFromMFlow=dpFromMFlow,
+      geometry=geometry,
+      constantFluidProperties=
+        SorpLib.Components.Fittings.Records.FluidProperties(
+          p=p_ref,
+          T=T_ref,
+          rho=rho_ref,
+          eta=eta_ref),
+      flowDirectionDependentZeta=flowDirectionDependentZeta,
+      zeta_a=zeta_a,
+      zeta_b=zeta_b,
+      m_flow=m_flow,
+      fluidProperties_a=fluidProperties_a,
+      fluidProperties_b=fluidProperties_b,
+      fluidProperties_a_ad=fluidProperties_a_ad,
+      fluidProperties_b_ad=fluidProperties_b_ad,
+      avoid_events=avoid_events,
+      m_flow_small=m_flow_small)
+    "Pressure loss model"
+    annotation (Dialog(tab="Resistance Characterisation", group="Models"),
+                choicesAllMatching=true);
+
+  replaceable parameter SorpLib.Components.Fittings.Records.GeometryGenericReistance geometry
+    constrainedby SorpLib.Components.Fittings.Records.GeometryGenericReistance(
+      final dynamicPressureLoss=dynamicPressureLoss,
+      final geodeticPressureLoss=geodeticPressureLoss,
+      final frictionPressureLoss=frictionPressureLoss,
+      final fittingPressureLosss=fittingPressureLosss)
+    "Resistor geometry"
+    annotation (Dialog(tab="Resistance Characterisation", group="Geometry"),
+                choicesAllMatching=true);
+
+  parameter Modelica.Units.SI.Pressure p_ref = 1e5
+    "Reference pressure that might be used for pressure loss calculations"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=positionFluidProperties==
+                  SorpLib.Choices.ResistorFluidProperties.Constant));
+  parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature that might be used for pressure loss calculations"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=positionFluidProperties==
+                  SorpLib.Choices.ResistorFluidProperties.Constant));
+  parameter Modelica.Units.SI.Density rho_ref = 997
+    "Reference density that might be used for pressure loss calculations"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=positionFluidProperties==
+                  SorpLib.Choices.ResistorFluidProperties.Constant));
+  parameter Modelica.Units.SI.DynamicViscosity eta_ref = 8.9e-4
+    "Reference dynamic viscosity that might be used for pressure loss calculations"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=positionFluidProperties==
+                  SorpLib.Choices.ResistorFluidProperties.Constant));
+
+  parameter Boolean flowDirectionDependentZeta = false
+    " = true, if loss factors differ with flow direction (e.g., sudden expansion)
+    and area and density at port a or b are used"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fittings",
+                enable=fittingPressureLosss),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Real[:] zeta_a(each unit="1") = {0}
+    "Loss factors due to fittings at port a"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fittings",
+                enable=fittingPressureLosss));
+  parameter Real[:] zeta_b(each unit="1") = zeta_a
+    "Loss factors due to fittings at port b"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fittings",
+                enable=fittingPressureLosss and flowDirectionDependentZeta));
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_small = 1e-4
+    "Regularization mass flow rate"
+    annotation (Dialog(tab="Advanced", group="Numerics"));
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput p_a(final unit="Pa") = p_ref if
+       instreamingPropertiesByInput
+    "Pressure at port a for design flow direction (i.e., a->b)"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=instreamingPropertiesByInput));
+  Modelica.Blocks.Interfaces.RealInput T_a(final unit="K") = T_ref if
+       instreamingPropertiesByInput
+    "Temperature at port a for design flow direction (i.e., a->b)"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=instreamingPropertiesByInput));
+  Modelica.Blocks.Interfaces.RealInput rho_a(final unit="kg/m3") = rho_ref if
+     instreamingPropertiesByInput
+    "Density at port a for design flow direction (i.e., a->b)"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=instreamingPropertiesByInput));
+  Modelica.Blocks.Interfaces.RealInput eta_a(final unit="Pa.s") = eta_ref if
+       instreamingPropertiesByInput
+    "Dynamic viscosity at port a for design flow direction (i.e., a->b)"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=instreamingPropertiesByInput));
+
+  Modelica.Blocks.Interfaces.RealInput p_b_ad(final unit="Pa") = p_ref if
+       instreamingPropertiesByInput
+    "Pressure at port b for reverse design flow direction (i.e., a<-b)"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=instreamingPropertiesByInput));
+  Modelica.Blocks.Interfaces.RealInput T_b_ad(final unit="K") = T_ref if
+       instreamingPropertiesByInput
+    "Temperature at port b for reverse design flow direction (i.e., a<-b)"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=instreamingPropertiesByInput));
+  Modelica.Blocks.Interfaces.RealInput rho_b_ad(final unit="kg/m3") = rho_ref if
+     instreamingPropertiesByInput
+    "Density at port b for reverse design flow direction (i.e., a<-b)"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=instreamingPropertiesByInput));
+  Modelica.Blocks.Interfaces.RealInput eta_b_ad(final unit="Pa.s") = eta_ref if
+       instreamingPropertiesByInput
+    "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)"
+    annotation (Dialog(tab="Resistance Characterisation", group="Fluid Properties",
+                enable=instreamingPropertiesByInput));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput p_a_internal(final unit="Pa")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput T_a_internal(final unit="K")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput rho_a_internal(final unit="kg/m3")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput eta_a_internal(final unit="Pa.s")
+    "Needed for connecting to conditional connector";
+
+  Modelica.Blocks.Interfaces.RealInput p_b_ad_internal(final unit="Pa")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput T_b_ad_internal(final unit="K")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput rho_b_ad_internal(final unit="kg/m3")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput eta_b_ad_internal(final unit="Pa.s")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of ports
+  //
+public
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-90,-10},{-70,10}}),
+                iconTransformation(extent={{-90,-10},{-70,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{70,-10},{90,10}}),
+                iconTransformation(extent={{70,-10},{90,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of models
+  //
+  PressureLossModel pressureLossModel
+    "Model to calculate the pressure loss";
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Components.Fittings.Records.FluidProperties fluidProperties_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)";
+  SorpLib.Components.Fittings.Records.FluidProperties fluidProperties_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)";
+  SorpLib.Components.Fittings.Records.FluidProperties fluidProperties_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)";
+  SorpLib.Components.Fittings.Records.FluidProperties fluidProperties_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+  Modelica.Units.SI.PressureDifference dp
+    "Static pressure difference between port a and b";
+  Modelica.Units.SI.MassFlowRate m_flow
+    "Mass flow rate";
+
+equation
+  //
+  // Assertions
+  //
+  assert(dynamicPressureLoss or geodeticPressureLoss or
+         frictionPressureLoss or fittingPressureLosss,
+         "At least one option (i.e., dynamic pressure loss, geodetic pressure " +
+         "loss, friction pressure loss, or fitting pressure loss) must be taken " +
+         "into account when calculating the pressure loss!",
+         level=AssertionLevel.error);
+
+  if not dpFromMFlow then
+    assert(not dynamicPressureLoss and not geodeticPressureLoss and
+           (frictionPressureLoss or fittingPressureLosss),
+           "Mass flow rate can only be calculated from the static pressure loss " +
+           "if just friction- or fitting-caused pressure losses are considered!",
+           level=AssertionLevel.error);
+  end if;
+
+  //
+  // Connectors
+  //
+  connect(p_a_internal, p_a);
+  connect(T_a_internal, T_a);
+  connect(rho_a_internal, rho_a);
+  connect(eta_a_internal, eta_a);
+
+  connect(p_b_ad_internal, p_b_ad);
+  connect(T_b_ad_internal, T_b_ad);
+  connect(rho_b_ad_internal, rho_b_ad);
+  connect(eta_b_ad_internal, eta_b_ad);
+
+  if not instreamingPropertiesByInput then
+    p_a_internal = p_ref
+      "Needed for connecting to conditional connector: Set dummy value as not
+      needed in this case";
+    T_a_internal = T_ref
+      "Needed for connecting to conditional connector: Set dummy value as not
+      needed in this case";
+    rho_a_internal = rho_ref
+      "Needed for connecting to conditional connector: Set dummy value as not
+      needed in this case";
+    eta_a_internal = eta_ref
+      "Needed for connecting to conditional connector: Set dummy value as not
+      needed in this case";
+
+    p_b_ad_internal = p_ref
+      "Needed for connecting to conditional connector: Set dummy value as not
+      needed in this case";
+    T_b_ad_internal = T_ref
+      "Needed for connecting to conditional connector: Set dummy value as not
+      needed in this case";
+    rho_b_ad_internal = rho_ref
+      "Needed for connecting to conditional connector: Set dummy value as not
+      needed in this case";
+    eta_b_ad_internal = eta_ref
+      "Needed for connecting to conditional connector: Set dummy value as not
+      needed in this case";
+  end if;
+
+  //
+  // Momentum balance
+  //
+  dp = port_a.p - port_b.p
+    "Pressure difference between port a and b";
+  dp = pressureLossModel.dp_static
+    "Pressure loss";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + port_b.m_flow
+    "Steady-state mass balance";
+  port_a.m_flow = m_flow
+    "Mass flow rate at port a";
+
+  port_a.Xi_outflow = inStream(port_b.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+  port_b.Xi_outflow = inStream(port_a.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+
+  //
+  // Energy balance
+  //
+  port_a.h_outflow = inStream(port_b.h_outflow)
+    "Stream variable: Trivial equation since no change of energy";
+  port_b.h_outflow = inStream(port_a.h_outflow)
+    "Stream variable: Trivial equation since no change of energy";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all resistors. It defines fundamental 
+parameters and variables required by all resistors. Models that inherit properties 
+from this partial model have to redeclare the fluid ports. Moreover, fluid properties
+at port a and b must be calculated for both the design and reverse the design flow
+direction. In this context, appropriate fluid property models are required. Furthermore, 
+the geometry record and pressure loss model may be redeclared and constrained.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Pressure <i>fluidProperties_a.p</i> at port a for design flow direction 
+  (i.e., a->b).
+  </li>
+  <li>
+  Temperature <i>fluidProperties_a.T</i> at port a for design flow direction 
+  (i.e., a->b).
+  </li>
+  <li>
+  Density <i>fluidProperties_a.rho</i> at port a for design flow direction 
+  (i.e., a->b).
+  </li>
+  <li>
+  Dynamic viscosity <i>fluidProperties_a.eta</i> at port a for design flow  
+  direction (i.e., a->b).
+  </li>
+  <br/>
+  <li>
+  Pressure <i>fluidProperties_b.p</i> at port b for design flow direction 
+  (i.e., a->b).
+  </li>
+  <li>
+  Temperature <i>fluidProperties_b.T</i> at port b for design flow direction 
+  (i.e., a->b).
+  </li>
+  <li>
+  Density <i>fluidProperties_b.rho</i> at port b for design flow direction 
+  (i.e., a->b).
+  </li>
+  <li>
+  Dynamic viscosity <i>fluidProperties_b.eta</i> at port b for design flow  
+  direction (i.e., a->b).
+  </li>
+  <br/>  
+  <li>
+  Pressure <i>fluidProperties_a_ad.p</i> at port a for reverse design flow  
+  direction (i.e., b->a).
+  </li>
+  <li>
+  Temperature <i>fluidProperties_a_ad.T</i> at port a for reverse design flow  
+  direction (i.e., b->a).
+  </li>
+  <li>
+  Density <i>fluidProperties_a_ad.rho</i> at port a for reverse design flow  
+  direction (i.e., b->a).
+  </li>
+  <li>
+  Dynamic viscosity <i>fluidProperties_a_ad.eta</i> at port a for reverse design 
+  flow direction (i.e., b->a).
+  </li>
+  <br/>  
+  <li>
+  Pressure <i>fluidProperties_b_ad.p</i> at port b for reverse design flow  
+  direction (i.e., b->a).
+  </li>
+  <li>
+  Temperature <i>fluidProperties_b_ad.T</i> at port b for reverse design flow  
+  direction (i.e., b->a).
+  </li>
+  <li>
+  Density <i>fluidProperties_b_ad.rho</i> at port b for reverse design flow  
+  direction (i.e., b->a).
+  </li>
+  <li>
+  Dynamic viscosity <i>fluidProperties_b_ad.eta</i> at port b for reverse design 
+  flow direction (i.e., b->a).
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Polygon(
+          points={{-80,50},{-80,-50},{-50,-50},{-50,-50},{50,-50},{50,-50},{80,-50},
+              {80,50},{-80,50}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Line(
+          points={{-60,-20},{-60,-20},{-60,20},{60,-20},{60,20}},
+          color={0,0,0},
+          thickness=1),
+        Text(
+          extent={{-60,40},{60,20}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={135,135,135},
+          fillPattern=FillPattern.Solid,
+          textString="ṁ = f(Δp, ...)"),
+        Line(
+          points={{-60,-30},{60,-30}},
+          color={0,0,0},
+          thickness=1,
+          arrow={Arrow.Open,Arrow.Open})}));
+end PartialResistance;
diff --git a/SorpLib/Components/Fittings/BaseClasses/PartialTJunction.mo b/SorpLib/Components/Fittings/BaseClasses/PartialTJunction.mo
new file mode 100644
index 0000000..3c29c9d
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/PartialTJunction.mo
@@ -0,0 +1,408 @@
+within SorpLib.Components.Fittings.BaseClasses;
+partial model PartialTJunction
+  "Base model for all T-junction elements"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding geometry
+  //
+  parameter Modelica.Units.SI.Volume V = 5e-5
+    "Fluid volume of the T-junction"
+    annotation (Dialog(tab = "General", group = "Geometry"));
+
+  //
+  // Definition of parameters regarding calculation setup
+  //
+  parameter SorpLib.Choices.IndependentVariablesVolume independentStateVariables=
+    SorpLib.Choices.IndependentVariablesVolume.phX
+    "Independent state variables"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean pressureNoStateVariable = true
+    " = true, if pressure is not a state variable and is not needed to calculate
+    fluid properties like density (e.g., incompressible fluid)"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean neglectTermVp = false
+    " = true, if term p * v is neglected for the specific internal energy (i.e., 
+    u = h)"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Modelica.Units.SI.Pressure p_initial = 1e5
+    "Initial value of pressure"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+  parameter Modelica.Units.SI.Temperature T_initial = 298.15
+    "Initial value of temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=(independentStateVariables==
+                  SorpLib.Choices.IndependentVariablesVolume.pTX)));
+  parameter Modelica.Units.SI.SpecificEnthalpy h_initial = 0
+    "Initial value of specific enthalpy"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=(independentStateVariables==
+                  SorpLib.Choices.IndependentVariablesVolume.phX)));
+  parameter Modelica.Units.SI.MassFraction[no_components] X_i_initial=
+    fill(1/no_components, no_components)
+    "Initial values of mass fractions"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=no_components>1));
+
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_overallMassBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the overall mass balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BalanceEquations type_independentMassBalances=
+    type_overallMassBalance
+    "Handling of independent mass balances and corresponding initialisations"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations",
+                enable=no_components>1),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BalanceEquations type_energyBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the energy balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult = true);
+
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-10,-88},{10,-68}}),
+                iconTransformation(extent={{-10,-88},{10,-68}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-0.5*m_flow_start))
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{-90,-10},{-70,10}}),
+                iconTransformation(extent={{-90,-10},{-70,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_c
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-0.5*m_flow_start))
+    "Fluid port c"
+    annotation (Placement(transformation(extent={{70,-10},{90,10}}),
+                iconTransformation(extent={{70,-10},{90,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p(
+    start=p_initial,
+    stateSelect= if not pressureNoStateVariable then StateSelect.prefer
+      else StateSelect.avoid)
+    "Pressure";
+  Modelica.Units.SI.Temperature T(
+    start=T_initial,
+    stateSelect= if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then StateSelect.prefer
+      else StateSelect.avoid)
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+  Modelica.Units.SI.Density rho
+    "Density";
+  Modelica.Units.SI.MassFraction[no_components] X_i(
+    start=X_i_initial,
+    each stateSelect=if no_components > 1 then StateSelect.prefer
+      else StateSelect.avoid)
+    "Mass fractions";
+
+  Modelica.Units.SI.SpecificEnthalpy h(
+    start=h_initial,
+    stateSelect= if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.phX then StateSelect.prefer
+      else StateSelect.avoid)
+    "Specific enthalpy";
+  Modelica.Units.SI.SpecificEnthalpy[no_components] h_i
+    "Specific enthalpy of individual components";
+  Modelica.Units.SI.SpecificInternalEnergy u
+    "Specific internal energy";
+
+  Modelica.Units.SI.Mass m
+    "Mass";
+  Modelica.Units.SI.Mass[no_components] m_i
+    "Mass of individual components";
+  Modelica.Units.SI.MassFlowRate dm_dtau
+    "Derivative of mass w.r.t. time";
+  Modelica.Units.SI.MassFlowRate[no_components] dm_i_dtau
+    "Derivative of individual components' masses w.r.t. time";
+  Modelica.Units.SI.MassFlowRate mc_flow
+    "Sum of all convective mass flow rates across boundaries";
+  Modelica.Units.SI.MassFlowRate[no_components] mc_i_flow
+    "Sum of all individual components' convective mass flow rates across 
+    boundaries";
+
+  Modelica.Units.SI.InternalEnergy U
+    "Internal energy";
+  Real dU_dtau(final unit="W")
+    "Derivative of internal energy w.r.t. time";
+  Modelica.Units.SI.EnthalpyFlowRate Hb_flow
+    "Sum of all enthalpy flow rates across boundaries";
+
+initial equation
+  if not pressureNoStateVariable and type_overallMassBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    p = p_initial
+      "Fixed initial value";
+
+  elseif not pressureNoStateVariable and type_overallMassBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    der(p) = 0
+      "Steady-state initialisation of overall mass balance";
+
+  end if;
+
+  if type_independentMassBalances ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    X_i = X_i_initial
+      "Fixed initial values";
+
+  elseif type_independentMassBalances ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    der(X_i) = zeros(no_components)
+      "Steady-state initialisation of independent mass balances";
+
+  end if;
+
+  if type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial then
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      T = T_initial
+        "Fixed initial value";
+
+    else
+      h = h_initial
+        "Fixed initial value";
+
+    end if;
+
+  elseif type_energyBalance ==
+    SorpLib.Choices.BalanceEquations.TransientSteadyStateInitial then
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      der(T) = 0
+        "Steady-state initial value";
+
+    else
+      der(h) = 0
+        "Steady-state initial value";
+
+    end if;
+  end if;
+
+equation
+  //
+  // Property calculation
+  //
+  v = 1 / rho
+    "Specific volume";
+
+  u = if neglectTermVp then h else h - p * v
+    "Specific internal energy";
+
+  //
+  // Momentum balance
+  //
+  port_a.p = p
+    "Total pressure at the port (i.e., homogenous volume)";
+  port_b.p = p
+    "Total pressure at the port (i.e., homogenous volume)";
+  port_c.p = p
+    "Total pressure at the port (i.e., homogenous volume)";
+
+  //
+  // Mass balance
+  //
+  m = V / v
+    "Mass";
+  m_i = m .* X_i
+    "Mass of individual components";
+
+  dm_dtau = mc_flow
+    "Overall mass balance";
+  dm_i_dtau = mc_i_flow
+    "Individual components' mass balances";
+
+  if type_independentMassBalances==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_i_dtau = zeros(no_components)
+      "Steady-state independent mass balances";
+
+  else
+    dm_i_dtau = X_i .* dm_dtau .+ m .* der(X_i)
+      "Transient independent mass balances";
+
+  end if;
+
+  mc_flow = port_a.m_flow + port_b.m_flow + port_c.m_flow
+    "Sum of all convective mass flow rates across boundaries";
+
+  if avoid_events then
+    for ind_comp in 1:no_components loop
+      if ind_comp <> no_components then
+        mc_i_flow[ind_comp] =
+          port_a.m_flow * noEvent(actualStream(port_a.Xi_outflow[ind_comp])) +
+          port_b.m_flow * noEvent(actualStream(port_b.Xi_outflow[ind_comp])) +
+          port_c.m_flow * noEvent(actualStream(port_c.Xi_outflow[ind_comp]))
+          "Sum of all convective mass flow rates of component ind_comp across 
+          boundaries";
+
+      else
+        mc_i_flow[ind_comp] =  mc_flow - sum(mc_i_flow[1:no_components-1])
+          "Sum of all convective mass flow rates of last component across 
+          boundaries";
+
+      end if;
+    end for;
+
+  else
+    for ind_comp in 1:no_components loop
+      if ind_comp <> no_components then
+        mc_i_flow[ind_comp] =
+          port_a.m_flow * actualStream(port_a.Xi_outflow[ind_comp]) +
+          port_b.m_flow * actualStream(port_b.Xi_outflow[ind_comp]) +
+          port_c.m_flow * actualStream(port_c.Xi_outflow[ind_comp])
+          "Sum of all convective mass flow rates of component ind_comp across 
+          boundaries";
+
+      else
+        mc_i_flow[ind_comp] =  mc_flow - sum(mc_i_flow[1:no_components-1])
+          "Sum of all convective mass flow rates of last component across 
+          boundaries";
+
+      end if;
+    end for;
+  end if;
+
+  port_a.Xi_outflow = X_i[1:no_components-1]
+    "Independent mass fractions leaving the port (i.e., homogenous volume)";
+  port_b.Xi_outflow = X_i[1:no_components-1]
+    "Independent mass fractions leaving the port (i.e., homogenous volume)";
+  port_c.Xi_outflow = X_i[1:no_components-1]
+    "Independent mass fractions leaving the port (i.e., homogenous volume)";
+
+  //
+  // Energy balance
+  //
+  U = m * u
+    "Internal energy";
+
+  dU_dtau = Hb_flow
+    "Energy balane";
+
+  if avoid_events then
+    Hb_flow =
+      port_a.m_flow * noEvent(actualStream(port_a.h_outflow)) +
+      port_b.m_flow * noEvent(actualStream(port_b.h_outflow)) +
+      port_c.m_flow * noEvent(actualStream(port_c.h_outflow))
+      "Sum of all enthalpy flow rates across boundaries";
+
+  else
+    Hb_flow =
+      port_a.m_flow * actualStream(port_a.h_outflow) +
+      port_b.m_flow * actualStream(port_b.h_outflow) +
+      port_c.m_flow * actualStream(port_c.h_outflow)
+      "Sum of all enthalpy flow rates across boundaries";
+
+  end if;
+
+  port_a.h_outflow = h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+  port_b.h_outflow = h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+  port_c.h_outflow = h
+    "Specific enthalpy leaving the port (i.e., homogenous volume)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all T-junction elements. It defines 
+fundamental parameters and variables required by all T-junction elements. Models 
+that inherit properties from this partial model have to redeclare the fluid ports.
+Furthermore, conservation equations must be completed, which may require additional
+variables. In this context, appropriate fluid property models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Temperature <i>T</i> or specific enthalpy <i>h</i>, depending on the independent
+  state variables.
+  </li>
+  <li>
+  Density <i>&rho;</i>.
+  </li>
+  <li>
+  Specific enthalpies of all components <i>h<sub>i</sub></i>.
+  </li>
+  <br/>
+  <li>
+  Partial derivative of the overall mass w.r.t. time <i>dm_dtau</i>.
+  </li>
+  <li>
+  Partial derivative of the internal energy w.r.t. time <i>dU_dtau</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"), Icon(graphics={Polygon(
+          points={{-80,50},{-80,-50},{-50,-50},{-50,-80},{50,-80},{50,-50},{80,-50},
+              {80,50},{-80,50}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid)}));
+end PartialTJunction;
diff --git a/SorpLib/Components/Fittings/BaseClasses/PartialTubeInsidePressureLoss.mo b/SorpLib/Components/Fittings/BaseClasses/PartialTubeInsidePressureLoss.mo
new file mode 100644
index 0000000..fce5b44
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/PartialTubeInsidePressureLoss.mo
@@ -0,0 +1,45 @@
+within SorpLib.Components.Fittings.BaseClasses;
+partial model PartialTubeInsidePressureLoss
+  "Base model for all tube-inside pressure loss models"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialPressureLoss(
+    final psi = 1,
+    redeclare replaceable parameter SorpLib.Components.Fittings.Records.GeometryTube geometry
+    constrainedby SorpLib.Components.Fittings.Records.GeometryTube);
+
+equation
+  //
+  // Calculate the hydraulic mass flow rate
+  //
+  m_flow_hyd = m_flow / geometry.no_hydraulicParallelFlows
+    "Hydraulic mass flow rate";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all pressure loss models applied in tubes.
+It defines fundamental parameters and variables required by all pressure loss models. 
+Models that inherit properties from this partial model have to complete the friction-
+based pressure loss correlation.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Friction factor <i>lambda_mean_dd</i> for design flow direction (i.e., a->b).
+  </li>
+  <li>
+  Friction factor <i>lambda_mean_rdd</i> for reverse design flow direction (i.e., 
+  a->b).
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialTubeInsidePressureLoss;
diff --git a/SorpLib/Components/Fittings/BaseClasses/package.mo b/SorpLib/Components/Fittings/BaseClasses/package.mo
new file mode 100644
index 0000000..9babbcd
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Fittings;
+package BaseClasses "Base models and functions for all fittings"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial fitting models and functions, containing fundamental 
+definitions for fittings. The content of this package is only of interest when 
+adding new fittings to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/Fittings/BaseClasses/package.order b/SorpLib/Components/Fittings/BaseClasses/package.order
new file mode 100644
index 0000000..dd99e0e
--- /dev/null
+++ b/SorpLib/Components/Fittings/BaseClasses/package.order
@@ -0,0 +1,7 @@
+PartialInertiaInducer
+PartialMultiPort
+PartialResistance
+PartialTJunction
+PartialPressureLoss
+PartialTubeInsidePressureLoss
+PartialOpenAdsorberPressureLoss
diff --git a/SorpLib/Components/Fittings/InertiaInducers/GasInertiaInducer.mo b/SorpLib/Components/Fittings/InertiaInducers/GasInertiaInducer.mo
new file mode 100644
index 0000000..08a494a
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/GasInertiaInducer.mo
@@ -0,0 +1,66 @@
+within SorpLib.Components.Fittings.InertiaInducers;
+model GasInertiaInducer "Gas inertia inducer"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialInertiaInducer(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The gas inertia inducer describes the change of the gas velocity due to its 
+inertia. Thus, sudden changes in the velocity (i.e., mass flow rate) caused by,
+for example, a pressure drop can be puffered, which increases the numerical
+stability.
+</p>
+<pre>
+    dm_flow/d&tau; = &Delta;p * &Psi;;
+</pre>
+<p>
+Herein, the derivative of the mass flow rate <i>m_flow</i> w.r.t. time <i>&tau;</i>
+is calculated from the pressure difference <i>&Delta;p</i> and momentum factor 
+<i>&Psi;</i>, which directly follows from a simplified momentum balance.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks to break algebraic loops.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+The model has the mass flow rate <i>m_flow</i> as dynamic state.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end GasInertiaInducer;
diff --git a/SorpLib/Components/Fittings/InertiaInducers/LiquidInertiaInducer.mo b/SorpLib/Components/Fittings/InertiaInducers/LiquidInertiaInducer.mo
new file mode 100644
index 0000000..491f60f
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/LiquidInertiaInducer.mo
@@ -0,0 +1,65 @@
+within SorpLib.Components.Fittings.InertiaInducers;
+model LiquidInertiaInducer "Liquid inertia inducer"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialInertiaInducer(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The liquid inertia inducer describes the change of the liquid velocity due to its 
+inertia. Thus, sudden changes in the velocity (i.e., mass flow rate) caused by,
+for example, a pressure drop can be puffered, which increases the numerical
+stability.
+</p>
+<pre>
+    dm_flow/d&tau; = &Delta;p * &Psi;;
+</pre>
+<p>
+Herein, the derivative of the mass flow rate <i>m_flow</i> w.r.t. time <i>&tau;</i>
+is calculated from the pressure difference <i>&Delta;p</i> and momentum factor 
+<i>&Psi;</i>, which directly follows from a simplified momentum balance.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks to break algebraic loops.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+The model has the mass flow rate <i>m_flow</i> as dynamic state.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LiquidInertiaInducer;
diff --git a/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_GasInertiaInducer.mo b/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_GasInertiaInducer.mo
new file mode 100644
index 0000000..9fdf87c
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_GasInertiaInducer.mo
@@ -0,0 +1,77 @@
+within SorpLib.Components.Fittings.InertiaInducers.Tester;
+model Test_GasInertiaInducer "Tester for the gas inertia inducer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar"),
+    use_mFlowInput=true,
+    T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 100000,
+    T_fixed=303.15)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.InertiaInducers.GasInertiaInducer inertiaInducer(
+      f_momentum=1e-5) "Inertia model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow(
+    amplitude=2,
+    f=1/250,
+    offset=0)
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, inertiaInducer.port_a) annotation (Line(
+      points={{-60,0},{-6,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, inertiaInducer.port_b) annotation (Line(
+      points={{60,0},{6,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_mFlow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,2},{-61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the gas inertia model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasInertiaInducer;
diff --git a/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_LiquidInertiaInducer.mo b/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_LiquidInertiaInducer.mo
new file mode 100644
index 0000000..8970bc6
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_LiquidInertiaInducer.mo
@@ -0,0 +1,78 @@
+within SorpLib.Components.Fittings.InertiaInducers.Tester;
+model Test_LiquidInertiaInducer
+  "Tester for the liquid inertia inducer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar"),
+    use_mFlowInput=true,
+    T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 100000,
+    T_fixed=303.15)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.InertiaInducers.LiquidInertiaInducer inertiaInducer(
+      f_momentum=1e-5) "Inertia model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow(
+    amplitude=2,
+    f=1/250,
+    offset=0)
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, inertiaInducer.port_a) annotation (Line(
+      points={{-60,0},{-6,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, inertiaInducer.port_b) annotation (Line(
+      points={{60,0},{6,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_mFlow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,2},{-61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the liquid inertia model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidInertiaInducer;
diff --git a/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_VLEInertiaInducer.mo b/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_VLEInertiaInducer.mo
new file mode 100644
index 0000000..f292bb9
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/Tester/Test_VLEInertiaInducer.mo
@@ -0,0 +1,77 @@
+within SorpLib.Components.Fittings.InertiaInducers.Tester;
+model Test_VLEInertiaInducer "Tester for the VLE inertia inducer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar"),
+    use_mFlowInput=true,
+    T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 100000,
+    T_fixed=303.15)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.InertiaInducers.VLEInertiaInducer inertiaInducer(
+      f_momentum=1e-5) "Inertia model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow(
+    amplitude=2,
+    f=1/250,
+    offset=0)
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, inertiaInducer.port_a) annotation (Line(
+      points={{-60,0},{-6,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, inertiaInducer.port_b) annotation (Line(
+      points={{60,0},{6,0}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_mFlow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,2},{-61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the inertia model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end Test_VLEInertiaInducer;
diff --git a/SorpLib/Components/Fittings/InertiaInducers/Tester/package.mo b/SorpLib/Components/Fittings/InertiaInducers/Tester/package.mo
new file mode 100644
index 0000000..39bc2d6
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/Tester/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Fittings.InertiaInducers;
+package Tester "Models to test and varify multi port models"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented inertia inducers. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Fittings/InertiaInducers/Tester/package.order b/SorpLib/Components/Fittings/InertiaInducers/Tester/package.order
new file mode 100644
index 0000000..3410f8a
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/Tester/package.order
@@ -0,0 +1,3 @@
+Test_LiquidInertiaInducer
+Test_GasInertiaInducer
+Test_VLEInertiaInducer
diff --git a/SorpLib/Components/Fittings/InertiaInducers/VLEInertiaInducer.mo b/SorpLib/Components/Fittings/InertiaInducers/VLEInertiaInducer.mo
new file mode 100644
index 0000000..d0e369a
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/VLEInertiaInducer.mo
@@ -0,0 +1,66 @@
+within SorpLib.Components.Fittings.InertiaInducers;
+model VLEInertiaInducer "VLE inertia inducer"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialInertiaInducer(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The VLE inertia inducer describes the change of the VLE velocity due to its 
+inertia. Thus, sudden changes in the velocity (i.e., mass flow rate) caused by,
+for example, a pressure drop can be puffered, which increases the numerical
+stability.
+</p>
+<pre>
+    dm_flow/d&tau; = &Delta;p * &Psi;;
+</pre>
+<p>
+Herein, the derivative of the mass flow rate <i>m_flow</i> w.r.t. time <i>&tau;</i>
+is calculated from the pressure difference <i>&Delta;p</i> and momentum factor 
+<i>&Psi;</i>, which directly follows from a simplified momentum balance.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks to break algebraic loops.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+The model has the mass flow rate <i>m_flow</i> as dynamic state.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end VLEInertiaInducer;
diff --git a/SorpLib/Components/Fittings/InertiaInducers/package.mo b/SorpLib/Components/Fittings/InertiaInducers/package.mo
new file mode 100644
index 0000000..aa0cbb0
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Fittings;
+package InertiaInducers "Package containing inertia inducers"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains inertia inducers based on the Modelica Standard library 
+(MSL). Inertia inducers may be used to describe the acceleration of a fluid
+caused by a sudden pressure change, thus also allowing to break algebraic loops.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end InertiaInducers;
diff --git a/SorpLib/Components/Fittings/InertiaInducers/package.order b/SorpLib/Components/Fittings/InertiaInducers/package.order
new file mode 100644
index 0000000..c47972d
--- /dev/null
+++ b/SorpLib/Components/Fittings/InertiaInducers/package.order
@@ -0,0 +1,4 @@
+LiquidInertiaInducer
+GasInertiaInducer
+VLEInertiaInducer
+Tester
diff --git a/SorpLib/Components/Fittings/MultiPorts/GasMultiPort.mo b/SorpLib/Components/Fittings/MultiPorts/GasMultiPort.mo
new file mode 100644
index 0000000..52aafd0
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/GasMultiPort.mo
@@ -0,0 +1,46 @@
+within SorpLib.Components.Fittings.MultiPorts;
+model GasMultiPort
+  "Gas multi port model (i.e., ideal splitter/junctions)"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialMultiPort(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out ports_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The gas multi port model s may be used if several connections shall be made to 
+one port. If the connections were made directly to the port, the calculation of 
+mixture quantities (i.e., stream variables) would be  carried out in the port: 
+This may lead to large linear systems of equations, which is usually not desired. 
+In contrast, no mixture quantities are calculated with this model. Instead, the 
+mixture quantities are calculated in a finite volume model or a comparable 
+model that must be located before port a. The calculated mixture quantities are 
+propagated to the other connections (i.e., port b).
+<br/><br/>
+This models is based on
+<a href=\"Modelica://Modelica.Fluid.Fittings.MultiPort\">Modelica.Fluid.Fittings.MultiPort</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end GasMultiPort;
diff --git a/SorpLib/Components/Fittings/MultiPorts/LiquidMultiPort.mo b/SorpLib/Components/Fittings/MultiPorts/LiquidMultiPort.mo
new file mode 100644
index 0000000..a25ff92
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/LiquidMultiPort.mo
@@ -0,0 +1,45 @@
+within SorpLib.Components.Fittings.MultiPorts;
+model LiquidMultiPort
+  "Liquid multi port model (i.e., ideal splitter/junctions)"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialMultiPort(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out ports_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The liquid multi port model s may be used if several connections shall be made to 
+one port. If the connections were made directly to the port, the calculation of 
+mixture quantities (i.e., stream variables) would be  carried out in the port: 
+This may lead to large linear systems of equations, which is usually not desired. 
+In contrast, no mixture quantities are calculated with this model. Instead, the 
+mixture quantities are calculated in a finite volume model or a comparable 
+model that must be located before port a. The calculated mixture quantities are 
+propagated to the other connections (i.e., port b).
+<br/><br/>
+This models is based on
+<a href=\"Modelica://Modelica.Fluid.Fittings.MultiPort\">Modelica.Fluid.Fittings.MultiPort</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LiquidMultiPort;
diff --git a/SorpLib/Components/Fittings/MultiPorts/Tester/Test_GasMultiPort.mo b/SorpLib/Components/Fittings/MultiPorts/Tester/Test_GasMultiPort.mo
new file mode 100644
index 0000000..bab394c
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/Tester/Test_GasMultiPort.mo
@@ -0,0 +1,84 @@
+within SorpLib.Components.Fittings.MultiPorts.Tester;
+model Test_GasMultiPort "Tester for the gas multi port model"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 100000,
+    T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource[5] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    each use_mFlowInput=true,
+    h_fixed={100e3,200e3,300e3,400e3,500e3})
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.MultiPorts.GasMultiPort multiPort(no_ports_b=5)
+    "Multi port model to split connections at port a"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow(
+    amplitude=1,
+    f=1/250,
+    offset=1)
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, multiPort.port_a) annotation (Line(
+      points={{-60,0},{-6,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, multiPort.ports_b) annotation (Line(
+      points={{60,0},{6,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_mFlow.y, fs_b[1].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[2].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[3].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[4].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[5].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the gas multi port model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasMultiPort;
diff --git a/SorpLib/Components/Fittings/MultiPorts/Tester/Test_LiquidMultiPort.mo b/SorpLib/Components/Fittings/MultiPorts/Tester/Test_LiquidMultiPort.mo
new file mode 100644
index 0000000..b500bfd
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/Tester/Test_LiquidMultiPort.mo
@@ -0,0 +1,84 @@
+within SorpLib.Components.Fittings.MultiPorts.Tester;
+model Test_LiquidMultiPort "Tester for the liquid multi port model"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 100000,
+    T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource[5] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    each use_mFlowInput=true,
+    h_fixed={100e3,200e3,300e3,400e3,500e3})
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.MultiPorts.LiquidMultiPort multiPort(no_ports_b=5)
+    "Multi port model to split connections at port a"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow(
+    amplitude=1,
+    f=1/250,
+    offset=1)
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, multiPort.port_a) annotation (Line(
+      points={{-60,0},{-6,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, multiPort.ports_b) annotation (Line(
+      points={{60,0},{6,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_mFlow.y, fs_b[1].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[2].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[3].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[4].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[5].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the liquid multi port model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidMultiPort;
diff --git a/SorpLib/Components/Fittings/MultiPorts/Tester/Test_VLEMultiPort.mo b/SorpLib/Components/Fittings/MultiPorts/Tester/Test_VLEMultiPort.mo
new file mode 100644
index 0000000..a34b973
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/Tester/Test_VLEMultiPort.mo
@@ -0,0 +1,88 @@
+within SorpLib.Components.Fittings.MultiPorts.Tester;
+model Test_VLEMultiPort "Tester for the VLE multi port model"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 100000,
+    T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource[5] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    each use_mFlowInput=true,
+    h_fixed={100e3,200e3,300e3,400e3,500e3})
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.MultiPorts.VLEMultiPort multiPort(no_ports_b=5)
+    "Multi port model to split connections at port a"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow(
+    amplitude=1,
+    f=1/250,
+    offset=1)
+    "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, multiPort.port_a) annotation (Line(
+      points={{-60,0},{-6,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, multiPort.ports_b) annotation (Line(
+      points={{60,0},{6,0}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_mFlow.y, fs_b[1].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[2].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[3].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[4].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+  connect(input_mFlow.y, fs_b[5].m_flow_input)
+    annotation (Line(points={{79,0},{70,0},{70,2},{61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the VLE multi port model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 20, 2023, by Mirko Engelpracht:<br/>
+  Minor revisions (documentation).
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end Test_VLEMultiPort;
diff --git a/SorpLib/Components/Fittings/MultiPorts/Tester/package.mo b/SorpLib/Components/Fittings/MultiPorts/Tester/package.mo
new file mode 100644
index 0000000..8f45612
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components.Fittings.MultiPorts;
+package Tester "Models to test and varify multi port models"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented multi port models. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Fittings/MultiPorts/Tester/package.order b/SorpLib/Components/Fittings/MultiPorts/Tester/package.order
new file mode 100644
index 0000000..0c82979
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/Tester/package.order
@@ -0,0 +1,3 @@
+Test_LiquidMultiPort
+Test_GasMultiPort
+Test_VLEMultiPort
diff --git a/SorpLib/Components/Fittings/MultiPorts/VLEMultiPort.mo b/SorpLib/Components/Fittings/MultiPorts/VLEMultiPort.mo
new file mode 100644
index 0000000..247da7c
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/VLEMultiPort.mo
@@ -0,0 +1,50 @@
+within SorpLib.Components.Fittings.MultiPorts;
+model VLEMultiPort
+  "VLE multi port model (i.e., ideal splitter/junctions)"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialMultiPort(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out ports_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The VLE multi port model s may be used if several connections shall be made to 
+one port. If the connections were made directly to the port, the calculation of 
+mixture quantities (i.e., stream variables) would be  carried out in the port: 
+This may lead to large linear systems of equations, which is usually not desired. 
+In contrast, no mixture quantities are calculated with this model. Instead, the 
+mixture quantities are calculated in a finite volume model or a comparable 
+model that must be located before port a. The calculated mixture quantities are 
+propagated to the other connections (i.e., port b).
+<br/><br/>
+This models is based on
+<a href=\"Modelica://Modelica.Fluid.Fittings.MultiPort\">Modelica.Fluid.Fittings.MultiPort</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 20, 2023, by Mirko Engelpracht:<br/>
+  Minor revisions (documentation).
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end VLEMultiPort;
diff --git a/SorpLib/Components/Fittings/MultiPorts/package.mo b/SorpLib/Components/Fittings/MultiPorts/package.mo
new file mode 100644
index 0000000..2b195f6
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Components.Fittings;
+package MultiPorts "Package containing multi port models for efficient connection of multiple ports to one port"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains multi port models based on the Modelica Standard library 
+(MSL). These models may be used if several connections shall be made to one port. 
+If the connections were made directly to the port, the calculation of mixture 
+quantities (i.e., stream variables) would be carried out in the port: This may 
+lead to large linear systems of equations, which is usually not desired. In 
+contrast, no mixture quantities are calculated with this model. Instead, the 
+mixture quantities are calculated in a finite volume model or a comparable model 
+that must be located before port a. The calculated mixture quantities are 
+propagated to the other connections (i.e., port b).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end MultiPorts;
diff --git a/SorpLib/Components/Fittings/MultiPorts/package.order b/SorpLib/Components/Fittings/MultiPorts/package.order
new file mode 100644
index 0000000..8ec22ee
--- /dev/null
+++ b/SorpLib/Components/Fittings/MultiPorts/package.order
@@ -0,0 +1,4 @@
+LiquidMultiPort
+GasMultiPort
+VLEMultiPort
+Tester
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/ConstantLambda.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/ConstantLambda.mo
new file mode 100644
index 0000000..8c4e651
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/ConstantLambda.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber;
+model ConstantLambda
+  "Pressure loss model with friction contribution according to constant Darcy friction number"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialOpenAdsorberPressureLoss(
+    final requireTransportPropreties=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real lambda_constant = 0.025
+    "Constant Darcy friction number"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+equation
+  lambda_mean_dd = lambda_constant
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = lambda_constant
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'ConstantLambda' pressure loss model calculates the pressure loss of a resistance
+for open adsorbers, with the friction-based pressure loss according to a constant Darcy
+friction number. The model also includes dynamic, geodetic, and installation-related 
+pressure losses. The pressure loss is calculated as a function of the mass flow rate, 
+and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = &lambda;<sub>constant</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Modifications due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantLambda;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/Kast.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/Kast.mo
new file mode 100644
index 0000000..f3ccbff
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/Kast.mo
@@ -0,0 +1,196 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber;
+model Kast
+  "Pressure loss model with friction contribution according to Kast"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialOpenAdsorberPressureLoss(
+     final requireTransportPropreties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust pressure drop correlation"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+  parameter Real f_particle = 1.8
+    "Particle-specific factor (i.e., 1.8 for spherical particles or 2.6 for sharp-
+    edged particles)"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Diameter d_hyd_mean_ = d_hyd_mean /
+    (2/3 * geometry.psi / (1 - geometry.psi) * geometry.d_particle)
+    "Corrected hydraulic average diameter";
+
+equation
+  lambda_mean_dd = f_correction * d_hyd_mean_ * (
+    64 / max(Re_mean_dd, 1e-12) + f_particle / max(Re_mean_dd, 1e-12) ^ (0.1))
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = f_correction * d_hyd_mean_ * (
+    64 / max(Re_mean_rdd, 1e-12) + f_particle / max(Re_mean_rdd, 1e-12) ^ (0.1))
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'Kast' pressure loss model calculates the pressure loss of a resistance for open
+adsorbers, with the friction-based pressure loss according to the Blasius correlation. 
+The model also includes dynamic, geodetic, and installation-related pressure losses. 
+The pressure loss is calculated as a function of the mass flow rate, and there is 
+no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = 64 / Re + f<sub>particle</sub> / Re<sup>0.1</sup>;
+</pre>
+<p>
+Herein, <i>Re</i> is the Reynold number and <i>f<sub>particle</sub></i> is a particle-
+specifc facotr (i.e., 1.8 for spherical particles or 2.6 for sharp-edged particles). 
+Note that the average diameter <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+must be corrected to
+</p>
+<pre>
+    <SPAN STYLE=\"text-decoration:overline\">d</SPAN> = 2/3 * &Psi; / (1 - &Psi;) * d<sub>particle</sub>;
+</pre>
+<p>
+with the void fraction <i>&Psi;</i> and particle diameter <i>d<sub>particle</sub></i>.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kast, W. (1998). Adsorption aus der Gasphase: Ingenieurwissenschaftliche Grundlagen und technische Verfahren (in German). VCH Verlagsgesellschaft, Weinheim, Basel, Cambridge, New York. DOI:  https://doi.org/10.1002/bbpc.19900940122.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Modifications due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Kast;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/LinearLambda.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/LinearLambda.mo
new file mode 100644
index 0000000..d7dd3c5
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/LinearLambda.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber;
+model LinearLambda
+  "Pressure loss model with friction contribution according to Darcy friction number that is linearly dependent on the mass flow rate"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialOpenAdsorberPressureLoss(
+    final requireTransportPropreties=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real lambda_linear(final unit="s/kg") = 0.025
+    "Darcy friction factor at mass flow rate of 1 kg/s"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+equation
+  lambda_mean_dd = lambda_linear * abs(m_flow_hyd)
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = lambda_linear * abs(m_flow_hyd)
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'LinearLambda' pressure loss model calculates the pressure loss of a resistance
+for open adsorbers, with the friction-based pressure loss according to a Darcy friction 
+number that is linearly dependent on the mass flow rate. The model also includes 
+dynamic, geodetic, and installation-related pressure losses. The pressure loss is 
+calculated as a function of the mass flow rate, and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = &lambda;<sub>linear</sub> * m&#x307;<sub>hyd</sub>;
+</pre>
+<p>
+Herein, <i>&lambda;<sub>linear</sub></i> is the Darcy friction number at a mass
+flow rate of 1 kg/s.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LinearLambda;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/QuadraticLambda.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/QuadraticLambda.mo
new file mode 100644
index 0000000..d37d3d7
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/QuadraticLambda.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber;
+model QuadraticLambda
+  "Pressure loss model with friction contribution according to Darcy friction number that is quadratically dependent on the mass flow rate"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialOpenAdsorberPressureLoss(
+    final requireTransportPropreties=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real lambda_quadratic(final unit="s2/kg2") = 0.025
+    "Darcy friction factor at mass flow rate of 1 kg/s"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+equation
+  lambda_mean_dd = lambda_quadratic * m_flow_hyd^2
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = lambda_quadratic * m_flow_hyd^2
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'QuadraticLambda' pressure loss model calculates the pressure loss of a resistance
+for open adsorbers, with the friction-based pressure loss according to a Darcy friction 
+number that is quadratically dependent on the mass flow rate. The model also includes 
+dynamic, geodetic, and installation-related pressure losses. The pressure loss is 
+calculated as a function of the mass flow rate, and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = &lambda;<sub>quadratic</sub> * m&#x307;<sub>hyd</sub><sup>2</sup>;
+</pre>
+<p>
+Herein, <i>&lambda;<sub>quadratic</sub></i> is the Darcy friction number at a mass
+flow rate of 1 kg/s.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end QuadraticLambda;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/ZeroFriction.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/ZeroFriction.mo
new file mode 100644
index 0000000..47b6f38
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/ZeroFriction.mo
@@ -0,0 +1,148 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber;
+model ZeroFriction
+  "Pressure loss model without friction contribution"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialOpenAdsorberPressureLoss(
+    final requireTransportPropreties=false);
+
+equation
+  lambda_mean_dd = 0
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = 0
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'ZeroFriction' pressure loss model calculates the pressure loss of an resistance
+for open adsorbers. The model includes dynamic, geodetic, and installation-related 
+pressure losses but not friction. The pressure loss is calculated as a function of 
+the mass flow rate, and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+This model assumes zero friction, so it does not calculate friction-based
+pressure losses:
+</p>
+<pre>
+    &lambda; = 0;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The 'ZeroFriction' pressure loss model is used within tubes if friction shall
+not be included.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Modifications due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeroFriction;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/package.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/package.mo
new file mode 100644
index 0000000..7fe2e52
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/package.mo
@@ -0,0 +1,40 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations;
+package OpenAdsorber "Pressure loss correlations for fluids flowing through open adsorbers"
+extends Modelica.Icons.FunctionsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains pressure loss correlations that can be used within tubes
+to calculate friction-based pressure losses:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.ZeroFriction\">ZeroFriction</a>: 
+  No friction is considered.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.ConstantLambda\">ConstantLambda</a>: 
+  Constant Darcy friction number.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.LinearLambda\">LinearLambda</a>: 
+  Darcy friction number that is linearly dependent on the mass flow rate.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.QuadraticLambda\">QuadraticLambda</a>: 
+  Darcy friction number that is quadratically dependent on the mass flow rate.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Kast\">Kast</a>: 
+  Darcy friction number according to Kast for packed beds.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end OpenAdsorber;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/package.order b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/package.order
new file mode 100644
index 0000000..10f68c9
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/OpenAdsorber/package.order
@@ -0,0 +1,5 @@
+ZeroFriction
+ConstantLambda
+LinearLambda
+QuadraticLambda
+Kast
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Blasius.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Blasius.mo
new file mode 100644
index 0000000..53d76d5
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Blasius.mo
@@ -0,0 +1,213 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model Blasius
+  "Pressure loss model with friction contribution according to Blasius"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust pressure drop correlation"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transition = 100
+    "Transition length to change between laminar and turbulent flow regime"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer noDiffTransition = 3
+    "Specification how often transition function can be differentiated"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Real wf_dd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_dd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_dd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the design direction";
+  Real wf_rdd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_rdd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_rdd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the reverse design direction";
+
+equation
+  lambda_mean_dd = f_correction* (
+    wf_dd * 64 / max(Re_mean_dd, 1e-12) + (1-wf_dd) *
+    0.3164 * max(Re_mean_dd, 1e-12) ^ (-0.25))
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = f_correction *
+    (wf_rdd * 64 / max(Re_mean_rdd, 1e-12) + (1-wf_rdd) *
+    0.3164 * max(Re_mean_rdd, 1e-12) ^ (-0.25))
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'Blasius' pressure loss model calculates the pressure loss of a tube resistance, with
+the friction-based pressure loss according to the Blasius correlation. The model also 
+includes dynamic, geodetic, and installation-related pressure losses. The pressure loss 
+is calculated as a function of the mass flow rate, and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The laminar Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = 64 / Re <strong>for</strong> Re &le; 2300;
+</pre>
+<p>
+and the turbulent Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = 0.3164 / Re<sup>0.25</sup> <strong>for</strong> 2300 &le; Re &le; 10<sup>5</sup>;
+</pre>
+<p>
+Herein, <i>Re</i> is the Reynold number. Smooth transition is applied using the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>
+to change between laminar and turbulent flow regime.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  Smooth tube
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kast, W., (Revised by Hermann Nirschl), and Gaddis, E.S., and Wirth, KE., and Stichlmair, J. (2010). L1 Pressure Drop in Single Phase Flow. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_70.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Modifications due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Blasius;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Colebrook.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Colebrook.mo
new file mode 100644
index 0000000..5d8abaa
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Colebrook.mo
@@ -0,0 +1,289 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model Colebrook
+  "Pressure loss model with friction contribution according to Colebrook"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust pressure drop correlation"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+  parameter Boolean useExplicitFormulation = true
+    " = true, if explicit formulation usign the Lambert W function shall be
+    used; otherwise, use implicit formulation"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useExactLambertWFunction = false
+    " = true, if exact iterative solution of the Lambert W function shall be
+    used; otherwise, use closed form approximation"
+    annotation (Dialog(tab="Advanced", group="Numerics",
+                       enable=useExplicitFormulation),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transition = 2000
+    "Transition length to change between laminar and turbulent flow regime"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer noDiffTransition = 3
+    "Specification how often transition function can be differentiated"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Real lambda_mean_turb_dd
+    "Average Darcy friction factor for the design direction";
+  Real lambda_mean_turb_rdd
+    "Average Darcy friction factor for the reverse design direction";
+
+  Real wf_dd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_dd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_dd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the design direction";
+  Real wf_rdd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_rdd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_rdd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the reverse design direction";
+
+equation
+  //
+  // Calculate turbulent Darcy friction factor
+  //
+  if useExplicitFormulation then
+    if useExactLambertWFunction then
+      lambda_mean_turb_dd = 1 / (2 *
+        Modelica.Fluid.Dissipation.Utilities.Functions.General.LambertWIter(
+        log(10) * Re_mean_dd / (2 * 2.51) * 10 ^ ((geometry.roughness * Re_mean_dd) /
+        (2 * 2.51 * 14.8 * d_hyd_mean))) / log(10) - (geometry.roughness * Re_mean_dd) /
+        (2.51 * 14.8 * d_hyd_mean)) ^ 2
+        "Average Darcy friction factor for the design direction";
+      lambda_mean_turb_rdd =  1 / (2 *
+        Modelica.Fluid.Dissipation.Utilities.Functions.General.LambertWIter(
+        log(10) * Re_mean_rdd / (2 * 2.51) * 10 ^ ((geometry.roughness * Re_mean_rdd) /
+        (2 * 2.51 * 14.8 * d_hyd_mean))) / log(10) - (geometry.roughness * Re_mean_rdd) /
+        (2.51 * 14.8 * d_hyd_mean)) ^ 2
+        "Average Darcy friction factor for the reverse design direction";
+
+    else
+      lambda_mean_turb_dd = 1 / (2 *
+        Modelica.Fluid.Dissipation.Utilities.Functions.General.LambertW(
+        log(10) * Re_mean_dd / (2 * 2.51) * 10 ^ ((geometry.roughness * Re_mean_dd) /
+        (2 * 2.51 * 14.8 * d_hyd_mean))) / log(10) - (geometry.roughness * Re_mean_dd) /
+        (2.51 * 14.8 * d_hyd_mean)) ^ 2
+        "Average Darcy friction factor for the design direction";
+      lambda_mean_turb_rdd = 1 / (2 *
+        Modelica.Fluid.Dissipation.Utilities.Functions.General.LambertW(
+        log(10) * Re_mean_rdd / (2 * 2.51) * 10 ^ ((geometry.roughness * Re_mean_rdd) /
+        (2 * 2.51 * 14.8 * d_hyd_mean))) / log(10) - (geometry.roughness * Re_mean_rdd) /
+        (2.51 * 14.8 * d_hyd_mean)) ^ 2
+        "Average Darcy friction factor for the reverse design direction";
+
+    end if;
+
+  else
+    1 / sqrt(max(lambda_mean_turb_dd, 1e-12)) = -2 * Modelica.Math.log10(
+      2.51 / (max(Re_mean_dd, 1e-12) * sqrt(max(lambda_mean_turb_dd, 1e-12))) +
+      geometry.roughness / d_hyd_mean / 3.71)
+      "Average Darcy friction factor for the design direction";
+    1 / sqrt(max(lambda_mean_turb_rdd, 1e-12)) = -2 * Modelica.Math.log10(
+      2.51 / (max(Re_mean_rdd, 1e-12) * sqrt(max(lambda_mean_turb_rdd, 1e-12))) +
+      geometry.roughness / d_hyd_mean / 3.71)
+      "Average Darcy friction factor for the reverse design direction";
+
+  end if;
+
+  //
+  // Calculate overall Darcy friction factor
+  //
+  lambda_mean_dd = f_correction* (
+    wf_dd * 64 / max(Re_mean_dd, 1e-12) + (1-wf_dd) * lambda_mean_turb_dd)
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = f_correction* (
+    wf_rdd * 64 / max(Re_mean_rdd, 1e-12) + (1-wf_rdd) * lambda_mean_turb_rdd)
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'Colebrook' pressure loss model calculates the pressure loss of a tube resistance, 
+with the friction-based pressure loss according to the Colebrook correlation. The 
+model also includes dynamic, geodetic, and installation-related pressure losses. The 
+pressure loss is calculated as a function of the mass flow rate, and there is no 
+inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The laminar Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = 64 / Re <strong>for</strong> Re &le; 2300;
+</pre>
+<p>
+and the turbulent Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    1 / <strong>sqrt</strong>(&lambda;) = -2 <strong>log</strong>(2.51 / (Re * <strong>sqrt</strong>(&lambda;)) + &epsilon; / 3.71) <strong>for</strong> 4000 &le; Re;
+</pre>
+<p>
+Herein, <i>Re</i> is the Reynold number and <i>&epsilon;</i> is the relative
+roughness. Smooth transition is applied using the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>
+to change between laminar and turbulent flow regime.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  Rough tube
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>useExplicitFormulation</i>:
+  Defines if explicit formulation of the turbulent Darcy friction factor shall be
+  used by applying the Lambert W function.
+  </li>
+  <li>
+  <i>useExactLambertWFunction</i>:
+  Defines if approximation or exact solution (i.e., iteration) of the Lambert W
+  function shall be used.
+  </li>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kast, W., (Revised by Hermann Nirschl), and Gaddis, E.S., and Wirth, KE., and Stichlmair, J. (2010). L1 Pressure Drop in Single Phase Flow. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_70.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Colebrook;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/ConstantLambda.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/ConstantLambda.mo
new file mode 100644
index 0000000..a278933
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/ConstantLambda.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model ConstantLambda
+  "Pressure loss model with friction contribution according to constant Darcy friction number"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real lambda_constant = 0.025
+    "Constant Darcy friction number"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+equation
+  lambda_mean_dd = lambda_constant
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = lambda_constant
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'ConstantLambda' pressure loss model calculates the pressure loss of a tube 
+resistance, withthe friction-based pressure loss according to a constant Darcy
+friction number. The model also includes dynamic, geodetic, and installation-related 
+pressure losses. The pressure loss is calculated as a function of the mass flow rate, 
+and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = &lambda;<sub>constant</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Modifications due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantLambda;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Konakov.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Konakov.mo
new file mode 100644
index 0000000..06e10cb
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/Konakov.mo
@@ -0,0 +1,213 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model Konakov
+  "Pressure loss model with friction contribution according to Konakov"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust pressure drop correlation"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transition = 100
+    "Transition length to change between laminar and turbulent flow regime"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer noDiffTransition = 3
+    "Specification how often transition function can be differentiated"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Real wf_dd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_dd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_dd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the design direction";
+  Real wf_rdd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_rdd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_rdd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the reverse design direction";
+
+equation
+  lambda_mean_dd = f_correction* (
+    wf_dd * 64 / max(Re_mean_dd, 1e-12) + (1-wf_dd) *
+    1/(1.8*Modelica.Math.log10(max(Re_mean_dd, 1e-12)) - 1.5)^2)
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = f_correction* (
+    wf_rdd * 64 / max(Re_mean_rdd, 1e-12) + (1-wf_rdd) *
+    1/(1.8*Modelica.Math.log10(max(Re_mean_rdd, 1e-12)) - 1.5)^2)
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'Konakov' pressure loss model calculates the pressure loss of a tube resistance, with
+the friction-based pressure loss according to the Konakov correlation. The model also 
+includes dynamic, geodetic, and installation-related pressure losses. The pressure loss 
+is calculated as a function of the mass flow rate, and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The laminar Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = 64 / Re <strong>for</strong> Re &le; 2300;
+</pre>
+<p>
+and the turbulent Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = 1 / [1.8 * <strong>log</strong>(Re) - 1.5]<sup>2</sup> <strong>for</strong> 2300 &le; Re &le; 10<sup>6</sup>;
+</pre>
+<p>
+Herein, <i>Re</i> is the Reynold number. Smooth transition is applied using the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>
+to change between laminar and turbulent flow regime.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  Smooth tube
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kast, W., (Revised by Hermann Nirschl), and Gaddis, E.S., and Wirth, KE., and Stichlmair, J. (2010). L1 Pressure Drop in Single Phase Flow. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_70.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Modifications due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Konakov;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/LinearLambda.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/LinearLambda.mo
new file mode 100644
index 0000000..63498bf
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/LinearLambda.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model LinearLambda
+  "Pressure loss model with friction contribution according to Darcy friction number that is linearly dependent on the mass flow rate"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real lambda_linear(final unit="s/kg") = 0.025
+    "Darcy friction factor at mass flow rate of 1 kg/s"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+equation
+  lambda_mean_dd = lambda_linear * abs(m_flow_hyd)
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = lambda_linear * abs(m_flow_hyd)
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'LinearLambda' pressure loss model calculates the pressure loss of a tube 
+resistance, withthe friction-based pressure loss according to a Darcy friction 
+number that is linearly dependent on the mass flow rate. The model also includes 
+dynamic, geodetic, and installation-related pressure losses. The pressure loss is 
+calculated as a function of the mass flow rate, and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = &lambda;<sub>linear</sub> * m&#x307;<sub>hyd</sub>;
+</pre>
+<p>
+Herein, <i>&lambda;<sub>linear</sub></i> is the Darcy friction number at a mass
+flow rate of 1 kg/s.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LinearLambda;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/MishraGupaSchmidt.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/MishraGupaSchmidt.mo
new file mode 100644
index 0000000..50a1fec
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/MishraGupaSchmidt.mo
@@ -0,0 +1,241 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model MishraGupaSchmidt
+  "Pressure loss model with friction contribution according to Mishra, Gupa, and Schmidt"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust pressure drop correlation"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+  parameter Modelica.Units.SI.Diameter d_avg_helix = 0.1
+    "Average diameter of the helix tube (i.e., top-view projection)"
+    annotation (Dialog(tab="General", group="Geometry"));
+  parameter Modelica.Units.SI.Height h_helix = 0.025
+    "Inclinde of the helix tube"
+    annotation (Dialog(tab="General", group="Geometry"));
+  final parameter Modelica.Units.SI.Diameter d_bend_avg_helix = d_avg_helix *
+    (1 + (h_helix / Modelica.Constants.pi / d_avg_helix) ^ 2)
+    "Average bending diameter of the helix tube"
+    annotation (Dialog(tab="General", group="Geometry", enable=false));
+
+  final parameter Modelica.Units.SI.ReynoldsNumber Re_crit = 2300 *
+    (1 + 8.6 * (d_hyd_mean / d_bend_avg_helix) ^ (0.45))
+    "Critical Reynolds number"
+    annotation (Dialog(tab="Advanced", group="Numerics", enable=false));
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transition = 100
+    "Transition length to change between laminar and turbulent flow regime"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer noDiffTransition = 3
+    "Specification how often transition function can be differentiated"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Real wf_dd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_dd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_dd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the design direction";
+  Real wf_rdd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_rdd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_rdd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the reverse design direction";
+
+equation
+  lambda_mean_dd = f_correction* (wf_dd * 64 / max(Re_mean_dd, 1e-12) * (1 +
+    0.033 * Modelica.Math.log10(max(Re_mean_dd * sqrt(d_hyd_mean /
+    d_bend_avg_helix), 1e-12)) ^ 4) + (1-wf_dd) * 0.3164 *
+    max(Re_mean_dd, 1e-12) ^ (-0.25) * (1 + 0.095 * sqrt(d_hyd_mean /
+    d_bend_avg_helix) * max(Re_mean_dd, 1e-12) ^ (0.25)))
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = f_correction* (wf_rdd * 64 / max(Re_mean_rdd, 1e-12) * (1 +
+    0.033 * Modelica.Math.log10(max(Re_mean_rdd * sqrt(d_hyd_mean /
+    d_bend_avg_helix), 1e-12)) ^ 4) + (1-wf_rdd) * 0.3164 *
+    max(Re_mean_rdd, 1e-12) ^ (-0.25) * (1 + 0.095 * sqrt(d_hyd_mean /
+    d_bend_avg_helix) * max(Re_mean_rdd, 1e-12) ^ (0.25)))
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'MishraGupaSchmidt' pressure loss model calculates the pressure loss of a tube 
+resistance, with the friction-based pressure loss according to the Mishra, Gupa, and
+Schmidt correlation. The model also includes dynamic, geodetic, and installation-related 
+pressure losses. The pressure loss is calculated as a function of the mass flow rate, 
+and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The laminar Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = 64 / Re * [1 + 0.033 * (<strong>log</strong>(Re * <strong>sqrt</strong>(d/D)))<sup>4</sup>] <strong>for</strong> Re &le; Re<sub>crit</sub>;
+</pre>
+<p>
+and the turbulent Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; =0.3164 / Re<sup>0.25</sup> * [1 + 0.095 * <strong>sqrt</strong>(d/D) * Re<sup>0.25</sup>] <strong>for</strong> Re<sub>crit</sub> &le; Re &le; 10<sup>5</sup>;
+</pre>
+<p>
+Herein, <i>Re</i> is the Reynold number, <i>d</i> is the hydraulic diameter, and <i>D</i> is 
+the average diameter of the helix tube:
+</p>
+<pre>
+    D = D* * [1 + (h / &pi; / D*)<sup>2</sup>];
+</pre>
+<p>
+Herein, <i>D*</i> is the average diameter assuming a horizontal approximation, and <i>h</i>
+is the inclinde of the helix tube. Smooth transition is applied using the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>
+to change between laminar and turbulent flow regime, with the critical Renolds number
+<i>Re<sub>crit</sub></i> calculated as:
+</p>
+<pre>
+    Re<sub>crit</sub> = 2300 * [1 + 8.6 (d / D*)<sup>0.45</sup>];
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  Smooth helix tube
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kast, W., (Revised by Hermann Nirschl), and Gaddis, E.S., and Wirth, KE., and Stichlmair, J. (2010). L1 Pressure Drop in Single Phase Flow. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_70.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MishraGupaSchmidt;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/PrandtlKarman.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/PrandtlKarman.mo
new file mode 100644
index 0000000..200ff91
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/PrandtlKarman.mo
@@ -0,0 +1,278 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model PrandtlKarman
+  "Pressure loss model with friction contribution according to Prandtl and Karman"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust pressure drop correlation"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+  parameter Boolean useExplicitFormulation = true
+    " = true, if explicit formulation usign the Lambert W function shall be
+    used; otherwise, use implicit formulation"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useExactLambertWFunction = false
+    " = true, if exact iterative solution of the Lambert W function shall be
+    used; otherwise, use closed form approximation"
+    annotation (Dialog(tab="Advanced", group="Numerics",
+                       enable=useExplicitFormulation),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transition = 100
+    "Transition length to change between laminar and turbulent flow regime"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer noDiffTransition = 3
+    "Specification how often transition function can be differentiated"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Real lambda_mean_turb_dd
+    "Average Darcy friction factor for the design direction";
+  Real lambda_mean_turb_rdd
+    "Average Darcy friction factor for the reverse design direction";
+
+  Real wf_dd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_dd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_dd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the design direction";
+  Real wf_rdd = if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(Re_mean_rdd, 2300, Re_transition,
+    noDiffTransition) else SorpLib.Numerics.smoothTransition(Re_mean_rdd, 2300,
+    Re_transition, noDiffTransition)
+    "Weighting factor for the reverse design direction";
+
+equation
+  //
+  // Calculate turbulent Darcy friction factor
+  //
+  if useExplicitFormulation then
+    if useExactLambertWFunction then
+      lambda_mean_turb_dd = 1.32547 /
+        Modelica.Fluid.Dissipation.Utilities.Functions.General.LambertWIter(
+        0.458338 * Re_mean_dd) ^2
+        "Average Darcy friction factor for the design direction";
+      lambda_mean_turb_rdd = 1.32547 /
+        Modelica.Fluid.Dissipation.Utilities.Functions.General.LambertWIter(
+        0.458338 * Re_mean_rdd) ^2
+        "Average Darcy friction factor for the reverse design direction";
+
+    else
+      lambda_mean_turb_dd = 1.32547 /
+        Modelica.Fluid.Dissipation.Utilities.Functions.General.LambertW(0.458338 *
+        Re_mean_dd) ^2
+        "Average Darcy friction factor for the design direction";
+      lambda_mean_turb_rdd = 1.32547 /
+        Modelica.Fluid.Dissipation.Utilities.Functions.General.LambertW(0.458338 *
+        Re_mean_rdd) ^2
+        "Average Darcy friction factor for the reverse design direction";
+
+    end if;
+
+  else
+    1 / sqrt(max(lambda_mean_turb_dd, 1e-12)) = -0.8 + 2 * Modelica.Math.log10(
+      max(Re_mean_dd, 1e-12) * sqrt(max(lambda_mean_turb_dd, 1e-12)))
+      "Average Darcy friction factor for the design direction";
+    1 / sqrt(max(lambda_mean_turb_rdd, 1e-12)) = -0.8 + 2 * Modelica.Math.log10(
+      max(Re_mean_rdd, 1e-12) * sqrt(max(lambda_mean_turb_rdd, 1e-12)))
+      "Average Darcy friction factor for the reverse design direction";
+
+  end if;
+
+  //
+  // Calculate overall Darcy friction factor
+  //
+  lambda_mean_dd = f_correction* (
+    wf_dd * 64 / max(Re_mean_dd, 1e-12) + (1-wf_dd) * lambda_mean_turb_dd)
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = f_correction* (
+    wf_rdd * 64 / max(Re_mean_rdd, 1e-12) + (1-wf_rdd) * lambda_mean_turb_rdd)
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'PrandtlKarman' pressure loss model calculates the pressure loss of a tube 
+resistance, with the friction-based pressure loss according to the Prandtl and Karman 
+correlation. The model also includes dynamic, geodetic, and installation-related 
+pressure losses. The pressure loss is calculated as a function of the mass flow 
+rate, and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The laminar Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = 64 / Re <strong>for</strong> Re &le; 2300;
+</pre>
+<p>
+and the turbulent Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    1 / <strong>sqrt</strong>(&lambda;) = 2 <strong>log</strong>(Re * <strong>sqrt</strong>(&lambda;)) - 0.8 <strong>for</strong> 2300 &le; Re;
+</pre>
+<p>
+Herein, <i>Re</i> is the Reynold number. Smooth transition is applied using the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>
+to change between laminar and turbulent flow regime.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  Smooth tube
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>useExplicitFormulation</i>:
+  Defines if explicit formulation of the turbulent Darcy friction factor shall be
+  used by applying the Lambert W function.
+  </li>
+  <li>
+  <i>useExactLambertWFunction</i>:
+  Defines if approximation or exact solution (i.e., iteration) of the Lambert W
+  function shall be used.
+  </li>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kast, W., (Revised by Hermann Nirschl), and Gaddis, E.S., and Wirth, KE., and Stichlmair, J. (2010). L1 Pressure Drop in Single Phase Flow. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_70.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PrandtlKarman;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/QuadraticLambda.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/QuadraticLambda.mo
new file mode 100644
index 0000000..b540109
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/QuadraticLambda.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model QuadraticLambda
+  "Pressure loss model with friction contribution according to Darcy friction number that is quadratically dependent on the mass flow rate"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real lambda_quadratic(final unit="s2/kg2") = 0.025
+    "Darcy friction factor at mass flow rate of 1 kg/s"
+    annotation (Dialog(tab="General", group="Calculation Setup"));
+
+equation
+  lambda_mean_dd = lambda_quadratic * m_flow_hyd^2
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = lambda_quadratic * m_flow_hyd^2
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'QuadraticLambda' pressure loss model calculates the pressure loss of a tube 
+resistance, withthe friction-based pressure loss according to a Darcy friction 
+number that is quadratically dependent on the mass flow rate. The model also includes 
+dynamic, geodetic, and installation-related pressure losses. The pressure loss is 
+calculated as a function of the mass flow rate, and there is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+The Darcy friction factor <i>&lambda;</i> is defined as
+</p>
+<pre>
+    &lambda; = &lambda;<sub>quadratic</sub> * m&#x307;<sub>hyd</sub><sup>2</sup>;
+</pre>
+<p>
+Herein, <i>&lambda;<sub>quadratic</sub></i> is the Darcy friction number at a mass
+flow rate of 1 kg/s.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pressure loss model is used within tubes if friction shall be included..
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>Re_transition</i>:
+  Defines the transition length to change between laminar and turbulent flow
+  regime.
+  </li>
+  <li>
+  <i>noDiffTransition</i>:
+  Defines how often the transition function can be differentiated.
+  </li>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end QuadraticLambda;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/ZeroFriction.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/ZeroFriction.mo
new file mode 100644
index 0000000..aba9b28
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/ZeroFriction.mo
@@ -0,0 +1,148 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside;
+model ZeroFriction
+  "Pressure loss model without friction contribution"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss(
+    final requireTransportPropreties=false);
+
+equation
+  lambda_mean_dd = 0
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = 0
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'ZeroFriction' pressure loss model calculates the pressure loss of a tube resistance. 
+The model includes dynamic, geodetic, and installation-related pressure losses but not 
+friction. The pressure loss is calculated as a function of the mass flow rate, and there 
+is no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+This model assumes zero friction, so it does not calculate friction-based
+pressure losses:
+</p>
+<pre>
+    &lambda; = 0;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The 'ZeroFriction' pressure loss model is used within tubes if friction shall
+not be included.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Modifications due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeroFriction;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/package.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/package.mo
new file mode 100644
index 0000000..c14288a
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/package.mo
@@ -0,0 +1,56 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations;
+package TubeInside "Pressure loss correlations for fluids flowing through pipes"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains pressure loss correlations that can be used within tubes
+to calculate friction-based pressure losses:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.ZeroFriction\">ZeroFriction</a>: 
+  No friction is considered.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.ConstantLambda\">ConstantLambda</a>: 
+  Constant Darcy friction number.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.LinearLambda\">LinearLambda</a>: 
+  Darcy friction number that is linearly dependent on the mass flow rate.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.QuadraticLambda\">QuadraticLambda</a>: 
+  Darcy friction number that is quadratically dependent on the mass flow rate.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Blasius\">Blasius</a>: 
+  Darcy friction number according to Blasius for smooth, straight tubes.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Konakov\">Konakov</a>: 
+  Darcy friction number according to Konakov for smooth, straight tubes.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.PrandtlKarman\">PrandtlKarman</a>: 
+  Darcy friction number according to Prandtl and Karman for smooth, straight tubes.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Colebrook\">Colebrook</a>: 
+  Darcy friction number according to Colebrook for rough, straight tubes.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.MishraGupaSchmidt\">MishraGupaSchmidt</a>: 
+  Darcy friction number according to Mishra, Gupa, and Schmidt for smooth, helix tubes.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TubeInside;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/package.order b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/package.order
new file mode 100644
index 0000000..daf3698
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/TubeInside/package.order
@@ -0,0 +1,9 @@
+ZeroFriction
+ConstantLambda
+LinearLambda
+QuadraticLambda
+Blasius
+Konakov
+PrandtlKarman
+Colebrook
+MishraGupaSchmidt
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/ZeroFriction.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/ZeroFriction.mo
new file mode 100644
index 0000000..40a20e9
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/ZeroFriction.mo
@@ -0,0 +1,148 @@
+within SorpLib.Components.Fittings.PressureLossCorrelations;
+model ZeroFriction
+  "Pressure loss model without friction contribution"
+  extends BaseClasses.PartialPressureLoss(
+    final psi = 1,
+    final requireTransportPropreties=false);
+
+equation
+  m_flow_hyd = m_flow
+    "Hydraulic mass flow rate";
+
+  lambda_mean_dd = 0
+    "Average Darcy friction number for design flow direction (a->b)";
+  lambda_mean_rdd = 0
+    "Average Darcy friction number for reverse design flow direction (b->a)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The 'ZeroFriction' pressure loss model calculates the pressure loss of a generic 
+resistance. The model includes dynamic, geodetic, and installation-related pressure 
+losses but not friction. The pressure loss is calculated as a function of the mass 
+flow rate, and there may be no inverse function.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+This model assumes zero friction, so it does not calculate friction-based
+pressure losses:
+</p>
+<pre>
+    &lambda; = 0;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The 'ZeroFriction' pressure loss model is used within generic resistors as they
+do not account for friction-based pressure losses.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <br/>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses and
+  contains parameters defining which pressure losses shall be included.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <br/>
+  <li>
+  <i>showTotalPressures</i>:
+  Defines if the total pressure shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showVelocities</i>:
+  Defines if velocities shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showDarcyFrictionNumber</i>:
+  Defines if the Darcy friction number shall be calculated (i.e., diagnostics).
+  </li>
+  <li>
+  <i>showIndividualPressureLosses</i>:
+  Defines if individual pressure losses shall be calculated (i.e., diagnostics).
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeroFriction;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/package.mo b/SorpLib/Components/Fittings/PressureLossCorrelations/package.mo
new file mode 100644
index 0000000..6c0694f
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/package.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Fittings;
+package PressureLossCorrelations "Package containing pressure loss correlations for hydraulic resistors"
+extends Modelica.Icons.FunctionsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains pressure loss correlations that can be used within resistance
+models. The pressure loss correlations calculate the pressure drop as a function
+of mass flow rate. Pressure loss correlations are implemented for the following
+resistance types:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside\">TubeInside</a>: 
+  Pressure loss correlations for fluids flowing through a tube.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber\">OpenAdsorber</a>: 
+  Pressure loss correlations for fluids flowing through an open adsorber containing, 
+  e.g., a packed bed.
+  </li>
+</ul>
+<p>
+Furthermore, a 'ZeroFriction' pressure loss correlation exists for generic resistance
+models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructering the library.
+  </li>
+</ul>
+</html>"));
+end PressureLossCorrelations;
diff --git a/SorpLib/Components/Fittings/PressureLossCorrelations/package.order b/SorpLib/Components/Fittings/PressureLossCorrelations/package.order
new file mode 100644
index 0000000..5dea82b
--- /dev/null
+++ b/SorpLib/Components/Fittings/PressureLossCorrelations/package.order
@@ -0,0 +1,3 @@
+TubeInside
+OpenAdsorber
+ZeroFriction
diff --git a/SorpLib/Components/Fittings/Records/FluidProperties.mo b/SorpLib/Components/Fittings/Records/FluidProperties.mo
new file mode 100644
index 0000000..32b6a90
--- /dev/null
+++ b/SorpLib/Components/Fittings/Records/FluidProperties.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.Fittings.Records;
+record FluidProperties
+  "This record contains fluid properties required for resistors"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T
+    "Temperature";
+  Modelica.Units.SI.Density rho
+    "Density";
+  Modelica.Units.SI.DynamicViscosity eta
+    "Dynamic viscosity";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains fluid properties required for resistances.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end FluidProperties;
diff --git a/SorpLib/Components/Fittings/Records/GeometryGenericReistance.mo b/SorpLib/Components/Fittings/Records/GeometryGenericReistance.mo
new file mode 100644
index 0000000..158724c
--- /dev/null
+++ b/SorpLib/Components/Fittings/Records/GeometryGenericReistance.mo
@@ -0,0 +1,73 @@
+within SorpLib.Components.Fittings.Records;
+record GeometryGenericReistance
+  "This record contains the geometry of generic resistors"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean dynamicPressureLoss = false
+    " = true, if dynamic pressure loss shall be included (i.e., different
+    velocities at port a and b due to change of cross-sectional areas)"
+    annotation (Dialog(tab="General", group="Calculation Setup", enable=false),
+                choices(checkBox=true),
+                Evaluate=true);
+  parameter Boolean geodeticPressureLoss = false
+    " = true, if geodetic pressure loss shall be included (i.e., different
+    heights at port a and b)"
+    annotation (Dialog(tab="General", group="Calculation Setup", enable=false),
+                choices(checkBox=true),
+                Evaluate=true);
+  parameter Boolean frictionPressureLoss = true
+    " = true, if pressure loss due to friction shall be included"
+    annotation (Dialog(tab="General", group="Calculation Setup", enable=false),
+                choices(checkBox=true),
+                Evaluate=true);
+  parameter Boolean fittingPressureLosss = false
+    " = true, if pressure losses due to fittings shall be included"
+    annotation (Dialog(tab="General", group="Calculation Setup", enable=false),
+                choices(checkBox=true),
+                Evaluate=true);
+
+  //
+  // Definition of parameters regarding the geometry
+  //
+  parameter Modelica.Units.SI.Length l = 1
+    "Length (i.e., distance between port a and b)"
+    annotation (Dialog(tab="General", group="Geometry",
+                enable=frictionPressureLoss));
+  parameter Modelica.Units.SI.Diameter d_hyd_a = 0.01
+    "Hydraulic diameter at port a"
+    annotation (Dialog(tab="General", group="Geometry",
+                enable=dynamicPressureLoss or frictionPressureLoss or
+                  fittingPressureLosss));
+  parameter Modelica.Units.SI.Diameter d_hyd_b = d_hyd_a
+    "Hydraulic diameter at port b"
+    annotation (Dialog(tab="General", group="Geometry",
+                enable=dynamicPressureLoss or frictionPressureLoss or
+                  fittingPressureLosss));
+  parameter Modelica.Units.SI.Height z_a = 1
+    "Height at port a (only relevant if geodetic pressure loss is included)"
+    annotation (Dialog(tab="General", group="Geometry",
+                enable=geodeticPressureLoss));
+  parameter Modelica.Units.SI.Height z_b = z_a
+    "Height at port b (only relevant if geodetic pressure loss is included)"
+    annotation (Dialog(tab="General", group="Geometry",
+                enable=geodeticPressureLoss));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by all hydraulic resistors.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryGenericReistance;
diff --git a/SorpLib/Components/Fittings/Records/GeometryOpenAdsorber.mo b/SorpLib/Components/Fittings/Records/GeometryOpenAdsorber.mo
new file mode 100644
index 0000000..0215cde
--- /dev/null
+++ b/SorpLib/Components/Fittings/Records/GeometryOpenAdsorber.mo
@@ -0,0 +1,37 @@
+within SorpLib.Components.Fittings.Records;
+record GeometryOpenAdsorber
+  "This record contains the geometry of resistors for open adsorber"
+  extends SorpLib.Components.Fittings.Records.GeometryGenericReistance;
+
+  //
+  // Definition of parameters regarding the geometry
+  //
+  parameter Modelica.Units.SI.Diameter d_particle = 0.7 / 1000
+    "Diameter of the adsorbent particle"
+    annotation (Dialog(tab="General", group="Geometry"));
+  parameter Real psi(unit="1") = 0.32
+    "Void fraction of the open adsorber (i.e., 1 for free adsorber)"
+    annotation (Dialog(tab="General", group="Geometry"));
+  parameter Integer no_hydraulicParallelFlows = 1
+    "Number of hydraulically parallel flows (e.g., for heat exchanger tubes)"
+    annotation (Dialog(tab="General", group="Geometry",
+                enable=dynamicPressureLoss or frictionPressureLoss or
+                  fittingPressureLosss));
+
+  //
+  // Annotations
+  //
+    annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by hydraulic resistors for
+open adsorbers.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryOpenAdsorber;
diff --git a/SorpLib/Components/Fittings/Records/GeometryTube.mo b/SorpLib/Components/Fittings/Records/GeometryTube.mo
new file mode 100644
index 0000000..838e2e9
--- /dev/null
+++ b/SorpLib/Components/Fittings/Records/GeometryTube.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Fittings.Records;
+record GeometryTube
+  "This record contains the geometry of resistors for tubes"
+  extends SorpLib.Components.Fittings.Records.GeometryGenericReistance;
+
+  //
+  // Definition of parameters regarding the geometry
+  //
+  parameter Modelica.Units.SI.Length roughness = 7.5e-7
+    "Absolute roughness of tubes"
+    annotation (Dialog(tab="General", group="Geometry",
+                enable=frictionPressureLoss));
+  parameter Integer no_hydraulicParallelFlows = 1
+    "Number of hydraulically parallel flows (e.g., for heat exchanger tubes)"
+    annotation (Dialog(tab="General", group="Geometry",
+                enable=dynamicPressureLoss or frictionPressureLoss or
+                  fittingPressureLosss));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by hydraulic resistors for
+tubes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryTube;
diff --git a/SorpLib/Components/Fittings/Records/package.mo b/SorpLib/Components/Fittings/Records/package.mo
new file mode 100644
index 0000000..14be88b
--- /dev/null
+++ b/SorpLib/Components/Fittings/Records/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Fittings;
+package Records "Package containing records"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records. These records are used to cluster 
+variables and tidy up the model output.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Components/Fittings/Records/package.order b/SorpLib/Components/Fittings/Records/package.order
new file mode 100644
index 0000000..6827d69
--- /dev/null
+++ b/SorpLib/Components/Fittings/Records/package.order
@@ -0,0 +1,4 @@
+FluidProperties
+GeometryGenericReistance
+GeometryTube
+GeometryOpenAdsorber
diff --git a/SorpLib/Components/Fittings/Resistors/GasGenericResistance.mo b/SorpLib/Components/Fittings/Resistors/GasGenericResistance.mo
new file mode 100644
index 0000000..859e650
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/GasGenericResistance.mo
@@ -0,0 +1,448 @@
+within SorpLib.Components.Fittings.Resistors;
+model GasGenericResistance "Gas generic resistance"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialResistance(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX,
+    final frictionPressureLoss=false,
+    redeclare final model PressureLossModel =
+      SorpLib.Components.Fittings.PressureLossCorrelations.ZeroFriction,
+    fittingPressureLosss=true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.ThermodynamicState state_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)";
+  Medium.ThermodynamicState state_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+equation
+  //
+  // Calculate state properties (only if needed)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_a
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_b
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    if instreamingPropertiesByInput then
+      state_b_ad = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet or
+    positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  else
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=port_b.p,
+      h=inStream(port_a.h_outflow),
+      X=inStream(port_a.Xi_outflow))
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = Medium.setState_phX(
+      p=port_a.p,
+      h=inStream(port_b.h_outflow),
+      X=inStream(port_b.Xi_outflow))
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  end if;
+
+  //
+  // Pass and calculate further state properties
+  //
+  if positionFluidProperties==
+     SorpLib.Choices.ResistorFluidProperties.Constant then
+    fluidProperties_a.p = p_ref
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = T_ref
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = rho_ref
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = eta_ref
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = p_ref
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = T_ref
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = rho_ref
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = p_ref
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = T_ref
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = rho_ref
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = p_ref
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = T_ref
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = rho_ref
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = eta_ref
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  else
+    fluidProperties_a.p = if not instreamingPropertiesByInput then
+      port_a.p else p_a_internal
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_a) else T_a_internal
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_a) else rho_a_internal
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a) else eta_ref) else eta_a_internal
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = port_b.p
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = Medium.temperature(state=state_b)
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = Medium.density(state=state_b)
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b) else eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = port_a.p
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = Medium.temperature(state=state_a_ad)
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = Medium.density(state=state_a_ad)
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a_ad) else eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = if not instreamingPropertiesByInput then
+      port_b.p else p_b_ad_internal
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_b_ad) else T_b_ad_internal
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_b_ad) else rho_b_ad_internal
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b_ad) else eta_ref) else eta_b_ad_internal
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The gas generic resistance can be used to describe dynamic, geodetic, and
+fitting-based pressure losses. Friction-based pressure losses are not considered.
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+This model assumes zero friction, so it does not calculate friction-based
+pressure losses:
+</p>
+<pre>
+    &lambda; = 0;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The generic resistance is typically used to described pressure losses caused
+by fittings, e.g., sliders, bends, or changes in cross-section.
+</p>
+
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>instreamingPropertiesByInput</i>:
+  Defines if the instreaming fluid properties are provided via an input, so
+  they do not need to be calculated internally.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <li>
+  <i>dynamicPressureLoss</i>:
+  Defines if dynamic pressure losses are considered.
+  </li>
+  <li>
+  <i>geodeticPressureLoss</i>:
+  Defines if geodetic pressure losses are considered.
+  </li>
+  <li>
+  <i>fittingPressureLosss</i>:
+  Defines if fitting-based pressure losses are considered.
+  </li>
+  <br/>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end GasGenericResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/GasOpenAdsorberResistance.mo b/SorpLib/Components/Fittings/Resistors/GasOpenAdsorberResistance.mo
new file mode 100644
index 0000000..bfb37e4
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/GasOpenAdsorberResistance.mo
@@ -0,0 +1,461 @@
+within SorpLib.Components.Fittings.Resistors;
+model GasOpenAdsorberResistance "Gas resistance for open adsorbers"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialResistance(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX,
+    redeclare replaceable model PressureLossModel =
+      SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber.ZeroFriction
+      constrainedby
+      SorpLib.Components.Fittings.BaseClasses.PartialOpenAdsorberPressureLoss,
+    redeclare replaceable parameter SorpLib.Components.Fittings.Records.GeometryOpenAdsorber geometry
+      constrainedby SorpLib.Components.Fittings.Records.GeometryOpenAdsorber);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.ThermodynamicState state_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)";
+  Medium.ThermodynamicState state_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+equation
+  //
+  // Calculate state properties (only if needed)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_a
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_b
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    if instreamingPropertiesByInput then
+      state_b_ad = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet or
+    positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  else
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=port_b.p,
+      h=inStream(port_a.h_outflow),
+      X=inStream(port_a.Xi_outflow))
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = Medium.setState_phX(
+      p=port_a.p,
+      h=inStream(port_b.h_outflow),
+      X=inStream(port_b.Xi_outflow))
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  end if;
+
+  //
+  // Pass and calculate further state properties
+  //
+  if positionFluidProperties==
+     SorpLib.Choices.ResistorFluidProperties.Constant then
+    fluidProperties_a.p = p_ref
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = T_ref
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = rho_ref
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = eta_ref
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = p_ref
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = T_ref
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = rho_ref
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = p_ref
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = T_ref
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = rho_ref
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = p_ref
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = T_ref
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = rho_ref
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = eta_ref
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  else
+    fluidProperties_a.p = if not instreamingPropertiesByInput then
+      port_a.p else p_a_internal
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_a) else T_a_internal
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_a) else rho_a_internal
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a) else eta_ref) else eta_a_internal
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = port_b.p
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = Medium.temperature(state=state_b)
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = Medium.density(state=state_b)
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b) else eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = port_a.p
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = Medium.temperature(state=state_a_ad)
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = Medium.density(state=state_a_ad)
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a_ad) else eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = if not instreamingPropertiesByInput then
+      port_b.p else p_b_ad_internal
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_b_ad) else T_b_ad_internal
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_b_ad) else rho_b_ad_internal
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b_ad) else eta_ref) else eta_b_ad_internal
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The gas resistance for open adsorbers can be used to describe dynamic, geodetic, friction-based
+and fitting-based pressure losses.
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+Different models can be used to calculate friction-based pressure losses. These models
+cover laminar and turbulent flow regimes and are valid for smooth or rough tubes. Please
+check
+<a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside\">SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside</a>
+for more information on available pressure loss correlations.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The resistance for open adsorbers is typically used to describe pressure losses within 
+open adsorbers.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>instreamingPropertiesByInput</i>:
+  Defines if the instreaming fluid properties are provided via an input, so
+  they do not need to be calculated internally.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <li>
+  <i>dynamicPressureLoss</i>:
+  Defines if dynamic pressure losses are considered.
+  </li>
+  <li>
+  <i>geodeticPressureLoss</i>:
+  Defines if geodetic pressure losses are considered.
+  </li>
+  <li>
+  <i>frictionPressureLosss</i>:
+  Defines if friction-based pressure losses are considered.
+  </li>
+  <li>
+  <i>fittingPressureLosss</i>:
+  Defines if fitting-based pressure losses are considered.
+  </li>
+  <br/>
+  <li>
+  <i>PressureLossModel</i>:
+  Defines the pressure loss model for the friction-based pressure loss.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasOpenAdsorberResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/GasTubeResistance.mo b/SorpLib/Components/Fittings/Resistors/GasTubeResistance.mo
new file mode 100644
index 0000000..035feab
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/GasTubeResistance.mo
@@ -0,0 +1,460 @@
+within SorpLib.Components.Fittings.Resistors;
+model GasTubeResistance "Gas tube resistance"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialResistance(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX,
+    redeclare replaceable model PressureLossModel =
+      SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.ZeroFriction
+      constrainedby
+      SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss,
+    redeclare replaceable parameter SorpLib.Components.Fittings.Records.GeometryTube geometry
+      constrainedby SorpLib.Components.Fittings.Records.GeometryTube);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.ThermodynamicState state_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)";
+  Medium.ThermodynamicState state_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+equation
+  //
+  // Calculate state properties (only if needed)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_a
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_b
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    if instreamingPropertiesByInput then
+      state_b_ad = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet or
+    positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  else
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=port_b.p,
+      h=inStream(port_a.h_outflow),
+      X=inStream(port_a.Xi_outflow))
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = Medium.setState_phX(
+      p=port_a.p,
+      h=inStream(port_b.h_outflow),
+      X=inStream(port_b.Xi_outflow))
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  end if;
+
+  //
+  // Pass and calculate further state properties
+  //
+  if positionFluidProperties==
+     SorpLib.Choices.ResistorFluidProperties.Constant then
+    fluidProperties_a.p = p_ref
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = T_ref
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = rho_ref
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = eta_ref
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = p_ref
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = T_ref
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = rho_ref
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = p_ref
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = T_ref
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = rho_ref
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = p_ref
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = T_ref
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = rho_ref
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = eta_ref
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  else
+    fluidProperties_a.p = if not instreamingPropertiesByInput then
+      port_a.p else p_a_internal
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_a) else T_a_internal
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_a) else rho_a_internal
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a) else eta_ref) else eta_a_internal
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = port_b.p
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = Medium.temperature(state=state_b)
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = Medium.density(state=state_b)
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b) else eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = port_a.p
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = Medium.temperature(state=state_a_ad)
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = Medium.density(state=state_a_ad)
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a_ad) else eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = if not instreamingPropertiesByInput then
+      port_b.p else p_b_ad_internal
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_b_ad) else T_b_ad_internal
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_b_ad) else rho_b_ad_internal
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b_ad) else eta_ref) else eta_b_ad_internal
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The gas tube resistance can be used to describe dynamic, geodetic, friction-based
+and fitting-based pressure losses.
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+Different models can be used to calculate friction-based pressure losses. These models
+cover laminar and turbulent flow regimes and are valid for smooth or rough tubes. Please
+check
+<a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside\">SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside</a>
+for more information on available pressure loss correlations.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The tube resistance is typically used to describe pressure losses within tubes.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>instreamingPropertiesByInput</i>:
+  Defines if the instreaming fluid properties are provided via an input, so
+  they do not need to be calculated internally.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <li>
+  <i>dynamicPressureLoss</i>:
+  Defines if dynamic pressure losses are considered.
+  </li>
+  <li>
+  <i>geodeticPressureLoss</i>:
+  Defines if geodetic pressure losses are considered.
+  </li>
+  <li>
+  <i>frictionPressureLosss</i>:
+  Defines if friction-based pressure losses are considered.
+  </li>
+  <li>
+  <i>fittingPressureLosss</i>:
+  Defines if fitting-based pressure losses are considered.
+  </li>
+  <br/>
+  <li>
+  <i>PressureLossModel</i>:
+  Defines the pressure loss model for the friction-based pressure loss.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasTubeResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/LiquidGenericResistance.mo b/SorpLib/Components/Fittings/Resistors/LiquidGenericResistance.mo
new file mode 100644
index 0000000..571c910
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/LiquidGenericResistance.mo
@@ -0,0 +1,447 @@
+within SorpLib.Components.Fittings.Resistors;
+model LiquidGenericResistance "Liquid generic resistance"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialResistance(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX,
+    final frictionPressureLoss=false,
+    redeclare final model PressureLossModel =
+      SorpLib.Components.Fittings.PressureLossCorrelations.ZeroFriction,
+    fittingPressureLosss=true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.ThermodynamicState state_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)";
+  Medium.ThermodynamicState state_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+equation
+  //
+  // Calculate state properties (only if needed)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_a
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_b
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    if instreamingPropertiesByInput then
+      state_b_ad = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet or
+    positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  else
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=port_b.p,
+      h=inStream(port_a.h_outflow),
+      X=inStream(port_a.Xi_outflow))
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = Medium.setState_phX(
+      p=port_a.p,
+      h=inStream(port_b.h_outflow),
+      X=inStream(port_b.Xi_outflow))
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  end if;
+
+  //
+  // Pass and calculate further state properties
+  //
+  if positionFluidProperties==
+     SorpLib.Choices.ResistorFluidProperties.Constant then
+    fluidProperties_a.p = p_ref
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = T_ref
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = rho_ref
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = eta_ref
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = p_ref
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = T_ref
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = rho_ref
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = p_ref
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = T_ref
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = rho_ref
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = p_ref
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = T_ref
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = rho_ref
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = eta_ref
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  else
+    fluidProperties_a.p = if not instreamingPropertiesByInput then
+      port_a.p else p_a_internal
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_a) else T_a_internal
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_a) else rho_a_internal
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a) else eta_ref) else eta_a_internal
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = port_b.p
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = Medium.temperature(state=state_b)
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = Medium.density(state=state_b)
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b) else eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = port_a.p
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = Medium.temperature(state=state_a_ad)
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = Medium.density(state=state_a_ad)
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a_ad) else eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = if not instreamingPropertiesByInput then
+      port_b.p else p_b_ad_internal
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_b_ad) else T_b_ad_internal
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_b_ad) else rho_b_ad_internal
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b_ad) else eta_ref) else eta_b_ad_internal
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The liquid generic resistance can be used to describe dynamic, geodetic, and
+fitting-based pressure losses. Friction-based pressure losses are not considered.
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+This model assumes zero friction, so it does not calculate friction-based
+pressure losses:
+</p>
+<pre>
+    &lambda; = 0;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The generic resistance is typically used to described pressure losses caused
+by fittings, e.g., sliders, bends, or changes in cross-section.
+</p>
+
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>instreamingPropertiesByInput</i>:
+  Defines if the instreaming fluid properties are provided via an input, so
+  they do not need to be calculated internally.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <li>
+  <i>dynamicPressureLoss</i>:
+  Defines if dynamic pressure losses are considered.
+  </li>
+  <li>
+  <i>geodeticPressureLoss</i>:
+  Defines if geodetic pressure losses are considered.
+  </li>
+  <li>
+  <i>fittingPressureLosss</i>:
+  Defines if fitting-based pressure losses are considered.
+  </li>
+  <br/>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LiquidGenericResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/LiquidTubeResistance.mo b/SorpLib/Components/Fittings/Resistors/LiquidTubeResistance.mo
new file mode 100644
index 0000000..b5cfc4f
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/LiquidTubeResistance.mo
@@ -0,0 +1,460 @@
+within SorpLib.Components.Fittings.Resistors;
+model LiquidTubeResistance "Liquid tube resistance"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialResistance(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX,
+    redeclare replaceable model PressureLossModel =
+      SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.ZeroFriction
+      constrainedby
+      SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss,
+    redeclare replaceable parameter SorpLib.Components.Fittings.Records.GeometryTube geometry
+      constrainedby SorpLib.Components.Fittings.Records.GeometryTube);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.ThermodynamicState state_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)";
+  Medium.ThermodynamicState state_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+equation
+  //
+  // Calculate state properties (only if needed)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_a
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_b
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    if instreamingPropertiesByInput then
+      state_b_ad = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet or
+    positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  else
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=port_b.p,
+      h=inStream(port_a.h_outflow),
+      X=inStream(port_a.Xi_outflow))
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = Medium.setState_phX(
+      p=port_a.p,
+      h=inStream(port_b.h_outflow),
+      X=inStream(port_b.Xi_outflow))
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  end if;
+
+  //
+  // Pass and calculate further state properties
+  //
+  if positionFluidProperties==
+     SorpLib.Choices.ResistorFluidProperties.Constant then
+    fluidProperties_a.p = p_ref
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = T_ref
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = rho_ref
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = eta_ref
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = p_ref
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = T_ref
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = rho_ref
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = p_ref
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = T_ref
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = rho_ref
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = p_ref
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = T_ref
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = rho_ref
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = eta_ref
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  else
+    fluidProperties_a.p = if not instreamingPropertiesByInput then
+      port_a.p else p_a_internal
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_a) else T_a_internal
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_a) else rho_a_internal
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a) else eta_ref) else eta_a_internal
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = port_b.p
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = Medium.temperature(state=state_b)
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = Medium.density(state=state_b)
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b) else eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = port_a.p
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = Medium.temperature(state=state_a_ad)
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = Medium.density(state=state_a_ad)
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a_ad) else eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = if not instreamingPropertiesByInput then
+      port_b.p else p_b_ad_internal
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_b_ad) else T_b_ad_internal
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_b_ad) else rho_b_ad_internal
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b_ad) else eta_ref) else eta_b_ad_internal
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The liquid tube resistance can be used to describe dynamic, geodetic, friction-based
+and fitting-based pressure losses.
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+Different models can be used to calculate friction-based pressure losses. These models
+cover laminar and turbulent flow regimes and are valid for smooth or rough tubes. Please
+check
+<a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside\">SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside</a>
+for more information on available pressure loss correlations.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The tube resistance is typically used to describe pressure losses within tubes.
+</p>
+
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>instreamingPropertiesByInput</i>:
+  Defines if the instreaming fluid properties are provided via an input, so
+  they do not need to be calculated internally.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <li>
+  <i>dynamicPressureLoss</i>:
+  Defines if dynamic pressure losses are considered.
+  </li>
+  <li>
+  <i>geodeticPressureLoss</i>:
+  Defines if geodetic pressure losses are considered.
+  </li>
+  <li>
+  <i>frictionPressureLosss</i>:
+  Defines if friction-based pressure losses are considered.
+  </li>
+  <li>
+  <i>fittingPressureLosss</i>:
+  Defines if fitting-based pressure losses are considered.
+  </li>
+  <br/>
+  <li>
+  <i>PressureLossModel</i>:
+  Defines the pressure loss model for the friction-based pressure loss.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LiquidTubeResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_GasGenericResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasGenericResistance.mo
new file mode 100644
index 0000000..7c853ff
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasGenericResistance.mo
@@ -0,0 +1,115 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_GasGenericResistance
+  "Tester for the gas generic resistance"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGases.N2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium model of the ideal gas"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.GasGenericResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.Constant,
+    dynamicPressureLoss=true,
+    geodeticPressureLoss=true,
+    instreamingPropertiesByInput=false,
+    fittingPressureLosss=true,
+    rho_ref(displayUnit="kg/m3"),
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_a=0.15,
+      d_hyd_b=0.1,
+      z_a=9,
+      z_b=10),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=1,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{
+          -70,0},{-70,2},{-61.2,2}},
+                                   color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,5},
+          {61.2,5}},  color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=2500,
+      Tolerance=1e-06),       Documentation(info="<html>
+<p>
+This model checks the gas generic resistance model using an ideal gas.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasGenericResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_GasOpenAdsorberResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasOpenAdsorberResistance.mo
new file mode 100644
index 0000000..cd737e4
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasOpenAdsorberResistance.mo
@@ -0,0 +1,128 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_GasOpenAdsorberResistance
+  "Tester for the gas resistance for open adsorbers"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGases.N2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium model of the ideal gas"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model PressureLossModel =
+    SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber.Kast
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialOpenAdsorberPressureLoss
+    "Pressure loss model"
+    annotation (Dialog(tab="General", group="Models"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.GasOpenAdsorberResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=false,
+    geodeticPressureLoss=false,
+    frictionPressureLoss=true,
+    fittingPressureLosss=false,
+    instreamingPropertiesByInput=false,
+    rho_ref(displayUnit="kg/m3"),
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_a=0.15,
+      z_a=9,
+      psi=0.5),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final model PressureLossModel = PressureLossModel,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=0.5,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{
+          -70,0},{-70,2},{-61.2,2}},
+                                   color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,5},
+          {61.2,5}},  color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=2500,
+      Tolerance=1e-06,
+      __Dymola_Algorithm="Dassl"),       Documentation(info="<html>
+<p>
+This model checks the gas resistance model for open adsorbers using an 
+ideal gas.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasOpenAdsorberResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_GasTubeResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasTubeResistance.mo
new file mode 100644
index 0000000..054a411
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasTubeResistance.mo
@@ -0,0 +1,122 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_GasTubeResistance "Tester for the gas tube resistance"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGases.N2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium model of the ideal gas"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model PressureLossModel =
+    SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.ConstantLambda
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss
+    "Pressure loss model"
+    annotation (Dialog(tab="General", group="Models"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.GasTubeResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=false,
+    geodeticPressureLoss=false,
+    frictionPressureLoss=true,
+    fittingPressureLosss=false,
+    instreamingPropertiesByInput=false,
+    rho_ref(displayUnit="kg/m3"),
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(d_hyd_a=0.15, z_a=9),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final model PressureLossModel = PressureLossModel,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=1,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,2},{-61.2,2}},   color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,5},
+          {61.2,5}},  color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=2500,
+      Tolerance=1e-06,
+      __Dymola_Algorithm="Dassl"),       Documentation(info="<html>
+<p>
+This model checks the gas tube resistance model using an ideal gas.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasTubeResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureGenericResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureGenericResistance.mo
new file mode 100644
index 0000000..182c210
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureGenericResistance.mo
@@ -0,0 +1,109 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_GasVaporMixtureGenericResistance
+  "Tester for the gas generic resistance"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.GasGenericResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dpFromMFlow=true,
+    dynamicPressureLoss=false,
+    geodeticPressureLoss=false,
+    instreamingPropertiesByInput=false,
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(d_hyd_a=0.15, z_a=9),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=1,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{
+          -70,0},{-70,2},{-61.2,2}},
+                                   color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,5},
+          {61.2,5}},  color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the gas generic resistance model using an ideal gas-vapor 
+mixture.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasVaporMixtureGenericResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureOpenAdsorberResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureOpenAdsorberResistance.mo
new file mode 100644
index 0000000..ed3c6c1
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureOpenAdsorberResistance.mo
@@ -0,0 +1,127 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_GasVaporMixtureOpenAdsorberResistance
+  "Tester for the gas resistance for open adsorbers"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model PressureLossModel =
+    SorpLib.Components.Fittings.PressureLossCorrelations.OpenAdsorber.Kast
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialOpenAdsorberPressureLoss
+    "Pressure loss model"
+    annotation (Dialog(tab="General", group="Models"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.GasOpenAdsorberResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=false,
+    geodeticPressureLoss=false,
+    frictionPressureLoss=true,
+    fittingPressureLosss=false,
+    instreamingPropertiesByInput=false,
+    rho_ref(displayUnit="kg/m3"),
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_a=0.15,
+      z_a=9,
+      psi=0.5),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final model PressureLossModel = PressureLossModel,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=0.5,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,2},{-61.2,2}},   color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,5},
+          {61.2,5}},  color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=2500,
+      Tolerance=1e-06,
+      __Dymola_Algorithm="Dassl"),       Documentation(info="<html>
+<p>
+This model checks the gas tube resistance model using an ideal gas-vapor 
+mixture.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasVaporMixtureOpenAdsorberResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureTubeResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureTubeResistance.mo
new file mode 100644
index 0000000..e32de3f
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_GasVaporMixtureTubeResistance.mo
@@ -0,0 +1,125 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_GasVaporMixtureTubeResistance
+  "Tester for the gas tube resistance"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model PressureLossModel =
+    SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Colebrook
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss
+    "Pressure loss model"
+    annotation (Dialog(tab="General", group="Models"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.GasTubeResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=false,
+    geodeticPressureLoss=false,
+    frictionPressureLoss=true,
+    fittingPressureLosss=false,
+    instreamingPropertiesByInput=false,
+    rho_ref(displayUnit="kg/m3"),
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(d_hyd_a=0.15, z_a=9),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final model PressureLossModel = PressureLossModel,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=1,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{
+          -70,0},{-70,2},{-61.2,2}},
+                                   color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,5},
+          {61.2,5}},  color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=2500,
+      Tolerance=1e-06,
+      __Dymola_Algorithm="Dassl"),       Documentation(info="<html>
+<p>
+This model checks the gas tube resistance model using an ideal gas-vapor 
+mixture.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasVaporMixtureTubeResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_LiquidGenericResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_LiquidGenericResistance.mo
new file mode 100644
index 0000000..8635ad5
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_LiquidGenericResistance.mo
@@ -0,0 +1,185 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_LiquidGenericResistance
+  "Tester for the liquid generic resistance"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,20},{-50,40}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,20},{50,40}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a_wVolume(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-40},{-50,-20}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b_wVolume(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-40},{50,-20}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.LiquidGenericResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=true,
+    geodeticPressureLoss=true,
+    instreamingPropertiesByInput=false,
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_b=0.008,
+      z_a=9,
+      z_b=10),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,20},{10,40}})));
+
+  SorpLib.Components.Fittings.Resistors.LiquidGenericResistance
+    resistance_wVolume(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=true,
+    geodeticPressureLoss=true,
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_b=0.008,
+      z_a=9,
+      z_b=10),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-40},{10,-20}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume volume_a(
+    p_initial=600000,
+    T_initial=288.15,
+    mc_flow_initialX=-1,
+    useHeatPorts=false,
+    useHeatPortsY=false,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial,
+                                                            nPorts_cfp_xMinus=1,
+      nPorts_cfp_xPlus=1,
+    redeclare final package Medium = Medium) "Volume at port a"
+    annotation (Placement(transformation(extent={{-40,-40},{-20,-20}})));
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume volume_b(
+    p_initial=500000,
+    T_initial=288.15,
+    mc_flow_initialX=-1,
+    useHeatPorts=false,
+    useHeatPortsY=false,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial,
+                                                            nPorts_cfp_xMinus=1,
+      nPorts_cfp_xPlus=1,
+    redeclare final package Medium = Medium) "Volume at port b"
+    annotation (Placement(transformation(extent={{20,-40},{40,-20}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=1,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,30},{-8,30}},
+      color={28,108,200},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,30},{60,30}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a_wVolume.port, volume_a.cfp_xMinus[1]) annotation (Line(
+      points={{-60,-30},{-50,-30},{-50,-28.2},{-34.2,-28.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(volume_a.cfp_xPlus[1], resistance_wVolume.port_a) annotation (Line(
+      points={{-22.2,-28.2},{-16,-28.2},{-16,-30},{-8,-30}},
+      color={28,108,200},
+      thickness=1));
+  connect(resistance_wVolume.port_b, volume_b.cfp_xMinus[1]) annotation (Line(
+      points={{8,-30},{16,-30},{16,-28.2},{25.8,-28.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(volume_b.cfp_xPlus[1], fs_b_wVolume.port) annotation (Line(
+      points={{37.8,-28.2},{50,-28.2},{50,-30},{60,-30}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,32},{-61.2,32}}, color={0,0,127}));
+  connect(input_m_flow.y, fs_a_wVolume.m_flow_input) annotation (Line(points={{-79,
+          0},{-70,0},{-70,-28},{-61.2,-28}}, color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,35},
+          {61.2,35}}, color={0,0,127}));
+  connect(input_p.y, fs_b_wVolume.p_input) annotation (Line(points={{79,0},{70,0},
+          {70,-25},{61.2,-25}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the liquid generic resistance model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidGenericResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_LiquidTubeResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_LiquidTubeResistance.mo
new file mode 100644
index 0000000..77ed3f8
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_LiquidTubeResistance.mo
@@ -0,0 +1,199 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_LiquidTubeResistance
+  "Tester for the liquid tube resistance"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model PressureLossModel =
+    SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Colebrook
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss
+    "Pressure loss model"
+    annotation (Dialog(tab="General", group="Models"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,20},{-50,40}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,20},{50,40}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a_wVolume(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-40},{-50,-20}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b_wVolume(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-40},{50,-20}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.LiquidTubeResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=true,
+    geodeticPressureLoss=true,
+    frictionPressureLoss=true,
+    instreamingPropertiesByInput=false,
+    redeclare final model PressureLossModel = PressureLossModel,
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_b=0.008,
+      z_a=9,
+      z_b=10),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,20},{10,40}})));
+
+  SorpLib.Components.Fittings.Resistors.LiquidTubeResistance
+    resistance_wVolume(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=true,
+    geodeticPressureLoss=true,
+    frictionPressureLoss=true,
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_b=0.008,
+      z_a=9,
+      z_b=10),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final model PressureLossModel = PressureLossModel,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-40},{10,-20}})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume volume_a(
+    p_initial=600000,
+    T_initial=288.15,
+    mc_flow_initialX=-1,
+    useHeatPorts=false,
+    useHeatPortsY=false,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial,
+                                                            nPorts_cfp_xMinus=1,
+      nPorts_cfp_xPlus=1,
+    redeclare final package Medium = Medium) "Volume at port a"
+    annotation (Placement(transformation(extent={{-40,-40},{-20,-20}})));
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume volume_b(
+    p_initial=500000,
+    T_initial=288.15,
+    mc_flow_initialX=-1,
+    useHeatPorts=false,
+    useHeatPortsY=false,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial,
+                                                            nPorts_cfp_xMinus=1,
+      nPorts_cfp_xPlus=1,
+    redeclare final package Medium = Medium) "Volume at port b"
+    annotation (Placement(transformation(extent={{20,-40},{40,-20}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=1,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,30},{-8,30}},
+      color={28,108,200},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,30},{60,30}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a_wVolume.port, volume_a.cfp_xMinus[1]) annotation (Line(
+      points={{-60,-30},{-50,-30},{-50,-28.2},{-34.2,-28.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(volume_a.cfp_xPlus[1], resistance_wVolume.port_a) annotation (Line(
+      points={{-22.2,-28.2},{-16,-28.2},{-16,-30},{-8,-30}},
+      color={28,108,200},
+      thickness=1));
+  connect(resistance_wVolume.port_b, volume_b.cfp_xMinus[1]) annotation (Line(
+      points={{8,-30},{16,-30},{16,-28.2},{25.8,-28.2}},
+      color={28,108,200},
+      thickness=1));
+  connect(volume_b.cfp_xPlus[1], fs_b_wVolume.port) annotation (Line(
+      points={{37.8,-28.2},{50,-28.2},{50,-30},{60,-30}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,32},{-61.2,32}}, color={0,0,127}));
+  connect(input_m_flow.y, fs_a_wVolume.m_flow_input) annotation (Line(points={{-79,
+          0},{-70,0},{-70,-28},{-61.2,-28}}, color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,35},
+          {61.2,35}}, color={0,0,127}));
+  connect(input_p.y, fs_b_wVolume.p_input) annotation (Line(points={{79,0},{70,0},
+          {70,-25},{61.2,-25}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the liquid tube resistance model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidTubeResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_VLEGenericResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_VLEGenericResistance.mo
new file mode 100644
index 0000000..6b9e7f4
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_VLEGenericResistance.mo
@@ -0,0 +1,109 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_VLEGenericResistance "Tester for the VLE generic resistance"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.VLESource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.VLEGenericResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=true,
+    geodeticPressureLoss=true,
+    instreamingPropertiesByInput=false,
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_b=0.008,
+      z_a=9,
+      z_b=10),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=1,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{
+          -70,0},{-70,2},{-61.2,2}},
+                                   color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,5},
+          {61.2,5}},  color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the VLE generic resistance model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_VLEGenericResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/Test_VLETubeResistance.mo b/SorpLib/Components/Fittings/Resistors/Tester/Test_VLETubeResistance.mo
new file mode 100644
index 0000000..da7b652
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/Test_VLETubeResistance.mo
@@ -0,0 +1,121 @@
+within SorpLib.Components.Fittings.Resistors.Tester;
+model Test_VLETubeResistance "Tester for the VLE tube resistance"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model PressureLossModel =
+    SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Colebrook
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss
+    "Pressure loss model"
+    annotation (Dialog(tab="General", group="Models"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.VLESource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Fittings.Resistors.VLETubeResistance resistance(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.ActualInlet,
+    dynamicPressureLoss=true,
+    geodeticPressureLoss=true,
+    frictionPressureLoss=true,
+    instreamingPropertiesByInput=false,
+    redeclare final model PressureLossModel = PressureLossModel,
+    flowDirectionDependentZeta=true,
+    zeta_b={0.1,0.1,0.1},
+    geometry(
+      d_hyd_b=0.008,
+      z_a=9,
+      z_b=10),
+    zeta_a={0.1,0.2,0.4},
+    m_flow_start=-1,
+    redeclare final package Medium = Medium)
+    "Resistance model without volumes at inlet and outlet"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+  Modelica.Blocks.Sources.Sine input_m_flow(
+    amplitude=1,
+    f=1/500,
+    phase=1.5707963267949,
+    offset=0)  "Input signal for mass flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=5e5,
+    duration=2500,
+    offset=5e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, resistance.port_a) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(resistance.port_b, fs_b.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_m_flow.y, fs_a.m_flow_input) annotation (Line(points={{-79,0},{
+          -70,0},{-70,2},{-61.2,2}},
+                                   color={0,0,127}));
+  connect(input_p.y, fs_b.p_input) annotation (Line(points={{79,0},{70,0},{70,5},
+          {61.2,5}},  color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the VLE tube resistance model.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_VLETubeResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/package.mo b/SorpLib/Components/Fittings/Resistors/Tester/package.mo
new file mode 100644
index 0000000..3e41d93
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Fittings.Resistors;
+package Tester "Models to test and varify multi port models"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented inertia inducers. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Fittings/Resistors/Tester/package.order b/SorpLib/Components/Fittings/Resistors/Tester/package.order
new file mode 100644
index 0000000..6bb858e
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/Tester/package.order
@@ -0,0 +1,10 @@
+Test_LiquidGenericResistance
+Test_LiquidTubeResistance
+Test_GasGenericResistance
+Test_GasVaporMixtureGenericResistance
+Test_GasTubeResistance
+Test_GasVaporMixtureTubeResistance
+Test_GasOpenAdsorberResistance
+Test_GasVaporMixtureOpenAdsorberResistance
+Test_VLEGenericResistance
+Test_VLETubeResistance
diff --git a/SorpLib/Components/Fittings/Resistors/VLEGenericResistance.mo b/SorpLib/Components/Fittings/Resistors/VLEGenericResistance.mo
new file mode 100644
index 0000000..1dc18c7
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/VLEGenericResistance.mo
@@ -0,0 +1,448 @@
+within SorpLib.Components.Fittings.Resistors;
+model VLEGenericResistance "VLE generic resistance"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialResistance(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX,
+    final frictionPressureLoss=false,
+    redeclare final model PressureLossModel =
+      SorpLib.Components.Fittings.PressureLossCorrelations.ZeroFriction,
+    fittingPressureLosss=true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.ThermodynamicState state_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)";
+  Medium.ThermodynamicState state_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+equation
+  //
+  // Calculate state properties (only if needed)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_a
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_b
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    if instreamingPropertiesByInput then
+      state_b_ad = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet or
+    positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  else
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=port_b.p,
+      h=inStream(port_a.h_outflow),
+      X=inStream(port_a.Xi_outflow))
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = Medium.setState_phX(
+      p=port_a.p,
+      h=inStream(port_b.h_outflow),
+      X=inStream(port_b.Xi_outflow))
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  end if;
+
+  //
+  // Pass and calculate further state properties
+  //
+  if positionFluidProperties==
+     SorpLib.Choices.ResistorFluidProperties.Constant then
+    fluidProperties_a.p = p_ref
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = T_ref
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = rho_ref
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = eta_ref
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = p_ref
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = T_ref
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = rho_ref
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = p_ref
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = T_ref
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = rho_ref
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = p_ref
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = T_ref
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = rho_ref
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = eta_ref
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  else
+    fluidProperties_a.p = if not instreamingPropertiesByInput then
+      port_a.p else p_a_internal
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_a) else T_a_internal
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_a) else rho_a_internal
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a) else eta_ref) else eta_a_internal
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = port_b.p
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = Medium.temperature(state=state_b)
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = Medium.density(state=state_b)
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b) else eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = port_a.p
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = Medium.temperature(state=state_a_ad)
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = Medium.density(state=state_a_ad)
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a_ad) else eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = if not instreamingPropertiesByInput then
+      port_b.p else p_b_ad_internal
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_b_ad) else T_b_ad_internal
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_b_ad) else rho_b_ad_internal
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b_ad) else eta_ref) else eta_b_ad_internal
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The VLE generic resistance can be used to describe dynamic, geodetic, and
+fitting-based pressure losses. Friction-based pressure losses are not considered.
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+This model assumes zero friction, so it does not calculate friction-based
+pressure losses:
+</p>
+<pre>
+    &lambda; = 0;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The generic resistance is typically used to described pressure losses caused
+by fittings, e.g., sliders, bends, or changes in cross-section.
+</p>
+
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>instreamingPropertiesByInput</i>:
+  Defines if the instreaming fluid properties are provided via an input, so
+  they do not need to be calculated internally.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <li>
+  <i>dynamicPressureLoss</i>:
+  Defines if dynamic pressure losses are considered.
+  </li>
+  <li>
+  <i>geodeticPressureLoss</i>:
+  Defines if geodetic pressure losses are considered.
+  </li>
+  <li>
+  <i>fittingPressureLosss</i>:
+  Defines if fitting-based pressure losses are considered.
+  </li>
+  <br/>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end VLEGenericResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/VLETubeResistance.mo b/SorpLib/Components/Fittings/Resistors/VLETubeResistance.mo
new file mode 100644
index 0000000..86841fa
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/VLETubeResistance.mo
@@ -0,0 +1,461 @@
+within SorpLib.Components.Fittings.Resistors;
+model VLETubeResistance "VLE tube resistance"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialResistance(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX,
+    redeclare replaceable model PressureLossModel =
+      SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.ZeroFriction
+      constrainedby
+      SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss,
+    redeclare replaceable parameter SorpLib.Components.Fittings.Records.GeometryTube geometry
+      constrainedby SorpLib.Components.Fittings.Records.GeometryTube);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.ThermodynamicState state_a
+    "Fluid properties at port a for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_b
+    "Fluid properties at port b for design flow direction (i.e., a->b)";
+  Medium.ThermodynamicState state_a_ad
+    "Fluid properties at port a for reverse design flow direction (i.e., a<-b)";
+  Medium.ThermodynamicState state_b_ad
+    "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+equation
+  //
+  // Calculate state properties (only if needed)
+  //
+  if positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.Constant then
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_a
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortAInlet then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+    state_b_ad = state_b
+      "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.PortBInlet then
+    if instreamingPropertiesByInput then
+      state_b_ad = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_a = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port a for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_b = state_a
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_a
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  elseif positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.ActualInlet or
+    positionFluidProperties==
+    SorpLib.Choices.ResistorFluidProperties.AverageInstreaming then
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=Medium.p_default,
+      h=Medium.specificEnthalpy_pTX(
+        p=Medium.p_default,
+        T=Medium.T_default,
+        X=Medium.X_default),
+      X=Medium.X_default)
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = state_b
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  else
+    if instreamingPropertiesByInput then
+      state_a = Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+        "Fluid properties at port a for design flow direction (i.e., a->b):
+        Not needed, so set dummy values";
+      state_b_ad = state_a
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b): 
+        Not needed, so set dummy values";
+
+    else
+      state_a = Medium.setState_phX(
+        p=port_a.p,
+        h=inStream(port_a.h_outflow),
+        X=inStream(port_a.Xi_outflow))
+        "Fluid properties at port a for design flow direction (i.e., a->b)";
+      state_b_ad = Medium.setState_phX(
+        p=port_b.p,
+        h=inStream(port_b.h_outflow),
+        X=inStream(port_b.Xi_outflow))
+       "Fluid properties at port b for reverse design flow direction (i.e., a<-b)";
+
+    end if;
+
+    state_b = Medium.setState_phX(
+      p=port_b.p,
+      h=inStream(port_a.h_outflow),
+      X=inStream(port_a.Xi_outflow))
+      "Fluid properties at port b for design flow direction (i.e., a->b):
+      Not needed, so set dummy values";
+    state_a_ad = Medium.setState_phX(
+      p=port_a.p,
+      h=inStream(port_b.h_outflow),
+      X=inStream(port_b.Xi_outflow))
+      "Fluid properties at port a for reverse design flow direction (i.e., a<-b): 
+      Not needed, so set dummy values";
+
+  end if;
+
+  //
+  // Pass and calculate further state properties
+  //
+  if positionFluidProperties==
+     SorpLib.Choices.ResistorFluidProperties.Constant then
+    fluidProperties_a.p = p_ref
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = T_ref
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = rho_ref
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = eta_ref
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = p_ref
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = T_ref
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = rho_ref
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = p_ref
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = T_ref
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = rho_ref
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = p_ref
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = T_ref
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = rho_ref
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = eta_ref
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  else
+    fluidProperties_a.p = if not instreamingPropertiesByInput then
+      port_a.p else p_a_internal
+      "Pressure at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_a) else T_a_internal
+      "Temperature at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_a) else rho_a_internal
+      "Density at port a for design flow direction (i.e., a->b)";
+    fluidProperties_a.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a) else eta_ref) else eta_a_internal
+      "Dynamic viscosity at port a for design flow direction (i.e., a->b)";
+
+    fluidProperties_b.p = port_b.p
+      "Pressure at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.T = Medium.temperature(state=state_b)
+      "Temperature at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.rho = Medium.density(state=state_b)
+      "Density at port b for design flow direction (i.e., a->b)";
+    fluidProperties_b.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b) else eta_ref
+      "Dynamic viscosity at port b for design flow direction (i.e., a->b)";
+
+    fluidProperties_a_ad.p = port_a.p
+      "Pressure at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.T = Medium.temperature(state=state_a_ad)
+      "Temperature at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.rho = Medium.density(state=state_a_ad)
+      "Density at port a for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_a_ad.eta = if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_a_ad) else eta_ref
+      "Dynamic viscosity at port a for reverse design flow direction (i.e., a<-b)";
+
+    fluidProperties_b_ad.p = if not instreamingPropertiesByInput then
+      port_b.p else p_b_ad_internal
+      "Pressure at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.T = if not instreamingPropertiesByInput then
+      Medium.temperature(state=state_b_ad) else T_b_ad_internal
+      "Temperature at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.rho = if not instreamingPropertiesByInput then
+      Medium.density(state=state_b_ad) else rho_b_ad_internal
+      "Density at port b for reverse design flow direction (i.e., a<-b)";
+    fluidProperties_b_ad.eta = if not instreamingPropertiesByInput then
+      (if pressureLossModel.requireTransportPropreties then
+      Medium.dynamicViscosity(state=state_b_ad) else eta_ref) else eta_b_ad_internal
+      "Dynamic viscosity at port b for reverse design flow direction (i.e., a<-b)";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The VLE tube resistance can be used to describe dynamic, geodetic, friction-based
+and fitting-based pressure losses.
+
+<h4>Main equations</h4>
+<p>
+The static pressure drop <i>&Delta;p<sub>static</sub></i> is calculated as a function 
+of the hydraulic mass flow rate <i>m&#x307;<sub>hyd</sub> </i> and follows from the 
+extended Bernoulli equation for incompressible fluids:
+</p>
+<pre>
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * [&rho;<sub>b</sub> * w<sub>b</sub><sup>2</sup> - &rho;<sub>a</sub> * w<sub>a</sub><sup>2</sup>] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * <SPAN STYLE=\"text-decoration:overline\">w</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+    
+    &Delta;p<sub>static</sub> = p<sub>a</sub> - p<sub>b</sub> = 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * [1 / (&rho;<sub>b</sub> * A<sub>b</sub><sup>2</sup>) - 1 / (&rho;<sub>a</sub> * A<sub>a</sub><sup>2</sup>)] + g * [&rho;<sub>b</sub> * z<sub>b</sub> - &rho;<sub>a</sub> * z<sub>a</sub>] + 1/2 * m&#x307;<sub>hyd</sub><sup>2</sup> * 1/<SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN> * 1/<SPAN STYLE=\"text-decoration:overline\">A</SPAN><sup>2</sup> * [&sum; &zeta;<sub>i</sub> + l/ <SPAN STYLE=\"text-decoration:overline\">d</SPAN> * &lambda;];
+</pre>
+<p>
+Herein, <i>&rho;<sub>a</sub></i>/<i>&rho;<sub>b</sub></i> describes the fluid density 
+at port a/b, <i>w<sub>a</sub></i>/<i>w<sub>b</sub></i> is the fluid velocity at port a/b, 
+<i>z<sub>a</sub></i>/<i>z<sub>b</sub></i> is geodetic height port a/b, and <i>A<sub>a</sub></i>/<i>A<sub>b</sub></i> 
+is the cross-sectional area at port a/b. The variable <i> <SPAN STYLE=\"text-decoration:overline\">&rho;</SPAN></i> 
+is the average fluid density, <i> <SPAN STYLE=\"text-decoration:overline\">A</SPAN></i> is 
+the average cross-sectional area, <i><SPAN STYLE=\"text-decoration:overline\">d</SPAN></i> 
+is the average diameter, <i> <SPAN STYLE=\"text-decoration:overline\">w</SPAN></i> is the
+average fluid velocity, <i>l</i> is the length, and <i>&lambda;</i> is the Darcy friction factor.
+<br/><br/>
+The used fluid properties can be selected via the option <i>positionFluidProperties</i>, 
+and it is possible to choose constant fluid properties or fluid properties at the current 
+flow inlet. Note that the equation of the static pressure loss is implemented both for 
+the design direction (a->b) and reverse the design direction (b->a) to enable flow reversal
+ via the numerically robust functions
+<a href=\"Modelica://SorpLib.Numerics.regStep\">SorpLib.Numerics.regStep</a> and
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+
+<h4>Friction-based pressure loss</h4>
+<p>
+Different models can be used to calculate friction-based pressure losses. These models
+cover laminar and turbulent flow regimes and are valid for smooth or rough tubes. Please
+check
+<a href=\"Modelica://SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside\">SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside</a>
+for more information on available pressure loss correlations.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state flow regime
+  </li>
+  <li>
+  Incompressible fluid (i.e., may not be applicable for gases/gas mixtures)
+  </li>
+  <li>
+  Applies along a streamline and not for an entire flow field
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The tube resistance is typically used to describe pressure losses within tubes.
+</p>
+
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>positionFluidProperties</i>:
+  Defines the position of the fluid property calculation used to calculate
+  pressure losses.
+  </li>
+  <li>
+  <i>instreamingPropertiesByInput</i>:
+  Defines if the instreaming fluid properties are provided via an input, so
+  they do not need to be calculated internally.
+  </li>
+  <li>
+  <i>dpFromMFlow</i>:
+  Defines if static pressure loss is calculated from hydraulic mass flow rate
+  or vice versa.
+  </li>
+  <li>
+  <i>dynamicPressureLoss</i>:
+  Defines if dynamic pressure losses are considered.
+  </li>
+  <li>
+  <i>geodeticPressureLoss</i>:
+  Defines if geodetic pressure losses are considered.
+  </li>
+  <li>
+  <i>frictionPressureLosss</i>:
+  Defines if friction-based pressure losses are considered.
+  </li>
+  <li>
+  <i>fittingPressureLosss</i>:
+  Defines if fitting-based pressure losses are considered.
+  </li>
+  <br/>
+  <li>
+  <i>PressureLossModel</i>:
+  Defines the pressure loss model for the friction-based pressure loss.
+  </li>
+  <li>
+  <i>flowDirectionDependentZeta</i>:
+  Defines if the fitting-caused pressure loss is dependent on the flow direction.
+  </li>
+  <li>
+  <i>geometry</i>:
+  Defines the resistance geometry required to calculate pressure losses.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 22, 2023, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end VLETubeResistance;
diff --git a/SorpLib/Components/Fittings/Resistors/package.mo b/SorpLib/Components/Fittings/Resistors/package.mo
new file mode 100644
index 0000000..f7e66e6
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/package.mo
@@ -0,0 +1,23 @@
+within SorpLib.Components.Fittings;
+package Resistors "Package containing hydraulic resistors"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains hydraulic resistors based on the Modelica Standard library 
+(MSL). Hydraulic resistors can be used to calculate pressure losses as a function 
+of mass flow rate and vice versa. These resistors can be used on their own, to 
+represent pressure losses caused by fittings. Alternatively,  these resistors can 
+be used in components such as pipes or open adsorbers to calculate pressure losses 
+due to friction, geostatic height differences, or cross-section changes (i.e., 
+velocity changes).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructering the library.
+  </li>
+</ul>
+</html>"));
+end Resistors;
diff --git a/SorpLib/Components/Fittings/Resistors/package.order b/SorpLib/Components/Fittings/Resistors/package.order
new file mode 100644
index 0000000..0805c81
--- /dev/null
+++ b/SorpLib/Components/Fittings/Resistors/package.order
@@ -0,0 +1,8 @@
+LiquidGenericResistance
+LiquidTubeResistance
+GasGenericResistance
+GasTubeResistance
+GasOpenAdsorberResistance
+VLEGenericResistance
+VLETubeResistance
+Tester
diff --git a/SorpLib/Components/Fittings/TJunctions/GasMixtureTJunction.mo b/SorpLib/Components/Fittings/TJunctions/GasMixtureTJunction.mo
new file mode 100644
index 0000000..e17d9e1
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/GasMixtureTJunction.mo
@@ -0,0 +1,316 @@
+within SorpLib.Components.Fittings.TJunctions;
+model GasMixtureTJunction "Gas mixture T-junction element"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTJunction(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final neglectTermVp = false,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=
+      Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=Medium.reference_X),
+    X_i_initial=Medium.reference_X,
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_independentMassBalances=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture
+    "Medium model of the ideal gas mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean idealGasMixture = true
+    " = true, if medium is an ideal gas mixture and govering equations are  
+    explicitly written for an ideal gas mixture"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity at constant pressure";
+  Modelica.Media.Common.IsobaricVolumeExpansionCoefficient beta
+    "Isobaric expnasion coefficient";
+  Modelica.Media.Common.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Media.Common.JouleThomsonCoefficient my
+    "Joule-Thomson coefficient";
+
+equation
+  //
+  // Assertations
+  //
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=X_i)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=X_i)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  rho = Medium.density(state=state)
+    "Density";
+
+  for ind in 1:no_components loop
+    h_i[ind] = Medium.specificEnthalpy_i_T(ind_component=ind, T=T)
+      "Specific enthalpy of individual components";
+  end for;
+
+  cp = if ((independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  beta = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  kappa = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  my = if (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp))) then
+    v / cp * (beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  //
+  // Mass balance
+  //
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dm_dtau = V * (Medium.density_derX(state=state) * der(X_i) +
+        rho * (kappa *der(p) - beta * der(T)))
+        "Transient overall mass balance";
+
+    else
+      if idealGasMixture then
+        dm_dtau = V * (rho * (kappa * der(p) - beta / cp * der(h)) +
+          (Medium.density_derX(state=state) .+ rho .* beta .*
+          h_i ./ cp) * der(X_i))
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = V * (rho * ((kappa - beta * my) * der(p) - beta / cp *
+          der(h)) + (Medium.density_derX(state=state) .+ rho .* beta .*
+          h_i ./ cp) * der(X_i))
+          "Transient overall mass balance";
+
+      end if;
+    end if;
+  end if;
+
+  //
+  // Energy balance
+  //
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if idealGasMixture then
+        dU_dtau = u * dm_dtau + m * ((cp - p * v * beta) * der(T) +
+          (h_i .+ p .* v.^2 .* Medium.density_derX(state=state)) * der(X_i))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (v * (p * kappa - T * beta) * der(p) +
+          (cp - p * v * beta) * der(T) + (h_i .+ p .* v.^2 .*
+          Medium.density_derX(state=state)) * der(X_i))
+          "Transient energy balance";
+
+      end if;
+
+    else
+      if idealGasMixture then
+        dU_dtau = u * dm_dtau + m * ((1 - p * v * beta / cp) * der(h) +
+          p .* v.^2 .* (Medium.density_derX(state=state) .+ rho .*
+          beta .* h_i ./ cp) * der(X_i))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * ((1 - p * v * beta / cp) * der(h) +
+          v * (p * (kappa - beta * my) - 1) * der(p) + p .* v.^2 .*
+          (Medium.density_derX(state=state) .+ rho .* beta .* h_i ./ cp) *
+          der(X_i))
+          "Transient energy balance";
+
+      end if;
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a gas mixture T-junction element, applying a lumped modeling 
+approach. This T-junction is used to connect three gas mixture flows, thereby 
+calculating mixing properties via (transient) mass and energy balances.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The main equations are a momentum balance and (transient) mass and energy balances.
+Independent states are either the pressure <i>p</i>, temperature <i>T</i>, and mass
+fractions </i>X_i</i> or the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass
+fractions </i>X_i</i>. The most important equations can be found in the documentation 
+of the model
+<a href=\"Modelica://SorpLib.Basics.Volumes.FluidVolumes.GasMixtureVolume\">SorpLib.Basics.Volumes.FluidVolumes.GasMixtureVolume</a>.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Ideal gas mixture
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to connect three medium flows. In this model, the mixing
+properties are calculated via (dynamic) mass and energy balances. Hence, this model acts
+like a PT1-element and can be used to break algebraic loops.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>idealGasMixture</i>:
+  Defines if the medium is an ideal gas mixture and, thus, the governing equations 
+  can be simplified.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_independentMassBalances</i>:
+  Defines the type of the independent mass balances.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has three dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> , temperature <i>T</i>, and mass fractions <i>X_i</i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions <i>X_i</i>.
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid property model is a single state model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end GasMixtureTJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/GasTJunction.mo b/SorpLib/Components/Fittings/TJunctions/GasTJunction.mo
new file mode 100644
index 0000000..77cb9d1
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/GasTJunction.mo
@@ -0,0 +1,303 @@
+within SorpLib.Components.Fittings.TJunctions;
+model GasTJunction "Gas T-junction element"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTJunction(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final neglectTermVp = false,
+    final X_i_initial=ones(no_components),
+    final type_independentMassBalances=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    h_initial=
+      Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=Medium.reference_X),
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = SorpLib.Media.IdealGases.N2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium model of the ideal gas"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean idealGas = true
+    " = true, if medium is an ideal gas and govering equations are explicitly 
+    written for an ideal gas"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity at constant pressure";
+  Modelica.Media.Common.IsobaricVolumeExpansionCoefficient beta
+    "Isobaric expnasion coefficient";
+  Modelica.Media.Common.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Media.Common.JouleThomsonCoefficient my
+    "Joule-Thomson coefficient";
+
+equation
+  //
+  // Assertations
+  //
+  assert(no_components <= 1,
+    "The gas volume model can only handel pure fluids (i.e., with one component)!",
+    level = AssertionLevel.error);
+
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  rho = Medium.density(state=state)
+    "Density";
+  h_i = fill(h, no_components)
+    "Specific enthalpy of individual components: Liquid T-junction can handle
+    only one component";
+
+  cp = if ((independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  beta = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  kappa = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  my = if (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp))) then
+    v / cp * (beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  //
+  // Mass balance
+  //
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dm_dtau = V * rho * (kappa *der(p) - beta * der(T))
+        "Transient overall mass balance";
+
+    else
+      if idealGas then
+        dm_dtau = V * rho * (kappa * der(p) - beta / cp * der(h))
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = V * rho * ((kappa - beta * my) * der(p) - beta / cp * der(h))
+        "Transient overall mass balance";
+
+      end if;
+    end if;
+  end if;
+
+  //
+  // Energy balance
+  //
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if idealGas then
+        dU_dtau = u * dm_dtau + m * ((cp - p * v * beta) * der(T))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (
+        v * (p * kappa - T * beta) * der(p) + (cp - p * v * beta) * der(T))
+        "Transient energy balance";
+
+      end if;
+
+    else
+      if idealGas then
+        dU_dtau = u * dm_dtau + m * ((1 - p * v * beta / cp) * der(h))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (
+        (1 - p * v * beta / cp) * der(h) +
+        v * (p * (kappa - beta * my) - 1) * der(p))
+        "Transient energy balance";
+
+      end if;
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a gas T-junction element, applying a lumped modeling 
+approach. This T-junction is used to connect three gas flows, thereby calculating
+mixing properties via (transient) mass and energy balances.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The main equations are a momentum balance and (transient) mass and energy balances.
+Independent states are either the pressure <i>p</i>, temperature <i>T</i>, and mass
+fractions </i>X_i</i> or the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass
+fractions </i>X_i</i>. The most important equations can be found in the documentation 
+of the model
+<a href=\"Modelica://SorpLib.Basics.Volumes.FluidVolumes.GasVolume\">SorpLib.Basics.Volumes.FluidVolumes.GasVolume</a>.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Ideal gas
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to connect three medium flows. In this model, the mixing
+properties are calculated via (dynamic) mass and energy balances. Hence, this model acts
+like a PT1-element and can be used to break algebraic loops.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>idealGas</i>:
+  Defines if the medium is an ideal gas and, thus, the governing equations can
+  be simplified.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has three dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> , temperature <i>T</i>, and mass fractions <i>X_i</i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions <i>X_i</i>.
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid property model is a single state model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end GasTJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/GasVaporMixtureTJunction.mo b/SorpLib/Components/Fittings/TJunctions/GasVaporMixtureTJunction.mo
new file mode 100644
index 0000000..d9ca884
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/GasVaporMixtureTJunction.mo
@@ -0,0 +1,325 @@
+within SorpLib.Components.Fittings.TJunctions;
+model GasVaporMixtureTJunction "Gas-vapor mixture T-junction element"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTJunction(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final neglectTermVp = false,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=
+      Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=Medium.reference_X),
+    X_i_initial=Medium.reference_X,
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_independentMassBalances=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture
+    "Medium model of the ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean idealGasVaporMixture = true
+    " = true, if medium is an ideal gas-vapoor mixture and govering equations are  
+    explicitly written for an ideal gas mixture (i.e., unsaturated air)"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity at constant pressure";
+  Modelica.Media.Common.IsobaricVolumeExpansionCoefficient beta
+    "Isobaric expnasion coefficient";
+  Modelica.Media.Common.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Media.Common.JouleThomsonCoefficient my
+    "Joule-Thomson coefficient";
+
+equation
+  //
+  // Assertations
+  //
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  if idealGasVaporMixture then
+    assert(Medium.relativeHumidity(state=state) < 1.0,
+      "Govering equations according to ideal gas mixture can only be applied if " +
+      "dry air is not saturatred! Results may not be reasonable!",
+      level = AssertionLevel.warning);
+
+  end if;
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=X_i)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=X_i)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  rho = Medium.density(state=state)
+    "Density";
+
+  for ind in 1:no_components loop
+    h_i[ind] = Medium.specificEnthalpy_i(ind_component=ind, state=state)
+      "Specific enthalpy of individual components";
+  end for;
+
+  cp = if ((independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  beta = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  kappa = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  my = if (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp))) then
+    v / cp * (beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  //
+  // Mass balance
+  //
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dm_dtau = V * (Medium.density_derX(state=state) * der(X_i) +
+        rho * (kappa *der(p) - beta * der(T)))
+        "Transient overall mass balance";
+
+    else
+      if idealGasVaporMixture then
+        dm_dtau = V * (rho * (kappa * der(p) - beta / cp * der(h)) +
+          (Medium.density_derX(state=state) .+ rho .* beta .*
+          Medium.dh_dX_pT(state=state) ./ cp) * der(X_i))
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = V * (rho * ((kappa - beta * my) * der(p) -
+          beta / cp * der(h)) + (Medium.density_derX(state=state) .+ rho .*
+          beta .* Medium.dh_dX_pT(state=state) ./ cp) * der(X_i))
+          "Transient overall mass balance";
+
+      end if;
+    end if;
+  end if;
+
+  //
+  // Energy balance
+  //
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if idealGasVaporMixture then
+        dU_dtau = u * dm_dtau + m * ((cp - p * v * beta) * der(T) +
+          (Medium.dh_dX_pT(state=state) .+ p .* v.^2 .*
+          Medium.density_derX(state=state)) * der(X_i))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * (v * (p * kappa - T * beta) * der(p) +
+          (cp - p * v * beta) * der(T) + (Medium.dh_dX_pT(state=state) .+ p .*
+          v.^2 .* Medium.density_derX(state=state)) * der(X_i))
+          "Transient energy balance";
+
+      end if;
+
+    else
+      if idealGasVaporMixture then
+        dU_dtau = u * dm_dtau + m * ((1 - p * v * beta / cp) * der(h) +
+          p .* v.^2 .* (Medium.density_derX(state=state) .+ rho .*
+          beta .* Medium.dh_dX_pT(state=state) ./ cp) * der(X_i))
+          "Transient energy balance";
+
+      else
+        dU_dtau = u * dm_dtau + m * ((1 - p * v * beta / cp) * der(h) +
+          v * (p * (kappa - beta * my) - 1) * der(p) + p .* v.^2 .*
+          (Medium.density_derX(state=state) .+ rho .* beta .*
+          Medium.dh_dX_pT(state=state) ./ cp) * der(X_i))
+          "Transient energy balance";
+
+      end if;
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a gas-vapor mixture T-junction element, applying a lumped 
+modeling approach. This T-junction is used to connect three gas-vapor mixture flows, 
+thereby calculating mixing properties via (transient) mass and energy balances.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The main equations are a momentum balance and (transient) mass and energy balances.
+Independent states are either the pressure <i>p</i>, temperature <i>T</i>, and mass
+fractions </i>X_i</i> or the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass
+fractions </i>X_i</i>. The most important equations can be found in the documentation 
+of the model
+<a href=\"Modelica://SorpLib.Basics.Volumes.FluidVolumes.GasVaporMixtureVolume\">SorpLib.Basics.Volumes.FluidVolumes.GasVaporMixtureVolume</a>.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+  <li>
+  Ideal gas-vapor mixture
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to connect three medium flows. In this model, the mixing
+properties are calculated via (dynamic) mass and energy balances. Hence, this model acts
+like a PT1-element and can be used to break algebraic loops.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>idealGasVaporMixture</i>:
+  Defines if the medium is an ideal gas-vapor mixture and, thus, the governing  
+  equations can be simplified.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_independentMassBalances</i>:
+  Defines the type of the independent mass balances.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has three dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> , temperature <i>T</i>, and mass fractions <i>X_i</i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions <i>X_i</i>.
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid property model is a single state model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end GasVaporMixtureTJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/LiquidTJunction.mo b/SorpLib/Components/Fittings/TJunctions/LiquidTJunction.mo
new file mode 100644
index 0000000..b7bfe76
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/LiquidTJunction.mo
@@ -0,0 +1,331 @@
+within SorpLib.Components.Fittings.TJunctions;
+model LiquidTJunction "Liquid T-junction element"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTJunction(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final X_i_initial=ones(no_components),
+    final type_independentMassBalances=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    h_initial=
+      Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=Medium.reference_X),
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Boolean incompressibleLiquid = Medium.singleState
+    " = true, if medium is incompressible (i.e., partial derivative of specific
+    volume w.r.t. pressure at constant temperature is constant) and govering
+    equations are explicitly written for an incompressible fluid"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity at constant pressure";
+  Modelica.Media.Common.IsobaricVolumeExpansionCoefficient beta
+    "Isobaric expnasion coefficient";
+  Modelica.Media.Common.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Media.Common.JouleThomsonCoefficient my
+    "Joule-Thomson coefficient";
+
+equation
+  //
+  // Assertations
+  //
+  assert(no_components <= 1,
+    "The liquid volume model can only handel pure fluids (i.e., with one component)!",
+    level = AssertionLevel.error);
+
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  rho = Medium.density(state=state)
+    "Density";
+  h_i = fill(h, no_components)
+    "Specific enthalpy of individual components: Liquid T-junction can handle
+    only one component";
+
+  cp = if ((independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  beta = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  kappa = if (not incompressibleLiquid and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp))) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  my = if (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp))) then
+    v / cp * (beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  //
+  // Mass balance
+  //
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if incompressibleLiquid then
+        dm_dtau = -V * rho * beta * der(T)
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = V * rho * (kappa *der(p) - beta * der(T))
+          "Transient overall mass balance";
+
+      end if;
+
+    else
+      if incompressibleLiquid then
+        dm_dtau = -V * rho * beta * (my * der(p) + 1 / cp * der(h))
+          "Transient overall mass balance";
+
+      else
+        dm_dtau = V * rho * ((kappa - beta * my) * der(p) - beta / cp * der(h))
+          "Transient overall mass balance";
+
+      end if;
+    end if;
+  end if;
+
+  //
+  // Energy balance
+  //
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      if neglectTermVp then
+        dU_dtau = u * dm_dtau +
+          m * (v * (1 - T * beta) * der(p) +
+          cp * der(T))
+          "Transient energy balance";
+
+      else
+        if incompressibleLiquid then
+          dU_dtau = u * dm_dtau +
+            m * (-v * T * beta * der(p) +
+            (cp - p * v * beta) * der(T))
+            "Transient energy balance";
+
+        else
+          dU_dtau = u * dm_dtau +
+            m * (v * (p * kappa - T * beta) * der(p) +
+            (cp - p * v * beta) * der(T))
+            "Transient energy balance";
+
+        end if;
+      end if;
+
+    else
+      if neglectTermVp then
+        dU_dtau = u * dm_dtau + m * der(h)
+          "Transient energy balance";
+
+      else
+        if incompressibleLiquid then
+          dU_dtau = u * dm_dtau +
+            m * ((1 - p * v * beta / cp) * der(h) -
+            v * (p * beta * my + 1) * der(p))
+            "Transient energy balance";
+
+        else
+          dU_dtau = u * dm_dtau +
+            m * ((1 - p * v * beta / cp) * der(h) +
+            v * (p * (kappa - beta * my) - 1) * der(p))
+            "Transient energy balance";
+
+        end if;
+      end if;
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a liquid T-junction element, applying a lumped modeling 
+approach. This T-junction is used to connect three liquid flows, thereby calculating
+mixing properties via (transient) mass and energy balances.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The main equations are a momentum balance and (transient) mass and energy balances.
+Independent states are either the pressure <i>p</i>, temperature <i>T</i>, and mass
+fractions </i>X_i</i> or the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass
+fractions </i>X_i</i>. The most important equations can be found in the documentation 
+of the model
+<a href=\"Modelica://SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume\">SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume</a>.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to connect three medium flows. In this model, the mixing
+properties are calculated via (dynamic) mass and energy balances. Hence, this model acts
+like a PT1-element and can be used to break algebraic loops.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <li>
+  <i>incompressibleLiquid</i>:
+  Defines if the medium is incompressible and the partial derivative of specific 
+  volume w.r.t. pressure at constant temperature is constant, thus leading to
+  simplified governing equations.
+  </li>
+  <li>
+  <i>neglectTermVp</i>:
+  Defines if the term 'p*V' is neglected to calculate specific internal energy.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has three dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> , temperature <i>T</i>, and mass fractions <i>X_i</i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions <i>X_i</i>.
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid property model is a single state model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LiquidTJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasMixtureTJunction.mo b/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasMixtureTJunction.mo
new file mode 100644
index 0000000..657e110
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasMixtureTJunction.mo
@@ -0,0 +1,106 @@
+within SorpLib.Components.Fittings.TJunctions.Tester;
+model Test_GasMixtureTJunction
+  "Tester for the gas mixture T-junction element"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=293.15,
+    redeclare package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-60})));
+  SorpLib.Basics.Sources.Fluids.GasSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 200000,
+    m_flow_fixed=0,
+    T_fixed=303.15,
+    redeclare package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource fs_c(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=313.15,
+    X_fixed={0.7,0.1,0.1,0.1},
+    redeclare package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O)
+    "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.TJunctions.GasMixtureTJunction TJunction
+    "T-junction element"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow_a(
+    amplitude=1,
+    f=1/250,
+    offset=0)
+    "Input signal for mass flow rate at port a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-80})));
+  Modelica.Blocks.Sources.Sine input_mFlow_c(
+    amplitude=-1,
+    f=1/250,
+    offset=0) "Input signal for mass flow rate at port c"
+    annotation (Placement(transformation(extent={{90,-10},{70,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, TJunction.port_a) annotation (Line(
+      points={{0,-60},{0,-7.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, TJunction.port_b) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(TJunction.port_c, fs_c.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_mFlow_a.y, fs_a.m_flow_input) annotation (Line(points={{0,-69},{
+          0,-66},{2,-66},{2,-61.2}}, color={0,0,127}));
+  connect(input_mFlow_c.y, fs_c.m_flow_input)
+    annotation (Line(points={{69,0},{66,0},{66,2},{61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the gas mixture T-junction element.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasMixtureTJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasTJunction.mo b/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasTJunction.mo
new file mode 100644
index 0000000..821a1d7
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasTJunction.mo
@@ -0,0 +1,101 @@
+within SorpLib.Components.Fittings.TJunctions.Tester;
+model Test_GasTJunction "Tester for the gas T-junction element"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=293.15,
+    redeclare package Medium = Media.IdealGases.N2)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-60})));
+  SorpLib.Basics.Sources.Fluids.GasSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 200000,
+    m_flow_fixed=0,
+    T_fixed=303.15,
+    redeclare package Medium = Media.IdealGases.N2)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasSource fs_c(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=313.15,
+    redeclare package Medium = Media.IdealGases.N2)
+    "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.TJunctions.GasTJunction TJunction
+    "T-junction element"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow_a(
+    amplitude=1,
+    f=1/250,
+    offset=0)
+    "Input signal for mass flow rate at port a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-80})));
+  Modelica.Blocks.Sources.Sine input_mFlow_c(
+    amplitude=-1,
+    f=1/250,
+    offset=0) "Input signal for mass flow rate at port c"
+    annotation (Placement(transformation(extent={{90,-10},{70,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, TJunction.port_a) annotation (Line(
+      points={{0,-60},{0,-7.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, TJunction.port_b) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(TJunction.port_c, fs_c.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_mFlow_a.y, fs_a.m_flow_input) annotation (Line(points={{0,-69},{
+          0,-66},{2,-66},{2,-61.2}}, color={0,0,127}));
+  connect(input_mFlow_c.y, fs_c.m_flow_input)
+    annotation (Line(points={{69,0},{66,0},{66,2},{61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the gas T-junction element.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasTJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasVaporMixtureTJunction.mo b/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasVaporMixtureTJunction.mo
new file mode 100644
index 0000000..e21a3c9
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/Tester/Test_GasVaporMixtureTJunction.mo
@@ -0,0 +1,101 @@
+within SorpLib.Components.Fittings.TJunctions.Tester;
+model Test_GasVaporMixtureTJunction
+  "Tester for the gas-vapor mixture T-junction element"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=293.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-60})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 200000,
+    m_flow_fixed=0,
+    T_fixed=303.15)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_c(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=373.15,
+    X_fixed={0.25,0.25,0.25,0.25})
+    "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.TJunctions.GasVaporMixtureTJunction TJunction(
+      idealGasVaporMixture=true)
+    "T-junction element"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow_a(
+    amplitude=1,
+    f=1/250,
+    offset=0)
+    "Input signal for mass flow rate at port a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-80})));
+  Modelica.Blocks.Sources.Sine input_mFlow_c(
+    amplitude=-1,
+    f=1/250,
+    offset=0) "Input signal for mass flow rate at port c"
+    annotation (Placement(transformation(extent={{90,-10},{70,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, TJunction.port_a) annotation (Line(
+      points={{0,-60},{0,-7.8}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, TJunction.port_b) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(TJunction.port_c, fs_c.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(input_mFlow_a.y, fs_a.m_flow_input) annotation (Line(points={{0,-69},{
+          0,-66},{2,-66},{2,-61.2}}, color={0,0,127}));
+  connect(input_mFlow_c.y, fs_c.m_flow_input)
+    annotation (Line(points={{69,0},{66,0},{66,2},{61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the gas-vapor mixture T-junction element.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasVaporMixtureTJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/Tester/Test_LiquidTJunction.mo b/SorpLib/Components/Fittings/TJunctions/Tester/Test_LiquidTJunction.mo
new file mode 100644
index 0000000..85e5d4a
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/Tester/Test_LiquidTJunction.mo
@@ -0,0 +1,97 @@
+within SorpLib.Components.Fittings.TJunctions.Tester;
+model Test_LiquidTJunction "Tester for the liquid T-junction element"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=293.15) "
+    Fluid source a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-60})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 200000,
+    T_fixed=303.15)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_c(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=313.15) "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.TJunctions.LiquidTJunction TJunction(
+      type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial)
+    "T-junction element"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow_a(
+    amplitude=1,
+    f=1/250,
+    offset=0)
+    "Input signal for mass flow rate at port a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-80})));
+  Modelica.Blocks.Sources.Sine input_mFlow_c(
+    amplitude=-1,
+    f=1/250,
+    offset=0) "Input signal for mass flow rate at port c"
+    annotation (Placement(transformation(extent={{90,-10},{70,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, TJunction.port_a) annotation (Line(
+      points={{0,-60},{0,-7.8}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, TJunction.port_b) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(TJunction.port_c, fs_c.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_mFlow_a.y, fs_a.m_flow_input) annotation (Line(points={{0,-69},{
+          0,-66},{2,-66},{2,-61.2}}, color={0,0,127}));
+  connect(input_mFlow_c.y, fs_c.m_flow_input)
+    annotation (Line(points={{69,0},{66,0},{66,2},{61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the liquid T-junction element.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidTJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/Tester/Test_VLETJunction.mo b/SorpLib/Components/Fittings/TJunctions/Tester/Test_VLETJunction.mo
new file mode 100644
index 0000000..1fcf03e
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/Tester/Test_VLETJunction.mo
@@ -0,0 +1,97 @@
+within SorpLib.Components.Fittings.TJunctions.Tester;
+model Test_VLETJunction "Tester for the VLE T-junction element"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=293.15) "
+    Fluid source a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-60})));
+  SorpLib.Basics.Sources.Fluids.VLESource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="bar") = 200000,
+    T_fixed=303.15)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.VLESource fs_c(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=313.15) "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Fittings.TJunctions.VLETJunction TJunction(
+      type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial)
+    "T-junction element"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow_a(
+    amplitude=1,
+    f=1/250,
+    offset=0)
+    "Input signal for mass flow rate at port a"
+    annotation (Placement(transformation(extent={{10,-10},{-10,10}},
+        rotation=270,
+        origin={0,-80})));
+  Modelica.Blocks.Sources.Sine input_mFlow_c(
+    amplitude=-1,
+    f=1/250,
+    offset=0) "Input signal for mass flow rate at port c"
+    annotation (Placement(transformation(extent={{90,-10},{70,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, TJunction.port_a) annotation (Line(
+      points={{0,-60},{0,-7.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, TJunction.port_b) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(TJunction.port_c, fs_c.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_mFlow_a.y, fs_a.m_flow_input) annotation (Line(points={{0,-69},{
+          0,-66},{2,-66},{2,-61.2}}, color={0,0,127}));
+  connect(input_mFlow_c.y, fs_c.m_flow_input)
+    annotation (Line(points={{69,0},{66,0},{66,2},{61.2,2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the VLE T-junction element.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end Test_VLETJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/Tester/package.mo b/SorpLib/Components/Fittings/TJunctions/Tester/package.mo
new file mode 100644
index 0000000..076cbc6
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/Tester/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Components.Fittings.TJunctions;
+package Tester "Models to test and varify multi port models"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented T-junction 
+elements. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Fittings/TJunctions/Tester/package.order b/SorpLib/Components/Fittings/TJunctions/Tester/package.order
new file mode 100644
index 0000000..c03fdd5
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/Tester/package.order
@@ -0,0 +1,5 @@
+Test_LiquidTJunction
+Test_GasTJunction
+Test_GasMixtureTJunction
+Test_GasVaporMixtureTJunction
+Test_VLETJunction
diff --git a/SorpLib/Components/Fittings/TJunctions/VLETJunction.mo b/SorpLib/Components/Fittings/TJunctions/VLETJunction.mo
new file mode 100644
index 0000000..e8d078c
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/VLETJunction.mo
@@ -0,0 +1,263 @@
+within SorpLib.Components.Fittings.TJunctions;
+model VLETJunction "VLE T-junction element"
+  extends SorpLib.Components.Fittings.BaseClasses.PartialTJunction(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX,
+    final pressureNoStateVariable = Medium.singleState,
+    final neglectTermVp = false,
+    final X_i_initial=ones(no_components),
+    final type_independentMassBalances=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    h_initial=
+      Medium.specificEnthalpy_pTX(p=p_initial, T=T_initial, X=Medium.reference_X),
+    type_overallMassBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    type_energyBalance=
+      SorpLib.Choices.BalanceEquations.TransientFixedInitial);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with a two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Medium.ThermodynamicState state
+    "Thermodynamic state required to calculate medium properties";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity at constant pressure";
+  Modelica.Media.Common.IsobaricVolumeExpansionCoefficient beta
+    "Isobaric expnasion coefficient";
+  Modelica.Media.Common.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Media.Common.JouleThomsonCoefficient my
+    "Joule-Thomson coefficient";
+
+equation
+  //
+  // Assertations
+  //
+  assert(no_components <= 1,
+    "The VLE volume model can only handel pure fluids (i.e., with one component)!",
+    level = AssertionLevel.error);
+
+  assert(pressureNoStateVariable or not (
+    type_energyBalance<>SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    type_overallMassBalance==SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial),
+    "Steady-state mass balance combined with transient energy balance is not " +
+    "sound if the fluid volume is fixed!",
+    level = AssertionLevel.warning);
+
+  //
+  // Calculation of properties
+  //
+  if independentStateVariables ==
+    SorpLib.Choices.IndependentVariablesVolume.pTX then
+    state = Medium.setState_pTX(p=p, T=T, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    h = Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+  else
+    state = Medium.setState_phX(p=p, h=h, X=Medium.reference_X)
+      "Thermodynamic state required to calculate medium properties";
+    T = Medium.temperature(state=state)
+      "Temperature";
+
+  end if;
+
+  rho = Medium.density(state=state)
+    "Density";
+  h_i = fill(h, no_components)
+    "Specific enthalpy of individual components: Liquid T-junction can handle
+    only one component";
+
+  cp = if ((independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.specificHeatCapacityCp(state=state) else 0
+    "Specific heat capacity";
+  beta = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.pTX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial) or
+    (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isobaricExpansionCoefficient(state=state) else 0
+    "Isobaric expnasion coefficient";
+  kappa = if (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp)) then
+    Medium.isothermalCompressibility(state=state) else 0
+    "Isothermal compressibility";
+  my = if (independentStateVariables==
+    SorpLib.Choices.IndependentVariablesVolume.phX and
+    (type_overallMassBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial or
+    (type_energyBalance<>
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial and
+    not neglectTermVp))) then
+    v / cp * (beta * T - 1) else 0
+    "Joule-Thomson coefficient";
+
+  //
+  // Mass balance
+  //
+  if type_overallMassBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dm_dtau = 0
+      "Steady-state overall mass balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dm_dtau = V * rho * (kappa *der(p) - beta * der(T))
+        "Transient overall mass balance";
+
+    else
+      dm_dtau = V * rho * ((kappa - beta * my) * der(p) - beta / cp * der(h))
+        "Transient overall mass balance";
+
+    end if;
+  end if;
+
+  //
+  // Energy balance
+  //
+  if type_energyBalance==
+    SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial then
+    dU_dtau = 0
+      "Steady-state energy balance";
+
+  else
+    if independentStateVariables==
+      SorpLib.Choices.IndependentVariablesVolume.pTX then
+      dU_dtau = u * dm_dtau + m * (v * (p * kappa - T * beta) * der(p) +
+        (cp - p * v * beta) * der(T))
+        "Transient energy balance";
+
+    else
+      dU_dtau = u * dm_dtau + m * ((1 - p * v * beta / cp) * der(h) +
+        v * (p * (kappa - beta * my) - 1) * der(p))
+        "Transient energy balance";
+
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model represents a VLE T-junction element, applying a lumped modeling approach. 
+This T-junction is used to connect three VLE flows, thereby calculating mixing properties 
+via (transient) mass and energy balances.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The main equations are a momentum balance and (transient) mass and energy balances.
+Independent states are either the pressure <i>p</i>, temperature <i>T</i>, and mass
+fractions </i>X_i</i> or the pressure <i>p</i>, specific enthalpy <i>h</i>, and mass
+fractions </i>X_i</i>. The most important equations can be found in the documentation 
+of the model
+<a href=\"Modelica://SorpLib.Basics.Volumes.FluidVolumes.VLEVolume\">SorpLib.Basics.Volumes.FluidVolumes.VLEVolume</a>.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Constant volume <i>V</i>
+  </li>
+  <li>
+  Homogenoues properties within the volume
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is typically used to connect three medium flows. In this model, the mixing
+properties are calculated via (dynamic) mass and energy balances. Hence, this model acts
+like a PT1-element and can be used to break algebraic loops.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>independentStateVariables</i>:
+  Defines independent state variables.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+<p>
+Note that not all combinations of govering equation types are reasonable. Typically,
+a transient mass balance is combined with a transient energy balance.
+</p>
+
+<h4>Dynamics</h4>
+<p>
+This model has three dynamic state that can be selected (see options):
+</p>
+<ul>
+  <li>
+  Pressure <i>p</i> , temperature <i>T</i>, and mass fractions <i>X_i</i> (recommended), or
+  </li>
+  <li>
+  pressure <i>p</i>, specific enthalpy <i>h</i>, and mass fractions <i>X_i</i>.
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid property model is a single state model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end VLETJunction;
diff --git a/SorpLib/Components/Fittings/TJunctions/package.mo b/SorpLib/Components/Fittings/TJunctions/package.mo
new file mode 100644
index 0000000..ccb863f
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Fittings;
+package TJunctions "Package containing T-junction elements"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains T-junction elements based on the Modelica Standard library 
+(MSL). These models may be used to connect three fluid flows.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TJunctions;
diff --git a/SorpLib/Components/Fittings/TJunctions/package.order b/SorpLib/Components/Fittings/TJunctions/package.order
new file mode 100644
index 0000000..8ae9319
--- /dev/null
+++ b/SorpLib/Components/Fittings/TJunctions/package.order
@@ -0,0 +1,6 @@
+LiquidTJunction
+GasTJunction
+GasMixtureTJunction
+GasVaporMixtureTJunction
+VLETJunction
+Tester
diff --git a/SorpLib/Components/Fittings/package.mo b/SorpLib/Components/Fittings/package.mo
new file mode 100644
index 0000000..a16b2e8
--- /dev/null
+++ b/SorpLib/Components/Fittings/package.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components;
+package Fittings "Adaptors for connections of fluid components and the regulation of fluid flow"
+  extends SorpLib.Icons.FittingsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package includes various models for fittings that can handle (ideal) liquids, 
+ideal gases, ideal gas mixtures, ideal gas-vapor mixtures, and real substances (i.e., 
+with a two-phase region). The following fittings are implemented:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.InertiaInducers\">InertiaInducers</a>: 
+  Inertia inducers may be used to describe the acceleration of a fluid caused by a 
+  sudden pressure change, thus also allowing to break algebraic loops.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.MultiPorts\">MultiPorts</a>: 
+  Multi port models may be used if several connections shall be made to one port. 
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.Resistors\">Resistors</a>: 
+  Hydraulic resistors can be used to calculate pressure losses as a function of mass 
+  flow rate and vice versa.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.Fittings.TJunctions\">TJunctions</a>: 
+  T-junction models may be used to connect three fluid flows.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Fittings;
diff --git a/SorpLib/Components/Fittings/package.order b/SorpLib/Components/Fittings/package.order
new file mode 100644
index 0000000..81198f0
--- /dev/null
+++ b/SorpLib/Components/Fittings/package.order
@@ -0,0 +1,7 @@
+BaseClasses
+Records
+PressureLossCorrelations
+InertiaInducers
+MultiPorts
+Resistors
+TJunctions
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/AdsorberDP.mo b/SorpLib/Components/HeatExchanger/Adsorbers/AdsorberDP.mo
new file mode 100644
index 0000000..15a578f
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/AdsorberDP.mo
@@ -0,0 +1,310 @@
+within SorpLib.Components.HeatExchanger.Adsorbers;
+model AdsorberDP
+  "Closed adsorber with pressure-driven mass trasnfer and vapor volume"
+  extends SorpLib.Components.HeatExchanger.BaseClasses.PartialPureComponentAdsorber(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    final no_components=MediumHX.nX,
+    final no_adsorptiveComponents=MediumAdsorptive.nX,
+    redeclare SorpLib.Components.Tubes.LiquidTube heatExchangerTubes(
+      redeclare package Medium = MediumHX,
+      redeclare model WallMaterial = WallMaterialHX),
+    redeclare SorpLib.Basics.Volumes.FluidVolumes.VLEVolume vaporVolume(
+      redeclare final package Medium = MediumAdsorptive,
+      final ms_flow_initial=m_flow_adsorptive_start,
+      final h_initial,
+      nPorts_cfp_xMinus=no_sorbentVolumes),
+    redeclare SorpLib.Basics.Volumes.SolidVolumes.SolidVolume casing(
+      redeclare final WallMaterialCS solidMedium,
+      redeclare final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+        dx=0,
+        dy=0,
+        dz=0,
+        A_xy=0,
+        A_xz=0,
+        A_yz=0,
+        V=geometry.V_wall_cas*geometry.no_hydraulicParallelTubes),
+      final T_initial=T_casingInitial,
+      final p=vaporVolume.fluidProperties.p,
+      independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX),
+    thermalConduction_casing1(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)),
+    thermalConduction_casing2(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)));
+
+  //
+  // Definition of parameters regarding the media
+  //
+  replaceable model WorkingPair =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+        redeclare replaceable package Medium = MediumAdsorptive)
+    "Working pair model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable package MediumHX =
+      Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid in the heat exchanger"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable package MediumAdsorptive = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of adsorptive"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model WallMaterialHX =
+      SorpLib.Media.Solids.MetalsAndMetalAlloys.Copper
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Heat exchanger wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable model WallMaterialCS =
+      Media.Solids.MetalsAndMetalAlloys.StainlessSteel_X5CrNi18_10
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Casing wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding transport phenomena
+  //
+  replaceable model MassTransferCoefficient =
+    MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow
+    constrainedby
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+    geometry=geometry)
+    "Model calculating the mass transfer coefficient"
+    annotation (Dialog(tab="Transport Phenomena", group="Mass Transfer"),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition and instantiation of models
+  //
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume[no_sorbentVolumes]
+    sorbentVolumes(
+    redeclare each final package Medium = MediumAdsorptive,
+    redeclare each final model PureWorkingPairModel = WorkingPair,
+    redeclare each final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+      dx=0,
+      dy=0,
+      dz=0,
+      A_xy=0,
+      A_xz=0,
+      A_yz=0,
+      V=geometry.V_particles*geometry.no_hydraulicParallelTubes),
+    each final m_sor_initial=m_sorInitial/geometry.no_sorbentVolumes,
+    each final T_initial=T_sorInitial,
+    each final x_initial=x_sorInitial,
+    each final msor_flow_initialX,
+    each final md_flow_initialX,
+    each final useAdsorbatePorts=false,
+    each final useDiffusivePorts=false,
+    each final useHeatPorts=false,
+    each final useHeatPortsX=false,
+    each final useHeatPortsY=false,
+    each final useHeatPortsZ=false,
+    each final ms_flow_initial=m_flow_adsorptive_start,
+    each final type_adsorbentMassBalance=type_overallMassBalance,
+    each final type_adsorptMassBalance=type_overallMassBalance,
+    each final type_energyBalance=type_energyBalance,
+    each final avoid_events=avoid_events,
+    each calcUptakeAveragedProperties=false,
+    each independentStateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+    each nSorptionPorts=1)
+    "Sorbent volumes"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={50,-30})));
+
+  SorpLib.Components.HeatTransfer.ClosedAdsorberHeatTransfer[min(no_sorbentVolumes,no_wallVolumes)]
+    heatTransfer_HeatExchangerToSorbentVolumes(
+    each final n_a=if no_wallVolumes > no_sorbentVolumes then factorDiscretization
+      else 1,
+    each final n_b=if no_wallVolumes < no_sorbentVolumes then factorDiscretization
+      else 1,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        VV_HeatExchanger,
+    final fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=sorbentVolumes.adsorbateProperties.p,
+      T=sorbentVolumes.adsorbateProperties.T,
+      rho=1 ./ sorbentVolumes.workingPair.medium_sorbent.state_variables.v,
+      cp=sorbentVolumes.workingPair.medium_sorbent.additional_variables.c,
+      eta=0,
+      lambda=sorbentVolumes.workingPair.medium_sorbent.additional_variables.lambda),
+    each final geometry=geometry)
+    "Heat transfer from heat exchanger to sorbent volumes"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={50,-54})));
+
+  SorpLib.Components.MassTransfer.VLEMassTransfers.ClosedAdsorberMassTransferDP[no_sorbentVolumes] massTransfer(
+    redeclare each final package Medium =MediumAdsorptive,
+    redeclare each final model MassTransferCoefficient =MassTransferCoefficient,
+    each final canBeActivated=false,
+    each final isFlapValve=false,
+    each final isFlowAB,
+    each final offset_dp,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    each final m_flow_start=m_flow_adsorptive_start,
+    each final avoid_events=avoid_events,
+    each final m_flow_small=m_flow_small,
+    each final noDiff=noDiff)
+    "Mass transfer between sorbent volumes and gas volume"
+    annotation (Placement(transformation(extent={{40,-20},{60,0}})));
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Components.HeatExchanger.Records.SummaryClosedAdsorber summary(
+    final p_vapor=vaporVolume.fluidProperties.p,
+    final T_vapor=vaporVolume.fluidProperties.T,
+    final rho_vapor=1/vaporVolume.fluidProperties.v,
+    final mass_vapor=vaporVolume.m,
+    final p_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.p)/
+      no_sorbentVolumes,
+    final T_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.T)/
+      no_sorbentVolumes,
+    final x_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.x_i[1])/
+      no_sorbentVolumes,
+    final mass_adsorpt=summary.x_adsorbate_avg*m_sorInitial,
+    final p_liq_inlet=heatExchangerTubes.state_a.p,
+    final p_liq_outlet=heatExchangerTubes.state_b.p,
+    final p_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.p)/
+        no_fluidVolumes,
+    final T_liq_inlet=heatExchangerTubes.state_a.T,
+    final T_liq_outlet=heatExchangerTubes.state_b.T,
+    final T_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.T)/
+        no_fluidVolumes,
+    final T_wall_avg=sum(heatExchangerTubes.wallVolumes.T)/
+      no_wallVolumes,
+    final m_flow_liq_inlet=port_a.m_flow,
+    final m_flow_liq_outlet=port_b.m_flow,
+    final m_flow_evaporator=evaporatorPort.m_flow,
+    final m_flow_condenser=condenserPort.m_flow,
+    final m_flow_massRecovery=sum(massRecoveryPorts.m_flow),
+    final Q_flow_wallToSorbent=heatExchangerTubes.Q_flow_wallHP,
+    final Q_flow_fluidWall=heatExchangerTubes.Q_flow_fluidWall,
+    final DH_liquid=heatExchangerTubes.DH_flow)
+    "Summary record";
+
+equation
+  //
+  // Connections of fluid ports
+  //
+  connect(massTransfer.port_b, sorbentVolumes.fp_sorption[1]) annotation (Line(
+        points={{58,-10},{70,-10},{70,-44},{51.6,-44},{51.6,-34.4}},
+                                                                 color={0,0,0}));
+  connect(massTransfer.port_a, vaporVolume.cfp_xMinus) annotation (Line(points={{42.2,
+          -10},{20,-10},{20,-20},{-1.8,-20},{-1.8,-4.2}},   color={0,0,0}));
+
+  //
+  // Connection of heat ports
+  //
+  if no_sorbentVolumes == no_wallVolumes then
+    //
+    // Identical discretization number
+    //
+    connect(heatExchangerTubes.hp_wall,
+      heatTransfer_HeatExchangerToSorbentVolumes.hp_a[1]) annotation (Line(
+        points={{50,-76},{50,-62}},
+        color={238,46,47},
+        thickness=1));
+    connect(heatTransfer_HeatExchangerToSorbentVolumes.hp_b[1],
+      sorbentVolumes.hp_sorption) annotation (Line(
+        points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+        color={238,46,47},
+        thickness=1));
+
+  elseif no_wallVolumes > no_sorbentVolumes then
+    //
+    // More wall volumes than sorbent volumes
+    //
+    for i in 1:no_sorbentVolumes loop
+      connect(heatExchangerTubes.hp_wall[1+(i-1)*factorDiscretization:i*factorDiscretization],
+      heatTransfer_HeatExchangerToSorbentVolumes[i].hp_a[1:factorDiscretization])
+        annotation (Line(
+          points={{50,-76},{50,-62}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+
+    connect(heatTransfer_HeatExchangerToSorbentVolumes.hp_b[1],
+      sorbentVolumes.hp_sorption) annotation (Line(
+        points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+        color={238,46,47},
+        thickness=1));
+
+  else
+    //
+    // More sorbent volumes than wall volumes
+    //
+    connect(heatExchangerTubes.hp_wall,
+      heatTransfer_HeatExchangerToSorbentVolumes.hp_a[1]) annotation (Line(
+        points={{50,-76},{50,-62}},
+        color={238,46,47},
+        thickness=1));
+
+    for i in 1:no_wallVolumes loop
+      connect(heatTransfer_HeatExchangerToSorbentVolumes[i].hp_b[1:factorDiscretization],
+        sorbentVolumes[1+(i-1)*factorDiscretization:i*factorDiscretization].hp_sorption)
+        annotation (Line(
+          points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED!
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library.
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorberDP;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/AdsorberDX.mo b/SorpLib/Components/HeatExchanger/Adsorbers/AdsorberDX.mo
new file mode 100644
index 0000000..0bbcc30
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/AdsorberDX.mo
@@ -0,0 +1,312 @@
+within SorpLib.Components.HeatExchanger.Adsorbers;
+model AdsorberDX
+  "Closed adsorber with loading-driven mass trasnfer and vapor volume"
+  extends SorpLib.Components.HeatExchanger.BaseClasses.PartialPureComponentAdsorber(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    final no_components=MediumHX.nX,
+    final no_adsorptiveComponents=MediumAdsorptive.nX,
+    redeclare SorpLib.Components.Tubes.LiquidTube heatExchangerTubes(
+      redeclare package Medium = MediumHX,
+      redeclare model WallMaterial = WallMaterialHX),
+    redeclare SorpLib.Basics.Volumes.FluidVolumes.VLEVolume vaporVolume(
+      redeclare final package Medium = MediumAdsorptive,
+      final ms_flow_initial=m_flow_adsorptive_start,
+      final h_initial,
+      nPorts_cfp_xMinus=no_sorbentVolumes),
+    redeclare SorpLib.Basics.Volumes.SolidVolumes.SolidVolume casing(
+      redeclare final WallMaterialCS solidMedium,
+      redeclare final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+        dx=0,
+        dy=0,
+        dz=0,
+        A_xy=0,
+        A_xz=0,
+        A_yz=0,
+        V=geometry.V_wall_cas*geometry.no_hydraulicParallelTubes),
+      final T_initial=T_casingInitial,
+      final p=vaporVolume.fluidProperties.p,
+      independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX),
+    thermalConduction_casing1(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)),
+    thermalConduction_casing2(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)));
+
+  //
+  // Definition of parameters regarding the media
+  //
+  replaceable model WorkingPair =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+        redeclare replaceable package Medium = MediumAdsorptive)
+    "Working pair model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable package MediumHX =
+      Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid in the heat exchanger"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable package MediumAdsorptive = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of adsorptive"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model WallMaterialHX =
+      SorpLib.Media.Solids.MetalsAndMetalAlloys.Copper
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Heat exchanger wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable model WallMaterialCS =
+      Media.Solids.MetalsAndMetalAlloys.StainlessSteel_X5CrNi18_10
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Casing wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding transport phenomena
+  //
+  replaceable model MassTransferCoefficient =
+    SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.GlueckaufArrhenius
+                                                                                                                           constrainedby
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDX(
+    geometry=geometry)
+    "Model calculating the mass transfer coefficient"
+    annotation (Dialog(tab="Transport Phenomena", group="Mass Transfer"),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition and instantiation of models
+  //
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume[no_sorbentVolumes]
+    sorbentVolumes(
+    redeclare each final package Medium = MediumAdsorptive,
+    redeclare each final model PureWorkingPairModel = WorkingPair,
+    redeclare each final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+      dx=0,
+      dy=0,
+      dz=0,
+      A_xy=0,
+      A_xz=0,
+      A_yz=0,
+      V=geometry.V_particles*geometry.no_hydraulicParallelTubes),
+    each final m_sor_initial=m_sorInitial/geometry.no_sorbentVolumes,
+    each final T_initial=T_sorInitial,
+    each final x_initial=x_sorInitial,
+    each final msor_flow_initialX,
+    each final md_flow_initialX,
+    each final useAdsorbatePorts=false,
+    each final useDiffusivePorts=false,
+    each final useHeatPorts=false,
+    each final useHeatPortsX=false,
+    each final useHeatPortsY=false,
+    each final useHeatPortsZ=false,
+    each final ms_flow_initial=m_flow_adsorptive_start,
+    each final type_adsorbentMassBalance=type_overallMassBalance,
+    each final type_adsorptMassBalance=type_overallMassBalance,
+    each final type_energyBalance=type_energyBalance,
+    each final avoid_events=avoid_events,
+    each calcUptakeAveragedProperties=false,
+    each independentStateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+    each nSorptionPorts=1)
+    "Sorbent volumes"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={50,-30})));
+
+  SorpLib.Components.HeatTransfer.ClosedAdsorberHeatTransfer[min(no_sorbentVolumes,no_wallVolumes)]
+    heatTransfer_HeatExchangerToSorbentVolumes(
+    each final n_a=if no_wallVolumes > no_sorbentVolumes then factorDiscretization
+      else 1,
+    each final n_b=if no_wallVolumes < no_sorbentVolumes then factorDiscretization
+      else 1,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        VV_HeatExchanger,
+    final fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=sorbentVolumes.adsorbateProperties.p,
+      T=sorbentVolumes.adsorbateProperties.T,
+      rho=1 ./ sorbentVolumes.workingPair.medium_sorbent.state_variables.v,
+      cp=sorbentVolumes.workingPair.medium_sorbent.additional_variables.c,
+      eta=0,
+      lambda=sorbentVolumes.workingPair.medium_sorbent.additional_variables.lambda),
+    each final geometry=geometry)
+    "Heat transfer from heat exchanger to sorbent volumes"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={50,-54})));
+
+  SorpLib.Components.MassTransfer.VLEMassTransfers.ClosedAdsorberMassTransferDX[no_sorbentVolumes] massTransfer(
+    redeclare each final package Medium =MediumAdsorptive,
+    redeclare each final model MassTransferCoefficient =MassTransferCoefficient,
+    final x_adsorpt_input=sorbentVolumes.x,
+    final T_adsorpt_input=sorbentVolumes.T,
+    each final canBeActivated=false,
+    each final isFlapValve=false,
+    each final isFlowAB,
+    each final offset_dp,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    each final m_flow_start=m_flow_adsorptive_start,
+    each final avoid_events=avoid_events,
+    each final m_flow_small=m_flow_small,
+    each final noDiff=noDiff)
+    "Mass transfer between sorbent volumes and gas volume"
+    annotation (Placement(transformation(extent={{40,-20},{60,0}})));
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Components.HeatExchanger.Records.SummaryClosedAdsorber summary(
+    final p_vapor=vaporVolume.fluidProperties.p,
+    final T_vapor=vaporVolume.fluidProperties.T,
+    final rho_vapor=1/vaporVolume.fluidProperties.v,
+    final mass_vapor=vaporVolume.m,
+    final p_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.p)/
+      no_sorbentVolumes,
+    final T_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.T)/
+      no_sorbentVolumes,
+    final x_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.x_i[1])/
+      no_sorbentVolumes,
+    final mass_adsorpt=summary.x_adsorbate_avg*m_sorInitial,
+    final p_liq_inlet=heatExchangerTubes.state_a.p,
+    final p_liq_outlet=heatExchangerTubes.state_b.p,
+    final p_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.p)/
+        no_fluidVolumes,
+    final T_liq_inlet=heatExchangerTubes.state_a.T,
+    final T_liq_outlet=heatExchangerTubes.state_b.T,
+    final T_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.T)/
+        no_fluidVolumes,
+    final T_wall_avg=sum(heatExchangerTubes.wallVolumes.T)/
+      no_wallVolumes,
+    final m_flow_liq_inlet=port_a.m_flow,
+    final m_flow_liq_outlet=port_b.m_flow,
+    final m_flow_evaporator=evaporatorPort.m_flow,
+    final m_flow_condenser=condenserPort.m_flow,
+    final m_flow_massRecovery=sum(massRecoveryPorts.m_flow),
+    final Q_flow_wallToSorbent=heatExchangerTubes.Q_flow_wallHP,
+    final Q_flow_fluidWall=heatExchangerTubes.Q_flow_fluidWall,
+    final DH_liquid=heatExchangerTubes.DH_flow)
+    "Summary record";
+
+equation
+  //
+  // Connections of fluid ports
+  //
+  connect(massTransfer.port_b, sorbentVolumes.fp_sorption[1]) annotation (Line(
+        points={{58,-10},{70,-10},{70,-44},{51.6,-44},{51.6,-34.4}},
+                                                                 color={0,0,0}));
+  connect(massTransfer.port_a, vaporVolume.cfp_xMinus) annotation (Line(points={{42.2,
+          -10},{20,-10},{20,-20},{-1.8,-20},{-1.8,-4.2}},   color={0,0,0}));
+
+  //
+  // Connection of heat ports
+  //
+  if no_sorbentVolumes == no_wallVolumes then
+    //
+    // Identical discretization number
+    //
+    connect(heatExchangerTubes.hp_wall,
+      heatTransfer_HeatExchangerToSorbentVolumes.hp_a[1]) annotation (Line(
+        points={{50,-76},{50,-62}},
+        color={238,46,47},
+        thickness=1));
+    connect(heatTransfer_HeatExchangerToSorbentVolumes.hp_b[1],
+      sorbentVolumes.hp_sorption) annotation (Line(
+        points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+        color={238,46,47},
+        thickness=1));
+
+  elseif no_wallVolumes > no_sorbentVolumes then
+    //
+    // More wall volumes than sorbent volumes
+    //
+    for i in 1:no_sorbentVolumes loop
+      connect(heatExchangerTubes.hp_wall[1+(i-1)*factorDiscretization:i*factorDiscretization],
+      heatTransfer_HeatExchangerToSorbentVolumes[i].hp_a[1:factorDiscretization])
+        annotation (Line(
+          points={{50,-76},{50,-62}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+
+    connect(heatTransfer_HeatExchangerToSorbentVolumes.hp_b[1],
+      sorbentVolumes.hp_sorption) annotation (Line(
+        points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+        color={238,46,47},
+        thickness=1));
+
+  else
+    //
+    // More sorbent volumes than wall volumes
+    //
+    connect(heatExchangerTubes.hp_wall,
+      heatTransfer_HeatExchangerToSorbentVolumes.hp_a[1]) annotation (Line(
+        points={{50,-76},{50,-62}},
+        color={238,46,47},
+        thickness=1));
+
+    for i in 1:no_wallVolumes loop
+      connect(heatTransfer_HeatExchangerToSorbentVolumes[i].hp_b[1:factorDiscretization],
+        sorbentVolumes[1+(i-1)*factorDiscretization:i*factorDiscretization].hp_sorption)
+        annotation (Line(
+          points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED!
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library.
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorberDX;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/SimpleAdsorberDP.mo b/SorpLib/Components/HeatExchanger/Adsorbers/SimpleAdsorberDP.mo
new file mode 100644
index 0000000..2effdcc
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/SimpleAdsorberDP.mo
@@ -0,0 +1,375 @@
+within SorpLib.Components.HeatExchanger.Adsorbers;
+model SimpleAdsorberDP
+  "Closed adsorber with pressure-driven mass transfer and without a vapor volume"
+  extends
+    SorpLib.Components.HeatExchanger.BaseClasses.PartialPureSimpleComponentAdsorber(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    final no_components=MediumHX.nX,
+    final no_adsorptiveComponents=MediumAdsorptive.nX,
+    redeclare SorpLib.Components.Fittings.MultiPorts.VLEMultiPort evaporatorSplitter(redeclare
+        final package Medium = MediumAdsorptive, no_ports_b=no_sorbentVolumes),
+    redeclare SorpLib.Components.Fittings.MultiPorts.VLEMultiPort condenserSplitter(redeclare
+        final package Medium = MediumAdsorptive, no_ports_b=no_sorbentVolumes),
+    redeclare SorpLib.Components.Fittings.MultiPorts.VLEMultiPort massRecoverySplitter(redeclare
+        final package Medium = MediumAdsorptive, no_ports_b=no_sorbentVolumes),
+    redeclare SorpLib.Components.Tubes.LiquidTube heatExchangerTubes(
+      redeclare package Medium = MediumHX,
+      redeclare model WallMaterial = WallMaterialHX),
+    redeclare SorpLib.Basics.Volumes.SolidVolumes.SolidVolume casing(
+      redeclare final WallMaterialCS solidMedium,
+      redeclare final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+        dx=0,
+        dy=0,
+        dz=0,
+        A_xy=0,
+        A_xz=0,
+        A_yz=0,
+        V=geometry.V_wall_cas*geometry.no_hydraulicParallelTubes),
+      final T_initial=T_casingInitial,
+      final p=summary.p_adsorbate_avg,
+      independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX),
+    thermalConduction_casing1(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)),
+    thermalConduction_casing2(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)));
+
+  //
+  // Definition of parameters regarding the media
+  //
+  replaceable model WorkingPair =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+        redeclare replaceable package Medium = MediumAdsorptive)
+    "Working pair model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable package MediumHX =
+      Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid in the heat exchanger"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable package MediumAdsorptive = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of adsorptive"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model WallMaterialHX =
+      SorpLib.Media.Solids.MetalsAndMetalAlloys.Copper
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Heat exchanger wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable model WallMaterialCS =
+      Media.Solids.MetalsAndMetalAlloys.StainlessSteel_X5CrNi18_10
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Casing wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding transport phenomena
+  //
+  replaceable model MassTransferCoefficientCondenser =
+    MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow
+    constrainedby
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+    geometry=geometry)
+    "Model calculating the mass transfer coefficient at the condenser port"
+    annotation (Dialog(tab="Transport Phenomena", group="Mass Transfer"),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+  replaceable model MassTransferCoefficientEvaporator =
+    MassTransferCoefficientCondenser
+    constrainedby
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+    geometry=geometry)
+    "Model calculating the mass transfer coefficient at the evaporator port"
+    annotation (Dialog(tab="Transport Phenomena", group="Mass Transfer"),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition and instantiation of models
+  //
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume[no_sorbentVolumes]
+    sorbentVolumes(
+    redeclare each final package Medium = MediumAdsorptive,
+    redeclare each final model PureWorkingPairModel = WorkingPair,
+    redeclare each final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+      dx=0,
+      dy=0,
+      dz=0,
+      A_xy=0,
+      A_xz=0,
+      A_yz=0,
+      V=geometry.V_particles*geometry.no_hydraulicParallelTubes),
+    each final m_sor_initial=m_sorInitial/geometry.no_sorbentVolumes,
+    each final T_initial=T_sorInitial,
+    each final x_initial=x_sorInitial,
+    each final msor_flow_initialX,
+    each final md_flow_initialX,
+    each final useAdsorbatePorts=false,
+    each final useDiffusivePorts=false,
+    each final useHeatPorts=false,
+    each final useHeatPortsX=false,
+    each final useHeatPortsY=false,
+    each final useHeatPortsZ=false,
+    each final ms_flow_initial=m_flow_adsorptive_start,
+    each final type_adsorbentMassBalance=type_overallMassBalance,
+    each final type_adsorptMassBalance=type_overallMassBalance,
+    each final type_energyBalance=type_energyBalance,
+    each final avoid_events=avoid_events,
+    each calcUptakeAveragedProperties=false,
+    each independentStateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+    each nSorptionPorts=if useMassRecoveryPorts then 3 else 2)
+    "Sorbent volumes"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={50,-30})));
+
+  SorpLib.Components.HeatTransfer.ClosedAdsorberHeatTransfer[min(no_sorbentVolumes,no_wallVolumes)]
+    heatTransfer_HeatExchangerToSorbentVolumes(
+    each final n_a=if no_wallVolumes > no_sorbentVolumes then factorDiscretization
+      else 1,
+    each final n_b=if no_wallVolumes < no_sorbentVolumes then factorDiscretization
+      else 1,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        VV_HeatExchanger,
+    final fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=sorbentVolumes.adsorbateProperties.p,
+      T=sorbentVolumes.adsorbateProperties.T,
+      rho=1 ./ sorbentVolumes.workingPair.medium_sorbent.state_variables.v,
+      cp=sorbentVolumes.workingPair.medium_sorbent.additional_variables.c,
+      eta=0,
+      lambda=sorbentVolumes.workingPair.medium_sorbent.additional_variables.lambda),
+    each final geometry=geometry)
+    "Heat transfer from heat exchanger to sorbent volumes"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={50,-54})));
+
+  SorpLib.Components.MassTransfer.VLEMassTransfers.ClosedAdsorberMassTransferDP[
+    no_sorbentVolumes] massTransferCondenser(
+    redeclare each final package Medium = MediumAdsorptive,
+    redeclare each final model MassTransferCoefficient =
+        MassTransferCoefficientCondenser,
+    each isFlapValve=true,
+    each isFlowAB=false,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    each final m_flow_start=m_flow_adsorptive_start,
+    each final avoid_events=avoid_events,
+    each final m_flow_small=m_flow_small,
+    each final noDiff=noDiff)
+    "Mass transfer between sorbent volumes and condenser port" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={60,0})));
+  SorpLib.Components.MassTransfer.VLEMassTransfers.ClosedAdsorberMassTransferDP[
+    no_sorbentVolumes] massTransferEvaporator(
+    redeclare each final package Medium = MediumAdsorptive,
+    redeclare each final model MassTransferCoefficient =
+        MassTransferCoefficientEvaporator,
+    each isFlapValve=true,
+    each isFlowAB=true,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    each final m_flow_start=m_flow_adsorptive_start,
+    each final avoid_events=avoid_events,
+    each final m_flow_small=m_flow_small,
+    each final noDiff=noDiff)
+    "Mass transfer between sorbent volumes and evaporator port" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,0})));
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Components.HeatExchanger.Records.SummarySimpleClosedAdsorber summary(
+    final p_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.p)/
+      no_sorbentVolumes,
+    final T_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.T)/
+      no_sorbentVolumes,
+    final x_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.x_i[1])/
+      no_sorbentVolumes,
+    final mass_adsorpt=summary.x_adsorbate_avg*m_sorInitial,
+    final p_liq_inlet=heatExchangerTubes.state_a.p,
+    final p_liq_outlet=heatExchangerTubes.state_b.p,
+    final p_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.p)/
+        no_fluidVolumes,
+    final T_liq_inlet=heatExchangerTubes.state_a.T,
+    final T_liq_outlet=heatExchangerTubes.state_b.T,
+    final T_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.T)/
+        no_fluidVolumes,
+    final T_wall_avg=sum(heatExchangerTubes.wallVolumes.T)/
+      no_wallVolumes,
+    final m_flow_liq_inlet=port_a.m_flow,
+    final m_flow_liq_outlet=port_b.m_flow,
+    final m_flow_evaporator=evaporatorPort.m_flow,
+    final m_flow_condenser=condenserPort.m_flow,
+    final m_flow_massRecovery=sum({sum(sorbentVolumes[i].fp_sorption.m_flow)
+     for i in 1:no_sorbentVolumes}) + evaporatorPort.m_flow+condenserPort.m_flow,
+    final Q_flow_wallToSorbent=heatExchangerTubes.Q_flow_wallHP,
+    final Q_flow_fluidWall=heatExchangerTubes.Q_flow_fluidWall,
+    final DH_liquid=heatExchangerTubes.DH_flow)
+    "Summary record";
+
+equation
+  //
+  // Connections of fluid portsuseMassRecoveryPorts
+  //
+  connect(massTransferCondenser.port_b, sorbentVolumes.fp_sorption[1])
+    annotation (Line(points={{60,-8},{60,-16},{70,-16},{70,-44},{51.6,-44},{51.6,
+          -34.4}}, color={0,0,0}));
+  connect(massTransferEvaporator.port_b, sorbentVolumes.fp_sorption[2])
+    annotation (Line(points={{0,-8},{0,-16},{70,-16},{70,-44},{51.6,-44},{51.6,-34.4}},
+                   color={0,0,0}));
+
+  if useMassRecoveryPorts then
+    connect(massRecoverySplitter.port_b, sorbentVolumes.fp_sorption[3])
+      annotation (Line(points={{0,-8},{0,-16},{70,-16},{70,-44},{51.6,-44},{51.6,-34.4}},
+                     color={0,0,0}));
+  end if;
+
+  connect(evaporatorPort, evaporatorSplitter.port_a) annotation (Line(
+      points={{-100,40},{0,40},{0,36}},
+      color={0,140,72},
+      thickness=1));
+  connect(condenserPort, condenserSplitter.port_a) annotation (Line(
+      points={{100,40},{60,40},{60,36}},
+      color={0,140,72},
+      thickness=1));
+  connect(massTransferEvaporator.port_a, evaporatorSplitter.ports_b)
+    annotation (Line(
+      points={{0,7.8},{0,24}},
+      color={0,140,72},
+      thickness=1));
+  connect(massTransferCondenser.port_a, condenserSplitter.ports_b) annotation (
+      Line(
+      points={{60,7.8},{60,24}},
+      color={0,140,72},
+      thickness=1));
+
+  //
+  // Connection of heat ports
+  //
+  if no_sorbentVolumes == no_wallVolumes then
+    //
+    // Identical discretization number
+    //
+    connect(heatExchangerTubes.hp_wall,
+      heatTransfer_HeatExchangerToSorbentVolumes.hp_a[1]) annotation (Line(
+        points={{50,-76},{50,-62}},
+        color={238,46,47},
+        thickness=1));
+    connect(heatTransfer_HeatExchangerToSorbentVolumes.hp_b[1],
+      sorbentVolumes.hp_sorption) annotation (Line(
+        points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+        color={238,46,47},
+        thickness=1));
+
+  elseif no_wallVolumes > no_sorbentVolumes then
+    //
+    // More wall volumes than sorbent volumes
+    //
+    for i in 1:no_sorbentVolumes loop
+      connect(heatExchangerTubes.hp_wall[1+(i-1)*factorDiscretization:i*factorDiscretization],
+      heatTransfer_HeatExchangerToSorbentVolumes[i].hp_a[1:factorDiscretization])
+        annotation (Line(
+          points={{50,-76},{50,-62}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+
+    connect(heatTransfer_HeatExchangerToSorbentVolumes.hp_b[1],
+      sorbentVolumes.hp_sorption) annotation (Line(
+        points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+        color={238,46,47},
+        thickness=1));
+
+  else
+    //
+    // More sorbent volumes than wall volumes
+    //
+    connect(heatExchangerTubes.hp_wall,
+      heatTransfer_HeatExchangerToSorbentVolumes.hp_a[1]) annotation (Line(
+        points={{50,-76},{50,-62}},
+        color={238,46,47},
+        thickness=1));
+
+    for i in 1:no_wallVolumes loop
+      connect(heatTransfer_HeatExchangerToSorbentVolumes[i].hp_b[1:factorDiscretization],
+        sorbentVolumes[1+(i-1)*factorDiscretization:i*factorDiscretization].hp_sorption)
+        annotation (Line(
+          points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+  end if;
+
+  connect(heatTransfer_sorbentVolumesToCasing.hp_a, sorbentVolumes.hp_sorption)
+    annotation (Line(
+      points={{-24,0},{-20,0},{-20,-20},{20,-20},{20,-44},{48.4,-44},{48.4,-37.6}},
+      color={238,46,47},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  connect(massRecoveryPorts, massRecoverySplitter.port_a) annotation (Line(
+      points={{0,60},{30,60},{30,36}},
+      color={0,140,72},
+      thickness=1));
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED!
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library.
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SimpleAdsorberDP;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/SimpleAdsorberDX.mo b/SorpLib/Components/HeatExchanger/Adsorbers/SimpleAdsorberDX.mo
new file mode 100644
index 0000000..288624c
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/SimpleAdsorberDX.mo
@@ -0,0 +1,374 @@
+within SorpLib.Components.HeatExchanger.Adsorbers;
+model SimpleAdsorberDX
+  "Closed adsorber with loading-driven mass transfer and without a vapor volume"
+  extends
+    SorpLib.Components.HeatExchanger.BaseClasses.PartialPureSimpleComponentAdsorber(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    final no_components=MediumHX.nX,
+    final no_adsorptiveComponents=MediumAdsorptive.nX,
+    redeclare SorpLib.Components.Fittings.MultiPorts.VLEMultiPort evaporatorSplitter(redeclare
+        final package Medium = MediumAdsorptive, no_ports_b=no_sorbentVolumes),
+    redeclare SorpLib.Components.Fittings.MultiPorts.VLEMultiPort condenserSplitter(redeclare
+        final package Medium = MediumAdsorptive, no_ports_b=no_sorbentVolumes),
+    redeclare SorpLib.Components.Fittings.MultiPorts.VLEMultiPort massRecoverySplitter(redeclare
+        final package Medium = MediumAdsorptive, no_ports_b=no_sorbentVolumes),
+    redeclare SorpLib.Components.Tubes.LiquidTube heatExchangerTubes(
+      redeclare package Medium = MediumHX,
+      redeclare model WallMaterial = WallMaterialHX),
+    redeclare SorpLib.Basics.Volumes.SolidVolumes.SolidVolume casing(
+      redeclare final WallMaterialCS solidMedium,
+      redeclare final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+        dx=0,
+        dy=0,
+        dz=0,
+        A_xy=0,
+        A_xz=0,
+        A_yz=0,
+        V=geometry.V_wall_cas*geometry.no_hydraulicParallelTubes),
+      final T_initial=T_casingInitial,
+      final p=summary.p_adsorbate_avg,
+      independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX),
+    thermalConduction_casing1(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)),
+    thermalConduction_casing2(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)));
+
+  //
+  // Definition of parameters regarding the media
+  //
+  replaceable model WorkingPair =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+        redeclare replaceable package Medium = MediumAdsorptive)
+    "Working pair model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable package MediumHX =
+      Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid in the heat exchanger"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable package MediumAdsorptive = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of adsorptive"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model WallMaterialHX =
+      SorpLib.Media.Solids.MetalsAndMetalAlloys.Copper
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Heat exchanger wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable model WallMaterialCS =
+      Media.Solids.MetalsAndMetalAlloys.StainlessSteel_X5CrNi18_10
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Casing wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding transport phenomena
+  //
+  replaceable model MassTransferCoefficientCondenser =
+    SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.GlueckaufArrhenius
+                                                                                                                           constrainedby
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDX(
+    geometry=geometry)
+    "Model calculating the mass transfer coefficient at the condenser port"
+    annotation (Dialog(tab="Transport Phenomena", group="Mass Transfer"),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+  replaceable model MassTransferCoefficientEvaporator =
+    MassTransferCoefficientCondenser
+    constrainedby
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDX(
+    geometry=geometry)
+    "Model calculating the mass transfer coefficient at the evaporator port"
+    annotation (Dialog(tab="Transport Phenomena", group="Mass Transfer"),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition and instantiation of models
+  //
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume[no_sorbentVolumes]
+    sorbentVolumes(
+    redeclare each final package Medium = MediumAdsorptive,
+    redeclare each final model PureWorkingPairModel = WorkingPair,
+    redeclare each final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+      dx=0,
+      dy=0,
+      dz=0,
+      A_xy=0,
+      A_xz=0,
+      A_yz=0,
+      V=geometry.V_particles*geometry.no_hydraulicParallelTubes),
+    each final m_sor_initial=m_sorInitial/geometry.no_sorbentVolumes,
+    each final T_initial=T_sorInitial,
+    each final x_initial=x_sorInitial,
+    each final msor_flow_initialX,
+    each final md_flow_initialX,
+    each final useAdsorbatePorts=false,
+    each final useDiffusivePorts=false,
+    each final useHeatPorts=false,
+    each final useHeatPortsX=false,
+    each final useHeatPortsY=false,
+    each final useHeatPortsZ=false,
+    each final ms_flow_initial=m_flow_adsorptive_start,
+    each final type_adsorbentMassBalance=type_overallMassBalance,
+    each final type_adsorptMassBalance=type_overallMassBalance,
+    each final type_energyBalance=type_energyBalance,
+    each final avoid_events=avoid_events,
+    each calcUptakeAveragedProperties=false,
+    each independentStateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+    each nSorptionPorts=if useMassRecoveryPorts then 3 else 2)
+    "Sorbent volumes"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={50,-30})));
+
+  SorpLib.Components.HeatTransfer.ClosedAdsorberHeatTransfer[min(no_sorbentVolumes,no_wallVolumes)]
+    heatTransfer_HeatExchangerToSorbentVolumes(
+    each final n_a=if no_wallVolumes > no_sorbentVolumes then factorDiscretization
+      else 1,
+    each final n_b=if no_wallVolumes < no_sorbentVolumes then factorDiscretization
+      else 1,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        VV_HeatExchanger,
+    final fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=sorbentVolumes.adsorbateProperties.p,
+      T=sorbentVolumes.adsorbateProperties.T,
+      rho=1 ./ sorbentVolumes.workingPair.medium_sorbent.state_variables.v,
+      cp=sorbentVolumes.workingPair.medium_sorbent.additional_variables.c,
+      eta=0,
+      lambda=sorbentVolumes.workingPair.medium_sorbent.additional_variables.lambda),
+    each final geometry=geometry)
+    "Heat transfer from heat exchanger to sorbent volumes"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={50,-54})));
+
+  SorpLib.Components.MassTransfer.VLEMassTransfers.ClosedAdsorberMassTransferDX[
+    no_sorbentVolumes] massTransferCondenser(
+    redeclare each final package Medium =MediumAdsorptive,
+    final x_adsorpt_input=sorbentVolumes.x,
+    final T_adsorpt_input=sorbentVolumes.T,
+    redeclare each final model MassTransferCoefficient =
+        MassTransferCoefficientCondenser,
+    each isFlapValve=true,
+    each isFlowAB=false,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    each final m_flow_start=m_flow_adsorptive_start,
+    each final avoid_events=avoid_events,
+    each final m_flow_small=m_flow_small,
+    each final noDiff=noDiff)
+    "Mass transfer between sorbent volumes and condenser port" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={60,0})));
+  SorpLib.Components.MassTransfer.VLEMassTransfers.ClosedAdsorberMassTransferDX[
+    no_sorbentVolumes] massTransferEvaporator(
+    redeclare each final package Medium =MediumAdsorptive,
+    final x_adsorpt_input=sorbentVolumes.x,
+    final T_adsorpt_input=sorbentVolumes.T,
+    redeclare each final model MassTransferCoefficient =
+        MassTransferCoefficientEvaporator,
+    each isFlapValve=true,
+    each isFlowAB=true,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    each final m_flow_start=m_flow_adsorptive_start,
+    each final avoid_events=avoid_events,
+    each final m_flow_small=m_flow_small,
+    each final noDiff=noDiff)
+    "Mass transfer between sorbent volumes and evaporator port" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,0})));
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Components.HeatExchanger.Records.SummarySimpleClosedAdsorber summary(
+    final p_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.p)/
+      no_sorbentVolumes,
+    final T_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.T)/
+      no_sorbentVolumes,
+    final x_adsorbate_avg=sum(sorbentVolumes.adsorbateProperties.x_i[1])/
+      no_sorbentVolumes,
+    final mass_adsorpt=summary.x_adsorbate_avg*m_sorInitial,
+    final p_liq_inlet=heatExchangerTubes.state_a.p,
+    final p_liq_outlet=heatExchangerTubes.state_b.p,
+    final p_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.p)/
+        no_fluidVolumes,
+    final T_liq_inlet=heatExchangerTubes.state_a.T,
+    final T_liq_outlet=heatExchangerTubes.state_b.T,
+    final T_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.T)/
+        no_fluidVolumes,
+    final T_wall_avg=sum(heatExchangerTubes.wallVolumes.T)/
+      no_wallVolumes,
+    final m_flow_liq_inlet=port_a.m_flow,
+    final m_flow_liq_outlet=port_b.m_flow,
+    final m_flow_evaporator=evaporatorPort.m_flow,
+    final m_flow_condenser=condenserPort.m_flow,
+    final m_flow_massRecovery=sum({sum(sorbentVolumes[i].fp_sorption.m_flow)
+     for i in 1:no_sorbentVolumes}) + evaporatorPort.m_flow+condenserPort.m_flow,
+    final Q_flow_wallToSorbent=heatExchangerTubes.Q_flow_wallHP,
+    final Q_flow_fluidWall=heatExchangerTubes.Q_flow_fluidWall,
+    final DH_liquid=heatExchangerTubes.DH_flow)
+    "Summary record";
+
+equation
+  //
+  // Connections of fluid portsuseMassRecoveryPorts
+  //
+  connect(massTransferCondenser.port_b, sorbentVolumes.fp_sorption[1])
+    annotation (Line(points={{60,-8},{60,-16},{70,-16},{70,-44},{51.6,-44},{51.6,
+          -34.4}}, color={0,0,0}));
+  connect(massTransferEvaporator.port_b, sorbentVolumes.fp_sorption[2])
+    annotation (Line(points={{0,-8},{0,-16},{70,-16},{70,-44},{51.6,-44},{51.6,-34.4}},
+                   color={0,0,0}));
+
+
+  connect(evaporatorPort, evaporatorSplitter.port_a) annotation (Line(
+      points={{-100,40},{0,40},{0,36}},
+      color={0,140,72},
+      thickness=1));
+  connect(condenserPort, condenserSplitter.port_a) annotation (Line(
+      points={{100,40},{60,40},{60,36}},
+      color={0,140,72},
+      thickness=1));
+  connect(massTransferEvaporator.port_a, evaporatorSplitter.ports_b)
+    annotation (Line(
+      points={{0,7.8},{0,24}},
+      color={0,140,72},
+      thickness=1));
+  connect(massTransferCondenser.port_a, condenserSplitter.ports_b) annotation (
+      Line(
+      points={{60,7.8},{60,24}},
+      color={0,140,72},
+      thickness=1));
+
+  //
+  // Connection of heat ports
+  //
+  if no_sorbentVolumes == no_wallVolumes then
+    //
+    // Identical discretization number
+    //
+    connect(heatExchangerTubes.hp_wall,
+      heatTransfer_HeatExchangerToSorbentVolumes.hp_a[1]) annotation (Line(
+        points={{50,-76},{50,-62}},
+        color={238,46,47},
+        thickness=1));
+    connect(heatTransfer_HeatExchangerToSorbentVolumes.hp_b[1],
+      sorbentVolumes.hp_sorption) annotation (Line(
+        points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+        color={238,46,47},
+        thickness=1));
+
+  elseif no_wallVolumes > no_sorbentVolumes then
+    //
+    // More wall volumes than sorbent volumes
+    //
+    for i in 1:no_sorbentVolumes loop
+      connect(heatExchangerTubes.hp_wall[1+(i-1)*factorDiscretization:i*factorDiscretization],
+      heatTransfer_HeatExchangerToSorbentVolumes[i].hp_a[1:factorDiscretization])
+        annotation (Line(
+          points={{50,-76},{50,-62}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+
+    connect(heatTransfer_HeatExchangerToSorbentVolumes.hp_b[1],
+      sorbentVolumes.hp_sorption) annotation (Line(
+        points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+        color={238,46,47},
+        thickness=1));
+
+  else
+    //
+    // More sorbent volumes than wall volumes
+    //
+    connect(heatExchangerTubes.hp_wall,
+      heatTransfer_HeatExchangerToSorbentVolumes.hp_a[1]) annotation (Line(
+        points={{50,-76},{50,-62}},
+        color={238,46,47},
+        thickness=1));
+
+    for i in 1:no_wallVolumes loop
+      connect(heatTransfer_HeatExchangerToSorbentVolumes[i].hp_b[1:factorDiscretization],
+        sorbentVolumes[1+(i-1)*factorDiscretization:i*factorDiscretization].hp_sorption)
+        annotation (Line(
+          points={{50,-46},{50,-44},{48.4,-44},{48.4,-37.6}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+  end if;
+
+  connect(heatTransfer_sorbentVolumesToCasing.hp_a, sorbentVolumes.hp_sorption)
+    annotation (Line(
+      points={{-24,0},{-20,0},{-20,-20},{20,-20},{20,-44},{48.4,-44},{48.4,-37.6}},
+      color={238,46,47},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  connect(massRecoveryPorts, massRecoverySplitter.port_a) annotation (Line(
+      points={{0,60},{30,60},{30,36}},
+      color={0,140,72},
+      thickness=1));
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED!
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library.
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SimpleAdsorberDX;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_AdsorberDP.mo b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_AdsorberDP.mo
new file mode 100644
index 0000000..6073db1
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_AdsorberDP.mo
@@ -0,0 +1,110 @@
+within SorpLib.Components.HeatExchanger.Adsorbers.Tester;
+model Test_AdsorberDP
+  "Tester for the closed adsorber with pressure-driven mass transfer"
+  extends Modelica.Icons.Example;
+
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=false,
+    use_VFlowInput=false,
+    V_flow_fixed=-10/60/1000,
+    use_TInput=true,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=false,
+    redeclare final package Medium =
+        Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.HeatExchanger.Adsorbers.AdsorberDP closedAdsorber(
+    no_fluidVolumes=10,
+    geometry(V_vapor_cas=10, no_hydraulicParallelTubes=1),
+    useCasing=false,
+    redeclare model VV_HeatExchanger =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlphaA
+        (constantAlphaA=300),
+    redeclare model VV_Casing =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA
+        (constantAlphaA=5),                                            redeclare
+      model WorkingPair =
+        SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+        calcEntropicProperties=false,
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Dubinin,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve,
+        approachSpecificVolume=SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve,
+        limitLowerPressureAdsorptive=true),
+    redeclare model WallMaterialCS =
+        Media.Solids.MetalsAndMetalAlloys.Aluminium,
+    redeclare model MassTransferCoefficient =
+        MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.KnudsenDiffusionPoiseuilleFlow)
+                                            "Closed adsorber model" annotation (
+     Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={0,0})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Pulse input_T(
+    amplitude=60,
+    width=50,
+    period=1000,
+    offset=273.15 + 25) "Input signal for temperature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, closedAdsorber.port_a) annotation (Line(
+      points={{-60,0},{-10,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(closedAdsorber.port_b, fs_b.port) annotation (Line(
+      points={{10,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_T.y, fs_a.T_input) annotation (Line(points={{-79,0},{-70,0},{-70,
+          -2},{-61.2,-2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=5000,
+      Tolerance=1e-04),
+                      Documentation(info="<html>
+<p>
+This model checks the closed adsorber heat exchanger with pressure-driven
+mass transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 5000 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AdsorberDP;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_AdsorberDX.mo b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_AdsorberDX.mo
new file mode 100644
index 0000000..5afe0ff
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_AdsorberDX.mo
@@ -0,0 +1,110 @@
+within SorpLib.Components.HeatExchanger.Adsorbers.Tester;
+model Test_AdsorberDX
+  "Tester for the closed adsorber with loading-driven mass transfer"
+  extends Modelica.Icons.Example;
+
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=false,
+    use_VFlowInput=false,
+    V_flow_fixed=-10/60/1000,
+    use_TInput=true,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=false,
+    redeclare final package Medium =
+        Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.HeatExchanger.Adsorbers.AdsorberDX closedAdsorber(
+    no_fluidVolumes=10,
+    geometry(V_vapor_cas=10, no_hydraulicParallelTubes=1),
+    useCasing=false,
+    redeclare model VV_HeatExchanger =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlphaA
+        (constantAlphaA=300),
+    redeclare model VV_Casing =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA
+        (constantAlphaA=5),                                            redeclare
+      model WorkingPair =
+        SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+        calcEntropicProperties=false,
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Dubinin,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve,
+        approachSpecificVolume=SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve,
+        limitLowerPressureAdsorptive=true),
+    redeclare model WallMaterialCS =
+        Media.Solids.MetalsAndMetalAlloys.Aluminium,
+    redeclare model MassTransferCoefficient =
+        MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.Glueckauf)
+                                            "Closed adsorber model" annotation (
+     Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={0,0})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Pulse input_T(
+    amplitude=60,
+    width=50,
+    period=1000,
+    offset=273.15 + 25) "Input signal for temperature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, closedAdsorber.port_a) annotation (Line(
+      points={{-60,0},{-10,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(closedAdsorber.port_b, fs_b.port) annotation (Line(
+      points={{10,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_T.y, fs_a.T_input) annotation (Line(points={{-79,0},{-70,0},{-70,
+          -2},{-61.2,-2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=5000,
+      Tolerance=1e-04),
+                      Documentation(info="<html>
+<p>
+This model checks the closed adsorber heat exchanger with loading-driven
+mass transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 5000 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AdsorberDX;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_SimpleAdsorberDP.mo b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_SimpleAdsorberDP.mo
new file mode 100644
index 0000000..7d4d423
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_SimpleAdsorberDP.mo
@@ -0,0 +1,132 @@
+within SorpLib.Components.HeatExchanger.Adsorbers.Tester;
+model Test_SimpleAdsorberDP
+  "Tester for the simple closed adsorber with pressure-driven mass transfer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=false,
+    use_VFlowInput=false,
+    V_flow_fixed=-10*10/60/1000,
+    use_TInput=true,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=false,
+    redeclare final package Medium =
+        Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  Basics.Sources.Fluids.VLESource evaporatorSource(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="kPa") = 1700,
+    T_fixed=288.15) "Evaporator source"
+    annotation (Placement(transformation(extent={{-70,10},{-50,30}})));
+
+  Basics.Sources.Fluids.VLESource condenserSource(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="kPa") = 5628,
+    T_fixed=308.15) "Condenser source"
+    annotation (Placement(transformation(extent={{50,10},{70,30}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.HeatExchanger.Adsorbers.SimpleAdsorberDP closedAdsorber(
+    no_fluidVolumes=10,
+    geometry(no_hydraulicParallelTubes=10),
+    useCasing=false,
+    redeclare model VV_HeatExchanger =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlphaA
+        (constantAlphaA=300),
+    redeclare model VV_Casing =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA
+        (constantAlphaA=5),
+    x_sorInitial=0.15,                                                 redeclare
+      model WorkingPair =
+        SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+        calcEntropicProperties=false,
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Dubinin,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve,
+        approachSpecificVolume=SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve,
+        limitLowerPressureAdsorptive=true),
+    redeclare model WallMaterialCS =
+        Media.Solids.MetalsAndMetalAlloys.Aluminium,
+    redeclare model MassTransferCoefficientCondenser =
+        MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.KnudsenDiffusionPoiseuilleFlow)
+                                            "Closed adsorber model" annotation (
+     Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={0,0})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Pulse input_T(
+    amplitude=60,
+    width=50,
+    period=1000,
+    offset=273.15 + 25) "Input signal for temperature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(evaporatorSource.port, closedAdsorber.evaporatorPort) annotation (
+      Line(
+      points={{-60,20},{-10,20},{-10,4}},
+      color={0,140,72},
+      thickness=1));
+  connect(condenserSource.port, closedAdsorber.condenserPort) annotation (Line(
+      points={{60,20},{10,20},{10,4}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a.port, closedAdsorber.port_a) annotation (Line(
+      points={{-60,0},{-10,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(closedAdsorber.port_b, fs_b.port) annotation (Line(
+      points={{10,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_T.y, fs_a.T_input) annotation (Line(points={{-79,0},{-70,0},{-70,
+          -2},{-61.2,-2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=5000,
+      __Dymola_NumberOfIntervals=2500,
+      __Dymola_Algorithm="Dassl"),
+                      Documentation(info="<html>
+<p>
+This model checks the simple closed adsorber heat exchanger with pressure-driven
+mass transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 5000 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_SimpleAdsorberDP;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_SimpleAdsorberDX.mo b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_SimpleAdsorberDX.mo
new file mode 100644
index 0000000..4a6a578
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/Test_SimpleAdsorberDX.mo
@@ -0,0 +1,132 @@
+within SorpLib.Components.HeatExchanger.Adsorbers.Tester;
+model Test_SimpleAdsorberDX
+  "Tester for the simple closed adsorber with loading-driven mass transfer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=false,
+    use_VFlowInput=false,
+    V_flow_fixed=-10*10/60/1000,
+    use_TInput=true,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=false,
+    redeclare final package Medium =
+        Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  Basics.Sources.Fluids.VLESource evaporatorSource(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="kPa") = 1700,
+    T_fixed=288.15) "Evaporator source"
+    annotation (Placement(transformation(extent={{-70,10},{-50,30}})));
+
+  Basics.Sources.Fluids.VLESource condenserSource(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed(displayUnit="kPa") = 5628,
+    T_fixed=308.15) "Condenser source"
+    annotation (Placement(transformation(extent={{50,10},{70,30}})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.HeatExchanger.Adsorbers.SimpleAdsorberDX closedAdsorber(
+    no_fluidVolumes=10,
+    geometry(no_hydraulicParallelTubes=10),
+    useCasing=false,
+    redeclare model VV_HeatExchanger =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlphaA
+        (constantAlphaA=300),
+    redeclare model VV_Casing =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA
+        (constantAlphaA=5),
+    x_sorInitial=0.15,                                                 redeclare
+      model WorkingPair =
+        SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+        calcEntropicProperties=false,
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Dubinin,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve,
+        approachSpecificVolume=SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve,
+        limitLowerPressureAdsorptive=true),
+    redeclare model WallMaterialCS =
+        Media.Solids.MetalsAndMetalAlloys.Aluminium,
+    redeclare model MassTransferCoefficientCondenser =
+        MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.GlueckaufArrhenius)
+                                            "Closed adsorber model" annotation (
+     Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={0,0})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Pulse input_T(
+    amplitude=60,
+    width=50,
+    period=1000,
+    offset=273.15 + 25) "Input signal for temperature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(evaporatorSource.port, closedAdsorber.evaporatorPort) annotation (
+      Line(
+      points={{-60,20},{-10,20},{-10,4}},
+      color={0,140,72},
+      thickness=1));
+  connect(condenserSource.port, closedAdsorber.condenserPort) annotation (Line(
+      points={{60,20},{10,20},{10,4}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a.port, closedAdsorber.port_a) annotation (Line(
+      points={{-60,0},{-10,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(closedAdsorber.port_b, fs_b.port) annotation (Line(
+      points={{10,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_T.y, fs_a.T_input) annotation (Line(points={{-79,0},{-70,0},{-70,
+          -2},{-61.2,-2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=5000,
+      __Dymola_NumberOfIntervals=2500,
+      __Dymola_Algorithm="Dassl"),
+                      Documentation(info="<html>
+<p>
+This model checks the simple closed adsorber heat exchanger with loading-driven
+mass transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 5000 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_SimpleAdsorberDX;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/Tester/package.mo b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/package.mo
new file mode 100644
index 0000000..65ee86c
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.HeatExchanger.Adsorbers;
+package Tester "Models to test and varify closed adsorbers"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all closed adsorber heat exchangers.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/Tester/package.order b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/package.order
new file mode 100644
index 0000000..e162433
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/Tester/package.order
@@ -0,0 +1,4 @@
+Test_AdsorberDP
+Test_AdsorberDX
+Test_SimpleAdsorberDP
+Test_SimpleAdsorberDX
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/package.mo b/SorpLib/Components/HeatExchanger/Adsorbers/package.mo
new file mode 100644
index 0000000..d179375
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.HeatExchanger;
+package Adsorbers "Adsorbers used in closed sorption systems"
+  extends SorpLib.Icons.AdsorbersPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains closed adsorber heat exchanger that are based on the Modelica
+Standard Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Adsorbers;
diff --git a/SorpLib/Components/HeatExchanger/Adsorbers/package.order b/SorpLib/Components/HeatExchanger/Adsorbers/package.order
new file mode 100644
index 0000000..4cffa73
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Adsorbers/package.order
@@ -0,0 +1,5 @@
+AdsorberDP
+AdsorberDX
+SimpleAdsorberDP
+SimpleAdsorberDX
+Tester
diff --git a/SorpLib/Components/HeatExchanger/BaseClasses/PartialHeatExchanger.mo b/SorpLib/Components/HeatExchanger/BaseClasses/PartialHeatExchanger.mo
new file mode 100644
index 0000000..fd2e200
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/BaseClasses/PartialHeatExchanger.mo
@@ -0,0 +1,132 @@
+within SorpLib.Components.HeatExchanger.BaseClasses;
+partial model PartialHeatExchanger
+  "Base model for all heat exchanger"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.Pressure p_initial = 1e5
+    "Initial value of pressure"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+  parameter Modelica.Units.SI.MassFraction[no_components] X_i_initial=
+    fill(1/no_components, no_components)
+    "Initial values of mass fractions"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_overallMassBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the overall mass balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BalanceEquations type_independentMassBalances=
+    type_overallMassBalance
+    "Handling of independent mass balances and corresponding initialisations"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BalanceEquations type_energyBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the energy balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult = true);
+
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_small = 1e-4
+    "Regularization mass flow rate"
+    annotation (Dialog(tab="Advanced", group="Numerics"));
+  parameter Integer noDiff = 2
+    "Specification how often transition functions can be differentiated"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-110,-10},{-90,10}}),
+                iconTransformation(extent={{-110,-10},{-90,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{90,-10},{110,10}}),
+                iconTransformation(extent={{90,-10},{110,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all heat exchangers. It defines some
+fundamental parameters required by all heat exchangers. Models that inherit properties 
+from this partial model have to redeclare the fluid ports. Moreover, the mass
+and energy balances must be completed using the ports.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Pressure <i>port_a.p</i> at port a.
+  </li>
+  <li>
+  Pressure <i>port_a.p</i> at port b.
+  </li>
+  <br/>
+  <li>
+  Mass flow rate <i>port_a.m_flow</i> at port a.
+  </li>
+  <li>
+  Mass flow rate <i>port_a.m_flow</i> at port b.
+  </li>
+  <br/>
+  <li>
+  Outflowing specific enthalpy <i>port_a.h_outflow</i> at port a.
+  </li>
+  <li>
+  Outflowing specific enthalpy <i>port_b.h_outflow</i> at port b.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 26, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialHeatExchanger;
diff --git a/SorpLib/Components/HeatExchanger/BaseClasses/PartialPureComponentAdsorber.mo b/SorpLib/Components/HeatExchanger/BaseClasses/PartialPureComponentAdsorber.mo
new file mode 100644
index 0000000..06b72f1
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/BaseClasses/PartialPureComponentAdsorber.mo
@@ -0,0 +1,1161 @@
+within SorpLib.Components.HeatExchanger.BaseClasses;
+partial model PartialPureComponentAdsorber
+  "Base model for all adsorber heat exchangers for pure component adsorption"
+  extends SorpLib.Components.HeatExchanger.BaseClasses.PartialHeatExchanger(
+    final p_initial,
+    final X_i_initial);
+
+  //
+  // Definition of general parameters
+  //
+  parameter Integer nPortsMassTransfer = 0
+    "Number of mass transfer ports"
+    annotation (Dialog(connectorSizing=true),
+                HideResult = true);
+
+  parameter Integer no_fluidVolumes(min=2)=2
+    "Discretization number of fluid volumes"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_wallVolumes(min=2)=no_fluidVolumes
+    "Discretization number of wall volumes (must be a factor of no_fluidVolumes)"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_sorbentVolumes(min=1)=no_wallVolumes
+    "Discretization number of sorbent volumes (must be a factor of no_wallVolumes)"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the geometry
+  //
+  replaceable parameter SorpLib.Components.HeatExchanger.Records.GeometryClosedAdsorber geometry
+    constrainedby
+    SorpLib.Components.HeatExchanger.Records.GeometryClosedAdsorber(
+      no_fluidVolumes=no_fluidVolumes,
+      no_wallVolumes=no_wallVolumes,
+      no_sorbentVolumes=no_sorbentVolumes)
+    "Geometry of the closed adsorber"
+    annotation (Dialog(tab = "General", group = "Geometry"),
+                choicesAllMatching = true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_adsorptiveComponents = 1
+    "Number of adsorptive components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of models describing transport phenomena
+  //
+  parameter Boolean useCasing = false
+    " = true, if casing is modeled"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionCasing = true
+    " = true, if thermal conduction in the casing is modeled"
+    annotation (Dialog(tab="Transport Phenomena", group="General",
+                enable=useCasing),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionPerpendicularFlowDirection = true
+    " = true, if thermal conduction perpendicular to the flow direction is
+    considered within the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionFlowDirection = false
+    " = true, if thermal conduction in the flow direction is considered within 
+    the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcFluidTransportProperties = true
+    " = true, if any transport model needs fluid or transport properties"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_InnerWallThermalConductionPerpendicularFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_hx/geometry.no_wallVolumes,
+        d_inner=geometry.d_hydInner_hx,
+        d_outer=(geometry.d_hydInner_hx + geometry.d_hydOuter_hx)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction perpendicular to the
+    flow direction within the heat exchanger wall near the fluid"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionPerpendicularFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model HX_OuterWallThermalConductionPerpendicularFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_hx/geometry.no_wallVolumes,
+        d_inner=(geometry.d_hydInner_hx + geometry.d_hydOuter_hx)/2,
+        d_outer=geometry.d_hydOuter_hx)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction perpendicular to the
+    flow direction within the heat exchanger wall near the heat port"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionPerpendicularFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model HX_WallThermalConductionFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.PlainWall
+      (
+      A_cross=geometry.A_crossWall_hx,
+      delta_wall=(geometry.l_hx/geometry.no_wallVolumes)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction in the flow direction
+    within the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model CS_InnerWallThermalConduction =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_cas,
+        d_inner=geometry.d_hydInner_cas,
+        d_outer=(geometry.d_hydInner_cas + geometry.d_hydOuter_cas)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction within the casing
+    near the phase separator"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useCasing and useConductionCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model CS_OuterWallThermalConduction =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_cas,
+        d_inner=(geometry.d_hydInner_cas + geometry.d_hydOuter_cas)/2,
+        d_outer=geometry.d_hydOuter_cas)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction within the casing
+    near the heat port"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useCasing and useConductionCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_FluidThermalConvectionTubeInside =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.GnielinskiDittusBoelter
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient
+    "Heat transfer correlation describing thermal convection at the tube inside
+    within the heat exchanger (i.e., form the fluid to the wall)"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Convection"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model VV_HeatExchanger =
+    HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlphaA
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialClosedAdsorberHeatTransferCoefficient
+    "Heat transfer correlation describing the heat transfer from the sorbent volumes
+    to heat exchanger tubes"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Convection"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model VV_Casing =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient
+    "Heat transfer correlation describing the heat transfer between the vapor
+    volume and casing"
+    annotation (Dialog(tab="Transport Phenomena", group="Generic",
+                enable = useCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_PressureDrop =
+    SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Konakov
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss
+    "Pressure drop correlation describing the pressure drop of the fluid within
+    the heat exchanger"
+    annotation (Dialog(tab="Transport Phenomena", group="Pressure Drop"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding initial values
+  //
+  parameter Modelica.Units.SI.Pressure p_fluidAInitial = 1.25e5
+    "Initial value of fluid pressure at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Pressure p_fluidBInitial = 1e5
+    "Initial value of fluid pressure at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Temperature T_fluidAInitial = 283.15
+    "Initial value of fluid temperature at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Temperature T_fluidBInitial = 303.15
+    "Initial value of fluid temperature at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+
+  parameter Modelica.Units.SI.Temperature T_wallAInitial = T_fluidAInitial
+    "Initial value of wall temperature at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Wall"));
+  parameter Modelica.Units.SI.Temperature T_wallBInitial = T_fluidBInitial
+    "Initial value of wall temperature at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Wall"));
+
+  parameter Modelica.Units.SI.Pressure p_vaporVolumeInitial = 1e3
+    "Initial value of the vapor pressure"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Vapor"));
+  parameter Modelica.Units.SI.Temperature T_vaporVolumeInitial = 303.15
+    "Initial value of vapor temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Vapor"));
+
+  parameter Modelica.Units.SI.Mass m_sorInitial = 725 * geometry.V_sorbent_hx /
+    geometry.no_sorbentVolumes
+    "Initial value of the sorbent mass"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Sorbent"));
+  parameter SorpLib.Units.Uptake x_sorInitial = 0.15
+    "Initial loading of the sorbent"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Sorbent"));
+  parameter Modelica.Units.SI.Temperature T_sorInitial = 303.15
+    "Initial value of sorbent temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Sorbent"));
+
+
+  parameter Modelica.Units.SI.Temperature T_casingInitial = 298.15
+    "Initial value of casing temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Casing",
+                enable=useCasing));
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_adsorptive_start = 1e-4
+    "Start value for adsorptive mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in evaporatorPort(final
+      no_components=no_adsorptiveComponents, m_flow(start=
+          m_flow_adsorptive_start)) "Evaporator port" annotation (Placement(
+        transformation(extent={{-110,30},{-90,50}}), iconTransformation(extent={
+            {-110,30},{-90,50}})));
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out condenserPort(final
+      no_components=no_adsorptiveComponents, m_flow(start=-
+          m_flow_adsorptive_start)) "Condenser port" annotation (Placement(
+        transformation(extent={{90,30},{110,50}}), iconTransformation(extent={{90,
+            30},{110,50}})));
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out[nPortsMassTransfer] massRecoveryPorts(
+    each final no_components=no_adsorptiveComponents,
+    each final m_flow(start=m_flow_adsorptive_start)) "Mass recovery ports"
+    annotation (Placement(transformation(extent={{-10,50},{10,70}}),
+        iconTransformation(extent={{-10,50},{10,70}})));
+
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_casing if
+    useCasing
+    "Heat ports at casing"
+    annotation (Placement(transformation(extent={{-10,-50},{10,-70}}),
+                iconTransformation(extent={{-10,-70},{10,-50}})));
+
+  //
+  // Definition and instanziation of models
+  //
+  replaceable Basics.Volumes.BaseClasses.PartialFluidVolume vaporVolume(
+    final calculateAdditionalProperties=calcFluidTransportProperties,
+    redeclare final SorpLib.Basics.Volumes.Records.VolumeGeometry
+      geometry(
+      dx=0,
+      dy=0,
+      dz=0,
+      A_xy=0,
+      A_xz=0,
+      A_yz=0,
+      V=geometry.V_vapor_cas),
+    final useHeatPorts=true,
+    final useHeatPortsX=false,
+    final useHeatPortsY=true,
+    final useHeatPortsZ=false,
+    final p_initial=p_vaporVolumeInitial,
+    final T_initial=T_vaporVolumeInitial,
+    final mc_flow_initialX=m_flow_adsorptive_start,
+    final type_energyBalance=type_energyBalance,
+    final type_overallMassBalance=type_overallMassBalance,
+    final avoid_events=avoid_events,
+    independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.phX,
+    nPorts_cfp_xPlus=2+nPortsMassTransfer)
+    "Vapor volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,0})));
+
+  replaceable SorpLib.Components.Tubes.BaseClasses.PartialTube heatExchangerTubes(
+    final no_fluidVolumes=no_fluidVolumes,
+    final no_wallVolumes=no_wallVolumes,
+    redeclare final SorpLib.Components.Tubes.Records.GeometryTube geometry(
+      no_hydraulicParallelTubes=geometry.no_hydraulicParallelTubes,
+      l=geometry.l_hx,
+      roughness=geometry.roughness_hx,
+      d_inner=geometry.d_inner_hx,
+      d_outer=geometry.d_outer_hx,
+      d_hydInner=geometry.d_hydInner_hx,
+      d_hydOuter=geometry.d_hydOuter_hx,
+      t_wall=geometry.t_wall_hx,
+      A_crossInner=geometry.A_crossInner_hx,
+      A_crossOuter=geometry.A_crossOuter_hx,
+      A_crossWall=geometry.A_crossWall_hx,
+      A_hydCrossInner=geometry.A_hydCrossInner_hx,
+      A_hydCrossOuter=geometry.A_hydCrossOuter_hx,
+      A_hydCrossWall=geometry.A_hydCrossWall_hx,
+      A_heatTransferInner=geometry.A_heatTransferInner_hx,
+      A_heatTransferOuter=geometry.A_heatTransferOuter_hx,
+      f_finAreaRatioInner=geometry.f_finAreaRatioInner_hx,
+      f_finAreaRatioOuter=geometry.f_finAreaRatioOuter_hx,
+      V_inner=geometry.V_inner_hx,
+      V_outer=geometry.V_outer_hx,
+      V_wall=geometry.V_wall_hx,
+      f_finVolumeRatioInner=geometry.f_finVolumeRatioInner_hx,
+      f_finVolumeRatioOuter=geometry.f_finVolumeRatioOuter_hx),
+    final useConductionPerpendicularFlowDirection=
+      useConductionPerpendicularFlowDirection,
+    final useConductionFlowDirection=useConductionFlowDirection,
+    final calcFluidTransportProperties=calcFluidTransportProperties,
+    redeclare final model InnerWallThermalConductionPerpendicularFlowDirection =
+      HX_InnerWallThermalConductionPerpendicularFlowDirection,
+    redeclare final model OuterWallThermalConductionPerpendicularFlowDirection =
+      HX_OuterWallThermalConductionPerpendicularFlowDirection,
+    redeclare final model WallThermalConductionFlowDirection =
+      HX_WallThermalConductionFlowDirection,
+    redeclare final model FluidThermalConvectionTubeInside =
+      HX_FluidThermalConvectionTubeInside,
+    redeclare final model PressureDrop = HX_PressureDrop,
+    final p_fluidAInitial=p_fluidAInitial,
+    final p_fluidBInitial=p_fluidBInitial,
+    final T_fluidAInitial=T_fluidAInitial,
+    final T_fluidBInitial=T_fluidBInitial,
+    final T_wallAInitial=T_wallAInitial,
+    final T_wallBInitial=T_wallBInitial,
+    final m_flow_start=m_flow_start,
+    final type_overallMassBalance=type_overallMassBalance,
+    final type_independentMassBalances=type_independentMassBalances,
+    final avoid_events=avoid_events,
+    final m_flow_small=m_flow_small,
+    final noDiff=noDiff)
+    "Heat exchanger tubes"
+    annotation (Placement(transformation(extent={{40,-90},{60,-70}})));
+
+  replaceable SorpLib.Basics.Volumes.BaseClasses.PartialVolume casing(
+    final useHeatPortsX=false,
+    final useHeatPortsY=true,
+    final useHeatPortsZ=false,
+    final type_energyBalance=type_energyBalance,
+    final avoid_events=avoid_events) if useCasing
+    "Casing"
+    annotation (Placement(transformation(extent={{-68,10},{-48,-10}})));
+
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_vaporVolumeToCasing(
+    final n_a=1,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient = VV_Casing) if
+                    useCasing "Heat transfer from vapor volume to casing"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={-32,0})));
+
+  HeatTransfer.ConductionHeatTransfer thermalConduction_casing1(
+    final n_a=1,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient =
+        CS_InnerWallThermalConduction,
+    final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    (useCasing and useConductionCasing)
+    "Thermal conduction of the first casing half"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={-58,22})));
+
+  HeatTransfer.ConductionHeatTransfer thermalConduction_casing2(
+    final n_a=1,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient =
+        CS_OuterWallThermalConduction,
+    final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    (useCasing and useConductionCasing)
+    "Thermal conduction of the second casing half"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={-58,-22})));
+
+  //
+  // Definition of protected parameters
+  //
+protected
+  final parameter Integer factorDiscretization=
+    integer(max(no_sorbentVolumes,no_wallVolumes)/
+    min(no_sorbentVolumes,no_wallVolumes))
+    "Discretization factor"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+
+equation
+  //
+  // Assertations
+  //
+  if no_wallVolumes < no_fluidVolumes then
+    assert(rem(no_fluidVolumes, no_wallVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of fluid volumes!");
+
+  elseif no_wallVolumes > no_fluidVolumes then
+    assert(rem(no_wallVolumes, no_fluidVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of fluid volumes!");
+
+  end if;
+
+  if no_wallVolumes < no_sorbentVolumes then
+    assert(rem(no_sorbentVolumes, no_wallVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of sorbent volumes!");
+
+  elseif no_wallVolumes > no_sorbentVolumes then
+    assert(rem(no_wallVolumes, no_sorbentVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of sorbent volumes!");
+
+  end if;
+
+  //
+  // Connection of fluid ports
+  //
+  connect(port_a, heatExchangerTubes.fp_a) annotation (Line(points={{-100,0},{-80,
+          0},{-80,-80},{40,-80}}, color={0,0,0}));
+  connect(heatExchangerTubes.fp_b, port_b) annotation (Line(points={{60,-80},{80,
+          -80},{80,0},{100,0}}, color={0,0,0}));
+
+  connect(evaporatorPort, vaporVolume.cfp_xPlus[1]) annotation (Line(
+      points={{-100,40},{-1.8,40},{-1.8,7.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(condenserPort, vaporVolume.cfp_xPlus[2]) annotation (Line(
+      points={{100,40},{-1.8,40},{-1.8,7.8}},
+      color={0,140,72},
+      thickness=1));
+
+  if nPortsMassTransfer > 0 then
+    connect(massRecoveryPorts, vaporVolume.cfp_xPlus[3:2+nPortsMassTransfer]) annotation (Line(
+        points={{0,60},{0,40},{-2,40},{-2,8},{-1.8,8},{-1.8,7.8}},
+        color={0,140,72},
+        thickness=1));
+  end if;
+
+  //
+  // Connection of heat ports
+  //
+  connect(vaporVolume.hp_yPlus, heatTransfer_vaporVolumeToCasing.hp_a[1])
+    annotation (Line(
+      points={{-6,0},{-24,0}},
+      color={238,46,47},
+      thickness=1));
+
+  if useCasing then
+    if useConductionCasing then
+      connect(heatTransfer_vaporVolumeToCasing.hp_b[1],
+        thermalConduction_casing1.hp_a[1]) annotation (Line(
+          points={{-40,4.44089e-16},{-42,4.44089e-16},{-42,32},{-58,32},{-58,30}},
+          color={238,46,47},
+          thickness=1));
+
+      connect(thermalConduction_casing1.hp_b[1], casing.hp_yMinus) annotation (Line(
+          points={{-58,14},{-58,6}},
+          color={238,46,47},
+          thickness=1));
+      connect(casing.hp_yPlus, thermalConduction_casing2.hp_a[1]) annotation (Line(
+          points={{-58,-6},{-58,-14}},
+          color={238,46,47},
+          thickness=1));
+      connect(thermalConduction_casing2.hp_b[1], hp_casing) annotation (Line(
+          points={{-58,-30},{-58,-32},{0,-32},{0,-60}},
+          color={238,46,47},
+          thickness=1));
+
+    else
+      connect(heatTransfer_vaporVolumeToCasing.hp_b[1], hp_casing);
+
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Rectangle(
+          extent={{-100,60},{100,-60}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Line(
+          points={{100,40},{-80,40},{80,0},{-80,-40},{100,-40}},
+          color={0,0,0},
+          thickness=1),
+        Ellipse(
+          extent={{-74,42},{-80,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,42},{-20,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,42},{-32,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-38,42},{-44,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,42},{-56,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,42},{-68,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,42},{52,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,42},{40,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,42},{28,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,42},{16,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,42},{4,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-2,42},{-8,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,42},{64,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{82,42},{76,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{82,-48},{76,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-48},{64,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,-48},{52,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,-48},{40,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,-48},{28,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,-48},{16,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-48},{4,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-2,-48},{-8,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,-48},{-20,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,-48},{-32,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-38,-48},{-44,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,-48},{-56,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,-48},{-68,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-74,-48},{-80,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{88,-38},{82,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,-38},{70,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{64,-38},{58,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,-38},{46,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,-38},{34,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,-38},{22,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,-38},{10,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,-38},{-2,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,-38},{-14,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-20,-38},{-26,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-32,-38},{-38,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,-40},{-50,-34}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,34},{-50,40}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-32,32},{-38,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-20,32},{-26,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,32},{-14,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,32},{-2,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,32},{10,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,32},{22,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,32},{34,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,32},{46,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{64,32},{58,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,32},{70,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{88,32},{82,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,30},{-72,36}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-52,26},{-58,32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-36,22},{-42,28}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,18},{-24,24}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-4,14},{-10,20}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{12,10},{6,16}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,6},{24,12}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{44,2},{38,8}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{60,-2},{54,4}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,24},{-14,30}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{6,20},{0,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,16},{16,22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{38,12},{32,18}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,8},{46,14}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{68,4},{62,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,-36},{-72,-30}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-52,-32},{-58,-26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-36,-28},{-42,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,-24},{-24,-18}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-4,-20},{-10,-14}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{12,-16},{6,-10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,-12},{24,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{44,-8},{38,-2}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{68,-10},{62,-4}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,-14},{46,-8}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{38,-18},{32,-12}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{24,-22},{18,-16}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{6,-26},{0,-20}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,-30},{-14,-24}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,24},{-50,30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,34},{-60,40}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-76,34},{-82,40}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,42},{-14,48}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,26},{-20,32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,12},{-2,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,14},{24,20}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,0},{46,6}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,32},{28,38}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,42},{70,48}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{82,32},{76,38}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{20,-14},{14,-8}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-28,-26},{-34,-20}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-52,-40},{-58,-34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-78,-42},{-84,-36}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-32,-48},{-38,-42}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-38},{4,-32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,-48},{34,-42}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-38},{64,-32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,-16},{40,-10}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid)}),
+    Diagram(coordinateSystem(extent={{-100,-100},{100,100}})),
+    Documentation(info="<html>
+<p>
+This partial model is the base model for all closed adsorber heat exchanger. It defines 
+fundamental parameters, models, and variables required by all closed adsorbers. Models 
+that inherit properties from this partial model have to redeclare all partial models 
+(i.e., fluid ports, tube, vapor volume, and casing). Moreover, sorbent volumes must be
+added as well as a mass transfer model describing the mass transfer between the sorbent 
+and vapor and a heat transfer model describing the heat transfer between the sorbent and
+heat exchanger. These models are not inserted in the partial model to allow for designing
+different heat exchanger cofigurations with various level of detal. Furthermore, 
+the geometry of the redeclared heat trasnfer must be correctly set using the geometry 
+record. In addition, the inputs 'fluidProperties' of the conductive heat transfer models 
+must be correctly set using properties of the casing.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library and documentation.
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureComponentAdsorber;
diff --git a/SorpLib/Components/HeatExchanger/BaseClasses/PartialPureSimpleComponentAdsorber.mo b/SorpLib/Components/HeatExchanger/BaseClasses/PartialPureSimpleComponentAdsorber.mo
new file mode 100644
index 0000000..0a13a3d
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/BaseClasses/PartialPureSimpleComponentAdsorber.mo
@@ -0,0 +1,1130 @@
+within SorpLib.Components.HeatExchanger.BaseClasses;
+partial model PartialPureSimpleComponentAdsorber
+  "Base model for all adsorber heat exchangers without a vapor volume for pure component adsorption"
+  extends SorpLib.Components.HeatExchanger.BaseClasses.PartialHeatExchanger(
+    final p_initial,
+    final X_i_initial);
+
+  //
+  // Definition of general parameters
+  //
+  parameter Integer no_fluidVolumes(min=2)=2
+    "Discretization number of fluid volumes"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_wallVolumes(min=2)=no_fluidVolumes
+    "Discretization number of wall volumes (must be a factor of no_fluidVolumes)"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_sorbentVolumes(min=1)=no_wallVolumes
+    "Discretization number of sorbent volumes (must be a factor of no_wallVolumes)"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the geometry
+  //
+  replaceable parameter SorpLib.Components.HeatExchanger.Records.GeometryClosedAdsorber geometry
+    constrainedby
+    SorpLib.Components.HeatExchanger.Records.GeometryClosedAdsorber(
+      no_fluidVolumes=no_fluidVolumes,
+      no_wallVolumes=no_wallVolumes,
+      no_sorbentVolumes=no_sorbentVolumes)
+    "Geometry of the closed adsorber"
+    annotation (Dialog(tab = "General", group = "Geometry"),
+                choicesAllMatching = true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_adsorptiveComponents = 1
+    "Number of adsorptive components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of models describing transport phenomena
+  //
+  parameter Boolean useCasing = false
+    " = true, if casing is modeled"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionCasing = true
+    " = true, if thermal conduction in the casing is modeled"
+    annotation (Dialog(tab="Transport Phenomena", group="General",
+                enable=useCasing),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionPerpendicularFlowDirection = true
+    " = true, if thermal conduction perpendicular to the flow direction is
+    considered within the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionFlowDirection = false
+    " = true, if thermal conduction in the flow direction is considered within 
+    the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcFluidTransportProperties = true
+    " = true, if any transport model needs fluid or transport properties"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useMassRecoveryPorts = false
+    " = true, if mass recovery ports are used"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_InnerWallThermalConductionPerpendicularFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_hx/geometry.no_wallVolumes,
+        d_inner=geometry.d_hydInner_hx,
+        d_outer=(geometry.d_hydInner_hx + geometry.d_hydOuter_hx)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction perpendicular to the
+    flow direction within the heat exchanger wall near the fluid"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionPerpendicularFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model HX_OuterWallThermalConductionPerpendicularFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_hx/geometry.no_wallVolumes,
+        d_inner=(geometry.d_hydInner_hx + geometry.d_hydOuter_hx)/2,
+        d_outer=geometry.d_hydOuter_hx)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction perpendicular to the
+    flow direction within the heat exchanger wall near the heat port"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionPerpendicularFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model HX_WallThermalConductionFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.PlainWall
+      (
+      A_cross=geometry.A_crossWall_hx,
+      delta_wall=(geometry.l_hx/geometry.no_wallVolumes)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction in the flow direction
+    within the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model CS_InnerWallThermalConduction =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_cas,
+        d_inner=geometry.d_hydInner_cas,
+        d_outer=(geometry.d_hydInner_cas + geometry.d_hydOuter_cas)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction within the casing
+    near the phase separator"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useCasing and useConductionCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model CS_OuterWallThermalConduction =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_cas,
+        d_inner=(geometry.d_hydInner_cas + geometry.d_hydOuter_cas)/2,
+        d_outer=geometry.d_hydOuter_cas)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction within the casing
+    near the heat port"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useCasing and useConductionCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_FluidThermalConvectionTubeInside =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.GnielinskiDittusBoelter
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient
+    "Heat transfer correlation describing thermal convection at the tube inside
+    within the heat exchanger (i.e., form the fluid to the wall)"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Convection"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model VV_HeatExchanger =
+    HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlphaA
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialClosedAdsorberHeatTransferCoefficient
+    "Heat transfer correlation describing the heat transfer from the sorbent volumes
+    to heat exchanger tubes"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Convection"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model VV_Casing =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient
+    "Heat transfer correlation describing the heat transfer between the vapor
+    volume and casing"
+    annotation (Dialog(tab="Transport Phenomena", group="Generic",
+                enable = useCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_PressureDrop =
+    SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Konakov
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss
+    "Pressure drop correlation describing the pressure drop of the fluid within
+    the heat exchanger"
+    annotation (Dialog(tab="Transport Phenomena", group="Pressure Drop"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding initial values
+  //
+  parameter Modelica.Units.SI.Pressure p_fluidAInitial = 1.25e5
+    "Initial value of fluid pressure at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Pressure p_fluidBInitial = 1e5
+    "Initial value of fluid pressure at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Temperature T_fluidAInitial = 283.15
+    "Initial value of fluid temperature at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Temperature T_fluidBInitial = 303.15
+    "Initial value of fluid temperature at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+
+  parameter Modelica.Units.SI.Temperature T_wallAInitial = T_fluidAInitial
+    "Initial value of wall temperature at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Wall"));
+  parameter Modelica.Units.SI.Temperature T_wallBInitial = T_fluidBInitial
+    "Initial value of wall temperature at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Wall"));
+
+  parameter Modelica.Units.SI.Pressure p_vaporVolumeInitial = 1e3
+    "Initial value of the vapor pressure"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Vapor"));
+  parameter Modelica.Units.SI.Temperature T_vaporVolumeInitial = 303.15
+    "Initial value of vapor temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Vapor"));
+
+  parameter Modelica.Units.SI.Mass m_sorInitial = 725 * geometry.V_sorbent_hx /
+    geometry.no_sorbentVolumes
+    "Initial value of the sorbent mass"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Sorbent"));
+  parameter SorpLib.Units.Uptake x_sorInitial = 0.15
+    "Initial loading of the sorbent"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Sorbent"));
+  parameter Modelica.Units.SI.Temperature T_sorInitial = 303.15
+    "Initial value of sorbent temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Sorbent"));
+
+  parameter Modelica.Units.SI.Temperature T_casingInitial = 298.15
+    "Initial value of casing temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Casing",
+                enable=useCasing));
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_adsorptive_start = 1e-4
+    "Start value for adsorptive mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in evaporatorPort(final
+      no_components=no_adsorptiveComponents, m_flow(start=
+          m_flow_adsorptive_start)) "Evaporator port" annotation (Placement(
+        transformation(extent={{-110,30},{-90,50}}), iconTransformation(extent={
+            {-110,30},{-90,50}})));
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out condenserPort(final
+      no_components=no_adsorptiveComponents, m_flow(start=-
+          m_flow_adsorptive_start)) "Condenser port" annotation (Placement(
+        transformation(extent={{90,30},{110,50}}), iconTransformation(extent={{90,
+            30},{110,50}})));
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out massRecoveryPorts(
+     no_components=no_adsorptiveComponents,
+     m_flow(start=m_flow_adsorptive_start)) if useMassRecoveryPorts
+    "Mass recovery ports"
+    annotation (Placement(transformation(extent={{-10,50},{10,70}}),
+        iconTransformation(extent={{-10,50},{10,70}})));
+
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_casing if
+    useCasing
+    "Heat ports at casing"
+    annotation (Placement(transformation(extent={{-10,-50},{10,-70}}),
+                iconTransformation(extent={{-10,-70},{10,-50}})));
+
+  //
+  // Definition and instanziation of models
+  //
+  replaceable SorpLib.Components.Fittings.BaseClasses.PartialMultiPort condenserSplitter
+    "Splitter for condenser port" annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={60,30})));
+  replaceable SorpLib.Components.Fittings.BaseClasses.PartialMultiPort evaporatorSplitter
+    "Splitter for evaporator port" annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,30})));
+  replaceable SorpLib.Components.Fittings.BaseClasses.PartialMultiPort massRecoverySplitter if
+       useMassRecoveryPorts
+    "Splitter for mass recovery port"
+                                   annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={30,30})));
+
+  replaceable SorpLib.Components.Tubes.BaseClasses.PartialTube heatExchangerTubes(
+    final no_fluidVolumes=no_fluidVolumes,
+    final no_wallVolumes=no_wallVolumes,
+    redeclare final SorpLib.Components.Tubes.Records.GeometryTube geometry(
+      no_hydraulicParallelTubes=geometry.no_hydraulicParallelTubes,
+      l=geometry.l_hx,
+      roughness=geometry.roughness_hx,
+      d_inner=geometry.d_inner_hx,
+      d_outer=geometry.d_outer_hx,
+      d_hydInner=geometry.d_hydInner_hx,
+      d_hydOuter=geometry.d_hydOuter_hx,
+      t_wall=geometry.t_wall_hx,
+      A_crossInner=geometry.A_crossInner_hx,
+      A_crossOuter=geometry.A_crossOuter_hx,
+      A_crossWall=geometry.A_crossWall_hx,
+      A_hydCrossInner=geometry.A_hydCrossInner_hx,
+      A_hydCrossOuter=geometry.A_hydCrossOuter_hx,
+      A_hydCrossWall=geometry.A_hydCrossWall_hx,
+      A_heatTransferInner=geometry.A_heatTransferInner_hx,
+      A_heatTransferOuter=geometry.A_heatTransferOuter_hx,
+      f_finAreaRatioInner=geometry.f_finAreaRatioInner_hx,
+      f_finAreaRatioOuter=geometry.f_finAreaRatioOuter_hx,
+      V_inner=geometry.V_inner_hx,
+      V_outer=geometry.V_outer_hx,
+      V_wall=geometry.V_wall_hx,
+      f_finVolumeRatioInner=geometry.f_finVolumeRatioInner_hx,
+      f_finVolumeRatioOuter=geometry.f_finVolumeRatioOuter_hx),
+    final useConductionPerpendicularFlowDirection=
+      useConductionPerpendicularFlowDirection,
+    final useConductionFlowDirection=useConductionFlowDirection,
+    final calcFluidTransportProperties=calcFluidTransportProperties,
+    redeclare final model InnerWallThermalConductionPerpendicularFlowDirection =
+      HX_InnerWallThermalConductionPerpendicularFlowDirection,
+    redeclare final model OuterWallThermalConductionPerpendicularFlowDirection =
+      HX_OuterWallThermalConductionPerpendicularFlowDirection,
+    redeclare final model WallThermalConductionFlowDirection =
+      HX_WallThermalConductionFlowDirection,
+    redeclare final model FluidThermalConvectionTubeInside =
+      HX_FluidThermalConvectionTubeInside,
+    redeclare final model PressureDrop = HX_PressureDrop,
+    final p_fluidAInitial=p_fluidAInitial,
+    final p_fluidBInitial=p_fluidBInitial,
+    final T_fluidAInitial=T_fluidAInitial,
+    final T_fluidBInitial=T_fluidBInitial,
+    final T_wallAInitial=T_wallAInitial,
+    final T_wallBInitial=T_wallBInitial,
+    final m_flow_start=m_flow_start,
+    final type_overallMassBalance=type_overallMassBalance,
+    final type_independentMassBalances=type_independentMassBalances,
+    final avoid_events=avoid_events,
+    final m_flow_small=m_flow_small,
+    final noDiff=noDiff)
+    "Heat exchanger tubes"
+    annotation (Placement(transformation(extent={{40,-90},{60,-70}})));
+
+  replaceable SorpLib.Basics.Volumes.BaseClasses.PartialVolume casing(
+    final useHeatPortsX=false,
+    final useHeatPortsY=true,
+    final useHeatPortsZ=false,
+    final type_energyBalance=type_energyBalance,
+    final avoid_events=avoid_events) if useCasing
+    "Casing"
+    annotation (Placement(transformation(extent={{-68,10},{-48,-10}})));
+
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_sorbentVolumesToCasing(
+    final n_a=no_sorbentVolumes,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient = VV_Casing) if
+                    useCasing "Heat transfer from sorbent volumes to casing"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={-32,0})));
+
+  HeatTransfer.ConductionHeatTransfer thermalConduction_casing1(
+    final n_a=1,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient =
+        CS_InnerWallThermalConduction,
+    final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    (useCasing and useConductionCasing)
+    "Thermal conduction of the first casing half"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={-58,22})));
+
+  HeatTransfer.ConductionHeatTransfer thermalConduction_casing2(
+    final n_a=1,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient =
+        CS_OuterWallThermalConduction,
+    final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    (useCasing and useConductionCasing)
+    "Thermal conduction of the second casing half"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={-58,-22})));
+
+  //
+  // Definition of protected parameters
+  //
+protected
+  final parameter Integer factorDiscretization=
+    integer(max(no_sorbentVolumes,no_wallVolumes)/
+    min(no_sorbentVolumes,no_wallVolumes))
+    "Discretization factor"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+
+equation
+  //
+  // Assertations
+  //
+  if no_wallVolumes < no_fluidVolumes then
+    assert(rem(no_fluidVolumes, no_wallVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of fluid volumes!");
+
+  elseif no_wallVolumes > no_fluidVolumes then
+    assert(rem(no_wallVolumes, no_fluidVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of fluid volumes!");
+
+  end if;
+
+  if no_wallVolumes < no_sorbentVolumes then
+    assert(rem(no_sorbentVolumes, no_wallVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of sorbent volumes!");
+
+  elseif no_wallVolumes > no_sorbentVolumes then
+    assert(rem(no_wallVolumes, no_sorbentVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of sorbent volumes!");
+
+  end if;
+
+  //
+  // Connection of fluid ports
+  //
+  connect(port_a, heatExchangerTubes.fp_a) annotation (Line(points={{-100,0},{-80,
+          0},{-80,-80},{40,-80}}, color={0,0,0}));
+  connect(heatExchangerTubes.fp_b, port_b) annotation (Line(points={{60,-80},{80,
+          -80},{80,0},{100,0}}, color={0,0,0}));
+
+  //
+  // Connection of heat ports
+  //
+
+  if useCasing then
+    if useConductionCasing then
+      connect(heatTransfer_sorbentVolumesToCasing.hp_b[1],
+        thermalConduction_casing1.hp_a[1]) annotation (Line(
+          points={{-40,4.44089e-16},{-42,4.44089e-16},{-42,32},{-58,32},{-58,30}},
+          color={238,46,47},
+          thickness=1));
+
+      connect(thermalConduction_casing1.hp_b[1], casing.hp_yMinus) annotation (Line(
+          points={{-58,14},{-58,6}},
+          color={238,46,47},
+          thickness=1));
+      connect(casing.hp_yPlus, thermalConduction_casing2.hp_a[1]) annotation (Line(
+          points={{-58,-6},{-58,-14}},
+          color={238,46,47},
+          thickness=1));
+      connect(thermalConduction_casing2.hp_b[1], hp_casing) annotation (Line(
+          points={{-58,-30},{-58,-32},{0,-32},{0,-60}},
+          color={238,46,47},
+          thickness=1));
+
+    else
+      connect(heatTransfer_sorbentVolumesToCasing.hp_b[1], hp_casing);
+
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Rectangle(
+          extent={{-100,60},{100,-60}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Line(
+          points={{100,40},{-80,40},{80,0},{-80,-40},{100,-40}},
+          color={0,0,0},
+          thickness=1),
+        Ellipse(
+          extent={{-74,42},{-80,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,42},{-20,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,42},{-32,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-38,42},{-44,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,42},{-56,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,42},{-68,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,42},{52,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,42},{40,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,42},{28,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,42},{16,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,42},{4,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-2,42},{-8,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,42},{64,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{82,42},{76,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{82,-48},{76,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-48},{64,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,-48},{52,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,-48},{40,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,-48},{28,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,-48},{16,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-48},{4,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-2,-48},{-8,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,-48},{-20,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,-48},{-32,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-38,-48},{-44,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,-48},{-56,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,-48},{-68,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-74,-48},{-80,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{88,-38},{82,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,-38},{70,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{64,-38},{58,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,-38},{46,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,-38},{34,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,-38},{22,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,-38},{10,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,-38},{-2,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,-38},{-14,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-20,-38},{-26,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-32,-38},{-38,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,-40},{-50,-34}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,34},{-50,40}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-32,32},{-38,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-20,32},{-26,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,32},{-14,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,32},{-2,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,32},{10,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,32},{22,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,32},{34,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,32},{46,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{64,32},{58,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,32},{70,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{88,32},{82,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,30},{-72,36}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-52,26},{-58,32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-36,22},{-42,28}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,18},{-24,24}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-4,14},{-10,20}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{12,10},{6,16}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,6},{24,12}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{44,2},{38,8}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{60,-2},{54,4}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,24},{-14,30}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{6,20},{0,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,16},{16,22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{38,12},{32,18}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,8},{46,14}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{68,4},{62,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,-36},{-72,-30}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-52,-32},{-58,-26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-36,-28},{-42,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,-24},{-24,-18}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-4,-20},{-10,-14}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{12,-16},{6,-10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,-12},{24,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{44,-8},{38,-2}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{68,-10},{62,-4}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,-14},{46,-8}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{38,-18},{32,-12}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{24,-22},{18,-16}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{6,-26},{0,-20}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,-30},{-14,-24}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,24},{-50,30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,34},{-60,40}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-76,34},{-82,40}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,42},{-14,48}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,26},{-20,32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,12},{-2,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,14},{24,20}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,0},{46,6}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,32},{28,38}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,42},{70,48}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{82,32},{76,38}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{20,-14},{14,-8}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-28,-26},{-34,-20}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-52,-40},{-58,-34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-78,-42},{-84,-36}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-32,-48},{-38,-42}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-38},{4,-32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,-48},{34,-42}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-38},{64,-32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,-16},{40,-10}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid)}),
+    Diagram(coordinateSystem(extent={{-100,-100},{100,100}})),
+    Documentation(info="<html>
+<p>
+This partial model is the base model for all closed adsorber heat exchanger without vapor
+volumes. It defines fundamental parameters, models, and variables required by all adsorbers. 
+Models that inherit properties from this partial model have to redeclare all partial models 
+(i.e., fluid ports, tube, vapor volume, and casing). Moreover, sorbent volumes must be
+added as well as a mass transfer model describing the mass transfer between the sorbent 
+and vapor and a heat transfer model describing the heat transfer between the sorbent and
+heat exchanger. These models are not inserted in the partial model to allow for designing
+different heat exchanger cofigurations with various level of detal. Furthermore, 
+the geometry of the redeclared heat trasnfer must be correctly set using the geometry 
+record. In addition, the inputs 'fluidProperties' of the conductive heat transfer models 
+must be correctly set using properties of the casing.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library and documentation.
+  </li>
+  <li>
+  January 19, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureSimpleComponentAdsorber;
diff --git a/SorpLib/Components/HeatExchanger/BaseClasses/PartialSimpleCondenserEvaporator.mo b/SorpLib/Components/HeatExchanger/BaseClasses/PartialSimpleCondenserEvaporator.mo
new file mode 100644
index 0000000..b713ead
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/BaseClasses/PartialSimpleCondenserEvaporator.mo
@@ -0,0 +1,629 @@
+within SorpLib.Components.HeatExchanger.BaseClasses;
+partial model PartialSimpleCondenserEvaporator
+  "Base model for all simple condensers and evaporators"
+  extends SorpLib.Components.HeatExchanger.BaseClasses.PartialHeatExchanger(
+    final p_initial,
+    final X_i_initial);
+
+  //
+  // Definition of general parameters
+  //
+  parameter Integer nPortsLiquid = 0
+    "Number of liquid VLE ports"
+    annotation (Dialog(connectorSizing=true),
+                HideResult = true);
+  parameter Integer nPortsVapor = 0
+    "Number of vapor VLE ports"
+    annotation (Dialog(connectorSizing=true),
+                HideResult = true);
+
+  parameter Integer no_fluidVolumes(min=2)=10
+    "Discretization number of fluid volumes"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_wallVolumes(min=2)=no_fluidVolumes
+    "Discretization number of wall volumes (must be a factor of no_fluidVolumes)"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the geometry
+  //
+  replaceable parameter SorpLib.Components.HeatExchanger.Records.GeometryCondenserEvaporator geometry
+    constrainedby
+    SorpLib.Components.HeatExchanger.Records.GeometryCondenserEvaporator(
+      no_fluidVolumes=no_fluidVolumes,
+      no_wallVolumes=no_wallVolumes)
+    "Geometry of the condenser or evaporator"
+    annotation (Dialog(tab = "General", group = "Geometry"),
+                choicesAllMatching = true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_VLEcomponents = 1
+    "Number of components within the VLE"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of models describing transport phenomena
+  //
+  parameter Boolean useCasing = false
+    " = true, if casing is modeled"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionCasing = true
+    " = true, if thermal conduction in the casing is modeled"
+    annotation (Dialog(tab="Transport Phenomena", group="General",
+                enable=useCasing),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionPerpendicularFlowDirection = true
+    " = true, if thermal conduction perpendicular to the flow direction is
+    considered within the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionFlowDirection = false
+    " = true, if thermal conduction in the flow direction is considered within 
+    the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcFluidTransportProperties = true
+    " = true, if any transport model needs fluid or transport properties"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer fluidPropertyPosition = 1
+    "Defines the position for fluid porperty calculation is discretization number
+    is different"
+    annotation (Dialog(tab="Transport Phenomena", group="General",
+                enable=no_fluidVolumes<>no_wallVolumes),
+                choices(choice=1 "First volume near port a",
+                        choice=2 "First volume near port b",
+                        choice=3 "Properties averaged over volumes"),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_InnerWallThermalConductionPerpendicularFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_hx/geometry.no_wallVolumes,
+        d_inner=geometry.d_hydInner_hx,
+        d_outer=(geometry.d_hydInner_hx + geometry.d_hydOuter_hx)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction perpendicular to the
+    flow direction within the heat exchanger wall near the fluid"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionPerpendicularFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model HX_OuterWallThermalConductionPerpendicularFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_hx/geometry.no_wallVolumes,
+        d_inner=(geometry.d_hydInner_hx + geometry.d_hydOuter_hx)/2,
+        d_outer=geometry.d_hydOuter_hx)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction perpendicular to the
+    flow direction within the heat exchanger wall near the heat port"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionPerpendicularFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model HX_WallThermalConductionFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.PlainWall
+      (
+      A_cross=geometry.A_crossWall_hx,
+      delta_wall=(geometry.l_hx/geometry.no_wallVolumes)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction in the flow direction
+    within the heat exchanger wall"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model CS_InnerWallThermalConduction =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_cas,
+        d_inner=geometry.d_hydInner_cas,
+        d_outer=(geometry.d_hydInner_cas + geometry.d_hydOuter_cas)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction within the casing
+    near the phase separator"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useCasing and useConductionCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model CS_OuterWallThermalConduction =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l_cas,
+        d_inner=(geometry.d_hydInner_cas + geometry.d_hydOuter_cas)/2,
+        d_outer=geometry.d_hydOuter_cas)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction within the casing
+    near the heat port"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useCasing and useConductionCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_FluidThermalConvectionTubeInside =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.GnielinskiDittusBoelter
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient
+    "Heat transfer correlation describing thermal convection at the tube inside
+    within the heat exchanger (i.e., form the fluid to the wall)"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Convection"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model PS_Casing =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient
+    "Heat transfer correlation describing the heat transfer between the phase
+    separator and casing"
+    annotation (Dialog(tab="Transport Phenomena", group="Generic",
+                enable = useCasing),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model HX_PressureDrop =
+    SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Konakov
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss
+    "Pressure drop correlation describing the pressure drop of the fluid within
+    the heat exchanger"
+    annotation (Dialog(tab="Transport Phenomena", group="Pressure Drop"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding initial values
+  //
+  parameter Modelica.Units.SI.Pressure p_fluidAInitial = 1.25e5
+    "Initial value of fluid pressure at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Pressure p_fluidBInitial = 1e5
+    "Initial value of fluid pressure at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Temperature T_fluidAInitial = 283.15
+    "Initial value of fluid temperature at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+  parameter Modelica.Units.SI.Temperature T_fluidBInitial = 303.15
+    "Initial value of fluid temperature at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Fluid"));
+
+  parameter Modelica.Units.SI.Temperature T_wallAInitial = T_fluidAInitial
+    "Initial value of wall temperature at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Wall"));
+  parameter Modelica.Units.SI.Temperature T_wallBInitial = T_fluidBInitial
+    "Initial value of wall temperature at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - HX Wall"));
+
+  parameter Modelica.Units.SI.Density d_phaseSeparatorInitial = 300
+    "Initial value of phase separator density"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Phase Separator"));
+  parameter Modelica.Units.SI.Temperature T_phaseSeparatorInitial = 288.15
+    "Initial value of phase separator temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Phase Separator"));
+
+  parameter Modelica.Units.SI.Temperature T_casingInitial = 298.15
+    "Initial value of casing temperature"
+    annotation (Dialog(tab="Initialisation", group="Initial Values - Casing",
+                enable=useCasing));
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_VLE_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of ports
+  //
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in[nPortsLiquid] liquidPort(
+    each final no_components=no_VLEcomponents,
+    each m_flow(start=m_flow_VLE_start))
+    "Liquid port"
+    annotation (Placement(transformation(extent={{-10,-28},{10,-48}}),
+        iconTransformation(extent={{-10,-48},{10,-28}})));
+  SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out[nPortsVapor] vaporPort(
+    each final no_components=no_VLEcomponents,
+    each m_flow(start=-m_flow_VLE_start))
+    "Vapor port"
+    annotation (Placement(transformation(extent={{-10,32},{10,52}}),
+        iconTransformation(extent={{-10,32},{10,52}})));
+
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in hp_casing if
+    useCasing
+    "Heat ports at casing"
+    annotation (Placement(transformation(extent={{-60,30},{-40,50}}),
+                iconTransformation(extent={{-60,30},{-40,50}})));
+
+  //
+  // Definition and instanziation of models
+  //
+  replaceable SorpLib.Basics.Volumes.BaseClasses.PartialPhaseSeparatorVolume
+    phaseSeparatorVolume(
+    final calculateAdditionalProperties=calcFluidTransportProperties,
+    final T_initial=T_phaseSeparatorInitial,
+    final rho_initial=d_phaseSeparatorInitial,
+    final mc_flow_initialX=m_flow_VLE_start,
+    redeclare final SorpLib.Basics.Volumes.Records.PhaseSeparatorGeometry geometry(
+      dx=0,
+      dy=0,
+      dz=0,
+      A_xy=0,
+      A_xz=0,
+      A_yz=0,
+      V=geometry.V_refrigerant,
+      A_base=geometry.A_refrigerant),
+    final useHeatPorts=true,
+    final useHeatPortsX=false,
+    final useHeatPortsY=true,
+    final useHeatPortsZ=false,
+    final type_energyBalance=type_energyBalance,
+    final type_overallMassBalance=type_overallMassBalance,
+    final avoid_events=avoid_events,
+    nPorts_cfp_xMinus=nPortsLiquid,
+    nPorts_cfp_xPlus=nPortsVapor)
+    "Phase separator"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,0})));
+
+  replaceable SorpLib.Components.Tubes.BaseClasses.PartialTube heatExchangerTubes(
+    final no_fluidVolumes=no_fluidVolumes,
+    final no_wallVolumes=no_wallVolumes,
+    redeclare final SorpLib.Components.Tubes.Records.GeometryTube geometry(
+      no_hydraulicParallelTubes=geometry.no_hydraulicParallelTubes,
+      l=geometry.l_hx,
+      roughness=geometry.roughness_hx,
+      d_inner=geometry.d_inner_hx,
+      d_outer=geometry.d_outer_hx,
+      d_hydInner=geometry.d_hydInner_hx,
+      d_hydOuter=geometry.d_hydOuter_hx,
+      t_wall=geometry.t_wall_hx,
+      A_crossInner=geometry.A_crossInner_hx,
+      A_crossOuter=geometry.A_crossOuter_hx,
+      A_crossWall=geometry.A_crossWall_hx,
+      A_hydCrossInner=geometry.A_hydCrossInner_hx,
+      A_hydCrossOuter=geometry.A_hydCrossOuter_hx,
+      A_hydCrossWall=geometry.A_hydCrossWall_hx,
+      A_heatTransferInner=geometry.A_heatTransferInner_hx,
+      A_heatTransferOuter=geometry.A_heatTransferOuter_hx,
+      f_finAreaRatioInner=geometry.f_finAreaRatioInner_hx,
+      f_finAreaRatioOuter=geometry.f_finAreaRatioOuter_hx,
+      V_inner=geometry.V_inner_hx,
+      V_outer=geometry.V_outer_hx,
+      V_wall=geometry.V_wall_hx,
+      f_finVolumeRatioInner=geometry.f_finVolumeRatioInner_hx,
+      f_finVolumeRatioOuter=geometry.f_finVolumeRatioOuter_hx),
+    final useConductionPerpendicularFlowDirection=
+      useConductionPerpendicularFlowDirection,
+    final useConductionFlowDirection=useConductionFlowDirection,
+    final calcFluidTransportProperties=calcFluidTransportProperties,
+    final fluidPropertyPosition=fluidPropertyPosition,
+    redeclare final model InnerWallThermalConductionPerpendicularFlowDirection =
+      HX_InnerWallThermalConductionPerpendicularFlowDirection,
+    redeclare final model OuterWallThermalConductionPerpendicularFlowDirection =
+      HX_OuterWallThermalConductionPerpendicularFlowDirection,
+    redeclare final model WallThermalConductionFlowDirection =
+      HX_WallThermalConductionFlowDirection,
+    redeclare final model FluidThermalConvectionTubeInside =
+      HX_FluidThermalConvectionTubeInside,
+    redeclare final model PressureDrop = HX_PressureDrop,
+    final p_fluidAInitial=p_fluidAInitial,
+    final p_fluidBInitial=p_fluidBInitial,
+    final T_fluidAInitial=T_fluidAInitial,
+    final T_fluidBInitial=T_fluidBInitial,
+    final T_wallAInitial=T_wallAInitial,
+    final T_wallBInitial=T_wallBInitial,
+    final m_flow_start=m_flow_start,
+    final type_overallMassBalance=type_overallMassBalance,
+    final type_independentMassBalances=type_independentMassBalances,
+    final avoid_events=avoid_events,
+    final m_flow_small=m_flow_small,
+    final noDiff=noDiff)
+    "Heat exchanger tubes"
+    annotation (Placement(transformation(extent={{40,-60},{60,-40}})));
+
+  replaceable SorpLib.Basics.Volumes.BaseClasses.PartialVolume casing(
+    final useHeatPortsX=false,
+    final useHeatPortsY=true,
+    final useHeatPortsZ=false,
+    final type_energyBalance=type_energyBalance,
+    final avoid_events=avoid_events) if useCasing
+    "Casing"
+    annotation (Placement(transformation(extent={{-60,-10},{-40,10}})));
+
+  replaceable SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransfer
+    heatTransfer_HeatExchangerToPhaseSeparator(
+    final n_a=no_wallVolumes,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties)
+    "Heat transfer from heat exchanger to phase separator" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={50,-20})));
+
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_phaseSeparatorToCasing(
+    final n_a=1,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient =
+        PS_Casing) if useCasing
+    "Heat transfer from phase seprator to casing"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={-24,0})));
+
+  HeatTransfer.ConductionHeatTransfer thermalConduction_casing1(
+    final n_a=1,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient =
+        CS_InnerWallThermalConduction,
+    final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    (useCasing and useConductionCasing)
+    "Thermal conduction of the first casing half"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={-50,-24})));
+
+  HeatTransfer.ConductionHeatTransfer thermalConduction_casing2(
+    final n_a=1,
+    final n_b=1,
+    final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare final model HeatTransferCoefficient =
+        CS_OuterWallThermalConduction,
+    final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    (useCasing and useConductionCasing)
+    "Thermal conduction of the second casing half"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={-50,24})));
+
+equation
+  //
+  // Assertations
+  //
+  if no_wallVolumes < no_fluidVolumes then
+    assert(rem(no_fluidVolumes, no_wallVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of fluid volumes!");
+
+  elseif no_wallVolumes > no_fluidVolumes then
+    assert(rem(no_wallVolumes, no_fluidVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of fluid volumes!");
+
+  end if;
+
+  //
+  // Connection of fluid ports
+  //
+  connect(port_a, heatExchangerTubes.fp_a) annotation (Line(points={{-100,0},{-80,
+          0},{-80,-50},{40,-50}}, color={0,0,0}));
+  connect(heatExchangerTubes.fp_b, port_b) annotation (Line(points={{60,-50},{80,
+          -50},{80,0},{100,0}}, color={0,0,0}));
+  connect(liquidPort, phaseSeparatorVolume.cfp_xMinus) annotation (Line(
+      points={{0,-38},{0,-20},{-1.8,-20},{-1.8,-4.2}},
+      color={0,140,72},
+      thickness=1));
+  connect(vaporPort, phaseSeparatorVolume.cfp_xPlus) annotation (Line(
+      points={{0,42},{0,20},{-1.8,20},{-1.8,7.8}},
+      color={0,140,72},
+      thickness=1));
+
+  //
+  // Connection of heat ports
+  //
+  connect(heatExchangerTubes.hp_wall,
+    heatTransfer_HeatExchangerToPhaseSeparator.hp_a) annotation (Line(
+      points={{50,-46},{50,-28}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_HeatExchangerToPhaseSeparator.hp_b[1],
+    phaseSeparatorVolume.hp_yMinus) annotation (Line(
+      points={{50,-12},{50,0},{6,0}},
+      color={238,46,47},
+      thickness=1));
+
+  if useCasing then
+    connect(phaseSeparatorVolume.hp_yPlus, heatTransfer_phaseSeparatorToCasing.hp_a[
+      1]) annotation (Line(
+        points={{-6,0},{-16,0}},
+        color={238,46,47},
+        thickness=1));
+
+    if useConductionCasing then
+      connect(heatTransfer_phaseSeparatorToCasing.hp_b[1],
+        thermalConduction_casing1.hp_a[1]) annotation (Line(
+          points={{-32,0},{-36,0},{-36,-40},{-50,-40},{-50,-32}},
+          color={238,46,47},
+          thickness=1));
+      connect(thermalConduction_casing1.hp_b[1], casing.hp_yMinus) annotation (Line(
+          points={{-50,-16},{-50,-6}},
+          color={238,46,47},
+          thickness=1));
+      connect(casing.hp_yPlus, thermalConduction_casing2.hp_a[1]) annotation (Line(
+          points={{-50,6},{-50,16}},
+          color={238,46,47},
+          thickness=1));
+      connect(thermalConduction_casing2.hp_b[1], hp_casing) annotation (Line(
+          points={{-50,32},{-50,40}},
+          color={238,46,47},
+          thickness=1));
+
+    else
+      connect(heatTransfer_phaseSeparatorToCasing.hp_b[1], hp_casing);
+
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},
+            {100,100}}),                                        graphics={
+        Text(
+          extent={{-60,30},{-40,10}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.None,
+          fontSize=20,
+          textString="1"),
+        Text(
+          extent={{40,30},{60,10}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.None,
+          fontSize=20,
+          textString="n"),
+        Line(
+          points={{0,40},{0,22},{-2,14},{2,0},{-2,-14},{2,-24},{0,-40}},
+          color={0,0,0},
+          smooth=Smooth.Bezier),
+        Rectangle(
+          extent={{-100,-2},{100,-40}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-100,-10},{-80,8},{-54,-2},{-36,0},{-6,6},{14,-2},{42,4},{74,
+              4},{94,-6},{-100,-10}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          smooth=Smooth.Bezier,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{-100,40},{100,-40}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Polygon(
+          points={{-20,4},{-20,4},{-32,18},{-8,18},{-20,4}},
+          lineColor={0,0,0},
+          lineThickness=0.5),
+        Ellipse(
+          extent={{-66,38},{-78,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-28,38},{-40,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-12,38},{-24,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,22},{4,10}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,38},{16,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{36,22},{24,10}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,24},{-70,12}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,38},{62,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{48,38},{36,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{86,24},{74,12}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-84,34},{-96,22}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid)}),
+    Diagram(coordinateSystem(extent={{-100,-100},{100,100}})),
+    Documentation(info="<html>
+<p>
+This partial model is the base model for all condensers and evaporators. It defines 
+fundamental parameters, models, and variables required by all condensers and evaporators.
+Models that inherit properties from this partial model have to redeclare all partial 
+models (i.e., fluid ports, tube, phase separator, casing, and heat transfer). Morover, 
+the geometry of the redeclared heat trasnfer must be correctly set using the geometry 
+record. In addition, the inputs 'fluidProperties' of the conductive heat transfer models 
+must be correctly set using properties of the casing.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 4, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation, including major revisions, after restructuring of the library.
+  </li>
+</ul>
+</html>"));
+end PartialSimpleCondenserEvaporator;
diff --git a/SorpLib/Components/HeatExchanger/BaseClasses/PartialSimpleDryCooler.mo b/SorpLib/Components/HeatExchanger/BaseClasses/PartialSimpleDryCooler.mo
new file mode 100644
index 0000000..b134239
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/BaseClasses/PartialSimpleDryCooler.mo
@@ -0,0 +1,392 @@
+within SorpLib.Components.HeatExchanger.BaseClasses;
+partial model PartialSimpleDryCooler
+  "Base model for all simple dry coolers"
+  extends SorpLib.Components.HeatExchanger.BaseClasses.PartialHeatExchanger(
+    final type_energyBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    final type_independentMassBalances=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    final type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial);
+
+  //
+  // Definition of general parameters
+  //
+  parameter Modelica.Units.SI.Pressure p_air = 1.01325e5
+    "Ambient pressure (i.e., used to calculate air properties)"
+    annotation (Dialog(tab="General", group="Ambient Conditions"));
+  parameter Modelica.Units.SI.Temperature T_air_in = 273.15 + 25
+    "Ambient temperature (i.e., used to calculate air properties)"
+    annotation (Dialog(tab="General", group="Ambient Conditions"));
+
+  parameter Integer flowDirection = 1
+    "Definition of flow direction of liquid stream: Relevant for energy balance"
+    annotation (Dialog(tab="General", group="Recooler Specifications"),
+                choices(choice=1 "A_to_B",
+                        choice=2 "B_to_A",
+                        choice=3 "Actual flow direction"),
+                Evaluate=true,
+                HideResult=true);
+  replaceable parameter SorpLib.Components.HeatExchanger.Records.ParametrizationDryCooler
+    typeDryRecooler
+    constrainedby
+    SorpLib.Components.HeatExchanger.Records.ParametrizationDryCooler
+    "Paremetrization record of recooler"
+    annotation (Dialog(tab="General", group="Recooler Specifications"),
+                Evaluate=true,
+                choicesAllMatching=true);
+  parameter Real scaleFactor = 1
+    "Scaling factor for recooler: In reality, only integers are sound since
+    they correspond to the number of fans"
+    annotation (Dialog(tab="General", group="Recooler Specifications"));
+
+  //
+  // Definition of scaled specification parameters
+  //
+  final parameter Modelica.Units.SI.MassFlowRate m_flow_liq_nom=
+    typeDryRecooler.m_flow_liq_nom * scaleFactor
+    "Scaled nominal mass flow rate of liquid"
+    annotation (HideResult=true);
+  final parameter Modelica.Units.SI.VolumeFlowRate V_flow_air_max=
+    typeDryRecooler.V_flow_air_max * scaleFactor
+    "Scaled maximal volume flow rate of air"
+    annotation (HideResult=true);
+  final parameter Modelica.Units.SI.Power  P_el_fan_max=
+    typeDryRecooler.P_el_fan_max * scaleFactor
+    "Scaled maximal electrical power consumption of fan unit"
+    annotation (HideResult=true);
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput relativeFanSpeed
+    "Input defining relative volume flow rate of air"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,-60}), iconTransformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,-60})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.ThermalConductance UA_internal
+    "Internal effective heat trasfer coefficient (i.e., liquid side)";
+  Modelica.Units.SI.ThermalConductance UA_external
+    "External effective heat trasfer coefficient (i.e., air side)";
+
+  Real C_air(unit="W/K")
+    "Heat capacity rate of air";
+  Real C_liquid(unit="W/K")
+    "Heat capacity rate of liquid";
+  Real C_min(unit="W/K") = min(C_air, C_liquid)
+    "Minimum heat capacity rate";
+  Real C_max(unit="W/K") = max(C_air, C_liquid)
+    "Maximum heat capacity rate";
+  Real C_ratio(unit="1") = C_min/C_max
+    "Ratio between minimum and maximum heat capacity rates";
+
+  Real NTU(unit="1")
+    "Number of transfer units";
+  Real efficiency(unit="1")
+    "Efficiency of dry cooler";
+
+  Modelica.Units.SI.HeatFlowRate Q_flow_max
+    "Maximum heat flow rate that could be transferred";
+  Modelica.Units.SI.HeatFlowRate Q_flow
+    "Actual heat flow rate that is transferred from liquid to air";
+
+  Modelica.Units.SI.MassFlowRate m_flow_air
+    "Mass flow rate of air";
+  Modelica.Units.SI.VolumeFlowRate V_flow_air
+    "Volume flow rate of air";
+
+  Modelica.Units.SI.PressureDifference dp_liq
+    "Pressure drop at liquid side";
+
+  Modelica.Units.SI.Power P_el_fans
+    "Total electrical power consumption of fan unit";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.Temperature T_liq_in
+    "Inlet temperature of liquid";
+  Modelica.Units.SI.SpecificHeatCapacity cp_liq_in
+    "Specific heat capacity of liquid at inlet";
+  Modelica.Units.SI.DynamicViscosity eta_liq_in
+    "Dynamic viscosity of liquid at inlet";
+
+  Modelica.Units.SI.Temperature T_air_out
+    "Outlet temperature of air";
+  Modelica.Units.SI.Density d_air_in
+    "Density of air at inlet";
+  Modelica.Units.SI.SpecificHeatCapacity cp_air_in
+    "Specific heat capacity of air at inlet";
+
+equation
+  //
+  // Momentum balance
+  //
+  dp_liq = port_a.p - port_b.p
+    "Pressure drop of liquid";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + port_b.m_flow
+    "Steady-state mass balance of liquid";
+
+  port_a.Xi_outflow = inStream(port_b.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+  port_b.Xi_outflow = inStream(port_a.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+
+  //
+  // Energy balance
+  //
+  port_a.h_outflow = inStream(port_b.h_outflow) - Q_flow / port_b.m_flow
+    "Steady-state energy balance depends on the flow direction";
+  port_b.h_outflow = inStream(port_a.h_outflow) - Q_flow / port_a.m_flow
+    "Steady-state energy balance depends on the flow direction";
+
+  T_air_out = T_air_in + Q_flow/scaleFactor / C_air
+    "Outlet temperature of air: Rescaling (see calculation of C_air)";
+
+  //
+  // NTU-method for heat exchangers
+  //
+  V_flow_air = V_flow_air_max * relativeFanSpeed
+    "Calculate actual volume flow rate of air (i.e., corresponds to load of dry
+     cooler)";
+  m_flow_air = V_flow_air * d_air_in
+    "Mass flow rate of air";
+
+  UA_internal = 2 * typeDryRecooler.delta *
+    (((abs(port_a.m_flow) / scaleFactor)^0.8) / (eta_liq_in^0.5))
+    "Internal effective heat transfer coefficient: Division by scaling factor
+     since mass flow rate is devided equally between fan units";
+  UA_external = 0.35 * typeDryRecooler.gamma * cp_air_in *
+    ((m_flow_air / scaleFactor)^0.8)
+    "External effective heat transfer coefficient: Division by scaling factor
+     since mass flow rate is devided equally between fan units";
+
+  C_air = m_flow_air/scaleFactor * cp_air_in
+    "Heat capacity rate of air: Division by scaling factor
+     since mass flow rate is devided equally between fan units";
+  C_liquid = abs(port_a.m_flow)/scaleFactor * cp_liq_in
+    "Heat capacity rate of liquid: Division by scaling factor
+     since mass flow rate is devided equally between fan units";
+
+  NTU = (UA_external * UA_internal / (UA_external + UA_internal)) / C_min
+    "Number of transfer units";
+  efficiency = (1 - exp(-NTU * (1  -C_ratio))) /
+    (1 - C_ratio * exp(-NTU * (1 - C_ratio)))
+    "Efficiency of dry cooler: Counter-flow arrangement";
+
+  Q_flow_max = C_min * (T_liq_in-T_air_in) * scaleFactor
+    "Maximum heat flow rate that could be transferred theoretically:
+     Rescaling (see calculation of C_i)";
+  Q_flow = Q_flow_max * efficiency
+    "Actual heat flow rate that is transferred";
+
+  //
+  // Apply affinity laws for pressure drop and power consumption calculations
+  //
+  if avoid_events then
+    dp_liq = typeDryRecooler.dp_liq_nom * SorpLib.Numerics.regSquare_noEvent(
+      x=port_a.m_flow,
+      delta_x=max(m_flow_small, 0.005 * m_flow_liq_nom)) /
+      m_flow_liq_nom^2
+      "Pressure drop of liquid";
+
+  else
+    dp_liq = typeDryRecooler.dp_liq_nom * SorpLib.Numerics.regSquare(
+      x=port_a.m_flow,
+      delta_x=max(m_flow_small, 0.005 * m_flow_liq_nom)) /
+      m_flow_liq_nom^2
+      "Pressure drop of liquid";
+
+  end if;
+
+  P_el_fans = ((V_flow_air / V_flow_air_max)^3) * P_el_fan_max
+    "Total electrical power consumption of fan unit";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all simple dry coolers. It defines the
+required parameters and variables and adds all relevant equations. Models that 
+inherit properties from this partial model have to redeclare the fluid ports. Moreover, 
+fluid properties at inlets must be added.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Liquid inlet temperature <i>T_liq_in</i>.
+  </li>
+  <li>
+  Specific heat capacity of the liquid at the inlet <i>cp_liq_in</i>.
+  </li>
+  <li>
+  Dynamic viscosity of the liquid at the inlet <i>eta_liq_in</i>.
+  </li>
+  <br/>
+  <li>
+  Specific heat capacity of the air at the inlet <i>cp_air_in</i>.
+  </li>
+  <li>
+  Density of the air at the inlet <i>d_air_in</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 26, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Polygon(
+          points={{-100,40},{-100,-40},{-60,-60},{60,-60},{100,-40},{100,40},{60,
+              60},{-60,60},{-100,40}},
+          lineColor={0,0,0},
+          lineThickness=0.5,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Line(
+          points={{-100,0},{-80,60},{-60,-60},{-40,60},{-20,-60},{0,60},{20,-60},
+              {40,60},{60,-60},{80,60},{98,0}},
+          color={28,108,200},
+          thickness=1,
+          smooth=Smooth.Bezier),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-60,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-40,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-20,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={0,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={20,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={40,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={60,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-60,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-40,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-20,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={0,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={20,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={40,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={60,46},
+          rotation=180),
+        Ellipse(
+          extent={{-60,64},{0,58}},
+          lineColor={0,0,0},
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{0,64},{60,58}},
+          lineColor={0,0,0},
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid)}));
+end PartialSimpleDryCooler;
diff --git a/SorpLib/Components/HeatExchanger/BaseClasses/package.mo b/SorpLib/Components/HeatExchanger/BaseClasses/package.mo
new file mode 100644
index 0000000..449bcda
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.HeatExchanger;
+package BaseClasses "Base models and functions for all heat exchangers"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial heat exchanger models, containing fundamental 
+definitions for heat exchangers. The content of this package is only of interest 
+when adding new heat exchangers to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/HeatExchanger/BaseClasses/package.order b/SorpLib/Components/HeatExchanger/BaseClasses/package.order
new file mode 100644
index 0000000..d77267e
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/BaseClasses/package.order
@@ -0,0 +1,5 @@
+PartialHeatExchanger
+PartialSimpleCondenserEvaporator
+PartialSimpleDryCooler
+PartialPureComponentAdsorber
+PartialPureSimpleComponentAdsorber
diff --git a/SorpLib/Components/HeatExchanger/CondensersEvaporators/SimpleCondenser.mo b/SorpLib/Components/HeatExchanger/CondensersEvaporators/SimpleCondenser.mo
new file mode 100644
index 0000000..53088a8
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/CondensersEvaporators/SimpleCondenser.mo
@@ -0,0 +1,155 @@
+within SorpLib.Components.HeatExchanger.CondensersEvaporators;
+model SimpleCondenser "Simple condenser for a pure component"
+  extends SorpLib.Components.HeatExchanger.BaseClasses.PartialSimpleCondenserEvaporator(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    final no_components=MediumHX.nX,
+    final no_VLEcomponents=MediumPS.nX,
+    redeclare SorpLib.Components.Tubes.LiquidTube heatExchangerTubes(
+      redeclare final package Medium = MediumHX,
+      redeclare model WallMaterial = WallMaterialHX),
+    redeclare SorpLib.Basics.Volumes.PhaseSeparatorVolumes.PhaseSeparatorVolume
+      phaseSeparatorVolume(
+        redeclare final package Medium = MediumPS),
+    redeclare SorpLib.Basics.Volumes.SolidVolumes.SolidVolume casing(
+      redeclare final WallMaterialCS solidMedium,
+      redeclare final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+        dx=0,
+        dy=0,
+        dz=0,
+        A_xy=0,
+        A_xz=0,
+        A_yz=0,
+        V=geometry.V_wall_cas),
+      final T_initial=T_casingInitial,
+      final p=phaseSeparatorVolume.p,
+      independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX),
+    redeclare SorpLib.Components.HeatTransfer.PoolCondensationHeatTransfer
+      heatTransfer_HeatExchangerToPhaseSeparator(
+      redeclare final model HeatTransferCoefficient = PS_HeatExchanger,
+      final fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=phaseSeparatorVolume.p,
+        T=phaseSeparatorVolume.T,
+        rho=phaseSeparatorVolume.rho,
+        cp=phaseSeparatorVolume.phaseSepratorProperties.cp,
+        eta=phaseSeparatorVolume.phaseSepratorProperties.eta,
+        lambda=phaseSeparatorVolume.phaseSepratorProperties.lambda),
+      final f_relativeFillingLevel=phaseSeparatorVolume.l_liq_rel),
+    thermalConduction_casing1(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)),
+    thermalConduction_casing2(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)));
+
+  //
+  // Definition of parameters
+  //
+  replaceable package MediumHX =
+      Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid in the heat exchanger"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable package MediumPS = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the real fluid in the phase separator"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model WallMaterialHX =
+      SorpLib.Media.Solids.MetalsAndMetalAlloys.Copper
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Heat exchanger wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable model WallMaterialCS =
+      Media.Solids.MetalsAndMetalAlloys.StainlessSteel_X5CrNi18_10
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Casing wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of tranport phenomena
+  //
+  replaceable model PS_HeatExchanger =
+    HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation.LinearAlphaA_fRel
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolCondensationHeatTransferCoefficient
+    "Heat transfer correlation describing the condensation at the outside of the
+    heat exchanger tubes"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Convection"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Components.HeatExchanger.Records.SummaryCondenserEvaporator summary(
+    final p_VLE=phaseSeparatorVolume.p,
+    final rho_VLE=phaseSeparatorVolume.rho,
+    final T_VLE=phaseSeparatorVolume.T,
+    final mass=phaseSeparatorVolume.m,
+    final p_liq_inlet=heatExchangerTubes.state_a.p,
+    final p_liq_outlet=heatExchangerTubes.state_b.p,
+    final p_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.p)/
+        heatExchangerTubes.no_fluidVolumes,
+    final T_liq_inlet=heatExchangerTubes.state_a.T,
+    final T_liq_outlet=heatExchangerTubes.state_b.T,
+    final T_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.T)/
+        heatExchangerTubes.no_fluidVolumes,
+    final T_wall_avg=sum(heatExchangerTubes.wallVolumes.T)/
+      heatExchangerTubes.no_wallVolumes,
+    final m_flow_liq_inlet=port_a.m_flow,
+    final m_flow_liq_outlet=port_b.m_flow,
+    final m_flow_vapor=sum(vaporPort.m_flow),
+    final m_flow_liquid=sum(liquidPort.m_flow),
+    final Q_flow_wallToPhaseSeparator=heatExchangerTubes.Q_flow_wallHP,
+    final Q_flow_fluidWall=heatExchangerTubes.Q_flow_fluidWall,
+    final DH_liquid=heatExchangerTubes.DH_flow)
+    "Summary record";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 4, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations due to restructering of the library.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SimpleCondenser;
diff --git a/SorpLib/Components/HeatExchanger/CondensersEvaporators/SimpleEvaporator.mo b/SorpLib/Components/HeatExchanger/CondensersEvaporators/SimpleEvaporator.mo
new file mode 100644
index 0000000..8c82c57
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/CondensersEvaporators/SimpleEvaporator.mo
@@ -0,0 +1,156 @@
+within SorpLib.Components.HeatExchanger.CondensersEvaporators;
+model SimpleEvaporator "Simple evaporator for a pure component"
+  extends
+    SorpLib.Components.HeatExchanger.BaseClasses.PartialSimpleCondenserEvaporator(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    final no_components=MediumHX.nX,
+    final no_VLEcomponents=MediumPS.nX,
+    redeclare SorpLib.Components.Tubes.LiquidTube heatExchangerTubes(
+      redeclare final package Medium = MediumHX,
+      redeclare model WallMaterial = WallMaterialHX),
+    redeclare SorpLib.Basics.Volumes.PhaseSeparatorVolumes.PhaseSeparatorVolume
+      phaseSeparatorVolume(
+        redeclare final package Medium = MediumPS),
+    redeclare SorpLib.Basics.Volumes.SolidVolumes.SolidVolume casing(
+      redeclare final WallMaterialCS solidMedium,
+      redeclare final SorpLib.Basics.Volumes.Records.VolumeGeometry geometry(
+        dx=0,
+        dy=0,
+        dz=0,
+        A_xy=0,
+        A_xz=0,
+        A_yz=0,
+        V=geometry.V_wall_cas),
+      final T_initial=T_casingInitial,
+      final p=phaseSeparatorVolume.p,
+      independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX),
+    redeclare SorpLib.Components.HeatTransfer.PoolBoilingHeatTransfer
+      heatTransfer_HeatExchangerToPhaseSeparator(
+      redeclare final model HeatTransferCoefficient = PS_HeatExchanger,
+      final fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=phaseSeparatorVolume.p,
+        T=phaseSeparatorVolume.T,
+        rho=phaseSeparatorVolume.rho,
+        cp=phaseSeparatorVolume.phaseSepratorProperties.cp,
+        eta=phaseSeparatorVolume.phaseSepratorProperties.eta,
+        lambda=phaseSeparatorVolume.phaseSepratorProperties.lambda),
+      final f_relativeFillingLevel=phaseSeparatorVolume.l_liq_rel),
+    thermalConduction_casing1(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)),
+    thermalConduction_casing2(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=casing.solidProperties.p,
+        T=casing.solidProperties.T,
+        rho=1/casing.solidProperties.v,
+        cp=casing.solidProperties.c,
+        eta=0,
+        lambda=casing.solidProperties.lambda)));
+
+  //
+  // Definition of parameters
+  //
+  replaceable package MediumHX =
+      Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid in the heat exchanger"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable package MediumPS = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the real fluid in the phase separator"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model WallMaterialHX =
+      SorpLib.Media.Solids.MetalsAndMetalAlloys.Copper
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Heat exchanger wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+  replaceable model WallMaterialCS =
+      Media.Solids.MetalsAndMetalAlloys.StainlessSteel_X5CrNi18_10
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Casing wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of tranport phenomena
+  //
+  replaceable model PS_HeatExchanger =
+    HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling.LinearAlphaA_fRel
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolBoilingHeatTransferCoefficient
+    "Heat transfer correlation describing the boiling at the outside of the
+    heat exchanger tubes"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Convection"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Components.HeatExchanger.Records.SummaryCondenserEvaporator summary(
+    final p_VLE=phaseSeparatorVolume.p,
+    final rho_VLE=phaseSeparatorVolume.rho,
+    final T_VLE=phaseSeparatorVolume.T,
+    final mass=phaseSeparatorVolume.m,
+    final p_liq_inlet=heatExchangerTubes.state_a.p,
+    final p_liq_outlet=heatExchangerTubes.state_b.p,
+    final p_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.p)/
+        heatExchangerTubes.no_fluidVolumes,
+    final T_liq_inlet=heatExchangerTubes.state_a.T,
+    final T_liq_outlet=heatExchangerTubes.state_b.T,
+    final T_liq_avg=sum(heatExchangerTubes.fluidVolumes.fluidProperties.T)/
+        heatExchangerTubes.no_fluidVolumes,
+    final T_wall_avg=sum(heatExchangerTubes.wallVolumes.T)/
+      heatExchangerTubes.no_wallVolumes,
+    final m_flow_liq_inlet=port_a.m_flow,
+    final m_flow_liq_outlet=port_b.m_flow,
+    final m_flow_vapor=sum(vaporPort.m_flow),
+    final m_flow_liquid=sum(liquidPort.m_flow),
+    final Q_flow_wallToPhaseSeparator=heatExchangerTubes.Q_flow_wallHP,
+    final Q_flow_fluidWall=heatExchangerTubes.Q_flow_fluidWall,
+    final DH_liquid=heatExchangerTubes.DH_flow)
+    "Summary record";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 4, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations due to restructering of the library.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SimpleEvaporator;
diff --git a/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/Test_SimpleCondenser.mo b/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/Test_SimpleCondenser.mo
new file mode 100644
index 0000000..a6d024e
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/Test_SimpleCondenser.mo
@@ -0,0 +1,130 @@
+within SorpLib.Components.HeatExchanger.CondensersEvaporators.Tester;
+model Test_SimpleCondenser "Tester for the simple condenser"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=false,
+    use_VFlowInput=true,
+    V_flow_fixed=-10/60/1000,
+    T_fixed=298.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=358.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource vaporSource(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=353.15) "Vapor Source" annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={0,30})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.HeatExchanger.CondensersEvaporators.SimpleCondenser condenser(
+    geometry(d_inner_cas=0.05, d_outer_cas=0.055),
+    useCasing=true,
+    redeclare model HX_FluidThermalConvectionTubeInside =
+        HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.Schmidt,
+    redeclare model HX_PressureDrop =
+        Fittings.PressureLossCorrelations.TubeInside.MishraGupaSchmidt,
+    redeclare package MediumHX = Medium,
+    redeclare model PS_HeatExchanger =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation.LinearAlphaA_fRel,
+    nPortsVapor=1) "Condenser model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_V_flow(
+    amplitude=5/1000/60,
+    f=1/500,
+    offset=-10/1000/60) "Input signal for volume flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=1e5,
+    duration=2500,
+    offset=2e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+  Modelica.Blocks.Sources.Ramp input_TWall(
+    height=-0.001,
+    duration=2000,
+    offset=0,
+    startTime=500)      "Input signal for wall temperature boundary"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,60})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, condenser.port_a) annotation (Line(
+      points={{-60,0},{-10,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(condenser.port_b, fs_b.port) annotation (Line(
+      points={{10,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(vaporSource.port, condenser.vaporPort[1]) annotation (Line(
+      points={{0,30},{0,4.2}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_V_flow.y, fs_a.V_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,2},{-61.2,2}}, color={0,0,127}));
+  connect(input_p.y, fs_b.p_input)
+    annotation (Line(points={{79,0},{70,0},{70,5},{61.2,5}}, color={0,0,127}));
+  connect(input_TWall.y, vaporSource.m_flow_input) annotation (Line(points={{0,49},
+          {0,40},{-2,40},{-2,31.2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the simple condenser.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 4, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_SimpleCondenser;
diff --git a/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/Test_SimpleEvaporator.mo b/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/Test_SimpleEvaporator.mo
new file mode 100644
index 0000000..c97a8d0
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/Test_SimpleEvaporator.mo
@@ -0,0 +1,130 @@
+within SorpLib.Components.HeatExchanger.CondensersEvaporators.Tester;
+model Test_SimpleEvaporator "Tester for the simple evaporator"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=false,
+    use_VFlowInput=true,
+    V_flow_fixed=-10/60/1000,
+    T_fixed=298.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=358.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource vaporSource(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=288.15) "Vapor Source" annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={0,30})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.HeatExchanger.CondensersEvaporators.SimpleEvaporator evaporator(
+    geometry(d_inner_cas=0.05, d_outer_cas=0.055),
+    redeclare model HX_FluidThermalConvectionTubeInside =
+        HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.GnielinskiDittusBoelter,
+
+    redeclare model HX_PressureDrop =
+        Fittings.PressureLossCorrelations.TubeInside.PrandtlKarman,
+    redeclare package MediumHX = Medium,
+    redeclare model PS_HeatExchanger =
+        SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling.LinearAlphaA_fRel,
+    nPortsVapor=1) "Evaporator model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_V_flow(
+    amplitude=5/1000/60,
+    f=1/500,
+    offset=-10/1000/60) "Input signal for volume flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=1e5,
+    duration=2500,
+    offset=2e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+  Modelica.Blocks.Sources.Ramp input_TWall(
+    height=0.001,
+    duration=2000,
+    offset=0,
+    startTime=500)      "Input signal for wall temperature boundary"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,60})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, evaporator.port_a) annotation (Line(
+      points={{-60,0},{-10,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(evaporator.port_b, fs_b.port) annotation (Line(
+      points={{10,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(vaporSource.port, evaporator.vaporPort[1]) annotation (Line(
+      points={{0,30},{0,4.2}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_V_flow.y, fs_a.V_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,2},{-61.2,2}}, color={0,0,127}));
+  connect(input_p.y, fs_b.p_input)
+    annotation (Line(points={{79,0},{70,0},{70,5},{61.2,5}}, color={0,0,127}));
+  connect(input_TWall.y, vaporSource.m_flow_input) annotation (Line(points={{0,49},
+          {0,40},{-2,40},{-2,31.2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the simple evaporator.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 4, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_SimpleEvaporator;
diff --git a/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/package.mo b/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/package.mo
new file mode 100644
index 0000000..db79882
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.HeatExchanger.CondensersEvaporators;
+package Tester "Models to test and varify condensers and evaporators"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all condensres and evaporators. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/package.order b/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/package.order
new file mode 100644
index 0000000..9e25a94
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/CondensersEvaporators/Tester/package.order
@@ -0,0 +1,2 @@
+Test_SimpleCondenser
+Test_SimpleEvaporator
diff --git a/SorpLib/Components/HeatExchanger/CondensersEvaporators/package.mo b/SorpLib/Components/HeatExchanger/CondensersEvaporators/package.mo
new file mode 100644
index 0000000..46a0a6e
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/CondensersEvaporators/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.HeatExchanger;
+package CondensersEvaporators "Condensers and evaporators used in closed sorption systems"
+  extends SorpLib.Icons.CondensersEvaporatorsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains condensers and evaporators that are based on the Modelica
+Standard Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end CondensersEvaporators;
diff --git a/SorpLib/Components/HeatExchanger/CondensersEvaporators/package.order b/SorpLib/Components/HeatExchanger/CondensersEvaporators/package.order
new file mode 100644
index 0000000..78303df
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/CondensersEvaporators/package.order
@@ -0,0 +1,3 @@
+SimpleCondenser
+SimpleEvaporator
+Tester
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/HXGeometry.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/HXGeometry.mo
deleted file mode 100644
index 05cfdd8..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/HXGeometry.mo
+++ /dev/null
@@ -1,60 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow.Geometry;
-record HXGeometry
-  "Geometry record for air air counterflow heat exchanger"
-  extends SorpLib.Internals.ClassTypes.Record;
-
-  parameter Modelica.SIunits.Length length(start = 1) "total length of heat exchanger";
-
-  parameter Modelica.SIunits.Length width(start = 1) "total width of heat exchanger";
-
-  parameter Modelica.SIunits.Length heightDuct1(start=0.0035)
-    "height of one duct (fluid 1)";
-
-  parameter Modelica.SIunits.Length heightDuct2(start=0.0035)
-    "height of one duct (fluid 2)";
-
-  parameter Modelica.SIunits.Length tSheet(start=0.0003)
-    "thickness of thermal sheet layer between fluid ducts";
-
-  parameter Modelica.SIunits.Length tCasing(start=0.003)
-    "thickness of casing wall";
-
-  parameter Integer numDucts(min=1,start=10)
-    "Number of alternating duct layers";
-
-  final parameter Modelica.SIunits.Length totalheight=numDucts*(heightDuct1 +
-      heightDuct2) + (2*numDucts - 1)*tSheet + 2*tCasing
-    "total height of heat exchanger";
-
-  final parameter Real ratioDuctheight=heightDuct1/heightDuct2
-    "ratio of duct height 1 to duct height 2";
-
-  final parameter Modelica.SIunits.Diameter hydraulicDiameter1=numDucts*2*heightDuct1*width/(numDucts*heightDuct1+width)
-    "hydraulic diameter of sum of all ducts 1";
-
-  final parameter Modelica.SIunits.Diameter hydraulicDiameter2=numDucts*2*heightDuct2*width/(numDucts*heightDuct2+width)
-    "hydraulic diameter of sum of all ducts 2";
-
-  final parameter Modelica.SIunits.Area flowCrossSection1=numDucts*heightDuct1*width
-    "Cross-sectional area of all ducts 1";
-
-  final parameter Modelica.SIunits.Area flowCrossSection2=numDucts*heightDuct2*width
-    "Cross-sectional area of all ducts 2";
-
-  final parameter Modelica.SIunits.Area areaHX=(2*numDucts - 1)*length*width
-    "total heat-exchange-surface for one fluid";
-
-  annotation (Documentation(info="<html>
-  <p>
-  This record containes all information necessary to describe an air/air counterflow heat exchanger. <br>  
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-    <li>December 11, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end HXGeometry;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/package.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/package.mo
deleted file mode 100644
index 9f6462c..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/package.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow;
-package Geometry
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-
-
-
-annotation (Documentation(info="<html>
-</html>"));
-end Geometry;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/package.order b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/package.order
deleted file mode 100644
index 9a0b501..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Geometry/package.order
+++ /dev/null
@@ -1 +0,0 @@
-HXGeometry
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HXAirAirParallelflow.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HXAirAirParallelflow.mo
deleted file mode 100644
index f793d15..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HXAirAirParallelflow.mo
+++ /dev/null
@@ -1,434 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow;
-model HXAirAirParallelflow "counterflow air-air heat exchanger"
-
-  /*********************** SIM ***********************************/
-  inner parameter TILMedia.GasTypes.BaseGas gasType=sim.gasType1 "Gas type"
-    annotation (Dialog(tab="SIM", group="SIM"), choices(choice=sim.gasType1
-        "Gas 1 as defined in SIM", choice=sim.gasType2
-        "Gas 2 as defined in SIM"));
-protected
-  outer TIL.SystemInformationManager sim "System Information Manager";
-  TIL.Internals.SimPort simPort;
-
-  /************************** Connectors ***********************************/
-
-public
-  TIL.Connectors.GasPort gasPort1A(final gasType=gasType) annotation (Placement(
-        transformation(extent={{-110,38},{-90,58}}), iconTransformation(extent={{-110,38},
-            {-90,58}})));
-  TIL.Connectors.GasPort gasPort1B(final gasType=gasType) annotation (Placement(
-        transformation(extent={{90,38},{110,58}}), iconTransformation(extent={{90,38},
-            {110,58}})));
-  TIL.Connectors.GasPort gasPort2B(final gasType=gasType) annotation (Placement(
-        transformation(extent={{-110,-56},{-90,-36}}), iconTransformation(
-          extent={{-110,-56},{-90,-36}})));
-  TIL.Connectors.GasPort gasPort2A(final gasType=gasType) annotation (Placement(
-        transformation(extent={{90,-56},{110,-36}}), iconTransformation(extent={{90,-56},
-            {110,-36}})));
-
-  /************************ Gas objects *************************/
-
-  TILMedia.Gas_ph gas1A(
-    final gasType=gasType,
-    final h=noEvent(actualStream(gasPort1A.h_outflow)),
-    final p=gasPort1A.p,
-    final xi=noEvent(actualStream(gasPort1A.xi_outflow)))
-    annotation (Placement(transformation(extent={{-80,18},{-60,38}})));
-  TILMedia.Gas_ph gas1B(
-    final gasType=gasType,
-    final h=noEvent(actualStream(gasPort1B.h_outflow)),
-    final p=gasPort1B.p,
-    final xi=noEvent(actualStream(gasPort1B.xi_outflow)))
-    annotation (Placement(transformation(extent={{60,18},{80,38}})));
-  TILMedia.Gas_ph gas2A(
-    final gasType=gasType,
-    final h=noEvent(actualStream(gasPort2A.h_outflow)),
-    final p=gasPort2A.p,
-    final xi=noEvent(actualStream(gasPort2A.xi_outflow)))
-    annotation (Placement(transformation(extent={{58,-42},{78,-22}})));
-  TILMedia.Gas_ph gas2B(
-    final gasType=gasType,
-    final p=gasPort2B.p,
-    final h=noEvent(actualStream(gasPort2B.h_outflow)),
-    final xi=noEvent(actualStream(gasPort2B.xi_outflow)))
-    annotation (Placement(transformation(extent={{-80,-42},{-60,-22}})));
-
-  /******************** Geometry characteristics ***********************/
-
-  parameter Integer nCells(min=1) = 1 "Number of discretization cells"
-    annotation (Dialog(group="Discretization"));
-
-  replaceable parameter Geometry.HXGeometry hxGeometry
-    constrainedby Geometry.HXGeometry "Heat exchanger geometry"
-    annotation (Dialog(group="Heat exchanger geometry"),
-    choicesAllMatching=true, Placement(transformation(extent={{58,-138},{78,
-            -118}})));
-
-  /************************** Components ************************************/
-
-  /************************** Gas volume **********************************/
-
-  Cells.Gas.Gas[nCells] gas1(
-    each final cellGeometry(
-      length=hxGeometry.length/nCells,
-      hydraulicDiameter=hxGeometry.hydraulicDiameter1,
-      flowCrossSection=hxGeometry.flowCrossSection1,
-      psi=1),
-    each final gasType=gasType,
-    each final TInitial=TInitial1,
-    each final xiInitial=xiInitial1,
-    each final pInitial=pInitial1,
-    each final m_flowStart=m_flowStart1,
-    each final generateEventsAtFlowReversal=generateEventsAtFlowReversal,
-    each final HydraulicMassFlowPosition=HydraulicMassFlowPosition1,
-    each final computeTransportProperties=computeTransportProperties1,
-    redeclare each final model PressureDropModel = PressureDrop1,
-    final fixedInitialPressure=cat(1, {fixedInitialPressure_firstCell1}, {fixedInitialPressure1 for i in 2:nCells}))
-    annotation (Placement(transformation(extent={{-10,40},{10,60}})));
-
-  Cells.Gas.Gas[nCells] gas2(
-    each final cellGeometry(
-      length=hxGeometry.length/nCells,
-      hydraulicDiameter=hxGeometry.hydraulicDiameter2,
-      flowCrossSection=hxGeometry.flowCrossSection2,
-      psi=1),
-    each final gasType=gasType,
-    each final TInitial=TInitial2,
-    each final xiInitial=xiInitial2,
-    each final pInitial=pInitial2,
-    each final m_flowStart=m_flowStart2,
-    each final generateEventsAtFlowReversal=generateEventsAtFlowReversal,
-    each final HydraulicMassFlowPosition=HydraulicMassFlowPosition2,
-    each final computeTransportProperties=computeTransportProperties2,
-    redeclare each final model PressureDropModel = PressureDrop2,
-    final fixedInitialPressure=cat(1, {fixedInitialPressure_firstCell2}, {fixedInitialPressure2 for i in 2:nCells}))
-                                           annotation (Placement(transformation(
-        extent={{-10,-10},{10,10}},
-        rotation=180,
-        origin={0,-50})));
-
-  /********************** Pressure drop in gas cell **************************/
-
-  replaceable model PressureDrop1 =
-      SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial.PartialPressureDrop
-    constrainedby
-    SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial.PartialPressureDrop
-    "Pressure drop model for fluid 1" annotation (
-    Placement(transformation(extent={{-36,-40},{-16,-20}})),
-    choices(
-      choice(redeclare model PressureDrop1 =
-            SorpLib.Components.Cells.Gas.PressureDropCorrelations.ZeroPressureDrop
-          "no pressure drop: dp = 0"),
-      choice(redeclare model PressureDrop1 =
-            SorpLib.Components.Cells.Gas.PressureDropCorrelations.ConstantResistanceCoefficient
-          "constant pressure drop coefficient: zeta = konst"),
-      choice(redeclare model PressureDrop1 =
-            SorpLib.Components.HeatExchanger.HXAirAirParallelflow.PressureDropCorrelations.VDIWaermeatlasN6
-          "pressure drop calculated using VDI Waermeatlas (N6)")),
-    Dialog(group="Pressure drop"));
-
-  replaceable model PressureDrop2 =
-      SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial.PartialPressureDrop
-    constrainedby
-    SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial.PartialPressureDrop
-    "Pressure drop model for fluid 2" annotation (
-    Placement(transformation(extent={{-36,-40},{-16,-20}})),
-    choices(
-      choice(redeclare model PressureDrop2 =
-            SorpLib.Components.Cells.Gas.PressureDropCorrelations.ZeroPressureDrop
-          "no pressure drop: dp = 0"),
-      choice(redeclare model PressureDrop2 =
-            SorpLib.Components.Cells.Gas.PressureDropCorrelations.ConstantResistanceCoefficient
-          "constant pressure drop coefficient: zeta = konst"),
-      choice(redeclare model PressureDrop2 =
-            SorpLib.Components.HeatExchanger.HXAirAirParallelflow.PressureDropCorrelations.VDIWaermeatlasN6
-          "pressure drop calculated using VDI Waermeatlas (N6)")),
-    Dialog(group="Pressure drop"));
-
-  /************************** Wall ***************************************/
-
-  Cells.Wall.Wall[nCells] wall(
-    each final volume=hxGeometry.width*hxGeometry.length*hxGeometry.tSheet*2*(hxGeometry.numDucts + 0.5)/nCells,
-    each final TInitial=TInitialWall,
-    redeclare each final model WallMaterial = WallMaterial)
-    annotation (Placement(transformation(extent={{-10,-5},{10,5}},
-        rotation=0,
-        origin={0,0})));
-
-  replaceable model WallMaterial = TILMedia.SolidTypes.TILMedia_Steel
-    constrainedby TILMedia.SolidTypes.BaseSolid "Wall material model"
-    annotation (Dialog(group="Wall material"), choicesAllMatching=true);
-
-  final parameter Modelica.SIunits.Mass massHX=sum(wall.mass)
-    "Mass of heat exchanger";
-
-  final parameter Modelica.SIunits.Mass massCasing=2*(hxGeometry.totalheight*hxGeometry.width + hxGeometry.length*
-      hxGeometry.totalheight)*hxGeometry.tCasing*wall[1].wallMaterial.d "Mass of casing";
-
-  /************************** HeatTransfer *******************************/
-
-  HeatAndMassTransfer.HeatTransfer heatTransferGasWall1[nCells](
-    redeclare each model HeatTransfer = HeatTransferGasWall1,
-    each n=1,
-    each useAlphaAInput=false,
-    cellGeometry_gas=gas1.cellGeometry,
-    properties_gas=gas1.properties,
-    mdotHydraulic_gas=gas1.mdotHydraulic,
-    each heatTransferArea=hxGeometry.areaHX/nCells)   annotation (Placement(transformation(
-        extent={{-8,-4},{8,4}},
-        rotation=90,
-        origin={0,22})));
-
-  HeatAndMassTransfer.HeatTransfer heatTransferGasWall2[nCells](
-    each n=1,
-    each useAlphaAInput=false,
-    redeclare each model HeatTransfer = HeatTransferGasWall2,
-    cellGeometry_gas=gas2.cellGeometry,
-    properties_gas=gas2.properties,
-    mdotHydraulic_gas=gas2.mdotHydraulic,
-    each heatTransferArea=hxGeometry.areaHX/nCells)   annotation (Placement(transformation(
-        extent={{-8,-4},{8,4}},
-        rotation=270,
-        origin={0,-22})));
-
-  replaceable model HeatTransferGasWall1 =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "Heat transfer model fluid 1 to wall" annotation (Dialog(group="Heat Transfer Model"), choices(
-        choice(redeclare model HeatTransferGasWall1 =
-            SorpLib.Components.HeatExchanger.HXAirAirParallelflow.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.ConstantAlpha
-          "Constant heat transfer coefficient")));
-
-  replaceable model HeatTransferGasWall2 =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "Heat transfer model fluid 2 to wall" annotation (Dialog(group="Heat Transfer Model"), choices(
-        choice(redeclare model HeatTransferGasWall2 =
-            SorpLib.Components.HeatExchanger.HXAirAirParallelflow.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.ConstantAlpha
-          "Constant heat transfer coefficient")));
-
-  /************************** General parameters ***********************************/
-
-  final parameter Boolean computeTransportProperties1=heatTransferGasWall1[1].computeTransportProperties annotation(Dialog(tab="Advanced", group="Transport properties"));
-
-  final parameter Boolean computeTransportProperties2=heatTransferGasWall2[1].computeTransportProperties annotation(Dialog(tab="Advanced", group="Transport properties"));
-
-  parameter Boolean generateEventsAtFlowReversal=false "If true, events are generated at flow reversal" annotation(Evaluate=true, Dialog(tab="Advanced", group="Event-Handling"));
-
-  parameter String HydraulicMassFlowPosition1="gas port B" "Position of hydraulic mass flow of gas cell (duct 1)" annotation(Evaluate=true, Dialog(tab="Advanced", group="Hydraulic mass flow position"),
-    choices(
-    choice="gas port A" "hydraulic mass flow at gas port A",
-    choice="gas port B" "hydraulic mass flow at gas port B"));
-
-  parameter String HydraulicMassFlowPosition2="gas port B" "Position of hydraulic mass flow of gas cell (duct 2)" annotation(Evaluate=true, Dialog(tab="Advanced", group="Hydraulic mass flow position"),
-    choices(
-    choice="gas port A" "hydraulic mass flow at gas port A",
-    choice="gas port B" "hydraulic mass flow at gas port B"));
-
-  /************************** Initialization ***********************************/
-
-  parameter Modelica.SIunits.Temperature TInitial1=293.15
-    "Initial Value of duct Air Temperature 1"
-    annotation (Dialog(group="Gas volume 1", tab="Start and Initialization"));
-  parameter Modelica.SIunits.Temperature TInitial2=293.15
-    "Initial Value of duct Air Temperature 2"
-    annotation (Dialog(group="Gas volume 2", tab="Start and Initialization"));
-  parameter Modelica.SIunits.Temperature TInitialWall=293.15
-    "Initial Value Wall Temperature"
-    annotation (Dialog(group="Wall volume", tab="Start and Initialization"));
-
-  parameter Modelica.SIunits.MassFraction xiInitial1[gasType.nc - 1]={0.01}
-    "Initial composition of fluid 1"
-    annotation (Dialog(group="Gas volume 1", tab="Start and Initialization"));
-  parameter Modelica.SIunits.MassFraction xiInitial2[gasType.nc - 1]={0.01}
-    "Initial composition of fluid 2"
-    annotation (Dialog(group="Gas volume 2", tab="Start and Initialization"));
-
-  parameter Modelica.SIunits.Pressure pInitial1=1e5
-    "Start pressure for iteration of fluid 1"
-    annotation (Dialog(group="Gas volume 1", tab="Start and Initialization"));
-  parameter Modelica.SIunits.Pressure pInitial2=1e5
-    "Start pressure for iteration of fluid 2"
-    annotation (Dialog(group="Gas volume 2", tab="Start and Initialization"));
-  parameter Boolean fixedInitialPressure1=true
-    "If true, initial pressure is fixed" annotation (Dialog(group="Gas volume 1", tab="Start and Initialization"));
-  parameter Boolean fixedInitialPressure_firstCell1=true
-    "Use false, if two pressure boundaries are connected" annotation (Dialog(group="Gas volume 1", tab="Start and Initialization"));
-  parameter Boolean fixedInitialPressure2=true
-    "If true, initial pressure is fixed" annotation (Dialog(group="Gas volume 2", tab="Start and Initialization"));
-  parameter Boolean fixedInitialPressure_firstCell2=true
-    "Use false, if two pressure boundaries are connected" annotation (Dialog(group="Gas volume 2", tab="Start and Initialization"));
-
-  parameter Modelica.SIunits.MassFlowRate m_flowStart1=0.2
-    "Start mass flow rate for iteration of fluid 1"
-    annotation (Dialog(group="Gas volume 1", tab="Start and Initialization"));
-  parameter Modelica.SIunits.MassFlowRate m_flowStart2=0.2
-    "Start mass flow rate for iteration of fluid 2"
-    annotation (Dialog(group="Gas volume 2", tab="Start and Initialization"));
-
-  /****************************** Summary********************************/
-
-  inner parameter Boolean includeSummaryArrays=true
-    "include array entries in summary" annotation (Dialog(tab="Advanced", group="Summary"));
-  inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary" annotation (Dialog(tab="Advanced", group="Summary"));
-protected
-  record Summary
-    extends TIL.Internals.ClassTypes.Record;
-    Modelica.SIunits.Temperature TGas1A if include;
-    Modelica.SIunits.Pressure pGas1A if include;
-    Modelica.SIunits.MassFraction xiGas1A if include;
-    TILMedia.Internals.Units.RelativeHumidity phiGas1A if include;
-    Modelica.SIunits.Temperature TGas1B if include;
-    Modelica.SIunits.Pressure pGas1B if include;
-    Modelica.SIunits.MassFraction xiGas1B if include;
-    TILMedia.Internals.Units.RelativeHumidity phiGas1B if include;
-    Modelica.SIunits.Temperature TGas2A if include;
-    Modelica.SIunits.Pressure pGas2A if include;
-    Modelica.SIunits.MassFraction xiGas2A if include;
-    TILMedia.Internals.Units.RelativeHumidity phiGas2A if include;
-    Modelica.SIunits.Temperature TGas2B if include;
-    Modelica.SIunits.Pressure pGas2B if include;
-    Modelica.SIunits.MassFraction xiGas2B if include;
-    TILMedia.Internals.Units.RelativeHumidity phiGas2B if include;
-    Modelica.SIunits.HeatFlowRate QdotGas1Wall if include;
-    Modelica.SIunits.HeatFlowRate QdotWallGas2 if include;
-    Modelica.SIunits.Pressure dp1 if include;
-    Modelica.SIunits.Pressure dp2 if include;
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-  public
-    replaceable Arrays arrays;
-    record Arrays
-      parameter Integer n if includeArrays;
-
-      Modelica.SIunits.Temperature TWall[n] if includeArrays;
-      Modelica.SIunits.Temperature TGas1[n] if includeArrays;
-      Modelica.SIunits.Temperature TGas2[n] if includeArrays;
-      Modelica.SIunits.Pressure pGas1[n] if includeArrays;
-      Modelica.SIunits.Pressure pGas2[n] if includeArrays;
-      Modelica.SIunits.MassFraction xiGas1[n,gasType.nc-1] if includeArrays;
-      Modelica.SIunits.MassFraction xiGas2[n,gasType.nc-1] if includeArrays;
-      TILMedia.Internals.Units.RelativeHumidity phiGas1[n] if includeArrays;
-      TILMedia.Internals.Units.RelativeHumidity phiGas2[n] if includeArrays;
-      Modelica.SIunits.HeatFlowRate QdotGas1Wall[n] if includeArrays;
-      Modelica.SIunits.HeatFlowRate QdotWallGas2[n] if includeArrays;
-
-    protected
-      outer parameter Boolean includeSummaryArrays;
-      parameter Boolean includeArrays=includeSummaryArrays;
-      outer parameter TILMedia.GasTypes.BaseGas gasType;
-    end Arrays;
-
-  end Summary;
-
-  replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    TGas1A=gas1A.T,
-    pGas1A=gas1A.p,
-    xiGas1A=gas1A.xi[1],
-    phiGas1A=gas1A.phi,
-    TGas1B=gas1B.T,
-    pGas1B=gas1B.p,
-    xiGas1B=gas1B.xi[1],
-    phiGas1B=gas1B.phi,
-    TGas2A=gas2A.T,
-    pGas2A=gas2A.p,
-    xiGas2A=gas2A.xi[1],
-    phiGas2A=gas2A.phi,
-    TGas2B=gas2B.T,
-    pGas2B=gas2B.p,
-    xiGas2B=gas2B.xi[1],
-    phiGas2B=gas2B.phi,
-    QdotGas1Wall=-sum(gas1[:].heatPortA.Q_flow),
-    QdotWallGas2=sum(gas2[:].heatPortA.Q_flow),
-    dp1=gasPort1A.p-gasPort1B.p,
-    dp2=gasPort2A.p-gasPort2B.p,
-    arrays(
-      final n=nCells,
-      TWall=wall.T,
-      TGas1=gas1.gas.T,
-      TGas2=gas2.gas.T,
-      pGas1=gas1.p,
-      pGas2=gas2.p,
-      xiGas1=gas1.xi,
-      xiGas2=gas2.xi,
-      phiGas1=gas1.gas.phi,
-      phiGas2=gas2.gas.phi,
-      QdotGas1Wall=-gas1.heatPortA.Q_flow,
-      QdotWallGas2=gas2.heatPortA.Q_flow));
-
-equation
-  /************************** Connect ***********************************/
-
-  for i in 1:nCells - 1 loop
-    connect(gas1[i + 1].gasPortA,gas1 [i].gasPortB);
-    connect(gas2[i].gasPortA,gas2 [i + 1].gasPortB);
-  end for;
-
-  connect(gasPort2B, gas2[1].gasPortB) annotation (Line(
-      points={{-100,-46},{-54,-46},{-54,-50},{-9.8,-50}},
-      color={255,153,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(gas2[nCells].gasPortA, gasPort2A) annotation (Line(
-      points={{10,-50},{56,-50},{56,-46},{100,-46}},
-      color={255,153,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(gasPort1A, gas1[1].gasPortA) annotation (Line(
-      points={{-100,48},{-56,48},{-56,50},{-10,50}},
-      color={255,153,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(gas1[nCells].gasPortB, gasPort1B) annotation (Line(
-      points={{9.8,50},{54,50},{54,48},{100,48}},
-      color={255,153,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(gas1.heatPortA, heatTransferGasWall1.heatPortB[1]) annotation (Line(
-      points={{0,40},{0,35},{0,30}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransferGasWall1.heatPortA, wall.heatPortB) annotation (Line(
-      points={{0,14},{0,4.75}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransferGasWall2.heatPortA, wall.heatPortA) annotation (Line(
-      points={{0,-14},{0,-5}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransferGasWall2.heatPortB[1], gas2.heatPortA) annotation (Line(
-      points={{0,-30},{0,-30},{0,-40}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (
-    Placement(transformation(extent={{50,-10},{70,10}})),
-    Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-80},{100,80}}),
-        graphics={Bitmap(
-          extent={{-124,-98},{122,94}},
-          imageSource=
-              "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",
-          fileName="modelica://SorpLib/Resources/Images/HXAirAir.png")}),
-    Diagram(coordinateSystem(extent={{-100,-80},{100,80}}, preserveAspectRatio=
-            false)),
-    Documentation(info="<html>
-  <p>
-    This model represents a counterflow air/air heat exchanger. The model consists of two gas channels, a separating wall cell, all connected by heat transfer resistances. At the moment, only a constant heat transfer coefficient is implemented. The model can be descretized in flow direction to build up a finite volume model.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 12, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end HXAirAirParallelflow;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/HeatTransfer.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/HeatTransfer.mo
deleted file mode 100644
index 875353e..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/HeatTransfer.mo
+++ /dev/null
@@ -1,22 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow.HeatAndMassTransfer;
-model HeatTransfer
-  extends SorpLib.Components.HeatTransfer.HeatTransfer;
-
-  inner parameter Modelica.SIunits.Area heatTransferArea;
-  inner parameter SorpLib.Components.Cells.Gas.Geometry.CellGeometry cellGeometry_gas;
-  inner input TILMedia.Internals.PropertyRecord properties_gas;
-  inner input Modelica.SIunits.MassFlowRate mdotHydraulic_gas;
-
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    Documentation(info="<html>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 11, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end HeatTransfer;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/ConstantAlpha.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/ConstantAlpha.mo
deleted file mode 100644
index ac9aa0d..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/ConstantAlpha.mo
+++ /dev/null
@@ -1,37 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow.HeatAndMassTransfer.TransportPhenomena.HeatTransfer;
-model ConstantAlpha
-  extends
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer(final computeTransportProperties=false);
-
-  parameter Modelica.SIunits.CoefficientOfHeatTransfer constantAlpha(start=100) "Constant heat transfer coefficient";
-
-  outer parameter Modelica.SIunits.Area heatTransferArea "Heat transfer area";
-
-equation
-
-    alphaA = constantAlpha*heatTransferArea;
-
-  annotation (Documentation(info="<html>
-<p>
-  This simple transfer model calculates the heat flow based on the temperature differnce with a constant alpha.
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i>Q</i><sub>in</sub> = <i><code>&alpha;</code> A</i> (<i>T</i><sub>in</sub> - <i>T</i><sub>out</sub>) </p>
-  <p>where <i><code>&alpha;</code></i> is a constant heat tranfer coefficient and <i>A</i> is the heat transfer area. </p>
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    In general, the heat transfer coefficient depends on fluid properties and geometry. Thus, a constant coefficient is only an approximation.
-  </p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 06, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ConstantAlpha;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.mo
deleted file mode 100644
index 4e880cc..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.mo
+++ /dev/null
@@ -1,10 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow.HeatAndMassTransfer.TransportPhenomena;
-package HeatTransfer
-  extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-
-
-
-end HeatTransfer;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.order b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.order
deleted file mode 100644
index 3bb1fa5..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.order
+++ /dev/null
@@ -1 +0,0 @@
-ConstantAlpha
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/package.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/package.mo
deleted file mode 100644
index 3eb2a57..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow.HeatAndMassTransfer;
-package TransportPhenomena
-    extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-end TransportPhenomena;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/package.order b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/package.order
deleted file mode 100644
index 2dc6ac8..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/TransportPhenomena/package.order
+++ /dev/null
@@ -1 +0,0 @@
-HeatTransfer
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/package.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/package.mo
deleted file mode 100644
index 841cc38..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow;
-package HeatAndMassTransfer
-     extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-end HeatAndMassTransfer;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/package.order b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/package.order
deleted file mode 100644
index 905f22a..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/HeatAndMassTransfer/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-HeatTransfer
-TransportPhenomena
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/VDIWaermeatlasN6.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/VDIWaermeatlasN6.mo
deleted file mode 100644
index fdf7853..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/VDIWaermeatlasN6.mo
+++ /dev/null
@@ -1,75 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow.PressureDropCorrelations;
-model VDIWaermeatlasN6
-  "Pressure drop correlation for plate heat exchangers (phi = 0) according to VDI Wärmeatlas (N6)"
-  extends
-    SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial.PartialPressureDrop(
-      final computeTransportProperties=true);
-
-  outer parameter Cells.Gas.Geometry.CellGeometry cellGeometry "cell geometry";
-
-  outer TILMedia.Internals.PropertyRecord properties "Fluid property record";
-
-  outer Modelica.SIunits.MassFlowRate mdotHydraulic
-    "Hydraulic mass flow rate";
-
-  Modelica.SIunits.ReynoldsNumber Re(start=1000) "Reynolds number";
-
-  Modelica.SIunits.Velocity v(start = 10);
-
-  parameter Modelica.SIunits.Velocity vLimit = 0.1
-    "Fluid velocity below which the pressure drop relation is regularized";
-
-  Real zeta(start=0.01);
-  Real zeta_lam(start=0.01);
-  Real zeta_tur(start=0.01);
-
-  Real weightingFactor(start=0.5);
-
-  /*************************************************************************/
-
-equation
-  v = mdotHydraulic/properties.d/cellGeometry.flowCrossSection;
-
-  Re = properties.d*abs(v)*cellGeometry.hydraulicDiameter/properties.transp.eta+10;
-
-  zeta_lam = 64/Re;
-  zeta_tur = (1.8*log(Re)/log(10) - 1.5)^(-2);
-  zeta = weightingFactor*zeta_lam + (1 - weightingFactor)*zeta_tur;
-
-  weightingFactor = TIL.Utilities.Numerics.smoothTransition(
-    Re,
-    2000.0,
-    100.0);
-
-  pressureDrop=(cellGeometry.length/cellGeometry.hydraulicDiameter)/(2*properties.d*cellGeometry.flowCrossSection^2)*zeta*TIL.Utilities.Numerics.squareFunction(mdotHydraulic);
-  annotation (Documentation(info="<html>
-<p>
-  This model calculates the pressure drop according to the VDI Wärmeatlas N6 (2011): pressure drop in plate heat exchangers. The model describes the special case for plates which have no angle (<code>&phi;</code>=0).<br>
-  The hydraulic mass flow rate, the fluid properties record, and the geometry are defined as outer objects and thus taken from the overlying model level.  
-</p>
-<h4>Main equations</h4>
-<p>
-<p>
-  <p align=\"center\"> <i><code>&Delta;</code>p</i> = sgn(<i><code>&#7745;</code></i><sub>hydraulic</sub>) <i>L</i> / <i>D</i> <code>&zeta;</code> / (2 <i><code>&rho;</code></i> <i>A</i><sup>2</sup>) <i><code>&#7745;</code></i><sub>hydraulic</sub><sup>2</sup> </p>
-<p>where <i><code>&Delta;</code>p</i> is the pressure drop, <i><code>&#7745;</code></i><sub>hydraulic</sub> is the hydraulic mass flow rate, <i>L</i> is the hydraulic length, <i>D</i> is the hydraulic diameter, <code>&zeta;</code> is the resistance coefficient, <i><code>&rho;</code></i> is the fluid density and <i>A</i> is the cross sectional area. </p>
-with
-  <p align=\"center\">  <code>&zeta;</code> = 64 / Re</p>
-for Reynolds numbers Re <code>&lt;</code> 2300 and 
-<p align=\"center\">  <code>&zeta;</code> = (1.8 lg(Re) -1.5)<sup>-2</sup></p>
-for Reynolds numbers Re <code>&gt;</code> 2300. 
-</p>
-<h4>References</h4>
-<ul>
-<li>VDI e.V., VDI Wärmeatlas 11., bearbeitete und erweiterte Auflage, Chapter N6, Darmstadt: Springer Berlin Heidelberg, 2011. </li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 13, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end VDIWaermeatlasN6;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/package.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/package.mo
deleted file mode 100644
index b7613eb..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow;
-package PressureDropCorrelations
-  extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-
-end PressureDropCorrelations;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/package.order b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/package.order
deleted file mode 100644
index 67b21bf..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/PressureDropCorrelations/package.order
+++ /dev/null
@@ -1 +0,0 @@
-VDIWaermeatlasN6
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/TestAirAirHX.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/TestAirAirHX.mo
deleted file mode 100644
index 9d3fa70..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/TestAirAirHX.mo
+++ /dev/null
@@ -1,105 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow.Testers;
-model TestAirAirHX
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.GasTypes.VDI4670_MoistAir gasType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundary1A(
-    V_flowFixed(displayUnit="m3/s") = -3,
-    use_volumeFlowRateInput=false,
-    streamVariablesInputType="T",
-    streamVariablesInputTypeConcentration="xi",
-    use_massFlowRateInput=false,
-    m_flowFixed=-0.33,
-    boundaryType="m_flow",
-    TFixed=432.15,
-    pFixed=111325)
-    annotation (Placement(transformation(extent={{-64,11},{-56,31}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundary1B(
-    V_flowFixed(displayUnit="m3/s") = -3,
-    use_volumeFlowRateInput=false,
-    streamVariablesInputType="T",
-    streamVariablesInputTypeConcentration="xi",
-    use_massFlowRateInput=false,
-    m_flowFixed=0.01,
-    boundaryType="p",
-    TFixed=293.15,
-    pFixed=101325)
-    annotation (Placement(transformation(extent={{56,10},{64,30}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundary2A(
-    V_flowFixed(displayUnit="m3/s") = -3,
-    use_volumeFlowRateInput=false,
-    streamVariablesInputType="T",
-    streamVariablesInputTypeConcentration="xi",
-    use_mixingRatioInput=false,
-    use_massFlowRateInput=false,
-    m_flowFixed=-0.33,
-    boundaryType="m_flow",
-    TFixed=313.15,
-    pFixed=111325) annotation (Placement(transformation(
-        extent={{-5,-13},{5,13}},
-        rotation=180,
-        origin={61,-21})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundary2B(
-    m_flowFixed=-0.1,
-    V_flowFixed(displayUnit="m3/s") = -3,
-    use_volumeFlowRateInput=false,
-    streamVariablesInputType="T",
-    streamVariablesInputTypeConcentration="xi",
-    boundaryType="p",
-    use_massFlowRateInput=false,
-    TFixed=293.15,
-    pFixed=101325) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=0,
-        origin={-60,-20})));
-  HXAirAirParallelflow hxAirAirCounterflow(
-    gasType=sim.gasType1,
-    nCells=5,
-    redeclare Geometry.HXGeometry hxGeometry(
-      length=1,
-      width=0.2,
-      heightDuct1=0.01,
-      heightDuct2=0.01,
-      tSheet=0.003,
-      tCasing=0.03,
-      numDucts=10),
-    redeclare model WallMaterial = TILMedia.SolidTypes.TILMedia_Steel,
-    includeSummaryArrays=true,
-    includeDefaultSummary=true,
-    generateEventsAtFlowReversal=false,
-    redeclare model PressureDrop1 = PressureDropCorrelations.VDIWaermeatlasN6,
-    redeclare model PressureDrop2 = PressureDropCorrelations.VDIWaermeatlasN6,
-    HydraulicMassFlowPosition1="gas port B",
-    HydraulicMassFlowPosition2="gas port B",
-    redeclare model HeatTransferGasWall1 =
-        HeatAndMassTransfer.TransportPhenomena.HeatTransfer.ConstantAlpha (
-          constantAlpha=100),
-    redeclare model HeatTransferGasWall2 =
-        HeatAndMassTransfer.TransportPhenomena.HeatTransfer.ConstantAlpha (
-          constantAlpha=100))
-    annotation (Placement(transformation(extent={{-16,-14},{18,14}})));
-
-equation
-  connect(gasBoundary2B.port, hxAirAirCounterflow.gasPort2B) annotation (Line(
-      points={{-60,-20},{-40,-20},{-40,-8.05},{-16,-8.05}},
-      color={255,153,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(hxAirAirCounterflow.gasPort2A, gasBoundary2A.port) annotation (Line(
-      points={{18,-8.05},{26,-8.05},{26,-8},{40,-8},{40,-21},{61,-21}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gasBoundary1A.port, hxAirAirCounterflow.gasPort1A) annotation (Line(
-      points={{-60,21},{-50,21},{-50,20},{-40,20},{-40,8.4},{-16,8.4}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gasBoundary1B.port, hxAirAirCounterflow.gasPort1B) annotation (Line(
-      points={{60,20},{40,20},{40,8.4},{18,8.4}},
-      color={255,153,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-            -100},{100,100}})),
-    experiment(StopTime=1000, Interval=1),
-    __Dymola_experimentSetupOutput);
-end TestAirAirHX;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/package.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/package.mo
deleted file mode 100644
index 4c41545..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/package.mo
+++ /dev/null
@@ -1,7 +0,0 @@
-within SorpLib.Components.HeatExchanger.HXAirAirParallelflow;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-annotation (Icon(graphics));
-end Testers;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/package.order b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/package.order
deleted file mode 100644
index 03ed2bd..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/Testers/package.order
+++ /dev/null
@@ -1 +0,0 @@
-TestAirAirHX
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/package.mo b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/package.mo
deleted file mode 100644
index bf7001b..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.HeatExchanger;
-package HXAirAirParallelflow "counterflow air-air heat exchanger"
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-
-annotation (Icon(graphics));
-end HXAirAirParallelflow;
diff --git a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/package.order b/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/package.order
deleted file mode 100644
index 19c00d2..0000000
--- a/SorpLib/Components/HeatExchanger/HXAirAirParallelflow/package.order
+++ /dev/null
@@ -1,5 +0,0 @@
-HXAirAirParallelflow
-Geometry
-HeatAndMassTransfer
-PressureDropCorrelations
-Testers
diff --git a/SorpLib/Components/HeatExchanger/Recoolers/SimpleDryCooler.mo b/SorpLib/Components/HeatExchanger/Recoolers/SimpleDryCooler.mo
new file mode 100644
index 0000000..4aa7726
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Recoolers/SimpleDryCooler.mo
@@ -0,0 +1,257 @@
+within SorpLib.Components.HeatExchanger.Recoolers;
+model SimpleDryCooler "Model of a simple dry cooler"
+  extends SorpLib.Components.HeatExchanger.BaseClasses.PartialSimpleDryCooler(
+    final noDiff,
+    final X_i_initial,
+    final p_initial,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    final no_components=Medium_liq.nX);
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium_liq =
+      Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Liquid medium"
+    annotation (Dialog(tab = "General", group = "Medium"),
+                choicesAllMatching=true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable package Medium_air =
+    Modelica.Media.Air.DryAirNasa
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Air medium"
+    annotation (Dialog(tab = "General", group = "Medium"),
+                choicesAllMatching=true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of state records
+  //
+  Medium_liq.ThermodynamicState state_liq_in
+    "Record describing current state properties of liquid at inlet";
+  Medium_air.ThermodynamicState state_air_in = Medium_air.setState_pT(
+    p = p_air,
+    T = T_air_in)
+    "Record describing current state properties of air at the inlet";
+
+equation
+  //
+  // Calculation of fluid properties
+  //
+  if flowDirection == 1 then
+    //
+    // Flow from port a to port b
+    //
+    state_liq_in = Medium_liq.setState_phX(
+      p = port_a.p,
+      h = inStream(port_a.h_outflow),
+      X = inStream(port_a.Xi_outflow))
+      "Record describing current state properties of liquid at inlet";
+
+  elseif flowDirection == 2 then
+    //
+    // Flow from port b to port a
+    //
+    state_liq_in = Medium_liq.setState_phX(
+      p = port_b.p,
+      h = inStream(port_b.h_outflow),
+      X = inStream(port_b.Xi_outflow))
+      "Record describing current state properties of liquid at inlet";
+
+  else
+    //
+    // Actual flow direction
+    //
+    if avoid_events then
+      state_liq_in = Medium_liq.setState_phX(
+        p = SorpLib.Numerics.regStep_noEvent(
+          x=port_a.m_flow,
+          y1=port_a.p,
+          y2=port_a.p,
+          x_small=m_flow_small),
+        h = SorpLib.Numerics.regStep_noEvent(
+          x=port_a.m_flow,
+          y1=inStream(port_a.h_outflow),
+          y2=inStream(port_b.h_outflow),
+          x_small=m_flow_small),
+        X = SorpLib.Numerics.regStep_noEvent(
+          x=port_a.m_flow,
+          y1=inStream(port_a.Xi_outflow),
+          y2=inStream(port_b.Xi_outflow),
+          x_small=m_flow_small))
+        "Record describing current state properties of liquid at inlet";
+
+    else
+      Medium_liq.setState_phX(
+        p = SorpLib.Numerics.regStep(
+          x=port_a.m_flow,
+          y1=port_a.p,
+          y2=port_a.p,
+          x_small=m_flow_small),
+        h = SorpLib.Numerics.regStep(
+          x=port_a.m_flow,
+          y1=inStream(port_a.h_outflow),
+          y2=inStream(port_b.h_outflow),
+          x_small=m_flow_small),
+        X = SorpLib.Numerics.regStep(
+          x=port_a.m_flow,
+          y1=inStream(port_a.Xi_outflow),
+          y2=inStream(port_b.Xi_outflow),
+          x_small=m_flow_small))
+        "Record describing current state properties of liquid at inlet";
+
+    end if;
+  end if;
+
+  //
+  // Calculate fluid properties at inlets
+  //
+  T_liq_in = Medium_liq.temperature(state=state_liq_in)
+    "Inlet temperature of liquid";
+  cp_liq_in = Medium_liq.specificHeatCapacityCp(state=state_liq_in)
+    "Specific heat capacity of liquid at inlet";
+  eta_liq_in = Medium_liq.dynamicViscosity(state=state_liq_in)
+    "Dynamic viscosity of liquid at inlet";
+
+  d_air_in = Medium_air.density(state=state_air_in)
+    "Density of air at inlet";
+  cp_air_in = Medium_air.specificHeatCapacityCp(state=state_air_in)
+    "Specific heat capacity of air at inlet";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+The model of the simple dry cooler describes the cooling of an (ideal) liquid. Air 
+is used as the cooling medium. The model can be adapted to the performance of real 
+dry coolers using two fitting parameters for the heat tranfer correlations.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has a steady-state energy balance
+</p>
+<pre>
+    0 = m&#x307;<sub>liq,in</sub> + m&#x307;<sub>liq,out</sub>;
+</pre>
+<p>
+and a steady-state energy balance
+</p>
+<pre>
+    h<sub>liq,out</sub>  = h<sub>liq,in</sub> - Q_flow / m&#x307;<sub>liq,out</sub>;
+</pre>
+<p>
+Herein, <i>m&#x307;<sub>liq,in</sub></i>/<i>m&#x307;<sub>liq,out</sub></i> are the 
+inlet/outlet liquid mass flow rates, <i>h<sub>liq,in</sub></i>/<i>h<sub>liq,out</sub></i> 
+are the liquid specific enthalies at inlet/outlet, <i>Q_flow</i> is the heat flow 
+rate transferred to the surrounding. The heat flow rate <i>Q_flow</i> ist calculated 
+with the effectiveness <i>&epsilon;</i> of the dry cooler and the maximal heat flow 
+rate <i>Q_flow<sub>max</sub></i> that can be transferred:
+</p>
+<pre>
+    Q_flow  = &epsilon; * Q_flow<sub>max</sub> = &epsilon; * C_flow<sub>min</sub> * (T<sub>liq,in</sub> - T<sub>air,in</sub>);
+</pre>
+<p>
+Herein, <i>T<sub>liq,in</sub></i>/<i>T<sub>air,in</sub></i> are the inlet temperatures of 
+the liquid/ambient air, and <i>C_flow<sub>min</sub></i> is the minimal heat capacity rate. 
+The minimal and maximal heat capacity rates are defined as follows:
+</p>
+<pre>
+    C_flow<sub>min</sub> = <strong>min</strong>(m&#x307;<sub>liq</sub>*c;<sub>p,liq</sub>, V_flow<sub>air</sub>*&rho;;<sub>air</sub>*c;<sub>p,air</sub>);
+
+    C_flow<sub>max</sub> = <strong>max</strong>(m&#x307;<sub>liq</sub>*c;<sub>p,liq</sub>, V_flow<sub>air</sub>*&rho;;<sub>air</sub>*c;<sub>p,air</sub>);
+</pre>
+<p>
+Herein, <i>c;<sub>p,liq</sub></i>/<i>c;<sub>p,air</sub></i> are the specific heat 
+capacities of the liquid/ambient air, <i>&rho;<sub>air</sub></i> is the density of the 
+ambient air, and <i>V_flow<sub>air</sub></i> is the volume flow rate of the ambient air.
+<br/><br/>
+For a counter-current flow heat exchanger, the effectiveness <i>&epsilon;</i> is defined as
+</p>
+<pre>
+    &epsilon; = [1 - <strong>exp</strong>(-NTU * (1 - C_flow<sub>min</sub>/C_flow<sub>max</sub>)] / [1 - C_flow<sub>min</sub>/C_flow<sub>max</sub> * <strong>exp</strong>(-NTU * (1 - C_flow<sub>min</sub>/C_flow<sub>max</sub>];
+</pre>
+<p>
+where the number of transfer units <i>NTU</i> for the dry cooler was calculated as 
+</p>
+<pre>
+    NTU = 1/C_flow<sub>min</sub> * (&alpha;A)<sub>liq</sub> * (&alpha;A)<sub>air</sub> / ((&alpha;A)<sub>liq</sub> + (&alpha;A)<sub>air</sub>);
+</pre>
+<p>
+Herein, the products of heat transfer coefficients and areas describe the heat transfer 
+on the liquid side <i>(&alpha;A)<sub>liq</sub></i> and the ambient air side 
+<i>(&alpha;A)<sub>air</sub></i> . Gibelhaus et al. selected mass-flow-dependent approaches 
+for the two products:
+</p>
+<pre>
+    (&alpha;A)<sub>liq</sub> = 2 * &delta; * m&#x307;<sub>liq</sub>^(0.8) *  &eta;<sub>liq</sub>^(-0.8);
+
+    (&alpha;A)<sub>air</sub> = 0.35 * &gamma; * (V_flow<sub>air</sub> * &rho;<sub>air</sub>)^(0.8);
+</pre>
+<p>
+where <i>&eta;<sub>liq</sub></i> is the dynamic viscosity of the liquid, and
+<i>&delta;</i>/<i>&gamma;</i> are fitting parameters. 
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The model is typically used to describe the cooling of the heat transfer fluid of
+the condeser or of the adsorber to the surrounding.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>flowDirection</i>:
+  Defines the flow dirction and, thus, the inlet property calculation.
+  </li>
+  <li>
+  <i>typeDryRecooler</i>:
+  Defines the type of the dry cooler.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Engelpracht, M. (2024). Experimental demonstration and model-based optimization of adsorption heat transformation for waste heat upgrading. In: Aachener Beiträge zur technischen Thermodynamik 51. DOI: http://dx.doi.org/10.18154/RWTH-2024-06878.
+  </li>
+  <li>
+  Gibelhaus, A. and Tangkrachang, T. and Bau, U. and Seiler, J. and Bardow, A. (2019). Integrated design and control of full sorption chiller systems. Energy 185 (2019), pp. 409-422. DOI: https://doi.org/10.1016/j.energy.2019.06.169.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 26, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SimpleDryCooler;
diff --git a/SorpLib/Components/HeatExchanger/Recoolers/Tester/Test_SimpleDryCooler.mo b/SorpLib/Components/HeatExchanger/Recoolers/Tester/Test_SimpleDryCooler.mo
new file mode 100644
index 0000000..a4be70e
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Recoolers/Tester/Test_SimpleDryCooler.mo
@@ -0,0 +1,111 @@
+within SorpLib.Components.HeatExchanger.Recoolers.Tester;
+model Test_SimpleDryCooler "Tester for the simple dry cooler"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed(displayUnit="l/min") = -0.0016666666666667,
+    use_TInput=true,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-50,-10},{-30,10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{50,-10},{30,10}})));
+
+  SorpLib.Components.Sensors.LiquidSensors.TemperatureSensor T_liqOut(
+    redeclare package Medium = Medium)
+    "Outlet liquid temperature"
+    annotation (Placement(transformation(extent={{10,4},{30,24}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.HeatExchanger.Recoolers.SimpleDryCooler dryCooler(
+    p_air=100000,
+    T_air_in(displayUnit="K") = 283.15,
+    redeclare final package Medium_liq = Medium)
+    "Simple dry cooler"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_fRelAir(
+    amplitude=0.45,
+    f=1/500,
+    offset=0.5)
+    "Input signal for relative air volume flow rate"
+    annotation (Placement(transformation(extent={{-40,-40},{-20,-20}})));
+  Modelica.Blocks.Sources.Sine input_TLiq(
+    amplitude=20,
+    f=1/250,
+    offset=273.15+40)
+    "Input signal for liquid inlet temperature"
+    annotation (Placement(transformation(extent={{-80,-10},{-60,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, dryCooler.port_a) annotation (Line(
+      points={{-40,0},{-10,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(dryCooler.port_b, fs_b.port) annotation (Line(
+      points={{10,0},{40,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(T_liqOut.port, dryCooler.port_b) annotation (Line(
+      points={{20,6},{20,0},{10,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_TLiq.y, fs_a.T_input) annotation (Line(points={{-59,0},{-50,0},{
+          -50,-2},{-41.2,-2}}, color={0,0,127}));
+  connect(input_fRelAir.y, dryCooler.relativeFanSpeed)
+    annotation (Line(points={{-19,-30},{0,-30},{0,-6}},   color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the simple dry cooler.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 26, 2024, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_SimpleDryCooler;
diff --git a/SorpLib/Components/HeatExchanger/Recoolers/Tester/package.mo b/SorpLib/Components/HeatExchanger/Recoolers/Tester/package.mo
new file mode 100644
index 0000000..407a43c
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Recoolers/Tester/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.HeatExchanger.Recoolers;
+package Tester "Models to test and varify dry cooler models"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented dry coolers. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/HeatExchanger/Recoolers/Tester/package.order b/SorpLib/Components/HeatExchanger/Recoolers/Tester/package.order
new file mode 100644
index 0000000..683f3e4
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Recoolers/Tester/package.order
@@ -0,0 +1 @@
+Test_SimpleDryCooler
diff --git a/SorpLib/Components/HeatExchanger/Recoolers/package.mo b/SorpLib/Components/HeatExchanger/Recoolers/package.mo
new file mode 100644
index 0000000..289eb7a
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Recoolers/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.HeatExchanger;
+package Recoolers "Recoolers used in closed and open sorption systems"
+  extends SorpLib.Icons.RecoolersPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains recooler models that are based on the open-source Modelica 
+Standard Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Recoolers;
diff --git a/SorpLib/Components/HeatExchanger/Recoolers/package.order b/SorpLib/Components/HeatExchanger/Recoolers/package.order
new file mode 100644
index 0000000..0265a95
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Recoolers/package.order
@@ -0,0 +1,2 @@
+SimpleDryCooler
+Tester
diff --git a/SorpLib/Components/HeatExchanger/Records/GeometryClosedAdsorber.mo b/SorpLib/Components/HeatExchanger/Records/GeometryClosedAdsorber.mo
new file mode 100644
index 0000000..7f3f7da
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Records/GeometryClosedAdsorber.mo
@@ -0,0 +1,229 @@
+within SorpLib.Components.HeatExchanger.Records;
+record GeometryClosedAdsorber
+  "This record contains the geometry of closed adsorbers"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters regarding the disretization
+  //
+  parameter Integer no_fluidVolumes(min=1) = 1
+    "Number of fluid volumes"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+  parameter Integer no_wallVolumes(min=1) = 1
+    "Number of wall volumes"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+  parameter Integer no_sorbentVolumes(min=1) = 1
+    "Number of sorbent volumes"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+
+  //
+  // Definition of parameters regarding the geometry of the casing
+  //
+  parameter Modelica.Units.SI.Length l_cas = 1.25
+    "Length of the casing"
+    annotation (Dialog(tab="Casing", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_inner_cas = 0.32
+    "Inner diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer_cas = 0.325
+    "Outer diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydInner_cas = d_inner_cas
+    "Hydraulic inner diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydOuter_cas = d_outer_cas
+    "Hydraulic outer diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+
+  parameter Modelica.Units.SI.Thickness t_wall_cas=
+    (d_outer_cas - d_inner_cas) / 2
+    "Wall thickness of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_crossInner_cas=
+    Modelica.Constants.pi/4 * d_inner_cas^2
+    "Inner cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter_cas=
+    Modelica.Constants.pi/4 * d_outer_cas^2
+    "Outer cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall_cas=
+    A_crossOuter_cas - A_crossInner_cas
+    "Wall cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossInner_cas=
+    Modelica.Constants.pi/4 * d_hydInner_cas^2
+    "Hydraulic inner cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossOuter_cas=
+    Modelica.Constants.pi/4 * d_hydOuter_cas^2
+    "Hydraulic outer cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossWall_cas=
+    A_hydCrossOuter_cas - A_hydCrossInner_cas
+    "Hydaulic wall cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferInner_cas=
+    Modelica.Constants.pi * d_inner_cas * l_cas
+    "Inner heat transfer area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter_cas=
+    Modelica.Constants.pi * d_outer_cas * l_cas
+    "Outer heat transfer area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_inner_cas=
+    Modelica.Constants.pi/4 * d_inner_cas^2 * l_cas
+    "Inner volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer_cas=
+    Modelica.Constants.pi/4 * d_outer_cas^2 * l_cas
+    "Outer volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall_cas=
+    V_outer_cas - V_inner_cas
+    "Wall volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_vapor_cas=
+    V_inner_cas - V_outer_hx - V_particles
+    "Vapor volume within the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+
+  //
+  // Definition of parameters regarding the the heat exchanger
+  //
+  parameter Integer no_hydraulicParallelTubes(min=1) = 1
+    "Number of hydraulically parallel tubes"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+  parameter Modelica.Units.SI.Length l_hx = 1
+    "Length of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+  parameter Modelica.Units.SI.Length roughness_hx = 7.5e-7
+    "Absolute roughness of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_inner_hx = 0.01
+    "Inner diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer_hx = 0.012
+    "Outer diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydInner_hx = d_inner_hx
+    "Hydraulic inner diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydOuter_hx = d_outer_hx
+    "Hydraulic outer diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Thickness t_wall_hx=
+    (d_outer_hx - d_inner_hx) / 2
+    "Wall thickness of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_crossInner_hx=
+    Modelica.Constants.pi/4 * d_inner_hx^2
+    "Inner cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter_hx=
+    Modelica.Constants.pi/4 * d_outer_hx^2
+    "Outer cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall_hx=
+    A_crossOuter_hx - A_crossInner_hx
+    "Wall cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossInner_hx = A_crossInner_hx
+    "Hydraulic inner cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossOuter_hx = A_crossOuter_hx
+    "Hydraulic outer cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossWall_hx=
+    A_hydCrossOuter_hx - A_hydCrossInner_hx
+    "Hydraulic wall cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferInner_hx=
+    Modelica.Constants.pi * d_inner_hx * l_hx
+    "Total inner heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter_hx=
+    Modelica.Constants.pi * d_outer_hx * l_hx
+    "Total outer heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Real f_finAreaRatioInner_hx(min=0, max=1) = 0
+    "Ratio of total inner fin area to total inner heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Real f_finAreaRatioOuter_hx(min=0, max=1) = 0
+    "Ratio of total outer fin area to total outer heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_inner_hx = A_crossInner_hx * l_hx
+    "Total inner volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer_hx = A_crossOuter_hx * l_hx
+    "Total outer volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall_hx = V_outer_hx - V_inner_hx
+    "Total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_sorbent_hx = 0.0025
+    "Total volume that can be filled with sorbent"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Real f_finVolumeRatioInner_hx(min=0, max=1) = 0
+    "Ratio of total inner fin volume to total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Real f_finVolumeRatioOuter_hx(min=0, max=1) = 0
+    "Ratio of total outer fin volume to total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+
+  //
+  // Definition of parameters regarding the sorbent gemeotry
+  //
+  parameter Real no_particles = (1-psi_particles) * V_sorbent_hx / V_particle
+    "Number of particles"
+    annotation (Dialog(tab="Sorbent", group="General"));
+  parameter Real psi_particles(unit="1") = 1 - 0.74
+    "Void fraction of the adsorber (i.e., ratio of the free fluid volume to
+    the total inner volume)"
+    annotation (Dialog(tab="Sorbent", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_particle = 0.7 / 1000
+    "Average diameter of the adsorbent particles"
+    annotation (Dialog(tab="Sorbent", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_cross_particle=
+    Modelica.Constants.pi/4 * d_particle^2
+    "Average cross-sectional area of the particle"
+    annotation (Dialog(tab="Sorbent", group="Areas"));
+  parameter Modelica.Units.SI.Area A_surface_particle=
+    Modelica.Constants.pi * d_particle^2
+    "Average suraface area of the particle"
+    annotation (Dialog(tab="Sorbent", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_particle=
+    Modelica.Constants.pi/6 * d_particle^3
+    "Average volume of the particle"
+    annotation (Dialog(tab="Sorbent", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_particles=
+    no_particles * V_particle
+    "Average volume of all particles"
+    annotation (Dialog(tab="Sorbent", group="Volumes"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by models calculating the heat
+transfer coefficients of closed adsorbers.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryClosedAdsorber;
diff --git a/SorpLib/Components/HeatExchanger/Records/GeometryCondenserEvaporator.mo b/SorpLib/Components/HeatExchanger/Records/GeometryCondenserEvaporator.mo
new file mode 100644
index 0000000..cdbfb8e
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Records/GeometryCondenserEvaporator.mo
@@ -0,0 +1,200 @@
+within SorpLib.Components.HeatExchanger.Records;
+record GeometryCondenserEvaporator
+  "This record contains the geometry of condensers or evaporators"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters regarding the disretization
+  //
+  parameter Integer no_fluidVolumes(min=1) = 1
+    "Number of fluid volumes"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+  parameter Integer no_wallVolumes(min=1) = 1
+    "Number of wall volumes"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+
+  //
+  // Definition of parameters regarding the geometry of the casing
+  //
+  parameter Modelica.Units.SI.Length l_cas = 1
+    "Length of the casing"
+    annotation (Dialog(tab="Casing", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_inner_cas = 0.100
+    "Inner diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer_cas = 0.103
+    "Outer diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydInner_cas = d_inner_cas
+    "Hydraulic inner diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydOuter_cas = d_outer_cas
+    "Hydraulic outer diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+
+  parameter Modelica.Units.SI.Thickness t_wall_cas=
+    (d_outer_cas - d_inner_cas) / 2
+    "Wall thickness of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_crossInner_cas=
+    Modelica.Constants.pi/4 * d_inner_cas^2
+    "Inner cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter_cas=
+    Modelica.Constants.pi/4 * d_outer_cas^2
+    "Outer cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall_cas=
+    A_crossOuter_cas - A_crossInner_cas
+    "Wall cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossInner_cas=
+    Modelica.Constants.pi/4 * d_hydInner_cas^2
+    "Hydraulic inner cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossOuter_cas=
+    Modelica.Constants.pi/4 * d_hydOuter_cas^2
+    "Hydraulic outer cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossWall_cas=
+    A_hydCrossOuter_cas - A_hydCrossInner_cas
+    "Hydaulic wall cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferInner_cas=
+    Modelica.Constants.pi * d_inner_cas * l_cas
+    "Inner heat transfer area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter_cas=
+    Modelica.Constants.pi * d_outer_cas * l_cas
+    "Outer heat transfer area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_inner_cas=
+    Modelica.Constants.pi/4 * d_inner_cas^2 * l_cas
+    "Inner volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer_cas=
+    Modelica.Constants.pi/4 * d_outer_cas^2 * l_cas
+    "Outer volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall_cas=
+    V_outer_cas - V_inner_cas
+    "Wall volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+
+  //
+  // Definition of parameters regarding the the heat exchanger
+  //
+  parameter Integer no_hydraulicParallelTubes(min=1) = 1
+    "Number of hydraulically parallel tubes"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+  parameter Modelica.Units.SI.Length l_hx = 1
+    "Length of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+  parameter Modelica.Units.SI.Length roughness_hx = 7.5e-7
+    "Absolute roughness of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_inner_hx = 0.01
+    "Inner diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer_hx = 0.012
+    "Outer diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydInner_hx = d_inner_hx
+    "Hydraulic inner diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydOuter_hx = d_outer_hx
+    "Hydraulic outer diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Thickness t_wall_hx=
+    (d_outer_hx - d_inner_hx) / 2
+    "Wall thickness of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_crossInner_hx=
+    Modelica.Constants.pi/4 * d_inner_hx^2
+    "Inner cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter_hx=
+    Modelica.Constants.pi/4 * d_outer_hx^2
+    "Outer cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall_hx=
+    A_crossOuter_hx - A_crossInner_hx
+    "Wall cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossInner_hx = A_crossInner_hx
+    "Hydraulic inner cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossOuter_hx = A_crossOuter_hx
+    "Hydraulic outer cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossWall_hx=
+    A_hydCrossOuter_hx - A_hydCrossInner_hx
+    "Hydraulic wall cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferInner_hx=
+    Modelica.Constants.pi * d_inner_hx * l_hx
+    "Total inner heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter_hx=
+    Modelica.Constants.pi * d_outer_hx * l_hx
+    "Total outer heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Real f_finAreaRatioInner_hx(min=0, max=1) = 0
+    "Ratio of total inner fin area to total inner heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Real f_finAreaRatioOuter_hx(min=0, max=1) = 0
+    "Ratio of total outer fin area to total outer heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_inner_hx = A_crossInner_hx * l_hx
+    "Total inner volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer_hx = A_crossOuter_hx * l_hx
+    "Total outer volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall_hx = V_outer_hx - V_inner_hx
+    "Total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Real f_finVolumeRatioInner_hx(min=0, max=1) = 0
+    "Ratio of total inner fin volume to total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Real f_finVolumeRatioOuter_hx(min=0, max=1) = 0
+    "Ratio of total outer fin volume to total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+
+  //
+  // Definition of parameters regarding the phase separator
+  //
+  parameter Modelica.Units.SI.Area A_refrigerant=0.05
+    "Base area of the phase seprator"
+    annotation (Dialog(tab="Phase Seperator", group="Areas"));
+  parameter Modelica.Units.SI.Volume V_refrigerant=
+    V_inner_cas - V_outer_hx
+    "Total volume of the phase seperator"
+    annotation (Dialog(tab="Phase Seperator", group="Volumes"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters describing condensers or evaporators.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 4, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations.
+  </li>
+  <li>
+  January 14, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryCondenserEvaporator;
diff --git a/SorpLib/Components/HeatExchanger/Records/ParametrizationDryCooler.mo b/SorpLib/Components/HeatExchanger/Records/ParametrizationDryCooler.mo
new file mode 100644
index 0000000..4323b88
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Records/ParametrizationDryCooler.mo
@@ -0,0 +1,59 @@
+within SorpLib.Components.HeatExchanger.Records;
+record ParametrizationDryCooler
+  "This record contains parameters describing dry coolers"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real gamma = 11.52
+    "Factor for external heat transfer coefficient"
+    annotation (Dialog(tab="Genral", group="Heat Transfer"));
+  parameter Real delta = 303.09
+    "Factor for internal heat transfer coefficient"
+    annotation (Dialog(tab="Genral", group="Heat Transfer"));
+
+  parameter Modelica.Units.SI.MassFlowRate m_flow_liq_nom=
+    28.78 / 3600 * 1000
+    "Nominal mass flow rate of liquid medium that shall be cooled"
+    annotation (Dialog(tab="Genral", group="Nominal Operating Point"));
+  parameter Modelica.Units.SI.PressureDifference dp_liq_nom=
+    0.77*10^5
+    "Nominal pressure drop of liquid medium at nominal mass flow rate"
+    annotation (Dialog(tab="Genral", group="Nominal Operating Point"));
+
+  parameter Modelica.Units.SI.VolumeFlowRate V_flow_air_max = 88368/3600
+    "Maximal air flow rate"
+    annotation (Dialog(tab="Genral", group="Maximal Operating Point"));
+  parameter Modelica.Units.SI.Power P_el_fan_max = 16.2*10^3
+    "Maximal power consumption of the fan units"
+    annotation (Dialog(tab="Genral", group="Maximal Operating Point"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains parameters characterizing dry coolers. The default parameters
+correspond to the dry cooler GFHC WD 063 from Guenther, fitted by Gibelhaus (2019).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Gibelhaus, A. and Tangkrachang, T. and Bau, U. and Seiler, J. and Bardow, A. (2019). Integrated design and control of full sorption chiller systems. Energy 185 (2019), pp. 409-422. DOI: https://doi.org/10.1016/j.energy.2019.06.169.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ParametrizationDryCooler;
diff --git a/SorpLib/Components/HeatExchanger/Records/SummaryClosedAdsorber.mo b/SorpLib/Components/HeatExchanger/Records/SummaryClosedAdsorber.mo
new file mode 100644
index 0000000..cd2e811
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Records/SummaryClosedAdsorber.mo
@@ -0,0 +1,118 @@
+within SorpLib.Components.HeatExchanger.Records;
+record SummaryClosedAdsorber
+  "This record summarizes the most important variables of closed adsorbers"
+  extends Modelica.Icons.Record;
+
+  //
+  // Variables describing the vapor
+  //
+  Modelica.Units.SI.Pressure p_vapor
+    "Average pressure in vapor volume"
+    annotation (Dialog(tab="General", group="Vapor volume"));
+  Modelica.Units.SI.Temperature T_vapor
+    "Average temperature in vapor volume"
+    annotation (Dialog(tab="General", group="Vapor volume"));
+  Modelica.Units.SI.Density rho_vapor
+    "Average density in vapor volume"
+    annotation (Dialog(tab="General", group="Vapor volume"));
+
+  Modelica.Units.SI.Mass mass_vapor
+    "Fluid mass in vapor volume"
+    annotation (Dialog(tab="General", group="Vapor volume"));
+
+  //
+  // Variables describing the sorbent
+  //
+  Modelica.Units.SI.Pressure p_adsorbate_avg
+    "Average adsorabte pressure"
+    annotation (Dialog(tab="General", group="Adsorbate"));
+  Modelica.Units.SI.Temperature T_adsorbate_avg
+    "Average adsorabte temperature"
+    annotation (Dialog(tab="General", group="Adsorbate"));
+  SorpLib.Units.Uptake x_adsorbate_avg
+    "Average adsorabte loading"
+    annotation (Dialog(tab="General", group="Adsorbate"));
+
+  Modelica.Units.SI.Mass mass_adsorpt
+    "Adsorpt mass"
+    annotation (Dialog(tab="General", group="Adsorbate"));
+
+  //
+  // Variables describing the heat exchanger
+  //
+  Modelica.Units.SI.Pressure p_liq_inlet
+    "Pressure of liquid at heat exchanger inlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Pressure p_liq_outlet
+    "Pressure of liquid at heat exchanger outlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Pressure p_liq_avg
+    "Average pressure of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.PressureDifference dp_liq = p_liq_inlet - p_liq_outlet
+    "Pressure difference of liquid in heat exchanger";
+
+  Modelica.Units.SI.Temperature T_liq_inlet
+    "Temperature of liquid at heat exchanger inlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Temperature T_liq_outlet
+    "Temperature of liquid at heat exchanger outlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Temperature T_liq_avg
+    "Average temperature of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+
+  Modelica.Units.SI.Temperature T_wall_avg
+    "Average wall temperature of heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+
+  //
+  // Variables required for balance equations
+  //
+  Modelica.Units.SI.MassFlowRate m_flow_liq_inlet
+    "Mass flow rate of liquid at inlet of heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_liq_outlet
+    "Mass flow rate of liquid at outlet of heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+
+  Modelica.Units.SI.MassFlowRate m_flow_evaporator
+    "Mass flow rate from evaporator"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_condenser
+    "Mass flow rate from condenser"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_massRecovery
+    "Mass flow rate from mass recovery ports"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+
+  Modelica.Units.SI.HeatFlowRate Q_flow_wallToSorbent
+    "Heat flow rate from heat exchanger walls to sorbent"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.HeatFlowRate Q_flow_fluidWall
+    "Heat flow rate from liquid to wall"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.HeatFlowRate DH_liquid
+    "Difference enthalpy flow of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record summarizes the most important variables of closed adsorbers
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations.
+  </li>
+  <li>
+  January 14, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SummaryClosedAdsorber;
diff --git a/SorpLib/Components/HeatExchanger/Records/SummaryCondenserEvaporator.mo b/SorpLib/Components/HeatExchanger/Records/SummaryCondenserEvaporator.mo
new file mode 100644
index 0000000..4fc69cc
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Records/SummaryCondenserEvaporator.mo
@@ -0,0 +1,97 @@
+within SorpLib.Components.HeatExchanger.Records;
+record SummaryCondenserEvaporator
+  "This record summarizes the most important variables of condensers or evaporators"
+  extends Modelica.Icons.Record;
+
+  //
+  // Variables describing the phase seperator
+  //
+  Modelica.Units.SI.Pressure p_VLE
+    "Average pressure in phase seperator"
+    annotation (Dialog(tab="General", group="Phase Seperator"));
+  Modelica.Units.SI.Density rho_VLE
+    "Average density in phase seperator"
+    annotation (Dialog(tab="General", group="Phase Seperator"));
+  Modelica.Units.SI.Temperature T_VLE
+    "Average temperature in phase seperator"
+    annotation (Dialog(tab="General", group="Phase Seperator"));
+
+  Modelica.Units.SI.Mass mass
+    "Fluid mass in phase seperator"
+    annotation (Dialog(tab="General", group="Phase Seperator"));
+
+  //
+  // Variables describing the heat exchanger
+  //
+  Modelica.Units.SI.Pressure p_liq_inlet
+    "Pressure of liquid at heat exchanger inlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Pressure p_liq_outlet
+    "Pressure of liquid at heat exchanger outlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Pressure p_liq_avg
+    "Average pressure of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.PressureDifference dp_liq = p_liq_inlet - p_liq_outlet
+    "Pressure difference of liquid in heat exchanger";
+
+  Modelica.Units.SI.Temperature T_liq_inlet
+    "Temperature of liquid at heat exchanger inlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Temperature T_liq_outlet
+    "Temperature of liquid at heat exchanger outlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Temperature T_liq_avg
+    "Average temperature of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+
+  Modelica.Units.SI.Temperature T_wall_avg
+    "Average wall temperature of heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+
+  //
+  // Variables required for balance equations
+  //
+  Modelica.Units.SI.MassFlowRate m_flow_liq_inlet
+    "Mass flow rate of liquid at inlet of heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_liq_outlet
+    "Mass flow rate of liquid at outlet of heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_vapor
+    "Mass flow rate of vapor from heat exchanger to working pair cells"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_liquid
+    "Mass flow rate of liquid"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+
+  Modelica.Units.SI.HeatFlowRate Q_flow_wallToPhaseSeparator
+    "Heat flow rate from heat exchanger walls to phase seperator"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.HeatFlowRate Q_flow_fluidWall
+    "Heat flow rate from liquid to wall"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.HeatFlowRate DH_liquid
+    "Difference enthalpy flow of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record summarizes the most important variables of condensers or evaporators.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 4, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations.
+  </li>
+  <li>
+  January 14, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SummaryCondenserEvaporator;
diff --git a/SorpLib/Components/HeatExchanger/Records/SummarySimpleClosedAdsorber.mo b/SorpLib/Components/HeatExchanger/Records/SummarySimpleClosedAdsorber.mo
new file mode 100644
index 0000000..1e448ed
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Records/SummarySimpleClosedAdsorber.mo
@@ -0,0 +1,101 @@
+within SorpLib.Components.HeatExchanger.Records;
+record SummarySimpleClosedAdsorber
+  "This record summarizes the most important variables of simple closed adsorbers"
+  extends Modelica.Icons.Record;
+
+  //
+  // Variables describing the sorbent
+  //
+  Modelica.Units.SI.Pressure p_adsorbate_avg
+    "Average adsorabte pressure"
+    annotation (Dialog(tab="General", group="Adsorbate"));
+  Modelica.Units.SI.Temperature T_adsorbate_avg
+    "Average adsorabte temperature"
+    annotation (Dialog(tab="General", group="Adsorbate"));
+  SorpLib.Units.Uptake x_adsorbate_avg
+    "Average adsorabte loading"
+    annotation (Dialog(tab="General", group="Adsorbate"));
+
+  Modelica.Units.SI.Mass mass_adsorpt
+    "Adsorpt mass"
+    annotation (Dialog(tab="General", group="Adsorbate"));
+
+  //
+  // Variables describing the heat exchanger
+  //
+  Modelica.Units.SI.Pressure p_liq_inlet
+    "Pressure of liquid at heat exchanger inlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Pressure p_liq_outlet
+    "Pressure of liquid at heat exchanger outlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Pressure p_liq_avg
+    "Average pressure of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.PressureDifference dp_liq = p_liq_inlet - p_liq_outlet
+    "Pressure difference of liquid in heat exchanger";
+
+  Modelica.Units.SI.Temperature T_liq_inlet
+    "Temperature of liquid at heat exchanger inlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Temperature T_liq_outlet
+    "Temperature of liquid at heat exchanger outlet"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+  Modelica.Units.SI.Temperature T_liq_avg
+    "Average temperature of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+
+  Modelica.Units.SI.Temperature T_wall_avg
+    "Average wall temperature of heat exchanger"
+    annotation (Dialog(tab="General", group="Heat Exchanger Tubes"));
+
+  //
+  // Variables required for balance equations
+  //
+  Modelica.Units.SI.MassFlowRate m_flow_liq_inlet
+    "Mass flow rate of liquid at inlet of heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_liq_outlet
+    "Mass flow rate of liquid at outlet of heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+
+  Modelica.Units.SI.MassFlowRate m_flow_evaporator
+    "Mass flow rate from evaporator"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_condenser
+    "Mass flow rate from condenser"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.MassFlowRate m_flow_massRecovery
+    "Mass flow rate from mass recovery ports"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+
+  Modelica.Units.SI.HeatFlowRate Q_flow_wallToSorbent
+    "Heat flow rate from heat exchanger walls to sorbent"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.HeatFlowRate Q_flow_fluidWall
+    "Heat flow rate from liquid to wall"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+  Modelica.Units.SI.HeatFlowRate DH_liquid
+    "Difference enthalpy flow of liquid in heat exchanger"
+    annotation (Dialog(tab="General", group="Balance Equations"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record summarizes the most important variables of simple closed adsorbers
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  March 5, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations.
+  </li>
+  <li>
+  January 14, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SummarySimpleClosedAdsorber;
diff --git a/SorpLib/Components/HeatExchanger/Records/package.mo b/SorpLib/Components/HeatExchanger/Records/package.mo
new file mode 100644
index 0000000..37a961e
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Records/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.HeatExchanger;
+package Records "Package containing records"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records. These records are used to cluster 
+variables and tidy up the model output.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Components/HeatExchanger/Records/package.order b/SorpLib/Components/HeatExchanger/Records/package.order
new file mode 100644
index 0000000..1fa2964
--- /dev/null
+++ b/SorpLib/Components/HeatExchanger/Records/package.order
@@ -0,0 +1,6 @@
+GeometryCondenserEvaporator
+GeometryClosedAdsorber
+ParametrizationDryCooler
+SummaryCondenserEvaporator
+SummaryClosedAdsorber
+SummarySimpleClosedAdsorber
diff --git a/SorpLib/Components/HeatExchanger/package.mo b/SorpLib/Components/HeatExchanger/package.mo
index a93fa27..1723ab8 100644
--- a/SorpLib/Components/HeatExchanger/package.mo
+++ b/SorpLib/Components/HeatExchanger/package.mo
@@ -1,10 +1,18 @@
 within SorpLib.Components;
-package HeatExchanger
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
+package HeatExchanger "Heat exchangers to transfer heat between different fluid fows"
+  extends SorpLib.Icons.HeatExchangersPackage;
 
-
-
-
-
-annotation (Icon(graphics));
+  annotation (Documentation(info="<html>
+<p>
+This package contains heat exchangers. Ready-to-use models are based on the Modelica 
+Standard library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
 end HeatExchanger;
diff --git a/SorpLib/Components/HeatExchanger/package.order b/SorpLib/Components/HeatExchanger/package.order
index e8076f9..cd7bf27 100644
--- a/SorpLib/Components/HeatExchanger/package.order
+++ b/SorpLib/Components/HeatExchanger/package.order
@@ -1 +1,5 @@
-HXAirAirParallelflow
+BaseClasses
+Records
+CondensersEvaporators
+Adsorbers
+Recoolers
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialClosedAdsorberHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialClosedAdsorberHeatTransferCoefficient.mo
new file mode 100644
index 0000000..268bce9
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialClosedAdsorberHeatTransferCoefficient.mo
@@ -0,0 +1,50 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialClosedAdsorberHeatTransferCoefficient
+  "Base model for all models calculating the product of heat transfer coefficient and area for closed adsorbers"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient;
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the sorbent)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryClosedAdsorber geometry
+    constrainedby
+    SorpLib.Components.HeatTransfer.Records.GeometryClosedAdsorber
+    "Geometry of the closed adsorber"
+    annotation(Dialog(tab = "General", group = "Heat Transfer", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the product of
+heat transfer coefficient and area <i>alphaA</i> describing the heat transfer
+between the sorbent and heat exchanger tubes. It defines fundamental parameters 
+and variables required by all heat transfer coefficient models. Models that inherit 
+properties from this partial model have to add an equation for calculating the 
+product of heat transfer coefficient and area.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialClosedAdsorberHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialConductiveHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialConductiveHeatTransferCoefficient.mo
new file mode 100644
index 0000000..0d32236
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialConductiveHeatTransferCoefficient.mo
@@ -0,0 +1,48 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialConductiveHeatTransferCoefficient
+  "Base model for all models calculating the product of heat transfer coefficient and area for thermal conduction"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient;
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the volume)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Definition of parameters
+  //
+  parameter Integer no_hydraulicParallelFlows(min=1) = 1
+    "Number of hydraulically parallel flows (e.g., tubes)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the product of
+heat transfer coefficient and area <i>alphaA</i> describing thermal conduction. 
+It defines fundamental parameters and variables required by all heat transfer 
+coefficient models. Models that inherit  properties from this partial model have 
+to add an equation for calculating the product of heat transfer coefficient and 
+area.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialConductiveHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialGenericHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialGenericHeatTransferCoefficient.mo
new file mode 100644
index 0000000..ec63e43
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialGenericHeatTransferCoefficient.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialGenericHeatTransferCoefficient
+  "Base model for all feneric models calculating the product of heat transfer coefficient and area"
+  extends SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient(
+    final computeTransportProperties=false);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all generic models calculating the product 
+of heat transfer coefficient and area <i>alphaA</i>. It defines fundamental parameters  
+and variables required by all heat transfer coefficient models. Models that inherit 
+properties from this partial model have to add an equation for calculating the 
+product of heat transfer coefficient and area.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialGenericHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialHeatTransfer.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialHeatTransfer.mo
new file mode 100644
index 0000000..6eb5493
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialHeatTransfer.mo
@@ -0,0 +1,231 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialHeatTransfer
+  "Base model for all heat transfer models"
+
+  //
+  // Definition of parameters regarding the calculation setup
+  //
+  parameter Integer n_a(min=1) = 1
+    "Number of heat ports a"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer n_b(min=1) = 1
+    "Number of heat ports b"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Integer exponetTemperature(min=1) = 1
+    "Exponent of the temperature when calculating the heat flow rate (i.e., 1 for
+    convection and conduction; 4 for radiation"
+    annotation (Dialog(tab="General", group="Calculation Setup", enable=false),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the heat transfer coefficient
+  //
+  parameter Boolean useAlphaAInput = false
+    " = true, if alphaA is given by input; otherwise, alphaA is calculated by
+    selected model"
+    annotation (Dialog(tab="General", group="Heat Transfer Coefficient"));
+  parameter Boolean calculateFluidProperties = false
+    "= true, to calculate fluid properties including transport properties"
+    annotation (Dialog(tab="General", group="Heat Transfer Coefficient",
+                enable=not useAlphaAInput),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+  replaceable model HeatTransferCoefficient =
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient(
+     T_avg_port_a = sum(hp_a.T)/n_a,
+     T_avg_port_b = sum(hp_b.T)/n_b)
+    "Model calculating the product of the heat transfer coefficient and area"
+    annotation (Dialog(tab="General", group="Heat Transfer Coefficient",
+                enable=not useAlphaAInput),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput alphaA_input(final unit="W/K") if
+    useAlphaAInput
+    "Input for the product of the heat transfer coefficient and area"
+    annotation (Placement(transformation(extent={{-20,-20},{20,20}},
+        rotation=270,
+        origin={0,50}),
+      iconTransformation(extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,40})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput alphaA_internal(final unit="W/K")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of ports
+  //
+public
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in[n_a] hp_a
+    "Heat port a"
+    annotation (Placement(transformation(extent={{-90,-10},{-70,10}}),
+                iconTransformation(extent={{-90,-10},{-70,10}})));
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_out[n_b] hp_b
+    "Heat port b"
+    annotation (Placement(transformation(extent={{70,-10},{90,10}}),
+                iconTransformation(extent={{70,-10},{90,10}})));
+
+  //
+  // Definition of models
+  //
+  HeatTransferCoefficient heatTransferCoefficient if not useAlphaAInput
+    "Model calculating the product of the heat transfer coefficient and area";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.TemperatureDifference DT_avg=
+    (sum(hp_a.T)/n_a)^exponetTemperature - (sum(hp_b.T)/n_b)^exponetTemperature
+    "Average driving potential (i.e., temperature difference) between ports a 
+    and b";
+  Modelica.Units.SI.HeatFlowRate Q_flow=
+    sum(hp_a.Q_flow)
+    "Total heat flow rate transferred from ports a to b";
+
+equation
+  //
+  // Assertions
+  //
+  if n_a < n_b then
+    assert(rem(n_b, n_a) == 0,
+      "Number of heat ports a must be a factor of the number of heat ports b!");
+
+  elseif n_a > n_b then
+    assert(rem(n_a, n_b) == 0,
+      "Number of heat ports a must be a factor of the number of heat ports b!");
+
+  end if;
+
+  //
+  // Connectors
+  //
+  connect(alphaA_internal, alphaA_input);
+  connect(alphaA_internal, heatTransferCoefficient.alphaA);
+
+  //
+  // Calculation of heat port properties depending on the discretization
+  //
+  0 = sum(hp_a.Q_flow) + sum(hp_b.Q_flow)
+    "Overall energy balance";
+
+  if n_a < n_b then
+    //
+    // Number of heat ports a is less than number of heat ports b:
+    // Connect multiple heat ports b with one heat port a!
+    //
+    for i in 1:n_a-1 loop
+      0 = hp_a[i].Q_flow +
+        sum(hp_b[1 + (i-1) * integer(n_b/n_a):i * integer(n_b/n_a)].Q_flow)
+        "N-1 energy balances";
+    end for;
+
+    for i in 1:n_a loop
+      for j in 1:integer(n_b/n_a) loop
+        hp_b[j + (i-1) * integer(n_b/n_a)].Q_flow = alphaA_internal/n_b * (
+          hp_b[j + (i-1) * integer(n_b/n_a)].T^exponetTemperature -
+          hp_a[i].T^exponetTemperature)
+          "Heat flow calculation depending on discretization";
+      end for;
+    end for;
+
+  elseif n_a > n_b then
+    //
+    // Number of heat ports a is greater than number of heat ports b:
+    // Connect multiple heat ports a with one heat port b!
+    //
+    for i in 1:n_b-1 loop
+      0 = hp_b[i].Q_flow +
+        sum(hp_a[1 + (i-1) * integer(n_a/n_b):i * integer(n_a/n_b)].Q_flow)
+        "N-1 energy balances";
+    end for;
+
+    for i in 1:n_b loop
+      for j in 1:integer(n_a/n_b) loop
+        hp_a[j + (i-1) * integer(n_a/n_b)].Q_flow = alphaA_internal/n_a * (
+          hp_a[j + (i-1) * integer(n_a/n_b)].T^exponetTemperature -
+          hp_b[i].T^exponetTemperature)
+          "Heat flow calculation depending on discretization";
+      end for;
+    end for;
+
+  else
+    //
+    // Number of heat ports a equals number of heat ports b:
+    // Connect one heat port a with one heat port b!
+    //
+    for i in 1:n_a-1 loop
+      0 = hp_a[i].Q_flow + hp_b[i].Q_flow
+        "N-1 energy balances";
+    end for;
+
+    for i in 1:n_a loop
+      hp_b[i].Q_flow = alphaA_internal/n_a * (hp_b[i].T^exponetTemperature -
+        hp_a[i].T^exponetTemperature)
+        "Heat flow calculation depending on discretisation";
+    end for;
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all heat transfers. It defines 
+fundamental parameters and variables required by all heat transfers. Models 
+that inherit properties from this partial model have to redeclare and constrain 
+the model calculating the product of heat transfer coefficient and area. In 
+this context, records may be added that containg geometry and fluid property 
+data. Furtheremore, it must be specified if the model calcualtes convective/conductive
+heat transfer or radiation heat transfer.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Exponent of the temperatures defining the driving temperatures <i>exponetTemperature</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  Separation into a partial model and documentation.
+  </li>
+  <li>
+  January 13, 2021, by Mirko Engelpracht:<br/>
+  Major revision allowing different discretizations for both ports.
+  </li>
+  <li>
+  December 06, 2017, by Andrej Gibelhaus:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Line(
+          points={{60,-50},{-60,-50}},
+          color={0,0,0},
+          arrow={Arrow.Filled,Arrow.Filled}), Rectangle(
+          extent={{-80,-40},{80,40}},
+          lineColor={238,46,47},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47})}));
+end PartialHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialHeatTransferCoefficient.mo
new file mode 100644
index 0000000..98f2ac6
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialHeatTransferCoefficient.mo
@@ -0,0 +1,87 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialHeatTransferCoefficient
+  "Base model for all models calculating the product of heat transfer coefficient and area"
+
+  //
+  // Definition of parameters regarding the heat transfer
+  //
+  parameter Boolean computeTransportProperties = false
+    "= true, if fluid transport properties are required and must be calculated"
+    annotation (Dialog(tab = "General", group = "Heat Transfer"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_avg_port_a
+    "Average temperature at port a"
+    annotation (Dialog(tab="General",group="Inputs", enable=false),
+                Evaluate=true);
+  input Modelica.Units.SI.Temperature T_avg_port_b
+    "Average temperature at port b"
+    annotation (Dialog(tab="General",group="Inputs", enable=false),
+                Evaluate=true);
+
+  //
+  // Definition of outputs
+  //
+  Modelica.Blocks.Interfaces.RealOutput alphaA(final unit="W/K")
+    "Value for alphaA for entire heat transfer resistance";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(graphics={Ellipse(
+          extent={{100,100},{-100,-100}},
+          lineColor={0,0,0},
+          fillColor={238,46,47},
+          fillPattern=FillPattern.Solid), Text(
+          extent={{-80,80},{80,-80}},
+          lineColor={0,0,0},
+          fillColor={238,46,47},
+          fillPattern=FillPattern.Solid,
+          textString="kA")}), Documentation(revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  Smaller revision after resctructering of the library and documentation.
+  </li>
+  <li>
+  January 13, 2021, by Mirko Engelpracht:<br/>
+  Smaller revision after resctructering of the library.
+  </li>
+  <li>
+  December 06, 2017, by Andrej Gibelhaus:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the product of heat
+transfer coefficient and area <i>alphaA</i>. It defines fundamental parameters and 
+variables required by all heat transfer coefficient models. Models that inherit 
+properties from this partial model have to add an equation for calculating the 
+product of heat transfer coefficient and area. In this context, records may be added
+that containg geometry and fluid property data.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialOpenAdsorberHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialOpenAdsorberHeatTransferCoefficient.mo
new file mode 100644
index 0000000..fb07901
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialOpenAdsorberHeatTransferCoefficient.mo
@@ -0,0 +1,55 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialOpenAdsorberHeatTransferCoefficient
+  "Base model for all models calculating the product of heat transfer coefficient and area for open adsorbers"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient;
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the gas (mixture) volume)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Modelica.Units.SI.MassFlowRate m_hyd_xMinus
+    "Hydraulic mass flow rate at design inlet"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Modelica.Units.SI.MassFlowRate m_hyd_xPlus
+    "Hydraulic mass flow rate at design outlet"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryOpenAdsorber geometry
+    constrainedby SorpLib.Components.HeatTransfer.Records.GeometryOpenAdsorber
+    "Geometry of the open adsorber"
+    annotation(Dialog(tab = "General", group = "Heat Transfer", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 23, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the product of
+heat transfer coefficient and area <i>alphaA</i> describing the heat transfer
+between the sorbent and gas phase. It defines fundamental parameters and variables
+required by all heat transfer coefficient models. Models that inherit properties 
+from this partial model have to add an equation for calculating the product of heat 
+transfer coefficient and area.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialOpenAdsorberHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialPoolBoilingHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialPoolBoilingHeatTransferCoefficient.mo
new file mode 100644
index 0000000..93326b7
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialPoolBoilingHeatTransferCoefficient.mo
@@ -0,0 +1,63 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialPoolBoilingHeatTransferCoefficient
+  "Base model for all models calculating the product of heat transfer coefficient and area for pool boiling"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient;
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the phase saperator fluid)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Real f_relativeFillingLevel(min=0, max=1, final unit="1")
+    "Relative filling level of the evaporator"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryTube geometry
+    constrainedby SorpLib.Components.HeatTransfer.Records.GeometryTube
+    "Geometry of the heat exchanger tubes providing the heat flow rate for pool
+    boiling"
+    annotation(Dialog(tab = "General", group = "Heat Transfer", enable=false));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 17, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the product of
+heat transfer coefficient and area <i>alphaA</i> describing pool boiling. It 
+defines fundamental parameters and variables required by all heat transfer 
+coefficient models. Models that inherit  properties from this partial model have 
+to add an equation for calculating the product of heat transfer coefficient and 
+area.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialPoolBoilingHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialPoolCondensationHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialPoolCondensationHeatTransferCoefficient.mo
new file mode 100644
index 0000000..6dbfb8c
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialPoolCondensationHeatTransferCoefficient.mo
@@ -0,0 +1,53 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialPoolCondensationHeatTransferCoefficient
+  "Base model for all models calculating the product of heat transfer coefficient and area for (pool) condensation"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient;
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the phase saperator fluid)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Real f_relativeFillingLevel(min=0, max=1, final unit="1")
+    "Relative filling level of the condenser"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryTube geometry
+    constrainedby SorpLib.Components.HeatTransfer.Records.GeometryTube
+    "Geometry of the heat exchanger tubes providing the heat flow rate for (pool)
+    condensation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 18, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the product of
+heat transfer coefficient and area <i>alphaA</i> describing (pool) condensation,
+such as film condensation. It defines fundamental parameters and variables required 
+by all heat transfer coefficient models. Models that inherit  properties from this 
+partial model have to add an equation for calculating the product of heat transfer 
+coefficient and area.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialPoolCondensationHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialRadiationHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialRadiationHeatTransferCoefficient.mo
new file mode 100644
index 0000000..7f86163
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialRadiationHeatTransferCoefficient.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialRadiationHeatTransferCoefficient
+  "Base model for all models calculating the product of heat transfer coefficient and area for radiation heat transfer"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 16, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the product of heat
+heat transfer coefficient and area <i>alphaA</i> describing radiation heat transfer.
+It defines fundamental parameters and variables required by all heat transfer 
+coefficient models. Models that inherit properties from this partial model have 
+to add an equation for calculating the product of heat transfer coefficient and area.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialRadiationHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/PartialTubeInsideHeatTransferCoefficient.mo b/SorpLib/Components/HeatTransfer/BaseClasses/PartialTubeInsideHeatTransferCoefficient.mo
new file mode 100644
index 0000000..9ca0a26
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/PartialTubeInsideHeatTransferCoefficient.mo
@@ -0,0 +1,55 @@
+within SorpLib.Components.HeatTransfer.BaseClasses;
+partial model PartialTubeInsideHeatTransferCoefficient
+  "Base model for all models calculating the product of heat transfer coefficient and area for the tube-inside heat transfer"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialHeatTransferCoefficient;
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the fluid volume)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Modelica.Units.SI.MassFlowRate m_hyd_xMinus
+    "Hydraulic mass flow rate at design inlet"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Modelica.Units.SI.MassFlowRate m_hyd_xPlus
+    "Hydraulic mass flow rate at design outlet"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryTube geometry
+    constrainedby SorpLib.Components.HeatTransfer.Records.GeometryTube
+    "Geometry of the (heat exchanger) tubes"
+    annotation(Dialog(tab = "General", group = "Heat Transfer", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 19, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the product of
+heat transfer coefficient and area <i>alphaA</i> describing convective heat transfer
+inside tubes. It defines fundamental parameters and variables required by all heat 
+transfer coefficient models. Models that inherit  properties from this partial model 
+have to add an equation for calculating the product of heat transfer coefficient 
+and area.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Product of heat transfer coefficient and area <i>alphaA</i>.
+  </li>
+</ul>
+</html>"));
+end PartialTubeInsideHeatTransferCoefficient;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/package.mo b/SorpLib/Components/HeatTransfer/BaseClasses/package.mo
new file mode 100644
index 0000000..a68199c
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Components.HeatTransfer;
+package BaseClasses "Base models and functions for all heat transfers"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial heat transfer and heat transfer coefficient models, 
+containing fundamental definitions of parameters and variables. The content of 
+this package is only of interest when adding new heat transfer and heat transfer
+coefficient models to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/HeatTransfer/BaseClasses/package.order b/SorpLib/Components/HeatTransfer/BaseClasses/package.order
new file mode 100644
index 0000000..a671d4d
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/BaseClasses/package.order
@@ -0,0 +1,10 @@
+PartialHeatTransfer
+PartialHeatTransferCoefficient
+PartialGenericHeatTransferCoefficient
+PartialConductiveHeatTransferCoefficient
+PartialRadiationHeatTransferCoefficient
+PartialPoolBoilingHeatTransferCoefficient
+PartialPoolCondensationHeatTransferCoefficient
+PartialTubeInsideHeatTransferCoefficient
+PartialClosedAdsorberHeatTransferCoefficient
+PartialOpenAdsorberHeatTransferCoefficient
diff --git a/SorpLib/Components/HeatTransfer/ClosedAdsorberHeatTransfer.mo b/SorpLib/Components/HeatTransfer/ClosedAdsorberHeatTransfer.mo
new file mode 100644
index 0000000..047d2ec
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/ClosedAdsorberHeatTransfer.mo
@@ -0,0 +1,106 @@
+within SorpLib.Components.HeatTransfer;
+model ClosedAdsorberHeatTransfer
+  "Model calculating a heat transfer describing heat transfer between sorbent and heat exchanger within closed adsorbers"
+  extends BaseClasses.PartialHeatTransfer(
+    final exponetTemperature=1,
+    redeclare replaceable model HeatTransferCoefficient =
+      SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlpha
+      constrainedby
+      SorpLib.Components.HeatTransfer.BaseClasses.PartialClosedAdsorberHeatTransferCoefficient(
+      fluidProperties=fluidProperties,
+      geometry=geometry));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryClosedAdsorber geometry
+    constrainedby
+    SorpLib.Components.HeatTransfer.Records.GeometryClosedAdsorber
+    "Geometry of the tube"
+    annotation(Dialog(tab = "General", group = "Heat Transfer Coefficient",
+               enable=false));
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the sorbent)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The heat transfer model is used to describe the heat transfer between the sorbent
+and heat exchanger within closed adsorbers. Thus, the closed adsorber heat transfer 
+model represents a thermal resistance between two models. Depending on the attached 
+temperatures (i.e., attached potential) and the chosen transport phenomena, this 
+model determines the heat flow rate between the connected models. 
+<br/><br/>
+The model has two heat ports, which sizes can be defined via a parameter. The 
+scalable heat ports enable the connection of various models. For example, this 
+enables to connect a discretized model to a lumped model, or two different
+disretized models.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has steady-state energy balance:
+</p>
+<pre>
+    0 = &sum; (hp_a.Q_flow) + &sum; (hp_b.Q_flow);
+</pre>
+<p>
+The heat flow rate <i>Q_flow</i> is proportional to the driving temperature
+difference <i>&Delta;T = hp_a.T - hp_b.T</i> and the production of heat transfer
+coefficient and area <i>&alpha;A</i>, which can be formulated as thermal resistance
+<i>R<sub>closedAdsorber</sub></i>. This product can be given as an input or calculated 
+using models describing heat transfer coefficient correlations.
+</p>
+<pre>
+    hp_a.Q_flow = &alpha;A * &Delta;T = 1 / R<sub>closedAdsorber</sub> * (hp_a.T - hp_b.T);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  The number of ports a and b must be an even integer multiple of each other.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The closed adsorber heat transfer is typically used to describe the heat transfer 
+between the sorbent and heat exchanger within closed adsorbers.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useAlphaAInput</i>:
+  Defines if the product of heat transfer coefficient and area is given via
+  an input or calculated using an approproate correlation model for the heat
+  transfer coefficient.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Text(
+          extent={{-60,20},{60,-20}},
+          lineColor={0,0,0},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47},
+          textString="Q_flow = 1/R_closedAdsorber * DT")}));
+end ClosedAdsorberHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/ConductionHeatTransfer.mo b/SorpLib/Components/HeatTransfer/ConductionHeatTransfer.mo
new file mode 100644
index 0000000..d3e98a3
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/ConductionHeatTransfer.mo
@@ -0,0 +1,103 @@
+within SorpLib.Components.HeatTransfer;
+model ConductionHeatTransfer
+  "Model calculating a heat transfer describing conduction"
+  extends BaseClasses.PartialHeatTransfer(
+    final exponetTemperature=1,
+    redeclare replaceable model HeatTransferCoefficient =
+      SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.ConstantResistance
+      constrainedby
+      SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient(
+      fluidProperties=fluidProperties,
+      no_hydraulicParallelFlows=no_hydraulicParallelFlows));
+
+  //
+  // Definition of parameters
+  //
+  parameter Integer no_hydraulicParallelFlows(min=1) = 1
+    "Number of hydraulically parallel flows (e.g., tubes)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer Coefficient"));
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the volume)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The heat transfer model is used to thermally connect models which can exchange 
+heat due to thermal conduction. Thus, the conduction heat transfer model represents 
+a thermal resistance betweed two models. Depending on the attached temperatures (i.e., 
+attached potential) and the chosen transport phenomena, this model determines the 
+heat flow rate between the connected models. 
+<br/><br/>
+The model has two heat ports, which sizes can be defined via a parameter. The 
+scalable heat ports enable the connection of various models. For example, this 
+enables to connect a discretized model to a lumped model, or two different
+disretized models.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has steady-state energy balance:
+</p>
+<pre>
+    0 = &sum; (hp_a.Q_flow) + &sum; (hp_b.Q_flow);
+</pre>
+<p>
+The heat flow rate <i>Q_flow</i> is proportional to the driving temperature
+difference <i>&Delta;T = hp_a.T - hp_b.T</i> and the production of heat transfer
+coefficient and area <i>&alpha;A</i>, which can be formulated as thermal resistance
+<i>R<sub>&lambda;</sub></i>. This product can be given as an input or calculated using 
+models describing heat transfer coefficient correlations.
+</p>
+<pre>
+    hp_a.Q_flow = &alpha;A * &Delta;T = 1 / R<sub>&lambda;</sub> * (hp_a.T - hp_b.T);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  The number of ports a and b must be an even integer multiple of each other.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The conductive heat transfer is typically used to desribe the heat transfer within
+solid volumes, such as tube walls, in axial and radial direction.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useAlphaAInput</i>:
+  Defines if the product of heat transfer coefficient and area is given via
+  an input or calculated using an approproate correlation model for the heat
+  transfer coefficient.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Text(
+          extent={{-60,20},{60,-20}},
+          lineColor={0,0,0},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47},
+          textString="Q_flow = 1/R_lambda * DT")}));
+end ConductionHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/GenericHeatTransfer.mo b/SorpLib/Components/HeatTransfer/GenericHeatTransfer.mo
new file mode 100644
index 0000000..6de84bd
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/GenericHeatTransfer.mo
@@ -0,0 +1,94 @@
+within SorpLib.Components.HeatTransfer;
+model GenericHeatTransfer
+  "Model calculating a generic heat transfer"
+  extends BaseClasses.PartialHeatTransfer(
+    final exponetTemperature=1,
+    redeclare replaceable model HeatTransferCoefficient =
+      SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlpha
+      constrainedby
+      SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The generic heat transfer model is used to thermally connect models which can 
+exchange heat. Thus, the generic heat transfer model represents a thermal 
+resistance betweed two models. Depending on the attached temperatures (i.e., 
+attached potential) and the chosen transport phenomena, this model determines the 
+heat flow rate between the connected models. 
+<br/><br/>
+The model has two heat ports, which sizes can be defined via a parameter. The 
+scalable heat ports enable the connection of various models. For example, this 
+enables to connect a discretized model to a lumped model, or two different
+disretized models.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has steady-state energy balance:
+</p>
+<pre>
+    0 = &sum; (hp_a.Q_flow) + &sum; (hp_b.Q_flow);
+</pre>
+<p>
+The heat flow rate <i>Q_flow</i> is proportional to the driving temperature
+difference <i>&Delta;T = hp_a.T - hp_b.T</i> and the production of heat transfer
+coefficient and area <i>&alpha;A</i>. This product can be given as an input or
+calculated using models describing heat transfer coefficient correlations.
+</p>
+<pre>
+    hp_a.Q_flow = &alpha;A * &Delta;T = &alpha;A * (hp_a.T - hp_b.T);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  The number of ports a and b must be an even integer multiple of each other.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The generic heat trasnfer is typically used to desribe the heat transfer between
+two components via simple models for the heat transfer coefficient.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useAlphaAInput</i>:
+  Defines if the product of heat transfer coefficient and area is given via
+  an input or calculated using an approproate correlation model for the heat
+  transfer coefficient.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  Separation into a partial model and documentation.
+  </li>
+  <li>
+  January 13, 2021, by Mirko Engelpracht:<br/>
+  Major revision allowing different discretizations for both ports.
+  </li>
+  <li>
+  December 06, 2017, by Andrej Gibelhaus:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"), Icon(graphics={Text(
+          extent={{-60,20},{60,-20}},
+          lineColor={0,0,0},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47},
+          textString="Q_flow = kA * DT")}));
+end GenericHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransfer.mo b/SorpLib/Components/HeatTransfer/HeatTransfer.mo
deleted file mode 100644
index e344cea..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransfer.mo
+++ /dev/null
@@ -1,117 +0,0 @@
-within SorpLib.Components.HeatTransfer;
-model HeatTransfer
-
-  /***************************** Connectors ***************************/
-
-  TIL.Connectors.HeatPort heatPortA annotation (Placement(transformation(extent=
-           {{-90,-10},{-70,10}}, rotation=0)));
-  TIL.Connectors.HeatPort heatPortB[n] annotation (Placement(transformation(
-          extent={{70,-10},{90,10}}, rotation=0)));
-
-  /***************************** Heat Transfer ******************************************/
-
-  replaceable model HeatTransfer =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "Heat Transfer Model" annotation (choices(choice(redeclare model
-                HeatTransfer =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha),
-            choice(redeclare model HeatTransfer =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA)), Dialog(enable=not useAlphaAInput, group="Heat transfer model"));
-
-  HeatTransfer heatTransfer "Heat Transfer" annotation (Placement(transformation(extent={{-10,-10},
-            {10,10}},
-        rotation=0,
-        origin={0,0})));
-
-  Modelica.Blocks.Interfaces.RealInput alphaAInput if useAlphaAInput annotation (Placement(
-        transformation(
-        extent={{-20,-20},{20,20}},
-        rotation=-90,
-        origin={0,45}), iconTransformation(
-        extent={{-10,-10},{10,10}},
-        rotation=-90,
-        origin={0,36})));
-
-  final parameter Boolean computeTransportProperties=heatTransfer.computeTransportProperties;
-
-protected
-  Modelica.Blocks.Interfaces.RealInput alphaA_=heatTransfer.alphaA if not useAlphaAInput
-    annotation (Placement(transformation(
-        extent={{-20,-20},{20,20}},
-        rotation=-90,
-        origin={40,45}), iconTransformation(
-        extent={{-20,-20},{20,20}},
-        rotation=-90,
-        origin={0,28})));
-  Modelica.Blocks.Interfaces.RealOutput getAlphaA annotation (Placement(
-        transformation(
-        extent={{-10,-10},{10,10}},
-        rotation=-90,
-        origin={20,10})));
-
-  /********************* Parameters ************************************/
-public
-  parameter Integer n(min=1) = 1 "Number of heat ports B";
-  parameter Boolean useAlphaAInput = false "If true, use alphaA input" annotation (Evaluate=true);
-
-equation
-
-  //Energy balance
-  heatPortA.Q_flow + sum(heatPortB.Q_flow) = 0.0;
-   for i in 1:n loop
-      heatPortB[i].Q_flow = getAlphaA/n*(heatPortB[i].T - heatPortA.T);
-   end for;
-
-  connect(alphaAInput, getAlphaA) annotation (Line(points={{0,45},{0,45},{0,22},
-          {20,22},{20,18},{20,10}}, color={0,0,127}));
-  connect(getAlphaA, getAlphaA)
-    annotation (Line(points={{20,10},{20,10}}, color={0,0,127}));
-  connect(alphaA_, getAlphaA) annotation (Line(points={{40,45},{40,45},{40,22},{
-          20,22},{20,10}}, color={0,0,127}));
-  annotation (Icon(coordinateSystem(extent={{-80,-40},{80,40}},
-          preserveAspectRatio=true), graphics={Rectangle(
-          extent={{-80,34},{80,-34}},
-          lineColor={255,0,0},
-          lineThickness=0.5), Text(
-          extent={{-42,22},{42,-30}},
-          lineColor={0,0,0},
-          lineThickness=0.5,
-          textStyle={TextStyle.Italic},
-          textString="alpha A")}),
-      Diagram(coordinateSystem(extent={{-80,-40},{80,40}},
-          preserveAspectRatio=true)),
-    Documentation(info="<html>
-  <p>
-    The heat transfer model is used to thermally connect models which can exchange heat. 
-    The heat transfer model represents a thermal resistance betweed two models. 
-    Depending on the attached temperatures (attached potential) and the chosen transport phenomena, the heat transfer model determines the heat flow rate between the connected models. 
-    The heat transfer model itself does not have a thermal capacity.<br>
-
-    The model has two heat ports, whereby one heat port (B) is scalable. 
-    The number of heat ports B is automatically adapted depending on connected models. 
-    The scalable heat port B enables the connection of various models to a single heat source or sink. 
-    For example, this enables to connect a discretized model to a lumped model.
-    If two discretized models are connected, the heat transfer model itself can be disctretized in 1-1 configuration.
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    The heat transfer model is modelled as thermal resistance with no thermal capacity. 
-    Thus, the energy balance reads:
-    <p align=\"center\"><i>Q</i><sub>in</sub> = <i>Q</i><sub>out</sub> </p>
-    where <i>Q</i> ist the heat flow. 
-    The heat flow is proportional to the attached temperature difference (potential) according to the following equation:
-    <p align=\"center\"><i>Q</i><sub>in</sub> = <i><code>&alpha;</code> A</i> (<i>T</i><sub>in</sub> - <i>T</i><sub>out</sub>) </p>
-    where <i><code>&alpha;</code> A</i> is the heat transfer coefficient multiplied with the heat transfer area, calculated in the internal heat transfer model, and <i>T</i> is the temperature.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 06, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end HeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ConstantAlpha.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ConstantAlpha.mo
new file mode 100644
index 0000000..b7fcb1d
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ConstantAlpha.mo
@@ -0,0 +1,63 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber;
+model ConstantAlpha
+  "Generic heat transfer correlation with constant heat transfer coefficient"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialClosedAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.CoefficientOfHeatTransfer constantAlpha = 1000
+    "Constant heat transfer coefficient"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A = geometry.A_heatTransferOuter_hx
+    "Constant heat transfer area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = geometry.no_hydraulicParallelTubes * constantAlpha * A /
+    min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>. 
+The product is enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i>
+to account for parallel flows modeled by just one flow:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * &alpha; * A / <strong>min</strong>(no<sub>sorbent volumes</sub>, no<sub>wall volumes</sub>) = const.;
+</pre>
+<p>
+Note that the area <i>A</i> is calculated from the geometry record taking into
+account the disretization: The smaller number of discretization volumes used for 
+the wall and the sorbent determines the number of heat transfer models that are used. 
+Accordingly, the total heat transfer surface is divided by the smaller number.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantAlpha;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ConstantAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ConstantAlphaA.mo
new file mode 100644
index 0000000..07891ff
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ConstantAlphaA.mo
@@ -0,0 +1,59 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber;
+model ConstantAlphaA
+  "Generic heat transfer correlation with constant product of heat transfer coefficient and area"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialClosedAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 1000
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = geometry.no_hydraulicParallelTubes * constantAlphaA /
+    min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> / <strong>min</strong>(no<sub>sorben volumes</sub>, no<sub>wall volumes</sub>) * const.;
+</pre>
+<p>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. Furhtermore, the product is diveded by the smaller discretization number
+of sorbent or wall volumes to account for discretization: The smaller discretization 
+number determines the number of heat transfer models that are used. Thus, the product
+<i>&alpha;A</i> is valid for one heat exchanger tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ExponentialAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ExponentialAlphaA.mo
new file mode 100644
index 0000000..fd98bc8
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/ExponentialAlphaA.mo
@@ -0,0 +1,114 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber;
+model ExponentialAlphaA
+  "Generic heat transfer correlation with product of heat transfer coefficient and area exponentially dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialClosedAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.TemperatureHeatTranferCorrelation calculationTemperature=
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA
+    "Defines the temperature used to calculate the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 25
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.ThermalConductance b = 0.1
+    "Temperature dependancy (i.e., factor) of the exponential part"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real c(final unit="1/K") = 1/273.15
+    "Temperature dependancy (i.e., exponential factor) of the exponential part"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  //
+  // Calculation of the product of heat transfer coefficient and area
+  //
+  if calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * exp(c * abs(T_avg_port_a))) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports a";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortB then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * exp(c * abs(T_avg_port_b))) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports b";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Average then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * exp(c * abs((T_avg_port_a + T_avg_port_b) / 2))) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports a and b";
+
+  else
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * exp(c * abs(T_avg_port_a - T_avg_port_b))) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature difference between ports a and b";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be exponentially dependent on the temperature. The temperature 
+used for the calculation can be selected.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is exponential
+dependent on the temperature <i>T</i>:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * [&alpha;A<sub>const</sub> + b * <strong>exp</strong>(c * <strong>abs</strong>(T))] / <strong>min</strong>(no<sub>sorben volumes</sub>, no<sub>wall volumes</sub>);
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i> and <i>b</i> are fitting parameters.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. Furhtermore, the product is diveded by the smaller discretization number
+of sorbent or wall volumes to account for discretization: The smaller discretization 
+number determines the number of heat transfer models that are used. Thus, the product
+<i>&alpha;A</i> is valid for one heat exchanger tube.
+</p>
+
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ExponentialAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/LinearAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/LinearAlphaA.mo
new file mode 100644
index 0000000..c87acd8
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/LinearAlphaA.mo
@@ -0,0 +1,111 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber;
+model LinearAlphaA
+  "Generic heat transfer correlation with product of heat transfer coefficient and area linearly dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialClosedAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.TemperatureHeatTranferCorrelation calculationTemperature=
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA
+    "Defines the temperature used to calculate the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 25
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real b(final unit="W/(K2)") = 0.1
+    "Temperature dependancy (i.e., linear factor) of the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  //
+  // Calculation of the product of heat transfer coefficient and area
+  //
+  if calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * abs(T_avg_port_a)) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports a";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortB then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * abs(T_avg_port_b)) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports b";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Average then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * abs((T_avg_port_a + T_avg_port_b) / 2)) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports a and b";
+
+  else
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * abs(T_avg_port_a - T_avg_port_b)) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature difference between ports a and b";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be linearly dependent on the temperature. The temperature used
+for the calculation can be selected.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is linear
+dependent on the temperature <i>T</i>:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * [&alpha;A<sub>const</sub> + b * <strong>abs</strong>(T)]/ <strong>min</strong>(no<sub>sorben volumes</sub>, no<sub>wall volumes</sub>);
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i> and <i>b</i> are fitting parameters.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. Furhtermore, the product is diveded by the smaller discretization number
+of sorbent or wall volumes to account for discretization: The smaller discretization 
+number determines the number of heat transfer models that are used. Thus, the product
+<i>&alpha;A</i> is valid for one heat exchanger tube.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LinearAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/PolynomialAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/PolynomialAlphaA.mo
new file mode 100644
index 0000000..5f3a807
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/PolynomialAlphaA.mo
@@ -0,0 +1,113 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber;
+model PolynomialAlphaA
+  "Generic heat transfer correlation with product of heat transfer coefficient and area polynomially dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialClosedAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.TemperatureHeatTranferCorrelation calculationTemperature=
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA
+    "Defines the temperature used to calculate the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 25
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.ThermalConductance b = 0.1
+    "Temperature dependancy (i.e., factor) of the polynomial part"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real c(final unit="1") = 1/3
+    "Temperature dependancy (i.e., exponent) of the polynomial part"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  //
+  // Calculation of the product of heat transfer coefficient and area
+  //
+  if calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * abs(T_avg_port_a) ^ c) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports a";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortB then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * abs(T_avg_port_b) ^ c) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports b";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Average then
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * abs((T_avg_port_a + T_avg_port_b) / 2) ^ c) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature at ports a and b";
+
+  else
+    alphaA = geometry.no_hydraulicParallelTubes * (
+      constantAlphaA + b * abs(T_avg_port_a - T_avg_port_b) ^ c) /
+      min(geometry.no_wallVolumes, geometry.no_sorbentVolumes)
+      "Average temperature difference between ports a and b";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be polynomially dependent on the temperature. The temperature 
+used for the calculation can be selected.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is polynomial
+dependent on the temperature <i>T</i>:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * [&alpha;A<sub>const</sub> + b * <strong>abs</strong>(T)<sup>c</sup>] / <strong>min</strong>(no<sub>sorben volumes</sub>, no<sub>wall volumes</sub>);
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i> and <i>b</i> are fitting parameters.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. Furhtermore, the product is diveded by the smaller discretization number
+of sorbent or wall volumes to account for discretization: The smaller discretization 
+number determines the number of heat transfer models that are used. Thus, the product
+<i>&alpha;A</i> is valid for one heat exchanger tube.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PolynomialAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/package.mo
new file mode 100644
index 0000000..d9b4475
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/package.mo
@@ -0,0 +1,44 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations;
+package ClosedAdsorber "Correlations for heat transfer coefficients describing the heat transfer within closed adsorbers"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for heat transfer coefficients describing
+the heat transfer between sorbent and heat exchanger within closed adsorbers:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlpha\">ConstantAlpha</a>: 
+  Generic heat transfer correlation with constant heat transfer coefficient.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ConstantAlphaA\">ConstantAlphaA</a>: 
+  Generic heat transfer correlation with constant product of heat transfer 
+  coefficient and area.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.LinearAlphaA\">LinearAlphaA</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is linearly dependent on the temperature.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.ExponentialAlphaA\">ExponentialAlphaA</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is exponentially dependent on the temperature.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.PolynomialAlphaA\">PolynomialAlphaA</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is polynomially dependent on the temperature.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ClosedAdsorber;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/package.order
new file mode 100644
index 0000000..4dba73a
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/ClosedAdsorber/package.order
@@ -0,0 +1,5 @@
+ConstantAlpha
+ConstantAlphaA
+LinearAlphaA
+ExponentialAlphaA
+PolynomialAlphaA
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantCylindricalWall.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantCylindricalWall.mo
new file mode 100644
index 0000000..2269041
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantCylindricalWall.mo
@@ -0,0 +1,81 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction;
+model ConstantCylindricalWall
+  "Heat transfer correlation describing thermal conduction through a cylindrical wall using constant fluid properties"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust the heat transfer coefficient correlation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Modelica.Units.SI.ThermalConductivity lambda = 230
+    "Thermal conductivity of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Length l_wall = 0.25
+    "Length of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Diameter d_inner = 0.010
+    "Inner diameter of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Diameter d_outer = 0.012
+    "Outer diameter of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = f_correction *
+    no_hydraulicParallelFlows * lambda * 2 * Modelica.Constants.pi *
+    l_wall / Modelica.Math.log(d_outer / d_inner)
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area for thermal conduction through a cylindrical wall assuming consant fluid 
+properties.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant thermal resistance <i>R<sub>&lambda;</sub></i>. It is 
+enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i>
+to account for parallel flows modeled by just one flow:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * 1 / R<sub>&lambda;</sub> = no<sub>parallel flows</sub> * &lambda; * 2 * &pi; * l / <strong>ln</strong>(d<sub>outer</sub>/d<sub>inner</sub>);
+</pre>
+<p>
+Herein, <i>&lambda;</i> is the thermal conductivity, <i>l</i> is the wall length, 
+<i>d<sub>outer</sub></i> is the outer diameter of the cylinder, and <i>d<sub>inner</sub></i>
+is the inner diameter of the cylinder.
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change. Then, this model can be used to describe thermal
+conduction, e.g., in radial flow direction of a heat exchanger tube.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Hahne, E. (2010). E1 Steady-State Heat Conduction. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_32.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ConstantCylindricalWall;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantPlainWall.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantPlainWall.mo
new file mode 100644
index 0000000..159fa6f
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantPlainWall.mo
@@ -0,0 +1,75 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction;
+model ConstantPlainWall
+  "Heat transfer correlation describing thermal conduction through a plain wall using constant fluid properties"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust the heat transfer coefficient correlation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Modelica.Units.SI.ThermalConductivity lambda = 230
+    "Thermal conductivity of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A_cross = 0.1
+    "Cross-sectional area of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Thickness delta_wall = 0.25
+    "Thickness of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = f_correction *
+    no_hydraulicParallelFlows * lambda * A_cross / delta_wall
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area for thermal conduction through a plain wall assuming consant fluid properties.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant thermal resistance <i>R<sub>&lambda;</sub></i>. It is 
+enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i>
+to account for parallel flows modeled by just one flow:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * 1 / R<sub>&lambda;</sub> = no<sub>parallel flows</sub> * &lambda; * A<sub>cross</sub> / &delta;;
+</pre>
+<p>
+Herein, <i>&lambda;</i> is the thermal conductivity, <i>A<sub>cross</sub></i> is the 
+cross sectional area of the plain wall, and <i>&delta;</i> is the wall thickness.
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change. Then, this model can be used to describe thermal
+conduction, e.g., in axial flow direction of a heat exchanger tube.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Hahne, E. (2010). E1 Steady-State Heat Conduction. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_32.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ConstantPlainWall;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantResistance.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantResistance.mo
new file mode 100644
index 0000000..a466cd5
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/ConstantResistance.mo
@@ -0,0 +1,53 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction;
+model ConstantResistance
+  "Constant thermal resistance describing thermal conduction"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalResistance constantR = 0.6 * 0.1 / 0.25
+    "Constant thermal resistance describing thermal conduction"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = no_hydraulicParallelFlows * 1 / constantR
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area for thermal conduction assuming a constant thermal resistance.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant thermal resistance <i>R<sub>&lambda;</sub></i>. It is 
+enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i>
+to account for parallel flows modeled by just one flow:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * 1 / R<sub>&lambda;</sub>;
+</pre>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ConstantResistance;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/CylindricalWall.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/CylindricalWall.mo
new file mode 100644
index 0000000..22e26a2
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/CylindricalWall.mo
@@ -0,0 +1,76 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction;
+model CylindricalWall
+  "Heat transfer correlation describing thermal conduction through a cylindrical wall"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient(
+     final computeTransportProperties=true,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust the heat transfer coefficient correlation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Modelica.Units.SI.Length l_wall = 0.25
+    "Length of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Diameter d_inner = 0.010
+    "Inner diameter of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Diameter d_outer = 0.012
+    "Outer diameter of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = f_correction *
+    no_hydraulicParallelFlows * fluidProperties.lambda * 2 *
+    Modelica.Constants.pi * l_wall / Modelica.Math.log(d_outer / d_inner)
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area for thermal conduction through a cylindrical wall.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a thermal resistance <i>R<sub>&lambda;</sub></i>. It is 
+enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i>
+to account for parallel flows modeled by just one flow:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * 1 / R<sub>&lambda;</sub> = no<sub>parallel flows</sub> * &lambda; * 2 * &pi; * l / <strong>ln</strong>(d<sub>outer</sub>/d<sub>inner</sub>);
+</pre>
+<p>
+Herein, <i>&lambda;</i> is the thermal conductivity, <i>l</i> is the wall length, 
+<i>d<sub>outer</sub></i> is the outer diameter of the cylinder, and <i>d<sub>inner</sub></i>
+is the inner diameter of the cylinder.
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used to describe thermal
+conduction, e.g., in radial flow direction of a heat exchanger tube.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Hahne, E. (2010). E1 Steady-State Heat Conduction. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_32.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end CylindricalWall;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/PlainWall.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/PlainWall.mo
new file mode 100644
index 0000000..d12244f
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/PlainWall.mo
@@ -0,0 +1,72 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction;
+model PlainWall
+  "Heat transfer correlation describing thermal conduction through a plain wall"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient(
+     final computeTransportProperties=true,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust the heat transfer coefficient correlation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Modelica.Units.SI.Area A_cross = 0.1
+    "Cross-sectional area of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Thickness delta_wall = 0.25
+    "Thickness of the wall"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = f_correction *
+    no_hydraulicParallelFlows * fluidProperties.lambda *
+    A_cross / delta_wall
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area for thermal conduction through a plain wall.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a thermal resistance <i>R<sub>&lambda;</sub></i>. It is 
+enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i>
+to account for parallel flows modeled by just one flow:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * 1 / R<sub>&lambda;</sub> = no<sub>parallel flows</sub> * &lambda; * A<sub>cross</sub> / &delta;;
+</pre>
+<p>
+Herein, <i>&lambda;</i> is the thermal conductivity, <i>A<sub>cross</sub></i> is the 
+cross sectional area of the plain wall, and <i>&delta;</i> is the wall thickness.
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used to describe thermal
+conduction, e.g., in axial flow direction of a heat exchanger tube.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Hahne, E. (2010). E1 Steady-State Heat Conduction. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_32.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PlainWall;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/package.mo
new file mode 100644
index 0000000..cd2cadf
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/package.mo
@@ -0,0 +1,40 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations;
+package Conduction "Correlations for heat transfer coefficients describing thermal conduction"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for heat transfer coefficients describing
+thermal conduction:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.ConstantResistance\">ConstantResistance</a>: 
+  Constant thermal resistance.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.ConstantPlainWall\">ConstantPlainWall</a>: 
+  Constant thermal conduction through plane wall.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.ConstantCylindricalWall\">ConstantCylindricalWall</a>: 
+  Constant thermal conduction through cylindrical wall.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.PlainWall\">PlainWall</a>: 
+  Thermal conduction through plane wall based on fluid properties.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall\">CylindricalWall</a>: 
+  Thermal conduction through cylindrical wall based on fluid properties.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Conduction;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/package.order
new file mode 100644
index 0000000..e773690
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Conduction/package.order
@@ -0,0 +1,5 @@
+ConstantResistance
+ConstantPlainWall
+ConstantCylindricalWall
+PlainWall
+CylindricalWall
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ConstantAlpha.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ConstantAlpha.mo
new file mode 100644
index 0000000..fd98b12
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ConstantAlpha.mo
@@ -0,0 +1,61 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic;
+model ConstantAlpha
+  "Generic heat transfer correlation with constant heat transfer coefficient"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient(
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.CoefficientOfHeatTransfer constantAlpha = 25
+    "Constant heat transfer coefficient"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A = 1
+    "Constant heat transfer area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = constantAlpha*A
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = &alpha; * A = const.;
+</pre>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  Completed documentation.
+  </li>
+  <li>
+  January 13, 2021, by Mirko Engelpracht:<br/>
+  Smaller revision after resctructering of the library.
+  </li>
+  <li>
+  December 06, 2017, by Andrej Gibelhaus:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end ConstantAlpha;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ConstantAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ConstantAlphaA.mo
new file mode 100644
index 0000000..9fec7d0
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ConstantAlphaA.mo
@@ -0,0 +1,58 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic;
+model ConstantAlphaA
+  "Generic heat transfer correlation with constant product of heat transfer coefficient and area"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient(
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 25
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA =constantAlphaA
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = const.;
+</pre>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  Completed documentation.
+  </li>
+  <li>
+  January 13, 2021, by Mirko Engelpracht:<br/>
+  Smaller revision after resctructering of the library.
+  </li>
+  <li>
+  December 06, 2017, by Andrej Gibelhaus:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end ConstantAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ExponentialAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ExponentialAlphaA.mo
new file mode 100644
index 0000000..17c94cb
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/ExponentialAlphaA.mo
@@ -0,0 +1,97 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic;
+model ExponentialAlphaA
+  "Generic heat transfer correlation with product of heat transfer coefficient and area exponentially dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient(
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.TemperatureHeatTranferCorrelation calculationTemperature=
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA
+    "Defines the temperature used to calculate the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 25
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.ThermalConductance b = 0.1
+    "Temperature dependancy (i.e., factor) of the exponential part"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real c(final unit="1/K") = 1/273.15
+    "Temperature dependancy (i.e., exponential factor) of the exponential part"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  //
+  // Calculation of the product of heat transfer coefficient and area
+  //
+  if calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA then
+    alphaA = constantAlphaA + b * exp(c * abs(T_avg_port_a))
+      "Average temperature at ports a";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortB then
+    alphaA = constantAlphaA + b * exp(c * abs(T_avg_port_b))
+      "Average temperature at ports b";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Average then
+    alphaA = constantAlphaA + b * exp(c * abs((T_avg_port_a + T_avg_port_b) / 2))
+      "Average temperature at ports a and b";
+
+  else
+    alphaA = constantAlphaA + b * exp(c * abs(T_avg_port_a - T_avg_port_b))
+      "Average temperature difference between ports a and b";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be exponentially dependent on the temperature. The temperature 
+used for the calculation can be selected.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is exponential
+dependent on the temperature <i>T</i>:
+</p>
+<pre>
+    &alpha;A = &alpha;A<sub>const</sub> + b * <strong>exp</strong>(c * <strong>abs</strong>(T));
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i>, <i>b</i>, and <i>c</i> are fitting parameters.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ExponentialAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/LinearAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/LinearAlphaA.mo
new file mode 100644
index 0000000..d6f5727
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/LinearAlphaA.mo
@@ -0,0 +1,95 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic;
+model LinearAlphaA
+  "Generic heat transfer correlation with product of heat transfer coefficient and area linearly dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient(
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.TemperatureHeatTranferCorrelation calculationTemperature=
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA
+    "Defines the temperature used to calculate the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 25
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real b(final unit="W/(K2)") = 0.1
+    "Temperature dependancy (i.e., linear factor) of the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  //
+  // Calculation of the product of heat transfer coefficient and area
+  //
+  if calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA then
+    alphaA = constantAlphaA + b * abs(T_avg_port_a)
+      "Average temperature at ports a";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortB then
+    alphaA = constantAlphaA + b * abs(T_avg_port_b)
+      "Average temperature at ports b";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Average then
+    alphaA = constantAlphaA + b * abs((T_avg_port_a + T_avg_port_b) / 2)
+      "Average temperature at ports a and b";
+
+  else
+    alphaA = constantAlphaA + b * abs(T_avg_port_a - T_avg_port_b)
+      "Average temperature difference between ports a and b";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be linearly dependent on the temperature. The temperature used
+for the calculation can be selected.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is linear
+dependent on the temperature <i>T</i>:
+</p>
+<pre>
+    &alpha;A = &alpha;A<sub>const</sub> + b * <strong>abs</strong>(T);
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i> and <i>b</i> are fitting parameters.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LinearAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/PolynomialAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/PolynomialAlphaA.mo
new file mode 100644
index 0000000..711e085
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/PolynomialAlphaA.mo
@@ -0,0 +1,97 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic;
+model PolynomialAlphaA
+  "Generic heat transfer correlation with product of heat transfer coefficient and area polynomially dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialGenericHeatTransferCoefficient(
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.TemperatureHeatTranferCorrelation calculationTemperature=
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA
+    "Defines the temperature used to calculate the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 25
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.ThermalConductance b = 0.1
+    "Temperature dependancy (i.e., factor) of the polynomial part"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real c(final unit="1") = 1/3
+    "Temperature dependancy (i.e., exponent) of the polynomial part"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  //
+  // Calculation of the product of heat transfer coefficient and area
+  //
+  if calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA then
+    alphaA = constantAlphaA + b * abs(T_avg_port_a) ^ c
+      "Average temperature at ports a";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortB then
+    alphaA = constantAlphaA + b * abs(T_avg_port_b) ^ c
+      "Average temperature at ports b";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Average then
+    alphaA = constantAlphaA + b * abs((T_avg_port_a + T_avg_port_b) / 2) ^ c
+      "Average temperature at ports a and b";
+
+  else
+    alphaA = constantAlphaA + b * abs(T_avg_port_a - T_avg_port_b) ^ c
+      "Average temperature difference between ports a and b";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be polynomially dependent on the temperature. The temperature 
+used for the calculation can be selected.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is polynomial
+dependent on the temperature <i>T</i>:
+</p>
+<pre>
+    &alpha;A = &alpha;A<sub>const</sub> + b * <strong>abs</strong>(T)<sup>c</sup>;
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i>, <i>b</i>, and <i>c</i> are fitting parameters.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PolynomialAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/package.mo
new file mode 100644
index 0000000..8c75d10
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/package.mo
@@ -0,0 +1,43 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations;
+package Generic "Generic correlations for heat transfer coefficients"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains generic correlations for heat transfer coefficients:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlpha\">ConstantAlpha</a>: 
+  Generic heat transfer correlation with constant heat transfer coefficient.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA\">ConstantAlphaA</a>: 
+  Generic heat transfer correlation with constant product of heat transfer 
+  coefficient and area.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.LinearAlphaA\">LinearAlphaA</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is linearly dependent on the temperature.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ExponentialAlphaA\">ExponentialAlphaA</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is exponentially dependent on the temperature.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic.PolynomialAlphaA\">PolynomialAlphaA</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is polynomially dependent on the temperature.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructering the library.
+  </li>
+</ul>
+</html>"));
+end Generic;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/package.order
new file mode 100644
index 0000000..4dba73a
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Generic/package.order
@@ -0,0 +1,5 @@
+ConstantAlpha
+ConstantAlphaA
+LinearAlphaA
+ExponentialAlphaA
+PolynomialAlphaA
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/CasingGasKast.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/CasingGasKast.mo
new file mode 100644
index 0000000..fe8d80f
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/CasingGasKast.mo
@@ -0,0 +1,213 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber;
+model CasingGasKast
+  "Heat transfer correlation describing the heat transfer between gas and casing according to Kast"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialOpenAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.MassFlowRateHeatTranferCorrelation calculationMassFlowRate=
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXMinus
+    "Defines the hydraulic mass flow rate used for calculations"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Real f_particle = 12
+    "Particle factor (i.e., 12 for spherical particles; 6 for cylinders)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real f_length = 1.15
+    "Length factor (i.e., 11.5 for spherical particles; 1.4 for broken spherical
+    particles; 1.75 for cylinders)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real f_correction = 1
+    "Correction factor"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.CoefficientOfHeatTransfer alpha
+    "Heat tranfer coefficient";
+
+  Modelica.Units.SI.Velocity v
+    "Hydraulic velocity";
+  Modelica.Units.SI.PecletNumber Pe
+    "Peclet number";
+  Modelica.Units.SI.ReynoldsNumber Nu
+    "Nusselt number";
+
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.NusseltNumber Nu_length
+    "Nusselt number correction to account for enhanced length";
+
+  Modelica.Units.SI.Length l_mixture
+    "Mixture length of spherical particles";
+
+  Modelica.Units.SI.Length l_heatTransfer
+    "Length of the tube accounting for discretization";
+  Modelica.Units.SI.Area A_heatTransfer
+    "Heat transfer area accounting for discretization";
+
+equation
+  //
+  // Calculation of the velocity and Peclet number
+  //
+  if calculationMassFlowRate==
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXMinus then
+    v = abs(m_hyd_xMinus) / (fluidProperties.rho *
+      geometry.A_crossInner_cas * geometry.psi_particles)
+      "Hydraulic velocity";
+
+  elseif calculationMassFlowRate==
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXPlus then
+    v = abs(m_hyd_xPlus) / (fluidProperties.rho *
+      geometry.A_crossInner_cas * geometry.psi_particles)
+      "Hydraulic velocity";
+
+  else
+    v = (abs(m_hyd_xMinus) + abs(m_hyd_xPlus)) / 2 / (fluidProperties.rho *
+      geometry.A_crossInner_cas * geometry.psi_particles)
+      "Hydraulic velocity";
+
+  end if;
+
+  Pe = v * l_mixture * fluidProperties.rho * fluidProperties.cp /
+    fluidProperties.lambda
+    "Peclet number";
+
+  //
+  // Calculation of the Nusselt numbers
+  //
+  l_mixture = f_length * geometry.d_particle
+    "Mixture length of spherical particles";
+
+  l_heatTransfer = geometry.l_cas / geometry.no_volumes
+    "Length of the tube accounting for discretization";
+  A_heatTransfer = geometry.A_heatTransferInner_cas / geometry.no_volumes
+    "Length of the tube accounting for discretization";
+
+  Nu_length = -1.55e-6*Pe^2 + 0.04285*Pe + 24.57
+    "Nusselt number correction to account for enhanced length: Own fit for 
+    spherical particles from Kast (1988), p. 136";
+  Nu = f_correction * Nu_length / (1 + f_particle * l_heatTransfer /
+    geometry.d_inner_cas / max(Pe, 1e-12))
+    "Nusselt number";
+
+  //
+  // Calculation of the heat transfer coefficient
+  //
+  alpha = Nu * fluidProperties.lambda/l_mixture
+    "Heat transfer coefficient";
+  alphaA = geometry.no_hydraulicParallelTubes * alpha * A_heatTransfer
+    "Product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This heat transfer model calculates the product of heat transfer coefficient and
+area describing the heat transfer between the gas and casing in open adsorbers.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated
+from the Nussel number <i>Nu</i>:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * Nu * &lambda; / l<sub>mixture</sub> * A<sub>heat transfer</sub> / no<sub>volumes</sub>;
+</pre>
+<p>
+Herein, <i>&lambda;</i> is the thermal conductivity, <i>l<sub>mixture</sub></i> 
+is the mixture length, and <i>A<sub>heat transfer</sub></i> is the heat transfer 
+area accounting for the discretization. The product is enlarged by the number of 
+hydrualic parallel flows <i>no<sub>parallel flows</sub></i> to account for parallel 
+flows modeled by just one flow. 
+<br/><br/>
+The Nusselt number is calculated as:
+</p>
+<pre>
+    Nu = f<sub>correction</sub> * Nu<sub>length</sub> / [1 + f<sub>correction</sub> * l<sub>heat transfer</sub> / (Pe * d<sub>inner casing</sub>)];
+</pre>
+<p>
+with:
+</p>
+<pre>
+    Nu<sub>length</sub> = -1.55E<sup>-6</sup> * Pe<sup></sup> + 0.04285 * Pe + 24.57;
+
+    l<sub>mixture</sub> = f<sub>particle</sub> * d<sub>particle</sub>;
+</pre>
+<p>
+Herein, <i>f<sub>i</sub></i> are correction factors, <i>Pe</i> is the Peclet number, 
+<i>Nu<sub>length</sub></i> is the Nusselt number correction, <i>d<sub>inner casing</sub></i>
+is the inner diameter of the casing, and <i>l<sub>heat transfer</sub></i> is the heat 
+transfer length accounting for the discretization:
+</p>
+<pre>
+    Pe = v * l<sub>mixture</sub> * &rho; * c<sub>p</sub> / &lambda;;
+
+    v =  <strong>abs</strong>(m<sub>flow,hyd</sub>) / (&rho; * A<sub>cross,inner casing</sub> * &psi;);
+
+    l<sub>heat transfer</sub> = l<sub>cas</sub> / no<sub>volumes</sub>;
+</pre>
+<p>
+Herein, <i>v</i> is the hydraulic flow velocity, <i>m<sub>flow,hyd</sub></i> is 
+the hydraulic mass flow rate, <i>l<sub>cas</sub></i> is the length of the casing,
+<i>A<sub>cross,inner casing</sub></i> is the cross-sectional inner area of the 
+casing, <i>&psi;</i> is the void fraction, <i>&rho;</i> is the fluid density,
+<i>c<sub>p</sub></i> is the isobaric heat capacity, and <i>&lambda;</i> is the 
+thermal conductivity.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This heat transfer correlation model is typically used to calculate the heat transfer
+between the gas and casing if accurate results are required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationMassFlowRate</i>:
+  Defines the hydraulic mass flow rate that is used for calculations.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Gnielinski, V. (2010). G9 Fluid-Particle Heat Transfer in Flow Through Packed Beds of Solids. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_42.
+  </li>
+  <li>
+  Kast, W. (1998). Adsorption aus der Gasphase: Ingenieurwissenschaftliche Grundlagen und technische Verfahren (in German). VCH Verlagsgesellschaft, Weinheim, Basel, Cambridge, New York. DOI:  https://doi.org/10.1002/bbpc.19900940122.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 23, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions after restructering of the library.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructering of the library.
+  </li>
+  <li>
+  December 11, 2017, by Andrej Gibelhaus:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end CasingGasKast;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/CasingSorbentKast.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/CasingSorbentKast.mo
new file mode 100644
index 0000000..0063184
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/CasingSorbentKast.mo
@@ -0,0 +1,202 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber;
+model CasingSorbentKast
+  "Heat transfer correlation describing the heat transfer between gas and sorbent according to Kast"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialOpenAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.MassFlowRateHeatTranferCorrelation calculationMassFlowRate=
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXMinus
+    "Defines the hydraulic mass flow rate used for calculations"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Real f_particle = 1 + 1.5 * (1 - geometry.psi_particles)
+    "Form factor for the particles (i.e., 1 + 1.5 * (1 - geometry.psi_particles)
+    for spherical particles; 1.6 for cylinders)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.NusseltNumber Nu_min = 2
+    "Minimum Nusselt number (i.e., 2 for spherical particles; 0.3 for cylinders)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Real f_correctionLaminar = 1
+    "Correction factor for the laminar flow regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real f_correctionTurbulent = 1
+    "Correction factor for the tubulent flow regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.CoefficientOfHeatTransfer alpha
+    "Heat tranfer coefficient";
+
+  Modelica.Units.SI.ReynoldsNumber Re
+    "Reynolds number";
+  Modelica.Units.SI.PrandtlNumber Pr
+    "Prandtl number";
+  Modelica.Units.SI.ReynoldsNumber Nu
+    "Nusselt number";
+
+  Modelica.Units.SI.NusseltNumber Nu_lamianr
+    "Nusselt number for laminar flow regime";
+  Modelica.Units.SI.NusseltNumber Nu_turbulent
+    "Nusselt number for turbulent regime";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.Area A_heatTransfer
+    "Heat transfer area accounting for discretization";
+
+equation
+  //
+  // Calculation of the Reynolds and Prandtl number
+  //
+  if calculationMassFlowRate==
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXMinus then
+    Re = abs(m_hyd_xMinus) * geometry.d_particle /
+      (geometry.A_crossInner_cas * geometry.psi_particles * fluidProperties.eta)
+      "Reynolds number";
+
+  elseif calculationMassFlowRate==
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXPlus then
+    Re = abs(m_hyd_xPlus) * geometry.d_particle /
+      (geometry.A_crossInner_cas * geometry.psi_particles * fluidProperties.eta)
+      "Reynolds number";
+
+  else
+    Re = (abs(m_hyd_xMinus) + abs(m_hyd_xPlus)) / 2 * geometry.d_particle /
+      (geometry.A_crossInner_cas * geometry.psi_particles * fluidProperties.eta)
+      "Reynolds number";
+
+  end if;
+
+  Pr = fluidProperties.eta * fluidProperties.cp / fluidProperties.lambda
+    "Prandtl number";
+
+  //
+  // Calculation of the Nusselt numbers
+  //
+  A_heatTransfer = geometry.no_particles * geometry.A_surface_particle /
+    geometry.no_volumes
+    "Length of the tube accounting for discretization";
+
+  Nu_lamianr = f_correctionLaminar * (0.664 * max(Re,1e-6)^0.5 * Pr^0.5)
+    "Nusselt number for laminar flow regime";
+  Nu_turbulent = f_correctionTurbulent * (0.037 * max(Re,1e-6)^0.8 * Pr) /
+    (1 + 2.443 * max(Re,1e-6)^(-0.8) * (Pr^(2/3) - 1))
+    "Nusselt number for turbulent regime";
+
+  Nu = f_particle * (Nu_min * (Nu_lamianr^2 + Nu_turbulent^2)^0.5)
+    "Nusselt number";
+
+  //
+  // Calculation of the heat transfer coefficient
+  //
+  alpha = Nu * fluidProperties.lambda/geometry.d_particle
+    "Heat transfer coefficient";
+  alphaA = geometry.no_hydraulicParallelTubes * alpha * A_heatTransfer
+    "Product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This heat transfer model calculates the product of heat transfer coefficient and
+area describing the heat transfer between gas and sorbent within open adsorbers.
+The model considers both, the laminar and turbulent flow regime.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated
+from the Nussel number <i>Nu</i> using Nusselt correlations for different flow
+regimes:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * Nu * &lambda; / d<sub>particle</sub> * A<sub>particles</sub> / no<sub>volumes</sub>;
+</pre>
+<p>
+Herein, <i>&lambda;</i> is the thermal conductivity, <i>d<sub>particle</sub></i> 
+is the diameter of one particle, and <i>A<sub>particles</sub></i> is the heat 
+transfer area of all particles accounting for the discretization. The product is 
+enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i> 
+to account for parallel flows modeled by just one flow. 
+<br/><br/>
+The Nusselt number depends on the flow regime:
+</p>
+<pre>
+    Nu = f<sub>particle</sub> * [Nu<sub>min</sub> * (Nu<sup>2</sup><sub>laminar</sub> + Nu<sup>2</sup><sub>turbulent</sub>)<sup>0.5</sup>];
+
+    Nu<sub>laminar</sub> = f<sub>correction,laminar</sub> * [0.664 * Re<sup>0.5</sup> * Pr<sup>0.5</sup>];
+
+    Nu<sub>turbulent</sub> = f<sub>correction,turbulent</sub> * 0.037 * Re<sup>0.8</sup> * Pr / (1 + 2.443 * Re<sup>-0.8</sup> * (Pr<sup>2/3</sup> - 1));
+</pre>
+<p>
+Herein, <i>f<sub>i</sub></i> are correction factors for the Nusselt correlations
+<i>Nu<sub>i</sub></i> of the different flow regimes <i>i</i>, <i>Nu<sub>min</sub>
+is a minimal Nusselt number, </i><i>Re</i> is the Reynolds number, and <i>Pr</i> is 
+the Prandtl number:
+</p>
+<pre>
+    Re = <strong>abs</strong>(m<sub>flow,hyd</sub>) * d<sub>particle</sub> / A<sub>cross,inner casing</sub> / &psi; / &eta;;
+
+    Pr = &eta; * c<sub>p</sub> / &lambda;;
+</pre>
+<p>
+Herein, <i>m<sub>flow,hyd</sub></i> is the hydraulic mass flow rate, 
+<i>A<sub>cross,inner casing</sub></i> is the hydraulic cross-sectional inner area
+of the casing, <i>&psi;</i> is the void fraction, <i>&eta;</i> is the dynamic 
+viscosity, <i>&lambda;</i> is the thermal conductivity, and <i>c<sub>p</sub></i>
+is the isobaric heat capacity.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This heat transfer correlation model is typically used to calculate the heat transfer
+between the sorbent and casing if accurate results are required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationMassFlowRate</i>:
+  Defines the hydraulic mass flow rate that is used for calculations.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Gnielinski, V. (2010). G1 Heat Transfer in Pipe Flow. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_34.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 23, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions after restructering of the library.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructering of the library.
+  </li>
+  <li>
+  December 11, 2017, by Andrej Gibelhaus:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end CasingSorbentKast;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/ConstantAlpha.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/ConstantAlpha.mo
new file mode 100644
index 0000000..92ae390
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/ConstantAlpha.mo
@@ -0,0 +1,62 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber;
+model ConstantAlpha
+  "Generic heat transfer correlation with constant heat transfer coefficient"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialOpenAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.CoefficientOfHeatTransfer constantAlpha = 1000
+    "Constant heat transfer coefficient"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A = geometry.A_heatTransferInner_cas
+    "Constant heat transfer area (i.e., geometry.A_heatTransferInner_cas or
+    geometry.no_particles * geometry.A_surface_particle)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = geometry.no_hydraulicParallelTubes * constantAlpha * A /
+    geometry.no_volumes
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>. 
+The product is enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i>
+to account for parallel flows modeled by just one flow:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * &alpha; * A / no<sub>volumes</sub> = const.;
+</pre>
+<p>
+Note that the area <i>A</i> is calculated from the geometry record taking into
+account the disretization. Thus, the area <i>A</i> belongs to one adsorber column.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 23, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantAlpha;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/ConstantAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/ConstantAlphaA.mo
new file mode 100644
index 0000000..d69ba2a
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/ConstantAlphaA.mo
@@ -0,0 +1,57 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber;
+model ConstantAlphaA
+  "Generic heat transfer correlation with constant product of heat transfer coefficient and area"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialOpenAdsorberHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 1000
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = geometry.no_hydraulicParallelTubes * constantAlphaA /
+    geometry.no_volumes
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> / no<sub>volumes</sub> * const.;
+</pre>
+<p>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. Furhtermore, the product is diveded by the discretization number. Thus, 
+the product <i>&alpha;A</i> is valid for one adsorber column.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 23, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/package.mo
new file mode 100644
index 0000000..1df2a03
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/package.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations;
+package OpenAdsorber "Correlations for heat transfer coefficients describing the heat transfer within open adsorbers"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for heat transfer coefficients describing
+the heat transfer between gas and sorbent/casing within open adsorbers:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber.ConstantAlpha\">ConstantAlpha</a>: 
+  Generic heat transfer correlation with constant heat transfer coefficient.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber.ConstantAlphaA\">ConstantAlphaA</a>: 
+  Generic heat transfer correlation with constant product of heat transfer 
+  coefficient and area.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber.CasingGasKast\">CasingGasKast</a>: 
+  Heat transfer correlation describing the heat transfer between the gas volume
+  and casing according to Kast.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber.CasingSorbentKast\">CasingSorbentKast</a>: 
+  Heat transfer correlation describing the heat transfer between the gas volume
+  and sorbent according to Kast.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end OpenAdsorber;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/package.order
new file mode 100644
index 0000000..d57aac9
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/OpenAdsorber/package.order
@@ -0,0 +1,4 @@
+ConstantAlpha
+ConstantAlphaA
+CasingGasKast
+CasingSorbentKast
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/ConstantAlpha.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/ConstantAlpha.mo
new file mode 100644
index 0000000..e849a9f
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/ConstantAlpha.mo
@@ -0,0 +1,54 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling;
+model ConstantAlpha
+  "Generic heat transfer correlation with constant heat transfer coefficient"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolBoilingHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.CoefficientOfHeatTransfer constantAlpha = 10000
+    "Constant heat transfer coefficient"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A = 1
+    "Constant heat transfer area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = constantAlpha*A
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = &alpha; * A = const.;
+</pre>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 17, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ConstantAlpha;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/ConstantAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/ConstantAlphaA.mo
new file mode 100644
index 0000000..179ec08
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/ConstantAlphaA.mo
@@ -0,0 +1,51 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling;
+model ConstantAlphaA
+  "Generic heat transfer correlation with constant product of heat transfer coefficient and area"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolBoilingHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 10000
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA =constantAlphaA
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = const.;
+</pre>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 17, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/LinearAlphaA_T.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/LinearAlphaA_T.mo
new file mode 100644
index 0000000..32fcff7
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/LinearAlphaA_T.mo
@@ -0,0 +1,96 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling;
+model LinearAlphaA_T
+  "Generic heat transfer correlation with product of heat transfer coefficient and area linearly dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolBoilingHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.TemperatureHeatTranferCorrelation calculationTemperature=
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Difference
+    "Defines the temperature used to calculate the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 100
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real b(final unit="W/(K2)") = 5000
+    "Temperature dependancy (i.e., linear factor) of the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  //
+  // Calculation of the product of heat transfer coefficient and area
+  //
+  if calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA then
+    alphaA = constantAlphaA + b * abs(T_avg_port_a)
+      "Average temperature at ports a";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortB then
+    alphaA = constantAlphaA + b * abs(T_avg_port_b)
+      "Average temperature at ports b";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Average then
+    alphaA = constantAlphaA + b * abs((T_avg_port_a + T_avg_port_b) / 2)
+      "Average temperature at ports a and b";
+
+  else
+    alphaA = constantAlphaA + b * abs(T_avg_port_a - T_avg_port_b)
+      "Average temperature difference between ports a and b";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be linearly dependent on the temperature. The temperature used
+for the calculation can be selected.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is linear
+dependent on the temperature <i>T</i>:
+</p>
+<pre>
+    &alpha;A = &alpha;A<sub>const</sub> + b * <strong>abs</strong>(T);
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i> and <i>b</i> are fitting parameters.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 17, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LinearAlphaA_T;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/LinearAlphaA_fRel.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/LinearAlphaA_fRel.mo
new file mode 100644
index 0000000..026ae72
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/LinearAlphaA_fRel.mo
@@ -0,0 +1,67 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling;
+model LinearAlphaA_fRel
+  "Generic heat transfer correlation with product of heat transfer coefficient and area linearly dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolBoilingHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 10
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.ThermalConductance b = 10000
+    "Temperature dependancy (i.e., linear factor) of the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = constantAlphaA + b * f_relativeFillingLevel
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be linearly dependent on the relative filling level.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is linear
+dependent on the relative filling levekl <i>f<sub>rel</sub></i>:
+</p>
+<pre>
+    &alpha;A = &alpha;A<sub>const</sub> + b * f<sub>rel</sub>;
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i> and <i>b</i> are fitting parameters.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 17, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LinearAlphaA_fRel;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/package.mo
new file mode 100644
index 0000000..eb28af1
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/package.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations;
+package PoolBoiling "Correlations for heat transfer coefficients describing pool boiling"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for heat transfer coefficients describing
+pool boiling:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling.ConstantAlpha\">ConstantAlpha</a>: 
+  Generic heat transfer correlation with constant heat transfer coefficient.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling.ConstantAlphaA\">ConstantAlphaA</a>: 
+  Generic heat transfer correlation with constant product of heat transfer 
+  coefficient and area.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling.LinearAlphaA_T\">LinearAlphaA_T</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is linearly dependent on the temperature.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling.LinearAlphaA_fRel\">LinearAlphaA_fRel</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is linearly dependent on the relative filling level.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PoolBoiling;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/package.order
new file mode 100644
index 0000000..fab30c1
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolBoiling/package.order
@@ -0,0 +1,4 @@
+ConstantAlpha
+ConstantAlphaA
+LinearAlphaA_T
+LinearAlphaA_fRel
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/ConstantAlpha.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/ConstantAlpha.mo
new file mode 100644
index 0000000..6fefccf
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/ConstantAlpha.mo
@@ -0,0 +1,54 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation;
+model ConstantAlpha
+  "Generic heat transfer correlation with constant heat transfer coefficient"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolCondensationHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.CoefficientOfHeatTransfer constantAlpha = 15000
+    "Constant heat transfer coefficient"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A = 1
+    "Constant heat transfer area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = constantAlpha*A
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = &alpha; * A = const.;
+</pre>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 18, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ConstantAlpha;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/ConstantAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/ConstantAlphaA.mo
new file mode 100644
index 0000000..661b622
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/ConstantAlphaA.mo
@@ -0,0 +1,51 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation;
+model ConstantAlphaA
+  "Generic heat transfer correlation with constant product of heat transfer coefficient and area"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolCondensationHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 10000
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA =constantAlphaA
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = const.;
+</pre>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 18, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/LinearAlphaA_T.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/LinearAlphaA_T.mo
new file mode 100644
index 0000000..89d757e
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/LinearAlphaA_T.mo
@@ -0,0 +1,96 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation;
+model LinearAlphaA_T
+  "Generic heat transfer correlation with product of heat transfer coefficient and area linearly dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolCondensationHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.TemperatureHeatTranferCorrelation calculationTemperature=
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Difference
+    "Defines the temperature used to calculate the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 100
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real b(final unit="W/(K2)") = 5000
+    "Temperature dependancy (i.e., linear factor) of the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  //
+  // Calculation of the product of heat transfer coefficient and area
+  //
+  if calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortA then
+    alphaA = constantAlphaA + b * abs(T_avg_port_a)
+      "Average temperature at ports a";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.PortB then
+    alphaA = constantAlphaA + b * abs(T_avg_port_b)
+      "Average temperature at ports b";
+
+  elseif calculationTemperature ==
+    SorpLib.Choices.TemperatureHeatTranferCorrelation.Average then
+    alphaA = constantAlphaA + b * abs((T_avg_port_a + T_avg_port_b) / 2)
+      "Average temperature at ports a and b";
+
+  else
+    alphaA = constantAlphaA + b * abs(T_avg_port_a - T_avg_port_b)
+      "Average temperature difference between ports a and b";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be linearly dependent on the temperature. The temperature used
+for the calculation can be selected.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is linear
+dependent on the temperature <i>T</i>:
+</p>
+<pre>
+    &alpha;A = &alpha;A<sub>const</sub> + b * <strong>abs</strong>(T);
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i> and <i>b</i> are fitting parameters.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 18, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LinearAlphaA_T;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/LinearAlphaA_fRel.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/LinearAlphaA_fRel.mo
new file mode 100644
index 0000000..220681c
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/LinearAlphaA_fRel.mo
@@ -0,0 +1,67 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation;
+model LinearAlphaA_fRel
+  "Generic heat transfer correlation with product of heat transfer coefficient and area linearly dependent on the temperature"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolCondensationHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 15000
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.ThermalConductance b = -15000
+    "Temperature dependancy (i.e., linear factor) of the product of heat transfer
+    coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = constantAlphaA + b * f_relativeFillingLevel
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming it to be linearly dependent on the relative filling level.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant part <i>&alpha;A<sub>const</sub></i> and a part that is linear
+dependent on the relative filling level <i>f<sub>rel</sub></i>:
+</p>
+<pre>
+    &alpha;A = &alpha;A<sub>const</sub> + b * f<sub>rel</sub>;
+</pre>
+<p>
+Herein, <i>&alpha;A<sub>const</sub></i> and <i>b</i> are fitting parameters.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationTemperature</i>:
+  Defines the temperature that is used for calculations.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 18, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end LinearAlphaA_fRel;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/package.mo
new file mode 100644
index 0000000..1a7d1be
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/package.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations;
+package PoolCondensation "Correlations for heat transfer coefficients describing (pool) condensation"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for heat transfer coefficients describing
+(pool) condensation:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation.ConstantAlpha\">ConstantAlpha</a>: 
+  Generic heat transfer correlation with constant heat transfer coefficient.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation.ConstantAlphaA\">ConstantAlphaA</a>: 
+  Generic heat transfer correlation with constant product of heat transfer 
+  coefficient and area.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation.LinearAlphaA_T\">LinearAlphaA_T</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is linearly dependent on the temperature.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation.LinearAlphaA_fRel\">LinearAlphaA_fRel</a>: 
+  Generic heat transfer correlation with a product of heat transfer coefficient 
+  and area that is linearly dependent on the relative filling level.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PoolCondensation;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/package.order
new file mode 100644
index 0000000..fab30c1
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/PoolCondensation/package.order
@@ -0,0 +1,4 @@
+ConstantAlpha
+ConstantAlphaA
+LinearAlphaA_T
+LinearAlphaA_fRel
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/ConstantResistance.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/ConstantResistance.mo
new file mode 100644
index 0000000..e6c63b8
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/ConstantResistance.mo
@@ -0,0 +1,51 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Radiation;
+model ConstantResistance
+  "Constant thermal resistance describing thermal radiation"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialRadiationHeatTransferCoefficient(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real constantR(final unit="W/K4") = 1 / Modelica.Constants.sigma / 0.1
+    "Constant thermal resistance describing thermal radiation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = 1 / (1 * constantR)
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area for thermal conduction assuming a constant thermal resistance.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant thermal resistance <i>R<sub>&sigma;</sub></i>:
+</p>
+<pre>
+    &alpha;A = 1 / R<sub>&sigma;</sub>;
+</pre>
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 16, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ConstantResistance;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/GrayCylinderInGrayCylinder.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/GrayCylinderInGrayCylinder.mo
new file mode 100644
index 0000000..a222b1e
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/GrayCylinderInGrayCylinder.mo
@@ -0,0 +1,78 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Radiation;
+model GrayCylinderInGrayCylinder
+  "Heat transfer correlation describing thermal radiation between a gray cylinder within a bigger gray cylinder"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialRadiationHeatTransferCoefficient(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust the heat transfer coefficient correlation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Real epsilon_1(min=0, max=1) = 0.15
+    "Emissivity of suraface 1 (i.e., inner cylinder)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real epsilon_2(min=0, max=1) = 0.15
+    "Emissivity of suraface 2 (i.e., outer cylinder)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A_1 = 0.1
+    "Surface 1 (i.e., inner cylinder)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A_2 = 0.2
+    "Surface 2 (i.e., outer cylinder)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = f_correction * 1 * Modelica.Constants.sigma /
+    (1/epsilon_1 + A_1/A_2 * (1/epsilon_2 - 1))
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area for thermal radiation between a gray cylinder within a bigger gray cylinder.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant thermal resistance <i>R<sub>&sigma;</sub></i>:
+</p>
+<pre>
+    &alpha;A = 1 / R<sub>&sigma;</sub> = &sigma; / (1/&epsilon;<sub>1</sub> + A<sub>1</sub>/A<sub>2</sub>) * (1/&epsilon;<sub>2</sub> - 1));
+</pre>
+<p>
+Herein, <i>&sigma;</i> is the Stefan-Blotzmann constant, <i>A<sub>1</sub></i> is 
+the area of the inner cylinder, <i>A<sub>2</sub></i> is the area of the outer
+cylinder, <i>&epsilon;<sub>1</sub></i> emission constant of surface 1, and 
+<i>&epsilon;<sub>2</sub></i> emission constant of surface 2.
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change. Then, this model can be used to describe thermal
+radiation between a gray cylinder within a bigger gray cylinder.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kabelac, S. and Vortmeyer, D. (2010). K1 Radiation of Surfaces. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_64.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 16, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end GrayCylinderInGrayCylinder;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/ParallelGraySurfaces.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/ParallelGraySurfaces.mo
new file mode 100644
index 0000000..52729d3
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/ParallelGraySurfaces.mo
@@ -0,0 +1,75 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Radiation;
+model ParallelGraySurfaces
+  "Heat transfer correlation describing thermal radation between two parallel, gray surfaces"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialRadiationHeatTransferCoefficient(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 1
+    "Correction factor to adjust the heat transfer coefficient correlation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Real epsilon_1(min=0, max=1) = 0.15
+    "Emissivity of suraface 1"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real epsilon_2(min=0, max=1) = 0.15
+    "Emissivity of suraface 2"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A_surfaces = 0.1
+    "Identical area of the surfaces exchanging heat"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = f_correction * 1 * Modelica.Constants.sigma * A_surfaces /
+    (1/epsilon_1 + 1/epsilon_2 - 1)
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area for thermal radiation between two parallel, gray surfaces that have an equal
+area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant thermal resistance <i>R<sub>&sigma;</sub></i>:
+</p>
+<pre>
+    &alpha;A = 1 / R<sub>&sigma;</sub> = &sigma; * A / (1/&epsilon;<sub>1</sub> + 1/&epsilon;<sub>2</sub> - 1);
+</pre>
+<p>
+Herein, <i>&sigma;</i> is the Stefan-Blotzmann constant, <i>A</i> is the area of the
+surfaces that exhange heat, <i>&epsilon;<sub>1</sub></i> emission constant of surface 
+1, and <i>&epsilon;<sub>2</sub></i> emission constant of surface 2.
+  
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change. Then, this model can be used to describe thermal
+radiation between two parallel, gray surfaces.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kabelac, S. and Vortmeyer, D. (2010). K1 Radiation of Surfaces. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_64.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 16, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ParallelGraySurfaces;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/package.mo
new file mode 100644
index 0000000..82ed765
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/package.mo
@@ -0,0 +1,32 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations;
+package Radiation "Correlations for heat transfer coefficients describing thermal radiation"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for heat transfer coefficients describing
+thermal radiation:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Radiation.ConstantResistance\">ConstantResistance</a>: 
+  Constant thermal resistance.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Radiation.ParallelGraySurfaces\">ParallelGraySurfaces</a>: 
+  Constant thermal radiation between two parallel, gray surfaces.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Radiation.GrayCylinderInGrayCylinder\">GrayCylinderInGrayCylinder</a>: 
+  Constant thermal radiation between a gray cylinder within a bigger, gray cylinder.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Radiation;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/package.order
new file mode 100644
index 0000000..cc67718
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/Radiation/package.order
@@ -0,0 +1,3 @@
+ConstantResistance
+ParallelGraySurfaces
+GrayCylinderInGrayCylinder
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/ConstantAlpha.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/ConstantAlpha.mo
new file mode 100644
index 0000000..606975e
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/ConstantAlpha.mo
@@ -0,0 +1,63 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside;
+model ConstantAlpha
+  "Generic heat transfer correlation with constant heat transfer coefficient"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.CoefficientOfHeatTransfer constantAlpha = 30000
+    "Constant heat transfer coefficient"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Area A = geometry.A_heatTransferInner
+    "Constant heat transfer area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = geometry.no_hydraulicParallelTubes * constantAlpha * A /
+    min(geometry.no_fluidVolumes, geometry.no_wallVolumes)
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>. 
+The product is enlarged by the number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i>
+to account for parallel flows modeled by just one flow:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * &alpha; * A / <strong>min</strong>(no<sub>fluid volumes</sub>, no<sub>wall volumes</sub>) = const.;
+</pre>
+<p>
+Note that the area <i>A</i> is calculated from the geometry record taking into
+account the disretization: The smaller number of discretization volumes used for 
+the fluid and the wall determines the number of heat transfer models that are used. 
+Accordingly, the total heat transfer surface is divided by the smaller number.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 19, 2024, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end ConstantAlpha;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/ConstantAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/ConstantAlphaA.mo
new file mode 100644
index 0000000..6bdffa2
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/ConstantAlphaA.mo
@@ -0,0 +1,60 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside;
+model ConstantAlphaA
+  "Generic heat transfer correlation with constant product of heat transfer coefficient and area"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient(
+    final computeTransportProperties=false,
+    final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.ThermalConductance constantAlphaA = 30000
+    "Constant product of heat transfer coefficient and area"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+equation
+  alphaA = geometry.no_hydraulicParallelTubes * constantAlphaA /
+    min(geometry.no_fluidVolumes, geometry.no_wallVolumes)
+    "Calculation of the product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of heat transfer coefficient and
+area assuming a constant heat transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated 
+assuming a constant heat transfer coefficient <i>&alpha;</i> and area <i>A</i>:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> / <strong>min</strong>(no<sub>fluid volumes</sub>, no<sub>wall volumes</sub>) * const.;
+</pre>
+<p>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. Furhtermore, the product is diveded by the smaller discretization number
+of fluid or wall volumes to account for discretization: The smaller discretization 
+number determines the number of heat transfer models that are used. Thus, the product
+<i>&alpha;A</i> is valid for one heat exchanger tube.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This simple heat transfer correlation model is typically used if the heat transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 19, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ConstantAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/GnielinskiDittusBoelter.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/GnielinskiDittusBoelter.mo
new file mode 100644
index 0000000..d6fac1f
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/GnielinskiDittusBoelter.mo
@@ -0,0 +1,415 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside;
+model GnielinskiDittusBoelter
+  "Heat transfer correlation according to Gnielinski, Dittus, and Boelter for straight tubes"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient(
+    final computeTransportProperties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.MassFlowRateHeatTranferCorrelation calculationMassFlowRate=
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXMinus
+    "Defines the hydraulic mass flow rate used for calculations"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Real f_correctionNoFlow = 1
+    "Correction factor to adjust the Nusselt-correlation for the no-flow regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real f_correctionLaminar = 1
+    "Correction factor to adjust the Nusselt-correlation for the laminar regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real f_correctionGnielinski = 1
+    "Correction factor to adjust the Nusselt-correlation for the turbulent regime
+    described by the correlation of Gnielinski"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real f_correctionDittusBoelter = 1.7
+    "Correction factor to adjust the Nusselt-correlation for the turbulent regime
+    described by the correlation of Dittus and Boelter"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Modelica.Units.SI.ReynoldsNumber Re_critNoFlow = 10
+    "Critical Reynolds number for the no-flow regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_critLaminar = 2300
+    "Critical Reynolds number for the laminar regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_critGnielinski = 1e4
+    "Critical Reynolds number for the turbulent regime described by the 
+    correlation of Gnielinski"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_critDittusBoelter = 1e6
+    "Critical Reynolds number for the turbulent regime described by the 
+    correlation of Dittus and Boelter"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true,
+              HideResult=true);
+
+  parameter Integer noDiff = 2
+    "Specification how often transition functions can be differentiated"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transitionNoFlow = 1
+    "Transition length for the no-flow regime"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transitionLaminar = 10
+    "Transition length for the laminar regime"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transitionTurbulent = 100
+    "Transition length for the turbulent regime"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.CoefficientOfHeatTransfer alpha
+    "Heat tranfer coefficient";
+
+  Modelica.Units.SI.ReynoldsNumber Re
+    "Reynolds number";
+  Modelica.Units.SI.PrandtlNumber Pr
+    "Prandtl number";
+  Modelica.Units.SI.ReynoldsNumber Nu
+    "Nusselt number";
+
+  Modelica.Units.SI.NusseltNumber Nu_noFlow
+    "Nusselt number for no-flow regime";
+  Modelica.Units.SI.NusseltNumber Nu_lamianr
+    "Nusselt number for laminar flow regime";
+  Modelica.Units.SI.NusseltNumber Nu_transition
+    "Nusselt number for transition regime";
+  Modelica.Units.SI.NusseltNumber Nu_Gnielinski
+    "Nusselt number for turbulent flow regime according to Gnielinski";
+  Modelica.Units.SI.NusseltNumber Nu_DittusBoelter
+    "Nusselt number for turbulent flow regime according to Dittus and Boelter";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.NusseltNumber Nu_lamianrFlow_transition
+    "Nusselt number for laminar flow at the transition point";
+  Modelica.Units.SI.NusseltNumber Nu_Gnielinski_transition
+    "Nusselt number for turbulent flow according to Gnielinski at the
+    transition point";
+
+  Modelica.Units.SI.NusseltNumber Nu_aux1
+    "Nusselt number according to transition between no-flow and laminar flow 
+    regime";
+  Modelica.Units.SI.NusseltNumber Nu_aux2
+    "Nusselt number according to transition between laminar flow regime and 
+    transition regime";
+  Modelica.Units.SI.NusseltNumber Nu_aux3
+    "Nusselt number according to transition between transition regime and 
+    turbulent regime according to Gnielinski";
+
+  Modelica.Units.SI.Length l_heatTransfer
+    "Length of the tube accounting for discretization";
+  Modelica.Units.SI.Area A_heatTransfer
+    "Heat transfer area accounting for discretization";
+
+  Real zeta
+    "Auxillary variable for Gnielinski's Nusselt correlation";
+  Real zeta_transition
+    "Auxillary variable for Gnielinski's Nusselt correlation at the transition 
+    point";
+
+  Real wf_noFlowLaminar
+    "Transition factor to change between no-flow and laminar flow regime";
+  Real wf_laminarTransition
+    "Transition factor for change between laminar and transition regime";
+  Real gamma
+    "Transition fractor transition regime";
+  Real wf_transitionGnielinski
+    "Transition factor for change between first transition regime and turbulent
+    regime according to Gnielinski";
+  Real wf_GnielinskiDittusBoelter
+    "Transition factor for change between turbulent regime according to Gnielinski
+    and turbulent regime according to Dittus and Boelter";
+
+equation
+  //
+  // Calculation of transition functions
+  //
+  gamma = (Re - Re_critLaminar) / (Re_critGnielinski - Re_critLaminar)
+    "Transition fractor transition regime";
+
+  if avoid_events then
+    wf_noFlowLaminar = SorpLib.Numerics.smoothTransition_noEvent(
+      x=Re,
+      transitionPoint=Re_critNoFlow,
+      transitionLength=Re_transitionNoFlow,
+      noDiff=noDiff)
+      "Transition factor to change between no-flow and laminar flow regime";
+    wf_laminarTransition  = SorpLib.Numerics.smoothTransition_noEvent(
+      x=Re,
+      transitionPoint=Re_critLaminar,
+      transitionLength=Re_transitionLaminar,
+      noDiff=noDiff)
+      "Transition factor for change between laminar and transition regime";
+    wf_transitionGnielinski = SorpLib.Numerics.smoothTransition_noEvent(
+      x=Re,
+      transitionPoint=Re_critGnielinski,
+      transitionLength=Re_transitionTurbulent,
+      noDiff=noDiff)
+      "Transition factor for change between first transition regime and turbulent
+      regime according to Gnielinski";
+    wf_GnielinskiDittusBoelter = SorpLib.Numerics.smoothTransition_noEvent(
+      x=Re,
+      transitionPoint=Re_critDittusBoelter,
+      transitionLength=Re_transitionTurbulent,
+      noDiff=noDiff)
+      "Transition factor for change between turbulent regime according to Gnielinski
+      and turbulent regime according to Dittus and Boelter";
+
+  else
+    wf_noFlowLaminar = SorpLib.Numerics.smoothTransition(
+      x=Re,
+      transitionPoint=Re_critNoFlow,
+      transitionLength=Re_transitionNoFlow,
+      noDiff=noDiff)
+      "Transition factor to change between no-flow and laminar flow regime";
+    wf_laminarTransition  = SorpLib.Numerics.smoothTransition(
+      x=Re,
+      transitionPoint=Re_critLaminar,
+      transitionLength=Re_transitionLaminar,
+      noDiff=noDiff)
+      "Transition factor for change between laminar and transition regime";
+    wf_transitionGnielinski = SorpLib.Numerics.smoothTransition(
+      x=Re,
+      transitionPoint=Re_critGnielinski,
+      transitionLength=Re_transitionTurbulent,
+      noDiff=noDiff)
+      "Transition factor for change between first transition regime and turbulent
+      regime according to Gnielinski";
+    wf_GnielinskiDittusBoelter = SorpLib.Numerics.smoothTransition(
+      x=Re,
+      transitionPoint=Re_critDittusBoelter,
+      transitionLength=Re_transitionTurbulent,
+      noDiff=noDiff)
+      "Transition factor for change between turbulent regime according to Gnielinski
+      and turbulent regime according to Dittus and Boelter";
+
+  end if;
+
+  //
+  // Calculation of the Reynolds and Prandtl number
+  //
+  if calculationMassFlowRate==
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXMinus then
+    Re = abs(m_hyd_xMinus) * geometry.d_hydInner /
+      (geometry.A_hydCrossInner * fluidProperties.eta)
+      "Reynolds number";
+
+  elseif calculationMassFlowRate==
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXPlus then
+    Re = abs(m_hyd_xPlus) * geometry.d_hydInner /
+      (geometry.A_hydCrossInner * fluidProperties.eta)
+      "Reynolds number";
+
+  else
+    Re = (abs(m_hyd_xMinus) + abs(m_hyd_xPlus)) / 2 * geometry.d_hydInner /
+      (geometry.A_hydCrossInner * fluidProperties.eta)
+      "Reynolds number";
+
+  end if;
+
+  Pr = fluidProperties.eta * fluidProperties.cp / fluidProperties.lambda
+    "Prandtl number";
+
+  //
+  // Calculation of the Nusselt numbers
+  //
+  l_heatTransfer = geometry.l /
+    min(geometry.no_fluidVolumes, geometry.no_wallVolumes)
+    "Length of the tube accounting for discretization";
+  A_heatTransfer = geometry.A_heatTransferInner /
+    min(geometry.no_fluidVolumes, geometry.no_wallVolumes)
+    "Length of the tube accounting for discretization";
+
+  zeta =
+    (1.8 * Modelica.Math.log10(max(Re,1e-12)) - 1.5)^(-2)
+    "Auxillary variable for Gnielinski's Nusselt correlation";
+  zeta_transition =
+    (1.8 * Modelica.Math.log10(max(Re_critGnielinski,1e-12)) - 1.5)^(-2)
+    "Auxillary variable for Gnielinski's Nusselt correlation at the transition 
+    point";
+
+  Nu_noFlow = f_correctionNoFlow * 3.66
+    "Nusselt number for laminar flow at the transition point";
+  Nu_lamianr = f_correctionLaminar * (
+    3.66^3 +
+    0.7^3 +
+    (1.615 * (Re * Pr * geometry.d_hydInner/l_heatTransfer)^(1/3) - 0.7)^3 +
+    ((2 / (1 + 22 * Pr))^(1/6) * (Re * Pr * geometry.d_hydInner/l_heatTransfer)^(1/2))^3)^(1/3)
+    "Nusselt number for laminar flow regime";
+  Nu_lamianrFlow_transition = f_correctionLaminar * (
+    3.66^3 +
+    0.7^3 +
+    (1.615 * (Re_critLaminar * Pr * geometry.d_hydInner/l_heatTransfer)^(1/3) - 0.7)^3 +
+    ((2 / (1 + 22 * Pr))^(1/6) * (Re_critLaminar * Pr * geometry.d_hydInner/l_heatTransfer)^(1/2))^3)^(1/3)
+    "Nusselt number for laminar flow at the transition point";
+  Nu_transition = (1-gamma) * Nu_lamianrFlow_transition +
+    gamma * Nu_Gnielinski_transition
+    "Nusselt number for transition regime";
+  Nu_Gnielinski_transition = f_correctionGnielinski * (zeta_transition/8) * Re_critGnielinski * Pr /
+    (1 + 12.7*sqrt(zeta_transition/8) * (Pr^(2/3) - 1)) *
+    (1 + (geometry.d_hydInner/l_heatTransfer)^(2/3))
+    "Nusselt number for turbulent flow according to Gnielinski at the
+    transition point";
+  Nu_Gnielinski = f_correctionGnielinski * (zeta/8) * Re * Pr /
+    (1 + 12.7*sqrt(zeta/8) * (Pr^(2/3) - 1)) *
+    (1 + (geometry.d_hydInner/l_heatTransfer)^(2/3))
+    "Nusselt number for turbulent flow regime according to Gnielinski";
+  Nu_DittusBoelter = f_correctionDittusBoelter * 0.023 * Re^(4/5) * Pr^(1/3)
+    "Nusselt number for turbulent flow regime according to Dittus and Boelter";
+
+  Nu_aux1 = wf_noFlowLaminar * Nu_noFlow +
+    (1-wf_noFlowLaminar) * Nu_lamianr
+    "Nusselt number according to transition between no-flow and laminar flow 
+    regime";
+  Nu_aux2 = wf_laminarTransition * Nu_aux1 +
+    (1-wf_laminarTransition) * Nu_transition
+    "Nusselt number according to transition between laminar flow regime and 
+    transition regime";
+  Nu_aux3 = wf_transitionGnielinski * Nu_aux2 +
+    (1-wf_transitionGnielinski) * Nu_Gnielinski
+    "Nusselt number according to transition between transition regime and 
+    turbulent regime according to Gnielinski";
+  Nu = wf_GnielinskiDittusBoelter * Nu_aux3 +
+    (1-wf_GnielinskiDittusBoelter) * Nu_DittusBoelter
+    "Nusselt number";
+
+  //
+  // Calculation of the heat transfer coefficient
+  //
+  alpha = Nu * fluidProperties.lambda/geometry.d_hydInner
+    "Heat transfer coefficient";
+  alphaA = geometry.no_hydraulicParallelTubes * alpha * A_heatTransfer
+    "Product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This heat transfer model calculates the product of heat transfer coefficient and
+area describing convective heat transfer within tubes. The model considers both,
+the laminar and turbulent flow regime.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated
+from the Nussel number <i>Nu</i> using Nusselt correlations for different flow
+regimes:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * Nu * &lambda; / d<sub>hyd,inner</sub> * A<sub>heat transfer</sub> / <strong>min</strong>(no<sub>fluid volumes</sub>, no<sub>wall volumes</sub>);
+</pre>
+<p>
+Herein, <i>&lambda;</i> is the thermal conductivity, <i>d<sub>hyd,inner</sub></i> 
+is the hydraulic inner diameter, and <i>A<sub>heat transfer</sub></i> is the heat 
+transfer area accounting for the discretization. The product is enlarged by the
+number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i> to account 
+for parallel flows modeled by just one flow. 
+<br/><br/>
+The Nusselt number depends on the flow regime:
+</p>
+<pre>
+    Nu<sub>no flow</sub> = f<sub>correction,no flow</sub> * 3.66;
+
+    Nu<sub>laminar</sub> = f<sub>correction,laminar</sub> * [3.66<sup>3</sup> + 0.7<sup>3</sup> + (1.615 * (Re * Pr * d<sub>hyd,inner</sub>/l<sub>heat transfer</sub>)<sup>(1/3)</sup> - 0.7)<sup>3</sup> + ((2 / (1 + 22 * Pr))<sup>(1/6)</sup> * (Re * Pr * d<sub>hyd,inner</sub>/l<sub>heat transfer</sub>)<sup>(1/2)</sup>)<sup>3</sup>]<sup>(1/3)</sup>;
+
+    Nu<sub>transition</sub> = (1-&gamma;) * Nu<sub>laminar</sub>(Re<sub>crit,laminar</sub>) + &gamma; * Nu<sub>Gnielinski</sub>(Re<sub>crit,Gnielinski</sub>);
+
+    Nu<sub>Gnielinski</sub> = f<sub>correction,Gnielinski</sub> * [(&zeta;/8) * Re * Pr / (1 + 12.7 * <strong>sqrt</strong>(&zeta;/8) * (Pr<sup>(2/3)</sup> - 1)) * (1 + (d<sub>hyd,inner</sub>/l<sub>heat transfer</sub>)<sup>(2/3)</sup>)];
+
+    Nu<sub>Dittus,Boelter</sub> = f<sub>correction,Dittus,Boelter</sub> * [0.023 * Re<sup>(4/5)</sup> * Pr<sup>(1/3)</sup>];
+</pre>
+<p>
+with:
+</p>
+<pre>
+    &zeta; = 1 / [1.8 * <strong>log<sub>10</sub></strong>(Re) - 1.5]<sup>2</sup>;
+
+    &gamma; = (Re - Re<sub>crit,laminar</sub>) / (Re<sub>crit,Gnielinski</sub> - Re<sub>crit,laminar</sub>);
+</pre>
+<p>
+Herein, <i>f<sub>i</sub></i> are correction factors for the Nusselt correlations
+<i>Nu<sub>i</sub></i> of the different flow regimes <i>i</i>, <i>Re</i> is the
+Reynolds number, <i>Pr</i> is the Prandtl number, <i>&zeta;</i> is a auxillary
+variable, <i>&gamma;</i> is a transition factor, and <i>l<sub>heat transfer</sub></i> 
+is the heat transfer length accounting for the discretization:
+</p>
+<pre>
+    Re = <strong>abs</strong>(m<sub>flow,hyd</sub>) * d<sub>hyd,inner</sub> / A<sub>cross,inner</sub> / &eta;;
+
+    Pr = &eta; * c<sub>p</sub> / &lambda;;
+
+    l<sub>heat transfer</sub> = l<sub>tube</sub> / <strong>min</strong>(no<sub>fluid volumes</sub>, no<sub>wall volumes</sub>);
+</pre>
+<p>
+Herein, <i>m<sub>flow,hyd</sub></i> is the hydraulic mass flow rate, 
+<i>A<sub>cross,inner</sub></i> is the hydraulic cross-sectional inner area, <i>&eta;</i> 
+is the dynamic viscosity, <i>&lambda;</i> is the thermal conductivity, and 
+<i>l<sub>tube</sub></i> is the tube length.
+<br/><br/>
+Smooth transition is applied using the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>
+to change between the different regimes using the corresponding critical Reynold
+numbers <i>Re<sub>i</sub></i>.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This heat transfer correlation model is typically used to describe convective
+heat transfer within tubes if accurate results are required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationMassFlowRate</i>:
+  Defines the hydraulic mass flow rate that is used for calculations.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Gnielinski, V. (2010). G1 Heat Transfer in Pipe Flow. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_34.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 19, 2024, by Mirko Engelpracht:<br/>
+  Major extensions (more flow regimes, documentation, stability).
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GnielinskiDittusBoelter;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/Schmidt.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/Schmidt.mo
new file mode 100644
index 0000000..8f542ad
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/Schmidt.mo
@@ -0,0 +1,338 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside;
+model Schmidt
+  "Heat transfer correlation according to Schmidt for helix tubes"
+  extends
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient(
+    final computeTransportProperties=true);
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.MassFlowRateHeatTranferCorrelation calculationMassFlowRate=
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXMinus
+    "Defines the hydraulic mass flow rate used for calculations"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true);
+
+  parameter Modelica.Units.SI.Length h_coil = 0.015
+    "Gradient of the helix (i.e., pitch between two coils)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Diameter d_coil = 0.1
+    "Average diameter of the helix (i.e., top-view projection)"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Modelica.Units.SI.Diameter d_helix=
+    d_coil * (1 + (h_coil / (Modelica.Constants.pi * d_coil))^2)
+    "Average beinding diameter of the tube"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Real f_correctionLaminar = 1
+    "Correction factor to adjust the Nusselt-correlation for the laminar regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+  parameter Real f_correctionTurbulent = 1
+    "Correction factor to adjust the Nusselt-correlation for the turbulent regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"));
+
+  parameter Modelica.Units.SI.ReynoldsNumber Re_critLaminar=
+    2300 * (1 + 8.6 * (geometry.d_hydInner / d_helix)^(0.45))
+    "Critical Reynolds number for the laminar regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_critTurbulent = 2.2e4
+    "Critical Reynolds number for the turbulent regime"
+    annotation(Dialog(tab = "General", group = "Heat Transfer"),
+              Evaluate=true,
+              HideResult=true);
+
+  parameter Integer noDiff = 2
+    "Specification how often transition functions can be differentiated"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transitionLaminar = 10
+    "Transition length for the laminar regime"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+  parameter Modelica.Units.SI.ReynoldsNumber Re_transitionTurbulent = 100
+    "Transition length for the turbulent regime"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.CoefficientOfHeatTransfer alpha
+    "Heat tranfer coefficient";
+
+  Modelica.Units.SI.ReynoldsNumber Re
+    "Reynolds number";
+  Modelica.Units.SI.PrandtlNumber Pr
+    "Prandtl number";
+  Modelica.Units.SI.ReynoldsNumber Nu
+    "Nusselt number";
+
+  Modelica.Units.SI.NusseltNumber Nu_lamianr
+    "Nusselt number for laminar flow regime";
+  Modelica.Units.SI.NusseltNumber Nu_transition
+    "Nusselt number for transition regime";
+  Modelica.Units.SI.NusseltNumber Nu_turbulent
+    "Nusselt number for turbulent flow regime";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.NusseltNumber Nu_laminar_transition
+    "Nusselt number for laminar regime at the transition point";
+  Modelica.Units.SI.NusseltNumber Nu_turbulent_transition
+    "Nusselt number for turbulent regime at the transition point";
+
+  Modelica.Units.SI.NusseltNumber Nu_aux
+    "Nusselt number according to transition between laminar and turbulent
+    regime";
+
+  Modelica.Units.SI.Area A_heatTransfer
+    "Heat transfer area accounting for discretization";
+
+  Real m
+    "Auxillary variable for the laminar Nusselt correlation";
+  Real zeta
+    "Auxillary variable for the turbulent Nusselt correlation";
+  Real zeta_transition
+    "Auxillary variable for the turbulent Nusselt correlation at the transition 
+    point";
+
+  Real wf_laminarTransition
+    "Transition factor for change between laminar and transition regime";
+  Real gamma
+    "Transition fractor transition regime";
+  Real wf_transitionTurbulent
+    "Transition factor for change between transition regime and turbulent regime";
+
+equation
+  //
+  // Calculation of transition functions
+  //
+  gamma = (Re_critTurbulent - Re) / (Re_critTurbulent - Re_critLaminar)
+    "Transition fractor transition regime";
+
+  if avoid_events then
+    wf_laminarTransition  = SorpLib.Numerics.smoothTransition_noEvent(
+      x=Re,
+      transitionPoint=Re_critLaminar,
+      transitionLength=Re_transitionLaminar,
+      noDiff=noDiff)
+      "Transition factor for change between laminar and transition regime";
+    wf_transitionTurbulent = SorpLib.Numerics.smoothTransition_noEvent(
+      x=Re,
+      transitionPoint=Re_critTurbulent,
+      transitionLength=Re_transitionTurbulent,
+      noDiff=noDiff)
+      "Transition factor for change between transition regime and turbulent 
+      regime";
+
+  else
+    wf_laminarTransition  = SorpLib.Numerics.smoothTransition(
+      x=Re,
+      transitionPoint=Re_critLaminar,
+      transitionLength=Re_transitionLaminar,
+      noDiff=noDiff)
+      "Transition factor for change between laminar and transition regime";
+    wf_transitionTurbulent = SorpLib.Numerics.smoothTransition(
+      x=Re,
+      transitionPoint=Re_critTurbulent,
+      transitionLength=Re_transitionTurbulent,
+      noDiff=noDiff)
+      "Transition factor for change between transition regime and turbulent 
+      regime";
+
+  end if;
+
+  //
+  // Calculation of the Reynolds and Prandtl number
+  //
+  if calculationMassFlowRate==
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXMinus then
+    Re = abs(m_hyd_xMinus) * geometry.d_hydInner /
+      (geometry.A_hydCrossInner * fluidProperties.eta)
+      "Reynolds number";
+
+  elseif calculationMassFlowRate==
+    SorpLib.Choices.MassFlowRateHeatTranferCorrelation.PortXPlus then
+    Re = abs(m_hyd_xPlus) * geometry.d_hydInner /
+      (geometry.A_hydCrossInner * fluidProperties.eta)
+      "Reynolds number";
+
+  else
+    Re = (abs(m_hyd_xMinus) + abs(m_hyd_xPlus)) / 2 * geometry.d_hydInner /
+      (geometry.A_hydCrossInner * fluidProperties.eta)
+      "Reynolds number";
+
+  end if;
+
+  Pr = fluidProperties.eta * fluidProperties.cp / fluidProperties.lambda
+    "Prandtl number";
+
+  //
+  // Calculation of the Nusselt numbers
+  //
+  A_heatTransfer = geometry.A_heatTransferInner /
+    min(geometry.no_fluidVolumes, geometry.no_wallVolumes)
+    "Length of the tube accounting for discretization";
+
+  m = 0.5 + 0.2903 * (geometry.d_hydInner / d_helix)^0.194
+    "Auxillary variable for the laminar Nusselt correlation";
+  zeta = 0.3164 / max(Re,1e-12)^0.25 +
+    0.03 * (geometry.d_hydInner/d_helix)^0.5
+    "Auxillary variable for Gnielinski's Nusselt correlation";
+  zeta_transition = 0.3164 / max(Re_critTurbulent,1e-12)^0.25 +
+    0.03 * (geometry.d_hydInner/d_helix)^0.5
+    "Auxillary variable for Gnielinski's Nusselt correlation at the transition 
+    point";
+
+  Nu_lamianr = f_correctionLaminar * (3.66 + 0.08 * (1 + 0.8 *
+    (geometry.d_hydInner / d_helix)^0.9) * Re^m * Pr^(1/3))
+    "Nusselt number for laminar flow regime";
+  Nu_laminar_transition = f_correctionLaminar * (3.66 + 0.08 * (1 + 0.8 *
+    (geometry.d_hydInner / d_helix)^0.9) * Re_critLaminar^m * Pr^(1/3))
+    "Nusselt number for laminar regime at the transition point";
+  Nu_transition = gamma*Nu_laminar_transition +
+    (1-gamma) * Nu_turbulent_transition
+    "Nusselt number for transition regime";
+  Nu_turbulent_transition = f_correctionTurbulent * (zeta_transition/8) *
+    Re_critTurbulent * Pr / (1 + 12.7*sqrt(zeta_transition/8) * (Pr^(2/3) - 1))
+    "Nusselt number for turbulent regime at the transition point";
+  Nu_turbulent = f_correctionTurbulent * (zeta/8) * Re * Pr /
+    (1 + 12.7*sqrt(zeta/8) * (Pr^(2/3) - 1))
+    "Nusselt number for turbulent flow regime";
+
+  Nu_aux = wf_laminarTransition * Nu_lamianr +
+    (1-wf_laminarTransition) * Nu_transition
+    "Nusselt number according to transition between laminar and turbulent
+    regime";
+  Nu = wf_transitionTurbulent * Nu_transition +
+    (1-wf_transitionTurbulent) * Nu_turbulent
+    "Nusselt number";
+
+  //
+  // Calculation of the heat transfer coefficient
+  //
+  alpha = Nu * fluidProperties.lambda/geometry.d_hydInner
+    "Heat transfer coefficient";
+  alphaA = geometry.no_hydraulicParallelTubes * alpha * A_heatTransfer
+    "Product of heat transfer coefficient and area";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This heat transfer model calculates the product of heat transfer coefficient and
+area describing convective heat transfer within helix tubes. The model considers 
+both, the laminar and turbulent flow regime.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of heat transfer coefficient and area <i>&alpha;A</i> is calculated
+from the Nussel number <i>Nu</i> using Nusselt correlations for different flow
+regimes:
+</p>
+<pre>
+    &alpha;A = no<sub>parallel flows</sub> * Nu * &lambda; / d<sub>hyd,inner</sub> * A<sub>heat transfer</sub> / <strong>min</strong>(no<sub>fluid volumes</sub>, no<sub>wall volumes</sub>);
+</pre>
+<p>
+Herein, <i>&lambda;</i> is the thermal conductivity, <i>d<sub>hyd,inner</sub></i> 
+is the hydraulic inner diameter, and <i>A<sub>heat transfer</sub></i> is the heat 
+transfer area accounting for the discretization. The product is enlarged by the
+number of hydrualic parallel flows <i>no<sub>parallel flows</sub></i> to account 
+for parallel flows modeled by just one flow. 
+<br/><br/>
+The Nusselt number depends on the flow regime:
+</p>
+<pre>
+    Nu<sub>laminar</sub> = f<sub>correction,laminar</sub> * [3.66 + 0.08 * (1 + 0.8 * (d<sub>hyd,inner</sub>/d<sub>helix</sub>)<sup>0.9</sup>) * Re^m * Pr^(1/3)];
+
+    Nu<sub>transition</sub> = (1-&gamma;) * Nu<sub>turbulent</sub>(Re<sub>crit,turbulent</sub>) + &gamma; * Nu<sub>laminar</sub>(Re<sub>crit,laminar</sub>);
+
+    Nu<sub>turbulent</sub> = f<sub>correction,turbulent</sub> * [(&zeta;/8) * Re * Pr / (1 + 12.7 * <strong>sqrt</strong>(&zeta;/8) * (Pr<sup>(2/3)</sup> - 1))];
+</pre>
+<p>
+with:
+</p>
+<pre>
+    m = 0.5 + 0.2903 * (d<sub>hyd,inner</sub>/d<sub>helix</sub>)<sup>0.194</sup>;
+
+    &zeta; = 0.3164 / Re^(0.25) + 0.03 * (d<sub>hyd,inner</sub>/d<sub>helix</sub>)<sup>0.5</sup>;
+
+    &gamma; = (Re<sub>crit,turbulent</sub> - Re) / (Re<sub>crit,turbulent</sub> - Re<sub>crit,laminar</sub>);
+</pre>
+<p>
+Herein, <i>f<sub>i</sub></i> are correction factors for the Nusselt correlations
+<i>Nu<sub>i</sub></i> of the different flow regimes <i>i</i>, <i>Re</i> is the
+Reynolds number, <i>Pr</i> is the Prandtl number, <i>m</i> is a auxillary variable
+for the laminar flow regime, <i>&zeta;</i> is a auxillary variable for the turbulent
+flow regime, <i>&gamma;</i> is a transition factor, and <i>d<sub>helix</sub></i> 
+is the average bending diameter of the helix tube:
+</p>
+<pre>
+    Re = <strong>abs</strong>(m<sub>flow,hyd</sub>) * d<sub>hyd,inner</sub> / A<sub>cross,inner</sub> / &eta;;
+
+    Pr = &eta; * c<sub>p</sub> / &lambda;;
+
+    d<sub>helix</sub> = d<sub>coil</sub> * [1 + (h<sub>coil</sub> / &pi; / d<sub>coil</sub>)<sup>2</sup>];
+</pre>
+<p>
+Herein, <i>m<sub>flow,hyd</sub></i> is the hydraulic mass flow rate, 
+<i>A<sub>cross,inner</sub></i> is the hydraulic cross-sectional inner area, 
+<i>&eta;</i> is the dynamic viscosity, <i>&lambda;</i> is the thermal conductivity, 
+<i>c<sub>p</sub></i> is ther isobaric heat capacity, <i>d<sub>coil</sub></i> is 
+the diameter of one coil (i.e., top-down view), and <i>h<sub>coil</sub></i> is the 
+gradient of the helix (i.e., pitch between two coils).
+<br/><br/>
+Smooth transition is applied using the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>
+to change between the different regimes using the corresponding critical Reynold
+numbers <i>Re<sub>i</sub></i>.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This heat transfer correlation model is typically used to describe convective
+heat transfer within tubes if accurate results are required.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>calculationMassFlowRate</i>:
+  Defines the hydraulic mass flow rate that is used for calculations.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Gnielinski, V. (2010). G3 Heat Transfer in Helically Coiled Tubes. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_36.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 19, 2024, by Mirko Engelpracht:<br/>
+  Major extensions (more flow regimes, documentation, stability).
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Schmidt;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/package.mo
new file mode 100644
index 0000000..2eb06bc
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/package.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations;
+package TubeInside "Correlations for heat transfer coefficients describing convective heat transfer within tubes"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for heat transfer coefficients describing
+convective heat transfer within tubes:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.ConstantAlpha\">ConstantAlpha</a>: 
+  Generic heat transfer correlation with constant heat transfer coefficient.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.ConstantAlphaA\">ConstantAlphaA</a>: 
+  Generic heat transfer correlation with constant product of heat transfer 
+  coefficient and area.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.GnielinskiDittusBoelter\">GnielinskiDittusBoelter</a>: 
+  Heat transfer correlation according to Gielinski, Dittus, and Boelter for
+  laminar and turbulent flow regimes within straigt tubes.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.Schmidt\">Schmidt</a>: 
+  Heat transfer correlation according to Schmidt for laminar and turbulent 
+  flow regimes within helix tubes.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TubeInside;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/package.order
new file mode 100644
index 0000000..6866f77
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/TubeInside/package.order
@@ -0,0 +1,4 @@
+ConstantAlpha
+ConstantAlphaA
+GnielinskiDittusBoelter
+Schmidt
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/package.mo
new file mode 100644
index 0000000..4301fd3
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/package.mo
@@ -0,0 +1,55 @@
+within SorpLib.Components.HeatTransfer;
+package HeatTransferCoefficientCorrelations "Package containing correlations for heat transfer coefficients"
+extends Modelica.Icons.FunctionsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains correlations for heat transfer coefficients that can be used 
+within heat transfer models. The correlations calculate the product of heat transfer
+coefficient and area as a function of fluid property data, gemeotry, and flow regime.
+Correlations for heat transfer coefficients are implemented for the following heat
+transfer models:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Generic\">Generic</a>: 
+  Correlations for generic heat transfer coefficients.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction\">Conduction</a>: 
+  Correlations for conduction heat transfer coefficients.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Radiation\">Radiation</a>: 
+  Correlations for radiation heat transfer coefficients.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling\">PoolBoiling</a>: 
+  Correlations for radiation heat transfer describing pool boiling.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation\">PoolCondensation</a>: 
+  Correlations for radiation heat transfer describing (pool) condensation.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside\">TubeInside</a>: 
+  Correlations for heat transfer coefficients inside of tubes (i.e., (foreced) convection).
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber\">ClosedAdsorber</a>: 
+  Correlations for heat transfer coefficients inside of closed adsorbers (i.e., (foreced) convection).
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber\">OpenAdsorber</a>: 
+  Correlations for heat transfer coefficients inside of open adsorbers (i.e., (foreced) convection).
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructering the library.
+  </li>
+</ul>
+</html>"));
+end HeatTransferCoefficientCorrelations;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/package.order b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/package.order
new file mode 100644
index 0000000..7fab39b
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/HeatTransferCoefficientCorrelations/package.order
@@ -0,0 +1,8 @@
+Generic
+Conduction
+Radiation
+PoolBoiling
+PoolCondensation
+TubeInside
+ClosedAdsorber
+OpenAdsorber
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/ConstantAlpha.mo b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/ConstantAlpha.mo
deleted file mode 100644
index dfa2441..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/ConstantAlpha.mo
+++ /dev/null
@@ -1,37 +0,0 @@
-within SorpLib.Components.HeatTransfer.HeatTransferPhenomena;
-model ConstantAlpha
-  extends
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer(final computeTransportProperties=false);
-
-  parameter Modelica.SIunits.CoefficientOfHeatTransfer constantAlpha(start=100)=100 "Constant heat transfer coefficient";
-
-  parameter Modelica.SIunits.Area heatTransferArea(start=1)=1 "Heat transfer area";
-
-equation
-
-    alphaA = constantAlpha*heatTransferArea;
-
-  annotation (Documentation(info="<html>
-<p>
-  This simple transfer model calculates the heat flow based on the temperature differnce with a constant alpha.
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i>Q</i><sub>in</sub> = <i><code>&alpha;</code> A</i> (<i>T</i><sub>in</sub> - <i>T</i><sub>out</sub>) </p>
-  <p>where <i><code>&alpha;</code></i> is a constant heat tranfer coefficient and <i>A</i> is the heat transfer area. </p>
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    In general, the heat transfer coefficient depends on fluid properties and geometry. Thus, a constant coefficient is only an approximation.
-  </p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 06, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ConstantAlpha;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/ConstantAlphaA.mo b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/ConstantAlphaA.mo
deleted file mode 100644
index 2f0975b..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/ConstantAlphaA.mo
+++ /dev/null
@@ -1,34 +0,0 @@
-within SorpLib.Components.HeatTransfer.HeatTransferPhenomena;
-model ConstantAlphaA
-  extends
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer(final computeTransportProperties=false);
-
-  parameter Modelica.SIunits.ThermalConductance constantAlphaA(start=100)
-    "Constant heat transfer coefficient multiplied with heat transfer area";
-
-equation
-  alphaA = constantAlphaA;
-  annotation (Documentation(info="<html>
-<p>
-  This simple transfer model calculates the heat flow based on the temperature differnce with a constant product of heat transfer coefficient times heat transfer area.
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i>Q</i><sub>in</sub> = <i><code>&alpha;</code> A</i> (<i>T</i><sub>in</sub> - <i>T</i><sub>out</sub>) </p>
-  <p>where <i><code>&alpha;</code> A</i> is a constant product of heat transfer coefficient times heat transfer area. </p>
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    In general, the heat transfer coefficient depends on fluid properties and geometry. Thus, a constant coefficient is only an approximation.
-  </p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 06, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ConstantAlphaA;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/PartialHeatTransfer.mo b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/PartialHeatTransfer.mo
deleted file mode 100644
index d63339b..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/PartialHeatTransfer.mo
+++ /dev/null
@@ -1,28 +0,0 @@
-within SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial;
-partial model PartialHeatTransfer
-
-  Modelica.SIunits.ThermalConductance alphaA "Heat transfer coeeficient multiplied with heat transfer area";
-
-  constant Boolean computeTransportProperties = false;
-
-  annotation (Icon(graphics={
-                         Bitmap(extent={{-100,-100},{100,100}},
-          imageSource=
-              "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",
-          fileName="modelica://TIL/Images/Alpha.png")}), Documentation(info="<html>
-<p>
-  This partial model is the basis for the heat transfer correlation models. <br>
-</p>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 06, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-
-end PartialHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/package.mo
deleted file mode 100644
index f992a6f..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.HeatTransfer.HeatTransferPhenomena;
-package Partial
-  extends SorpLib.Internals.ClassTypes.PartialPackage;
-
-
-end Partial;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/package.order b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/package.order
deleted file mode 100644
index f1ce3c2..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Partial/package.order
+++ /dev/null
@@ -1 +0,0 @@
-PartialHeatTransfer
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/HeatTransferSilicaGel_Lanzerath2015.mo b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/HeatTransferSilicaGel_Lanzerath2015.mo
deleted file mode 100644
index ad0ab2f..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/HeatTransferSilicaGel_Lanzerath2015.mo
+++ /dev/null
@@ -1,25 +0,0 @@
-within SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Records;
-model HeatTransferSilicaGel_Lanzerath2015 "Heat transfer coefficient heat exchanger to adsorbent (Silica gel) (Lanzerath2015)"
-  extends SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha(final constantAlpha=686.7, final heatTransferArea=Modelica.Constants.pi*0.02086*7.355);
-
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    Documentation(info="<html>
-<p>
-  The heat transfer coefficient in this record was determined by Lanzerath et. al. (2015) for silica gel 123 particles.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end HeatTransferSilicaGel_Lanzerath2015;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/HeatTransferZeolith13X_Lanzerath2015.mo b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/HeatTransferZeolith13X_Lanzerath2015.mo
deleted file mode 100644
index 04d6d67..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/HeatTransferZeolith13X_Lanzerath2015.mo
+++ /dev/null
@@ -1,26 +0,0 @@
-within SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Records;
-model HeatTransferZeolith13X_Lanzerath2015
-  "Heat transfer coefficient heat exchanger to adsorbent (Silica gel) (Lanzerath2015)"
-  extends SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha(final constantAlpha=294.6, final heatTransferArea=Modelica.Constants.pi*0.02086*7.355);
-
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    Documentation(info="<html>
-<p>
-  The heat transfer coefficient in this record was determined by Lanzerath et. al. (2015) for zeolite 13 X particles.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end HeatTransferZeolith13X_Lanzerath2015;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/package.order b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/package.order
deleted file mode 100644
index 14a2e44..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/Records/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-HeatTransferSilicaGel_Lanzerath2015
-HeatTransferZeolith13X_Lanzerath2015
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/package.mo b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/package.mo
deleted file mode 100644
index 6863038..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/package.mo
+++ /dev/null
@@ -1,7 +0,0 @@
-within SorpLib.Components.HeatTransfer;
-package HeatTransferPhenomena
-extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-end HeatTransferPhenomena;
diff --git a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/package.order b/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/package.order
deleted file mode 100644
index e8a95d5..0000000
--- a/SorpLib/Components/HeatTransfer/HeatTransferPhenomena/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-ConstantAlpha
-ConstantAlphaA
-Partial
diff --git a/SorpLib/Components/HeatTransfer/OpenAdsorberHeatTransfer.mo b/SorpLib/Components/HeatTransfer/OpenAdsorberHeatTransfer.mo
new file mode 100644
index 0000000..86e086f
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/OpenAdsorberHeatTransfer.mo
@@ -0,0 +1,113 @@
+within SorpLib.Components.HeatTransfer;
+model OpenAdsorberHeatTransfer
+  "Model calculating a heat transfer describing heat transfer between gas and sorbent/casing within open adsorbers"
+  extends BaseClasses.PartialHeatTransfer(
+    final exponetTemperature=1,
+    redeclare replaceable model HeatTransferCoefficient =
+      SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.OpenAdsorber.ConstantAlpha
+      constrainedby
+      SorpLib.Components.HeatTransfer.BaseClasses.PartialOpenAdsorberHeatTransferCoefficient(
+      fluidProperties=fluidProperties,
+      m_hyd_xMinus=m_hyd_xMinus,
+      m_hyd_xPlus=m_hyd_xPlus,
+      geometry=geometry));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryOpenAdsorber geometry
+    constrainedby SorpLib.Components.HeatTransfer.Records.GeometryOpenAdsorber
+    "Geometry of the open adsorber"
+    annotation(Dialog(tab = "General", group = "Heat Transfer Coefficient",
+               enable=false));
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the sorbent)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Modelica.Units.SI.MassFlowRate m_hyd_xMinus
+    "Hydraulic mass flow rate at design inlet"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Modelica.Units.SI.MassFlowRate m_hyd_xPlus
+    "Hydraulic mass flow rate at design outlet"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The heat transfer model is used to describe the heat transfer between the gas
+and sorbent/casing within open adsorbers. Thus, the closed adsorber heat transfer 
+model represents a thermal resistance between two models. Depending on the attached 
+temperatures (i.e., attached potential) and the chosen transport phenomena, this 
+model determines the heat flow rate between the connected models. 
+<br/><br/>
+The model has two heat ports, which sizes can be defined via a parameter. The 
+scalable heat ports enable the connection of various models. For example, this 
+enables to connect a discretized model to a lumped model, or two different
+disretized models.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has steady-state energy balance:
+</p>
+<pre>
+    0 = &sum; (hp_a.Q_flow) + &sum; (hp_b.Q_flow);
+</pre>
+<p>
+The heat flow rate <i>Q_flow</i> is proportional to the driving temperature
+difference <i>&Delta;T = hp_a.T - hp_b.T</i> and the production of heat transfer
+coefficient and area <i>&alpha;A</i>, which can be formulated as thermal resistance
+<i>R<sub>openAdsorber</sub></i>. This product can be given as an input or calculated 
+using models describing heat transfer coefficient correlations.
+</p>
+<pre>
+    hp_a.Q_flow = &alpha;A * &Delta;T = 1 / R<sub>openAdsorber</sub> * (hp_a.T - hp_b.T);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  The number of ports a and b must be an even integer multiple of each other.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The open adsorber heat transfer is typically used to describe the heat transfer 
+between the gas and sorbent/casing within open adsorbers.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useAlphaAInput</i>:
+  Defines if the product of heat transfer coefficient and area is given via
+  an input or calculated using an approproate correlation model for the heat
+  transfer coefficient.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 23, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Text(
+          extent={{-60,20},{60,-20}},
+          lineColor={0,0,0},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47},
+          textString="Q_flow = 1/R_openAdsorber * DT")}));
+end OpenAdsorberHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/PoolBoilingHeatTransfer.mo b/SorpLib/Components/HeatTransfer/PoolBoilingHeatTransfer.mo
new file mode 100644
index 0000000..4502478
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/PoolBoilingHeatTransfer.mo
@@ -0,0 +1,111 @@
+within SorpLib.Components.HeatTransfer;
+model PoolBoilingHeatTransfer
+  "Model calculating a heat transfer describing pool boiling"
+  extends BaseClasses.PartialHeatTransfer(
+    final exponetTemperature=1,
+    redeclare replaceable model HeatTransferCoefficient =
+      SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolBoiling.ConstantAlpha
+      constrainedby
+      SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolBoilingHeatTransferCoefficient(
+      fluidProperties=fluidProperties,
+      f_relativeFillingLevel=f_relativeFillingLevel,
+      geometry=geometry));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryTube geometry
+    constrainedby SorpLib.Components.HeatTransfer.Records.GeometryTube
+    "Geometry of the heat exchanger tubes providing the heat flow rate for pool
+    boiling"
+    annotation(Dialog(tab = "General", group = "Heat Transfer Coefficient",
+               enable=false));
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the volume)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Real f_relativeFillingLevel(min=0, max=1, final unit="1")
+    "Relative filling level of the evaporator"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The heat transfer model is used to describe pool boiling by connection a phase
+seperator volume with a heat source/sink, such as a heat exchanger tube. Thus, 
+the pool boiling heat transfer model represents a thermal resistance betweed 
+two models. Depending on the attached temperatures (i.e., attached potential) 
+and the chosen transport phenomena, this model determines the heat flow rate 
+between the connected models. 
+<br/><br/>
+The model has two heat ports, which sizes can be defined via a parameter. The 
+scalable heat ports enable the connection of various models. For example, this 
+enables to connect a discretized model to a lumped model, or two different
+disretized models.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has steady-state energy balance:
+</p>
+<pre>
+    0 = &sum; (hp_a.Q_flow) + &sum; (hp_b.Q_flow);
+</pre>
+<p>
+The heat flow rate <i>Q_flow</i> is proportional to the driving temperature
+difference <i>&Delta;T = hp_a.T - hp_b.T</i> and the production of heat transfer
+coefficient and area <i>&alpha;A</i>, which can be formulated as thermal resistance
+<i>R<sub>boiling</sub></i>. This product can be given as an input or calculated using 
+models describing heat transfer coefficient correlations.
+</p>
+<pre>
+    hp_a.Q_flow = &alpha;A * &Delta;T = 1 / R<sub>boiling</sub> * (hp_a.T - hp_b.T);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  The number of ports a and b must be an even integer multiple of each other.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The pool boiling heat transfer is typically used to desribe the heat transfer 
+within an evaporator.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useAlphaAInput</i>:
+  Defines if the product of heat transfer coefficient and area is given via
+  an input or calculated using an approproate correlation model for the heat
+  transfer coefficient.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 17, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Text(
+          extent={{-60,20},{60,-20}},
+          lineColor={0,0,0},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47},
+          textString="Q_flow = 1/R_boiling * DT")}));
+end PoolBoilingHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/PoolCondensationHeatTransfer.mo b/SorpLib/Components/HeatTransfer/PoolCondensationHeatTransfer.mo
new file mode 100644
index 0000000..9685e01
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/PoolCondensationHeatTransfer.mo
@@ -0,0 +1,111 @@
+within SorpLib.Components.HeatTransfer;
+model PoolCondensationHeatTransfer
+  "Model calculating a heat transfer describing (pool) condensation"
+  extends BaseClasses.PartialHeatTransfer(
+    final exponetTemperature=1,
+    redeclare replaceable model HeatTransferCoefficient =
+      SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.PoolCondensation.ConstantAlpha
+      constrainedby
+      SorpLib.Components.HeatTransfer.BaseClasses.PartialPoolCondensationHeatTransferCoefficient(
+      fluidProperties=fluidProperties,
+      f_relativeFillingLevel=f_relativeFillingLevel,
+      geometry=geometry));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryTube geometry
+    constrainedby SorpLib.Components.HeatTransfer.Records.GeometryTube
+    "Geometry of the heat exchanger tubes providing the heat flow rate for (pool)
+    condensation"
+    annotation(Dialog(tab = "General", group = "Heat Transfer Coefficient",
+               enable=false));
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the volume)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Real f_relativeFillingLevel(min=0, max=1, final unit="1")
+    "Relative filling level of the condenser"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The heat transfer model is used to describe (pool) condensation by connection a phase
+seperator volume with a heat source/sink, such as a heat exchanger tube. Thus, 
+the pool condensation heat transfer model represents a thermal resistance betweed 
+two models. Depending on the attached temperatures (i.e., attached potential) 
+and the chosen transport phenomena, this model determines the heat flow rate 
+between the connected models. 
+<br/><br/>
+The model has two heat ports, which sizes can be defined via a parameter. The 
+scalable heat ports enable the connection of various models. For example, this 
+enables to connect a discretized model to a lumped model, or two different
+disretized models.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has steady-state energy balance:
+</p>
+<pre>
+    0 = &sum; (hp_a.Q_flow) + &sum; (hp_b.Q_flow);
+</pre>
+<p>
+The heat flow rate <i>Q_flow</i> is proportional to the driving temperature
+difference <i>&Delta;T = hp_a.T - hp_b.T</i> and the production of heat transfer
+coefficient and area <i>&alpha;A</i>, which can be formulated as thermal resistance
+<i>R<sub>condensation</sub></i>. This product can be given as an input or calculated using 
+models describing heat transfer coefficient correlations.
+</p>
+<pre>
+    hp_a.Q_flow = &alpha;A * &Delta;T = 1 / R<sub>condensation</sub> * (hp_a.T - hp_b.T);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  The number of ports a and b must be an even integer multiple of each other.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The (pool) condensation heat transfer is typically used to desribe the heat transfer 
+within a condenser.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useAlphaAInput</i>:
+  Defines if the product of heat transfer coefficient and area is given via
+  an input or calculated using an approproate correlation model for the heat
+  transfer coefficient.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 18, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Text(
+          extent={{-60,20},{60,-20}},
+          lineColor={0,0,0},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47},
+          textString="Q_flow = 1/R_condensation * DT")}));
+end PoolCondensationHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/RadiationHeatTransfer.mo b/SorpLib/Components/HeatTransfer/RadiationHeatTransfer.mo
new file mode 100644
index 0000000..360f104
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/RadiationHeatTransfer.mo
@@ -0,0 +1,87 @@
+within SorpLib.Components.HeatTransfer;
+model RadiationHeatTransfer
+  "Model calculating a radiation heat transfer"
+  extends BaseClasses.PartialHeatTransfer(
+    final exponetTemperature=4,
+    redeclare replaceable model HeatTransferCoefficient =
+      SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Radiation.ConstantResistance
+      constrainedby
+      SorpLib.Components.HeatTransfer.BaseClasses.PartialRadiationHeatTransferCoefficient);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The heat transfer model is used to thermally connect models which can exchange 
+heat due to thermal radiation. Thus, the radiation heat transfer model represents 
+a thermal resistance betweed two models. Depending on the attached temperatures (i.e., 
+attached potential) and the chosen transport phenomena, this model determines the 
+heat flow rate between the connected models. 
+<br/><br/>
+The model has two heat ports, which sizes can be defined via a parameter. The 
+scalable heat ports enable the connection of various models. For example, this 
+enables to connect a discretized model to a lumped model, or two different
+disretized models.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has steady-state energy balance:
+</p>
+<pre>
+    0 = &sum; (hp_a.Q_flow) + &sum; (hp_b.Q_flow);
+</pre>
+<p>
+The heat flow rate <i>Q_flow</i> is proportional to the driving temperature
+difference <i>&Delta;T = hp_a.T<sup>4</sup> - hp_b.T<sup>4</sup></i> and the production 
+of heat transfer coefficient and area <i>&alpha;A</i>, which can be formulated as 
+thermal resistance <i>R<sub>&sigma;</sub></i>. This product can be given as an input 
+or calculated using models describing heat transfer coefficient correlations.
+</p>
+<pre>
+    hp_a.Q_flow = &alpha;A * &Delta;T = 1 / R<sub>&sigma;</sub> * (hp_a.T<sup>4</sup> - hp_b.T<sup>4</sup>);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  The number of ports a and b must be an even integer multiple of each other.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The conductive heat transfer is typically used to desribe the heat transfer between
+two components.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useAlphaAInput</i>:
+  Defines if the product of heat transfer coefficient and area is given via
+  an input or calculated using an approproate correlation model for the heat
+  transfer coefficient.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 16, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Text(
+          extent={{-60,20},{60,-20}},
+          lineColor={0,0,0},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47},
+          textString="Q_flow = 1/R_sigma * DT")}));
+end RadiationHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Records/FluidProperties.mo b/SorpLib/Components/HeatTransfer/Records/FluidProperties.mo
new file mode 100644
index 0000000..02ed664
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Records/FluidProperties.mo
@@ -0,0 +1,38 @@
+within SorpLib.Components.HeatTransfer.Records;
+record FluidProperties
+  "This record contains fluid properties required for heat transfer coefficients"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of variables describing fluid properties
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T
+    "Temperature";
+  Modelica.Units.SI.Density rho
+    "Density";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Isobaric specific heat capacity";
+  Modelica.Units.SI.DynamicViscosity eta
+    "Dynamic viscosity";
+  Modelica.Units.SI.ThermalConductivity lambda
+    "Thermal conductivity";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains fluid properties required for heat transfer coefficients.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end FluidProperties;
diff --git a/SorpLib/Components/HeatTransfer/Records/GeometryClosedAdsorber.mo b/SorpLib/Components/HeatTransfer/Records/GeometryClosedAdsorber.mo
new file mode 100644
index 0000000..5a195e5
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Records/GeometryClosedAdsorber.mo
@@ -0,0 +1,22 @@
+within SorpLib.Components.HeatTransfer.Records;
+record GeometryClosedAdsorber
+  "This record contains the geometry required for heat transfer coefficients of closed adsorbers"
+  extends SorpLib.Components.HeatExchanger.Records.GeometryClosedAdsorber;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by models calculating the heat
+transfer coefficients of closed adsorbers.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryClosedAdsorber;
diff --git a/SorpLib/Components/HeatTransfer/Records/GeometryOpenAdsorber.mo b/SorpLib/Components/HeatTransfer/Records/GeometryOpenAdsorber.mo
new file mode 100644
index 0000000..e5ccba3
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Records/GeometryOpenAdsorber.mo
@@ -0,0 +1,222 @@
+within SorpLib.Components.HeatTransfer.Records;
+record GeometryOpenAdsorber
+  "This record contains the geometry required for heat transfer coefficients of open adsorbers"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters regarding the disretization
+  //
+  parameter Integer no_volumes(min=1) = 1
+    "Number of discretization volumes in flow direction"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+
+  //
+  // Definition of parameters regarding the geometry of the casing
+  //
+  parameter Modelica.Units.SI.Length l_cas = 1
+    "Length of the casing"
+    annotation (Dialog(tab="Casing", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_inner_cas = 0.15
+    "Inner diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer_cas = 0.16
+    "Outer diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Thickness t_wall_cas=
+    (d_outer_cas - d_inner_cas) / 2
+    "Wall thickness of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_crossInner_cas=
+    Modelica.Constants.pi/4 * d_inner_cas^2
+    "Inner cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter_cas=
+    Modelica.Constants.pi/4 * d_outer_cas^2
+    "Outer cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall_cas=
+    A_crossOuter_cas - A_crossInner_cas
+    "Wall cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferInner_cas=
+    Modelica.Constants.pi * d_inner_cas * l_cas
+    "Inner heat transfer area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter_cas=
+    Modelica.Constants.pi * d_outer_cas * l_cas
+    "Outer heat transfer area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_inner_cas=
+    Modelica.Constants.pi/4 * d_inner_cas * l_cas
+    "Inner volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer_cas=
+    Modelica.Constants.pi/4 * d_outer_cas * l_cas
+    "Outer volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall_cas=
+    V_outer_cas - V_inner_cas
+    "Wall volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_free_cas=
+    V_inner_cas - V_inner_hx - V_outer_hx - V_sorbent_hx
+    "Free volume (i.e., gas/vapor volume) of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+
+  //
+  // Definition of parameters regarding the general geometry of the heat exchanger
+  //
+  parameter Integer no_hydraulicParallelTubes(min=1) = 1
+    "Number of hydraulically parallel tubes"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+
+  parameter Modelica.Units.SI.Length l_hx = 0
+    "Length of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+
+  parameter Modelica.Units.SI.Length roughness_hx = 0
+    "Absolute roughness of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+
+  //
+  // Definition of parameters regarding diameters of the heat exchanger
+  //
+  parameter Modelica.Units.SI.Diameter d_inner_hx = 0
+    "Inner diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer_hx = 0
+    "Outer diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+
+  parameter Modelica.Units.SI.Diameter d_hydInner_hx = d_inner_hx
+    "Hydraulic inner diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydOuter_hx = d_outer_hx
+    "Hydraulic outer diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+
+  parameter Modelica.Units.SI.Thickness t_wall_hx=
+    (d_outer_hx - d_inner_hx) / 2
+    "Wall thickness of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+
+  //
+  // Definition of parameters regarding areas of the heat exchanger
+  //
+  parameter Modelica.Units.SI.Area A_crossInner_hx=
+    Modelica.Constants.pi/4 * d_inner_hx^2
+    "Inner cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter_hx=
+    Modelica.Constants.pi/4 * d_outer_hx^2
+    "Outer cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall_hx=
+    A_crossOuter_hx - A_crossInner_hx
+    "Wall cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  parameter Modelica.Units.SI.Area A_hydCrossInner_hx = A_crossInner_hx
+    "Hydraulic inner cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossOuter_hx = A_crossOuter_hx
+    "Hydraulic outer cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossWall_hx=
+    A_hydCrossOuter_hx - A_hydCrossInner_hx
+    "Hydraulic wall cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  parameter Modelica.Units.SI.Area A_heatTransferInner_hx=
+    Modelica.Constants.pi * d_inner_hx * l_hx
+    "Total inner heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter_hx=
+    Modelica.Constants.pi * d_outer_hx * l_hx
+    "Total outer heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  parameter Real f_finAreaRatioInner_hx(min=0, max=1) = 0
+    "Ratio of total inner fin area to total inner heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Real f_finAreaRatioOuter_hx(min=0, max=1) = 0
+    "Ratio of total outer fin area to total outer heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  //
+  // Definition of parameters regarding volumes of the heat exchanger
+  //
+  parameter Modelica.Units.SI.Volume V_inner_hx = A_crossInner_hx * l_hx
+    "Total inner volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer_hx = A_crossOuter_hx * l_hx
+    "Total outer volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall_hx = V_outer_hx - V_inner_hx
+    "Total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_sorbent_hx=
+    2.5 * V_wall_hx
+    "Available volume for sorbent particles of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+
+  parameter Real f_finVolumeRatioInner_hx(min=0, max=1) = 0
+    "Ratio of total inner fin volume to total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Real f_finVolumeRatioOuter_hx(min=0, max=1) = 0
+    "Ratio of total outer fin volume to total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+
+  //
+  // Definition of parameters regarding the sorbent gemeotry
+  //
+  parameter Real no_particles = (1-psi_particles) * V_inner_cas / V_particle
+    "Number of particles"
+    annotation (Dialog(tab="Sorbent", group="General"));
+  parameter Real psi_particles(unit="1") = 1 - 0.74
+    "Void fraction of the adsorber (i.e., ratio of the free fluid volume to
+    the total inner volume)"
+    annotation (Dialog(tab="Sorbent", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_particle = 0.7 / 1000
+    "Average diameter of the adsorbent particles"
+    annotation (Dialog(tab="Sorbent", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_cross_particle=
+    Modelica.Constants.pi/4 * d_particle^2
+    "Average cross-sectional area of the particle"
+    annotation (Dialog(tab="Sorbent", group="Areas"));
+  parameter Modelica.Units.SI.Area A_surface_particle=
+    Modelica.Constants.pi * d_particle^2
+    "Average suraface area of the particle"
+    annotation (Dialog(tab="Sorbent", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_particle=
+    Modelica.Constants.pi/6 * d_particle^3
+    "Average volume of the particle"
+    annotation (Dialog(tab="Sorbent", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_particles=
+    no_particles * V_particle
+    "Average volume of all particles"
+    annotation (Dialog(tab="Sorbent", group="Volumes"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by models calculating the heat
+transfer coefficients at the inside or outside of open adsorbers.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 23, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryOpenAdsorber;
diff --git a/SorpLib/Components/HeatTransfer/Records/GeometryTube.mo b/SorpLib/Components/HeatTransfer/Records/GeometryTube.mo
new file mode 100644
index 0000000..91d6f5e
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Records/GeometryTube.mo
@@ -0,0 +1,22 @@
+within SorpLib.Components.HeatTransfer.Records;
+record GeometryTube
+  "This record contains the geometry required for heat transfer coefficients of tubes"
+  extends SorpLib.Components.Tubes.Records.GeometryTube;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by models calculating the heat
+transfer coefficients at the inside or outside of tubes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 17, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryTube;
diff --git a/SorpLib/Components/HeatTransfer/Records/package.mo b/SorpLib/Components/HeatTransfer/Records/package.mo
new file mode 100644
index 0000000..d839bb4
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Records/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.HeatTransfer;
+package Records "Package containing records"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records. These records are used to cluster 
+variables and tidy up the model output.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Components/HeatTransfer/Records/package.order b/SorpLib/Components/HeatTransfer/Records/package.order
new file mode 100644
index 0000000..e3da090
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Records/package.order
@@ -0,0 +1,4 @@
+FluidProperties
+GeometryTube
+GeometryClosedAdsorber
+GeometryOpenAdsorber
diff --git a/SorpLib/Components/HeatTransfer/Tester/Test_ClosedAdsorberHeatTransfer.mo b/SorpLib/Components/HeatTransfer/Tester/Test_ClosedAdsorberHeatTransfer.mo
new file mode 100644
index 0000000..c04ef11
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/Test_ClosedAdsorberHeatTransfer.mo
@@ -0,0 +1,121 @@
+within SorpLib.Components.HeatTransfer.Tester;
+model Test_ClosedAdsorberHeatTransfer
+  "Tester for the heat transfer between sorbent and wall in closed adsorbers"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource heatSource(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true,
+    use_QFlowInput=false)
+    "Heat source for fluid volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=270,
+                origin={0,60})));
+
+  //
+  // Definition of heat transfer models
+  //
+  SorpLib.Components.HeatTransfer.ClosedAdsorberHeatTransfer heatTransfer(
+      redeclare model HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.ClosedAdsorber.LinearAlphaA (
+          constantAlphaA=500, b=2),                           fluidProperties=
+     SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=adsorbateVolume.adsorbateProperties.p,
+      T=adsorbateVolume.adsorbateProperties.T,
+      rho=1/adsorbateVolume.workingPair.medium_sorbent.state_variables.v,
+      cp=adsorbateVolume.workingPair.medium_sorbent.additional_variables.c,
+      eta=0,
+      lambda=adsorbateVolume.workingPair.medium_sorbent.additional_variables.lambda))
+    "Heat transfer model"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,40})));
+
+  //
+  // Definition of liquid volume models
+  //
+  Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume adsorbateVolume(
+    T_initial=373.15,
+    useHeatPorts=false,
+    useHeatPortsX=false,
+    geometry(V=Modelica.Constants.pi/4*0.1^2*1),
+    redeclare model PureWorkingPairModel =
+        Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl,
+        limitLowerPressure=true,
+        limitLowerPressureAdsorptive=true),
+    x_initial=0.05,
+    redeclare final package Medium = Medium)
+    "Model of an adsorbate volume"
+    annotation (Placement(transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=0,
+        origin={0,0})));
+
+  //
+  // Definition of thermal boundaries
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=50,
+    f=1/250,
+    offset=273.15 + 75) "Input for temperature"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={0,80})));
+
+equation
+  //
+  // Connections
+  //
+  connect(heatSource.port, heatTransfer.hp_b[1]) annotation (Line(
+      points={{0,60},{0,48}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer.hp_a[1], adsorbateVolume.hp_sorption) annotation (Line(
+      points={{0,32},{0,28},{3.2,28},{3.2,15.2}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_T.y, heatSource.T_input) annotation (Line(points={{0,69},{0,64},
+          {5.2,64},{5.2,61}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the heat transfer between sorbent and wall within closed 
+adsorbers.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 22, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ClosedAdsorberHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Tester/Test_ConductionHeatTransfer.mo b/SorpLib/Components/HeatTransfer/Tester/Test_ConductionHeatTransfer.mo
new file mode 100644
index 0000000..6bdd671
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/Test_ConductionHeatTransfer.mo
@@ -0,0 +1,354 @@
+within SorpLib.Components.HeatTransfer.Tester;
+model Test_ConductionHeatTransfer
+  "Tester for the conduction heat transfer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Pressure p = 1e5
+    "Constant pressure"
+    annotation (Dialog(tab="General", group="Case Study"));
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a1(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,30},{-50,50}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b1(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,30},{50,50}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a2(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,10},{-50,30}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b2(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,10},{50,30}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a3(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b3(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a4(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,-30},{-50,-10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b4(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,-30},{50,-10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a5(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,-50},{-50,-30}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b5(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,-50},{50,-30}})));
+
+  //
+  // Definition of heat transfer models
+  //
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_a1(redeclare model
+      HeatTransferCoefficient =
+      HeatTransferCoefficientCorrelations.Conduction.ConstantResistance,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall1.solidProperties.p,
+      T=wall1.solidProperties.T,
+      rho=1/wall1.solidProperties.v,
+      cp=wall1.solidProperties.c,
+      eta=0,
+      lambda=wall1.solidProperties.lambda))
+    "Heat transfer at heat source a"
+    annotation (Placement(transformation(extent={{-40,30},{-20,50}})));
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_b1(redeclare model
+      HeatTransferCoefficient =
+      HeatTransferCoefficientCorrelations.Conduction.ConstantResistance,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall1.solidProperties.p,
+      T=wall1.solidProperties.T,
+      rho=1/wall1.solidProperties.v,
+      cp=wall1.solidProperties.c,
+      eta=0,
+      lambda=wall1.solidProperties.lambda))
+    "Heat transfer at heat source b"
+    annotation (Placement(transformation(extent={{20,30},{40,50}})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_a2(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.ConstantPlainWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall2.solidProperties.p,
+      T=wall2.solidProperties.T,
+      rho=1/wall2.solidProperties.v,
+      cp=wall2.solidProperties.c,
+      eta=0,
+      lambda=wall2.solidProperties.lambda))
+    "Heat transfer at heat source a"
+    annotation (Placement(transformation(extent={{-40,10},{-20,30}})));
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_b2(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.ConstantPlainWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall2.solidProperties.p,
+      T=wall2.solidProperties.T,
+      rho=1/wall2.solidProperties.v,
+      cp=wall2.solidProperties.c,
+      eta=0,
+      lambda=wall2.solidProperties.lambda))
+    "Heat transfer at heat source b"
+    annotation (Placement(transformation(extent={{20,10},{40,30}})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_a3(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.ConstantCylindricalWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall3.solidProperties.p,
+      T=wall3.solidProperties.T,
+      rho=1/wall3.solidProperties.v,
+      cp=wall3.solidProperties.c,
+      eta=0,
+      lambda=wall3.solidProperties.lambda))
+    "Heat transfer at heat source a"
+    annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_b3(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.ConstantCylindricalWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall3.solidProperties.p,
+      T=wall3.solidProperties.T,
+      rho=1/wall3.solidProperties.v,
+      cp=wall3.solidProperties.c,
+      eta=0,
+      lambda=wall3.solidProperties.lambda))
+    "Heat transfer at heat source b"
+    annotation (Placement(transformation(extent={{20,-10},{40,10}})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_a4(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.PlainWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall4.solidProperties.p,
+      T=wall4.solidProperties.T,
+      rho=1/wall4.solidProperties.v,
+      cp=wall4.solidProperties.c,
+      eta=0,
+      lambda=wall4.solidProperties.lambda))
+    "Heat transfer at heat source a"
+    annotation (Placement(transformation(extent={{-40,-30},{-20,-10}})));
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_b4(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.PlainWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall4.solidProperties.p,
+      T=wall4.solidProperties.T,
+      rho=1/wall4.solidProperties.v,
+      cp=wall4.solidProperties.c,
+      eta=0,
+      lambda=wall4.solidProperties.lambda))
+    "Heat transfer at heat source b"
+    annotation (Placement(transformation(extent={{20,-30},{40,-10}})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_a5(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.CylindricalWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall5.solidProperties.p,
+      T=wall5.solidProperties.T,
+      rho=1/wall5.solidProperties.v,
+      cp=wall5.solidProperties.c,
+      eta=0,
+      lambda=wall5.solidProperties.lambda))
+    "Heat transfer at heat source a"
+    annotation (Placement(transformation(extent={{-40,-50},{-20,-30}})));
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_b5(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.CylindricalWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall5.solidProperties.p,
+      T=wall5.solidProperties.T,
+      rho=1/wall5.solidProperties.v,
+      cp=wall5.solidProperties.c,
+      eta=0,
+      lambda=wall5.solidProperties.lambda))
+    "Heat transfer at heat source b"
+    annotation (Placement(transformation(extent={{20,-50},{40,-30}})));
+
+  //
+  // Definition of wall models
+  //
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wall1(
+    solidMedium(approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+        approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction),
+    T_initial=298.15,
+    p=p) "Wall model"
+    annotation (Placement(transformation(extent={{-10,30},{10,50}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wall2(
+    solidMedium(approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+        approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction),
+    T_initial=298.15,
+    p=p) "Wall model"
+    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wall3(
+    solidMedium(approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+        approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction),
+    T_initial=298.15,
+    p=p) "Wall model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wall4(
+    solidMedium(approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+        approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction),
+    T_initial=298.15,
+    p=p) "Wall model"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wall5(
+    solidMedium(approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+        approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction),
+    T_initial=298.15,
+    p=p) "Wall model"
+    annotation (Placement(transformation(extent={{-10,-50},{10,-30}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_T_a(
+    amplitude=50,
+    f=1/250,
+    offset=273.15 + 50)
+    "Input signal for temperature at sources a"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+  Modelica.Blocks.Sources.Trapezoid input_T_b(
+    amplitude=100,
+    rising=50,
+    width=100,
+    falling=50,
+    period=250,
+    offset=273.15)
+    "Input signal for temperature at sources b"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(hs_a1.port, ht_a1.hp_a[1]) annotation (Line(
+      points={{-60,40},{-38,40}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_a1.hp_b[1], wall1.hp_xMinus) annotation (Line(
+      points={{-22,40},{-6,40}},
+      color={238,46,47},
+      thickness=1));
+  connect(wall1.hp_xPlus, ht_b1.hp_a[1]) annotation (Line(
+      points={{6,40},{22,40}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_b1.hp_b[1], hs_b1.port) annotation (Line(
+      points={{38,40},{60,40}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a2.port, ht_a2.hp_a[1]) annotation (Line(
+      points={{-60,20},{-38,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_a2.hp_b[1], wall2.hp_xMinus) annotation (Line(
+      points={{-22,20},{-6,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(wall2.hp_xPlus, ht_b2.hp_a[1]) annotation (Line(
+      points={{6,20},{22,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_b2.hp_b[1], hs_b2.port) annotation (Line(
+      points={{38,20},{60,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a3.port, ht_a3.hp_a[1]) annotation (Line(
+      points={{-60,0},{-38,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_a3.hp_b[1], wall3.hp_xMinus) annotation (Line(
+      points={{-22,0},{-6,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(wall3.hp_xPlus, ht_b3.hp_a[1]) annotation (Line(
+      points={{6,0},{22,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_b3.hp_b[1], hs_b3.port) annotation (Line(
+      points={{38,0},{60,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a4.port, ht_a4.hp_a[1]) annotation (Line(
+      points={{-60,-20},{-38,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_a4.hp_b[1], wall4.hp_xMinus) annotation (Line(
+      points={{-22,-20},{-6,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(wall4.hp_xPlus, ht_b4.hp_a[1]) annotation (Line(
+      points={{6,-20},{22,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_b4.hp_b[1], hs_b4.port) annotation (Line(
+      points={{38,-20},{60,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a5.port, ht_a5.hp_a[1]) annotation (Line(
+      points={{-60,-40},{-38,-40}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_a5.hp_b[1], wall5.hp_xMinus) annotation (Line(
+      points={{-22,-40},{-6,-40}},
+      color={238,46,47},
+      thickness=1));
+  connect(wall5.hp_xPlus, ht_b5.hp_a[1]) annotation (Line(
+      points={{6,-40},{22,-40}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_b5.hp_b[1], hs_b5.port) annotation (Line(
+      points={{38,-40},{60,-40}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_T_a.y, hs_a1.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,45.2},{-61,45.2}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b1.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          45.2},{61,45.2}}, color={0,0,127}));
+  connect(input_T_a.y, hs_a2.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,25.2},{-61,25.2}}, color={0,0,127}));
+  connect(input_T_a.y, hs_a3.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,5.2},{-61,5.2}}, color={0,0,127}));
+  connect(input_T_a.y, hs_a4.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,-14.8},{-61,-14.8}}, color={0,0,127}));
+  connect(input_T_a.y, hs_a5.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,-34.8},{-61,-34.8}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b2.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          25.2},{61,25.2}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b3.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          5.2},{61,5.2}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b4.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          -14.8},{61,-14.8}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b5.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          -34.8},{61,-34.8}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the conduction heat transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 15, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ConductionHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Tester/Test_GenericHeatTransfer.mo b/SorpLib/Components/HeatTransfer/Tester/Test_GenericHeatTransfer.mo
new file mode 100644
index 0000000..ba2edc1
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/Test_GenericHeatTransfer.mo
@@ -0,0 +1,184 @@
+within SorpLib.Components.HeatTransfer.Tester;
+model Test_GenericHeatTransfer
+  "Tester for the generic heat transfer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a1(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,30},{-50,50}})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b1(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,30},{50,50}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a2(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,10},{-50,30}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b2(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,10},{50,30}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a3(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b3(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a4(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,-30},{-50,-10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b4(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,-30},{50,-10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a5(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,-50},{-50,-30}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b5(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,-50},{50,-30}})));
+
+  //
+  // Definition of heat transfer models
+  //
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_1(
+    redeclare model HeatTransferCoefficient =
+      HeatTransferCoefficientCorrelations.Generic.ConstantAlpha (
+        constantAlpha=25, A=1))
+    "Heat transfer model 1"
+    annotation (Placement(transformation(extent={{-10,30},{10,50}})));
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_2(redeclare
+      model HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA (
+          constantAlphaA=25))
+    "Heat transfer model 2"
+    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_3(redeclare
+      model HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Generic.LinearAlphaA (
+          constantAlphaA=25, b=0.1))
+    "Heat transfer model 3"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_4(redeclare
+      model HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Generic.ExponentialAlphaA (
+        constantAlphaA=25,
+        b=0.5,
+        c=1/273.15))
+    "Heat transfer model 4"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_5(redeclare
+      model HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Generic.PolynomialAlphaA (
+        constantAlphaA=25,
+        b=0.5,
+        c=1/3))
+    "Heat transfer model 5"
+    annotation (Placement(transformation(extent={{-10,-50},{10,-30}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_T_a(
+    amplitude=50,
+    f=1/250,
+    offset=273.15 + 50)
+    "Input signal for temperature at sources a"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+  Modelica.Blocks.Sources.Trapezoid input_T_b(
+    amplitude=100,
+    rising=50,
+    width=100,
+    falling=50,
+    period=250,
+    offset=273.15)
+    "Input signal for temperature at sources b"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(hs_a1.port, heatTransfer_1.hp_a[1]) annotation (Line(
+      points={{-60,40},{-8,40}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_1.hp_b[1], hs_b1.port) annotation (Line(
+      points={{8,40},{60,40}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a2.port, heatTransfer_2.hp_a[1]) annotation (Line(
+      points={{-60,20},{-8,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_2.hp_b[1], hs_b2.port) annotation (Line(
+      points={{8,20},{60,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a3.port, heatTransfer_3.hp_a[1]) annotation (Line(
+      points={{-60,0},{-8,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_3.hp_b[1], hs_b3.port) annotation (Line(
+      points={{8,0},{60,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a4.port, heatTransfer_4.hp_a[1]) annotation (Line(
+      points={{-60,-20},{-8,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_4.hp_b[1], hs_b4.port) annotation (Line(
+      points={{8,-20},{60,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a5.port, heatTransfer_5.hp_a[1]) annotation (Line(
+      points={{-60,-40},{-8,-40}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_5.hp_b[1], hs_b5.port) annotation (Line(
+      points={{8,-40},{60,-40}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_T_a.y, hs_a1.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,45.2},{-61,45.2}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b1.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          45.2},{61,45.2}}, color={0,0,127}));
+  connect(input_T_a.y, hs_a2.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,25.2},{-61,25.2}}, color={0,0,127}));
+  connect(input_T_a.y, hs_a3.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,5.2},{-61,5.2}}, color={0,0,127}));
+  connect(input_T_a.y, hs_a4.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,-14.8},{-61,-14.8}}, color={0,0,127}));
+  connect(input_T_a.y, hs_a5.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,-34.8},{-61,-34.8}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b2.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          25.2},{61,25.2}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b3.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          5.2},{61,5.2}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b4.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          -14.8},{61,-14.8}}, color={0,0,127}));
+  connect(input_T_b.y, hs_b5.T_input) annotation (Line(points={{79,0},{70,0},{70,
+          -34.8},{61,-34.8}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the generic heat transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 12, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GenericHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Tester/Test_OpenAdsorberHeatTransfer.mo b/SorpLib/Components/HeatTransfer/Tester/Test_OpenAdsorberHeatTransfer.mo
new file mode 100644
index 0000000..3fe572e
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/Test_OpenAdsorberHeatTransfer.mo
@@ -0,0 +1,183 @@
+within SorpLib.Components.HeatTransfer.Tester;
+model Test_OpenAdsorberHeatTransfer
+  "Tester for the heat transfer between gas and sorbent/casing in open adsorbers"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture
+    "Medium model"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_inlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=323.15,
+    redeclare final package Medium = Medium)
+    "Inlet fluid source"
+    annotation (Placement(transformation(extent={{-50,-10},{-30,10}})));
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_outlet(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    T_fixed=373.15,
+    redeclare final package Medium = Medium)
+    "Outlet fluid source"
+    annotation (Placement(transformation(extent={{30,-10},{50,10}})));
+
+  //
+  // Definition of heat transfer models
+  //
+  SorpLib.Components.HeatTransfer.OpenAdsorberHeatTransfer heatTransfer_gasCasing(
+    redeclare model HeatTransferCoefficient =
+      HeatTransferCoefficientCorrelations.OpenAdsorber.CasingGasKast,
+    fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=gasVolume.fluidProperties.p,
+      T=gasVolume.fluidProperties.T,
+      rho=1/gasVolume.fluidProperties.v,
+      cp=gasVolume.fluidProperties.cp,
+      eta=gasVolume.fluidProperties.eta,
+      lambda=gasVolume.fluidProperties.lambda),
+      m_hyd_xMinus=gasVolume.fluidProperties.mc_flow_xMinus,
+      m_hyd_xPlus=gasVolume.fluidProperties.mc_flow_xPlus)
+    "Heat transfer model between gas and casing" annotation (Placement(
+        transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,32})));
+
+  SorpLib.Components.HeatTransfer.OpenAdsorberHeatTransfer heatTransfer_gasSorbent(
+    redeclare model HeatTransferCoefficient =
+      HeatTransferCoefficientCorrelations.OpenAdsorber.CasingSorbentKast,
+    fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=gasVolume.fluidProperties.p,
+      T=gasVolume.fluidProperties.T,
+      rho=1/gasVolume.fluidProperties.v,
+      cp=gasVolume.fluidProperties.cp,
+      eta=gasVolume.fluidProperties.eta,
+      lambda=gasVolume.fluidProperties.lambda),
+      m_hyd_xMinus=gasVolume.fluidProperties.mc_flow_xMinus,
+      m_hyd_xPlus=gasVolume.fluidProperties.mc_flow_xPlus)
+    "Heat transfer model between gas and sorbent" annotation (Placement(
+        transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,-32})));
+
+  //
+  // Definition of volume models
+  //
+  SorpLib.Basics.Volumes.AdsorbateVolumes.AdsorbatePureGasVolume adsorbateVolume(
+    T_initial=323.15,
+    useHeatPorts=false,
+    useHeatPortsX=false,
+    geometry(V=(1-heatTransfer_gasSorbent.geometry.psi_particles)*heatTransfer_gasSorbent.geometry.V_inner_cas),
+    redeclare model PureWorkingPairModel =
+        Media.WorkingPairs.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010_Gas,
+    x_initial=0.05)
+    "Model of an adsorbate volume"
+    annotation (Placement(transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=0,
+        origin={0,-70})));
+
+  SorpLib.Basics.Volumes.FluidVolumes.GasVaporMixtureVolume gasVolume(
+    geometry(V=heatTransfer_gasSorbent.geometry.V_free_cas),
+    calculateAdditionalProperties=true,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFreeInitial,
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1,
+    redeclare final package Medium = Medium)
+    "Model of the gas volume"
+    annotation (Placement(transformation(extent={{-20,-20},{20,20}})));
+
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wallVolume(
+    p = gasVolume.fluidProperties.p,
+    T_initial=323.15,
+    useHeatPortsX=false,
+    useHeatPortsY=true,
+    geometry(V=heatTransfer_gasSorbent.geometry.V_wall_cas))
+    "Model of the wall volume"
+    annotation (Placement(
+        transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=0,
+        origin={0,70})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow(
+    amplitude=1,
+    f=1/250,
+    startTime=250) "Input for mass flow rate" annotation (Placement(
+        transformation(
+        extent={{10,10},{-10,-10}},
+        rotation=180,
+        origin={-70,0})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_inlet.port, gasVolume.cfp_xMinus[1]) annotation (Line(
+      points={{-40,0},{-30,0},{-30,3.6},{-8.4,3.6}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_outlet.port, gasVolume.cfp_xPlus[1]) annotation (Line(
+      points={{40,0},{30,0},{30,3.6},{15.6,3.6}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(wallVolume.hp_yMinus, heatTransfer_gasCasing.hp_b[1]) annotation (
+      Line(
+      points={{0,58},{0,40}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_gasCasing.hp_a[1], gasVolume.hp_yPlus) annotation (Line(
+      points={{0,24},{0,12}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_gasSorbent.hp_a[1], gasVolume.hp_sorption) annotation (
+      Line(
+      points={{0,-24},{0,-20},{3.2,-20},{3.2,-8.8}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_gasSorbent.hp_b[1], adsorbateVolume.hp_sorption)
+    annotation (Line(
+      points={{0,-40},{0,-44},{3.2,-44},{3.2,-54.8}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_mFlow.y, fs_inlet.m_flow_input) annotation (Line(points={{-59,0},
+          {-50,0},{-50,2},{-41.2,2}}, color={0,0,127}));
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the heat transfer between gas and sorbent/casing within 
+open adsorbers.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 23, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_OpenAdsorberHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Tester/Test_PoolBoilingHeatTransfer.mo b/SorpLib/Components/HeatTransfer/Tester/Test_PoolBoilingHeatTransfer.mo
new file mode 100644
index 0000000..104919e
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/Test_PoolBoilingHeatTransfer.mo
@@ -0,0 +1,173 @@
+within SorpLib.Components.HeatTransfer.Tester;
+model Test_PoolBoilingHeatTransfer
+  "Tester for the pool boiling heat transfer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the VLE liquid"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource liquidInlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    m_flow_fixed=-0.001,
+    h_fixed=0.5e6,
+    redeclare package Medium = Medium)
+    "Liquid inlet for phase seprator volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=90,
+                origin={0,-40})));
+  SorpLib.Basics.Sources.Fluids.VLESource vaporInlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    m_flow_fixed=1e-3,
+    h_fixed=1e-6,
+    redeclare package Medium = Medium)
+    "Vapor inlet for phase separator"
+    annotation (Placement(transformation(
+                extent={{10,-10},{-10,10}},
+                rotation=90,
+                origin={0,40})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource heatSource(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true,
+    use_QFlowInput=false)
+    "Heat source for phase seperator volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=180,
+                origin={60,0})));
+
+  //
+  // Definition of heat transfer models
+  //
+  SorpLib.Components.HeatTransfer.PoolBoilingHeatTransfer heatTransfer(
+    redeclare model HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.PoolBoiling.LinearAlphaA_fRel,
+    fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=phaseSeparator.p,
+        T=phaseSeparator.T,
+        rho=phaseSeparator.rho,
+        cp=phaseSeparator.phaseSepratorProperties.cp,
+        eta=phaseSeparator.phaseSepratorProperties.eta,
+        lambda=phaseSeparator.phaseSepratorProperties.lambda),
+    f_relativeFillingLevel=phaseSeparator.l_liq_rel) "Heat transfer model"
+    annotation (Placement(transformation(extent={{30,-10},{50,10}})));
+
+  //
+  // Definition of VLE models
+  //
+  SorpLib.Basics.Volumes.PhaseSeparatorVolumes.PhaseSeparatorVolume
+    phaseSeparator(
+    T_initial=293.15,
+    rho_initial=500,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    calculateAdditionalProperties=true,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium,
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1) "Model of a phase seperator volume" annotation (
+      Placement(transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={0,0})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_liquidPort(
+    amplitude=-0.0001,
+    rising=250,
+    width=400,
+    falling=250,
+    period=950,
+    startTime=50)
+    "Input for liquid port boundary"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={-30,-70})));
+  Modelica.Blocks.Sources.Ramp input_vaporPort(
+    height=0.0001,
+    duration=250,
+    startTime=500)
+    "Input for vapor Port"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={-30,70})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  Modelica.Blocks.Sources.Ramp input_T(
+    height=50,
+    duration=1500,
+    offset=273.15 + 25,
+    startTime=500) "Input for temperature" annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=0,
+        origin={80,0})));
+
+equation
+  //
+  // Connections
+  //
+  connect(liquidInlet.port, phaseSeparator.cfp_xMinus[1]) annotation (Line(
+      points={{0,-40},{0,-8.4},{-3.6,-8.4}},
+      color={0,140,72},
+      thickness=1));
+  connect(vaporInlet.port, phaseSeparator.cfp_xPlus[1]) annotation (Line(
+      points={{0,40},{0,15.6},{-3.6,15.6}},
+      color={0,140,72},
+      thickness=1));
+  connect(heatSource.port, heatTransfer.hp_b[1]) annotation (Line(
+      points={{60,0},{48,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer.hp_a[1], phaseSeparator.hp_yMinus) annotation (Line(
+      points={{32,0},{12,0}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_liquidPort.y, liquidInlet.m_flow_input)
+    annotation (Line(points={{-19,-70},{-2,-70},{-2,-41.2}}, color={0,0,127}));
+  connect(input_vaporPort.y,vaporInlet. m_flow_input)
+    annotation (Line(points={{-19,70},{-2,70},{-2,41.2}}, color={0,0,127}));
+  connect(input_T.y, heatSource.T_input) annotation (Line(points={{69,0},{66,0},
+          {66,-5.2},{61,-5.2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the pool boiling heat transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 17, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_PoolBoilingHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Tester/Test_PoolCondensationHeatTransfer.mo b/SorpLib/Components/HeatTransfer/Tester/Test_PoolCondensationHeatTransfer.mo
new file mode 100644
index 0000000..18ca44a
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/Test_PoolCondensationHeatTransfer.mo
@@ -0,0 +1,173 @@
+within SorpLib.Components.HeatTransfer.Tester;
+model Test_PoolCondensationHeatTransfer
+  "Tester for the pool condensation heat transfer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the VLE liquid"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource liquidInlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    m_flow_fixed=-0.001,
+    h_fixed=0.5e6,
+    redeclare package Medium = Medium)
+    "Liquid inlet for phase seprator volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=90,
+                origin={0,-40})));
+  SorpLib.Basics.Sources.Fluids.VLESource vaporInlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.SpecificEnthalpy,
+    use_mFlowInput=true,
+    m_flow_fixed=1e-3,
+    h_fixed=1e-6,
+    redeclare package Medium = Medium)
+    "Vapor inlet for phase separator"
+    annotation (Placement(transformation(
+                extent={{10,-10},{-10,10}},
+                rotation=90,
+                origin={0,40})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource heatSource(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true,
+    use_QFlowInput=false)
+    "Heat source for phase seprator volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=180,
+                origin={60,0})));
+
+  //
+  // Definition of heat transfer models
+  //
+  SorpLib.Components.HeatTransfer.PoolCondensationHeatTransfer heatTransfer(
+    redeclare model HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.PoolCondensation.LinearAlphaA_fRel,
+    fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=phaseSeparator.p,
+        T=phaseSeparator.T,
+        rho=phaseSeparator.rho,
+        cp=phaseSeparator.phaseSepratorProperties.cp,
+        eta=phaseSeparator.phaseSepratorProperties.eta,
+        lambda=phaseSeparator.phaseSepratorProperties.lambda),
+    f_relativeFillingLevel=phaseSeparator.l_liq_rel) "Heat transfer model"
+    annotation (Placement(transformation(extent={{30,-10},{50,10}})));
+
+  //
+  // Definition of VLE models
+  //
+  SorpLib.Basics.Volumes.PhaseSeparatorVolumes.PhaseSeparatorVolume
+    phaseSeparator(
+    T_initial=348.15,
+    rho_initial=500,
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    calculateAdditionalProperties=true,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare final package Medium = Medium,
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1) "Model of a phase seperator volume" annotation (
+      Placement(transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={0,0})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_liquidPort(
+    amplitude=-0.0001,
+    rising=250,
+    width=400,
+    falling=250,
+    period=950,
+    startTime=50)
+    "Input for liquid port boundary"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={-30,-70})));
+  Modelica.Blocks.Sources.Ramp input_vaporPort(
+    height=0.0001,
+    duration=250,
+    startTime=500)
+    "Input for vapor Port"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={-30,70})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  Modelica.Blocks.Sources.Ramp input_T(
+    height=-50,
+    duration=1500,
+    offset=273.15 + 75,
+    startTime=500) "Input for temperature" annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=0,
+        origin={80,0})));
+
+equation
+  //
+  // Connections
+  //
+  connect(liquidInlet.port, phaseSeparator.cfp_xMinus[1]) annotation (Line(
+      points={{0,-40},{0,-8.4},{-3.6,-8.4}},
+      color={0,140,72},
+      thickness=1));
+  connect(vaporInlet.port, phaseSeparator.cfp_xPlus[1]) annotation (Line(
+      points={{0,40},{0,15.6},{-3.6,15.6}},
+      color={0,140,72},
+      thickness=1));
+  connect(heatSource.port, heatTransfer.hp_b[1]) annotation (Line(
+      points={{60,0},{48,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer.hp_a[1], phaseSeparator.hp_yMinus) annotation (Line(
+      points={{32,0},{12,0}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_liquidPort.y, liquidInlet.m_flow_input)
+    annotation (Line(points={{-19,-70},{-2,-70},{-2,-41.2}}, color={0,0,127}));
+  connect(input_vaporPort.y,vaporInlet. m_flow_input)
+    annotation (Line(points={{-19,70},{-2,70},{-2,41.2}}, color={0,0,127}));
+  connect(input_T.y, heatSource.T_input) annotation (Line(points={{69,0},{66,0},
+          {66,-5.2},{61,-5.2}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the pool condensation heat transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 18, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_PoolCondensationHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Tester/Test_RadiationHeatTransfer.mo b/SorpLib/Components/HeatTransfer/Tester/Test_RadiationHeatTransfer.mo
new file mode 100644
index 0000000..39adc73
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/Test_RadiationHeatTransfer.mo
@@ -0,0 +1,242 @@
+within SorpLib.Components.HeatTransfer.Tester;
+model Test_RadiationHeatTransfer "Tester for the radiation heat transfer"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Pressure p = 1e5
+    "Constant pressure"
+    annotation (Dialog(tab="General", group="Case Study"));
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a1(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,10},{-50,30}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b1(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,10},{50,30}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a2(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b2(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_a3(use_TInput=true)
+    "Heat source a"
+    annotation (Placement(transformation(extent={{-70,-30},{-50,-10}})));
+  SorpLib.Basics.Sources.Thermal.HeatSource hs_b3(use_TInput=true)
+    "Heat source b"
+    annotation (Placement(transformation(extent={{70,-30},{50,-10}})));
+
+  //
+  // Definition of heat transfer models
+  //
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_a1(redeclare model
+      HeatTransferCoefficient =
+      HeatTransferCoefficientCorrelations.Conduction.ConstantResistance,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall1.solidProperties.p,
+      T=wall1.solidProperties.T,
+      rho=1/wall1.solidProperties.v,
+      cp=wall1.solidProperties.c,
+      eta=0,
+      lambda=wall1.solidProperties.lambda))
+    "Heat transfer at heat source a"
+    annotation (Placement(transformation(extent={{-40,10},{-20,30}})));
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_b1(redeclare model
+      HeatTransferCoefficient =
+      HeatTransferCoefficientCorrelations.Conduction.ConstantResistance,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall1.solidProperties.p,
+      T=wall1.solidProperties.T,
+      rho=1/wall1.solidProperties.v,
+      cp=wall1.solidProperties.c,
+      eta=0,
+      lambda=wall1.solidProperties.lambda))
+    "Heat transfer at heat source b"
+    annotation (Placement(transformation(extent={{20,10},{40,30}})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_a2(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.ConstantPlainWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall2.solidProperties.p,
+      T=wall2.solidProperties.T,
+      rho=1/wall2.solidProperties.v,
+      cp=wall2.solidProperties.c,
+      eta=0,
+      lambda=wall2.solidProperties.lambda))
+    "Heat transfer at heat source a"
+    annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_b2(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.ConstantPlainWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall2.solidProperties.p,
+      T=wall2.solidProperties.T,
+      rho=1/wall2.solidProperties.v,
+      cp=wall2.solidProperties.c,
+      eta=0,
+      lambda=wall2.solidProperties.lambda))
+    "Heat transfer at heat source b"
+    annotation (Placement(transformation(extent={{20,-10},{40,10}})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_a3(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.ConstantCylindricalWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall3.solidProperties.p,
+      T=wall3.solidProperties.T,
+      rho=1/wall3.solidProperties.v,
+      cp=wall3.solidProperties.c,
+      eta=0,
+      lambda=wall3.solidProperties.lambda))
+    "Heat transfer at heat source a"
+    annotation (Placement(transformation(extent={{-40,-30},{-20,-10}})));
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer ht_b3(redeclare model
+      HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.Conduction.ConstantCylindricalWall,
+      fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=wall3.solidProperties.p,
+      T=wall3.solidProperties.T,
+      rho=1/wall3.solidProperties.v,
+      cp=wall3.solidProperties.c,
+      eta=0,
+      lambda=wall3.solidProperties.lambda))
+    "Heat transfer at heat source b"
+    annotation (Placement(transformation(extent={{20,-30},{40,-10}})));
+
+  //
+  // Definition of wall models
+  //
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wall1(
+    solidMedium(approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+        approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction),
+    T_initial=298.15,
+    p=p) "Wall model"
+    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wall2(
+    solidMedium(approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+        approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction),
+    T_initial=298.15,
+    p=p) "Wall model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+  SorpLib.Basics.Volumes.SolidVolumes.SolidVolume wall3(
+    solidMedium(approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+        approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction),
+    T_initial=298.15,
+    p=p) "Wall model"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_T_a(
+    amplitude=50,
+    f=1/250,
+    offset=273.15 + 50)
+    "Input signal for temperature at sources a"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+  Modelica.Blocks.Sources.Trapezoid input_T_b(
+    amplitude=100,
+    rising=50,
+    width=100,
+    falling=50,
+    period=250,
+    offset=273.15)
+    "Input signal for temperature at sources b"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(hs_a1.port, ht_a1.hp_a[1]) annotation (Line(
+      points={{-60,20},{-38,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_a1.hp_b[1], wall1.hp_xMinus) annotation (Line(
+      points={{-22,20},{-6,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(wall1.hp_xPlus, ht_b1.hp_a[1]) annotation (Line(
+      points={{6,20},{22,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_b1.hp_b[1], hs_b1.port) annotation (Line(
+      points={{38,20},{60,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a2.port, ht_a2.hp_a[1]) annotation (Line(
+      points={{-60,0},{-38,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_a2.hp_b[1], wall2.hp_xMinus) annotation (Line(
+      points={{-22,0},{-6,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(wall2.hp_xPlus, ht_b2.hp_a[1]) annotation (Line(
+      points={{6,0},{22,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_b2.hp_b[1], hs_b2.port) annotation (Line(
+      points={{38,0},{60,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(hs_a3.port, ht_a3.hp_a[1]) annotation (Line(
+      points={{-60,-20},{-38,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_a3.hp_b[1], wall3.hp_xMinus) annotation (Line(
+      points={{-22,-20},{-6,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(wall3.hp_xPlus, ht_b3.hp_a[1]) annotation (Line(
+      points={{6,-20},{22,-20}},
+      color={238,46,47},
+      thickness=1));
+  connect(ht_b3.hp_b[1], hs_b3.port) annotation (Line(
+      points={{38,-20},{60,-20}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_T_a.y, hs_a1.T_input) annotation (Line(points={{-79,0},{-70,0},
+          {-70,25.2},{-61,25.2}},color={0,0,127}));
+  connect(input_T_b.y, hs_b1.T_input) annotation (Line(points={{79,0},{70,0},{
+          70,25.2},{61,25.2}},
+                            color={0,0,127}));
+  connect(input_T_a.y, hs_a2.T_input) annotation (Line(points={{-79,0},{-70,0},
+          {-70,5.2},{-61,5.2}},  color={0,0,127}));
+  connect(input_T_a.y, hs_a3.T_input) annotation (Line(points={{-79,0},{-70,0},
+          {-70,-14.8},{-61,-14.8}},
+                               color={0,0,127}));
+  connect(input_T_b.y, hs_b2.T_input) annotation (Line(points={{79,0},{70,0},{
+          70,5.2},{61,5.2}},color={0,0,127}));
+  connect(input_T_b.y, hs_b3.T_input) annotation (Line(points={{79,0},{70,0},{
+          70,-14.8},{61,-14.8}},
+                          color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the radiation heat transfer.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 16, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_RadiationHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Tester/Test_TubeInsideHeatTransfer.mo b/SorpLib/Components/HeatTransfer/Tester/Test_TubeInsideHeatTransfer.mo
new file mode 100644
index 0000000..c6ec2ce
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/Test_TubeInsideHeatTransfer.mo
@@ -0,0 +1,164 @@
+within SorpLib.Components.HeatTransfer.Tester;
+model Test_TubeInsideHeatTransfer
+  "Tester for the convective heat transfer within tubes"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource outlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=false,
+    T_fixed=298.15,
+    redeclare package Medium = Medium)
+    "Outlet of the liquid volume"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=180,
+        origin={50,0})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource inlet(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    T_fixed=323.15,
+    redeclare package Medium = Medium)
+    "Inlet of liquid volume"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=180,
+        origin={-50,0})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource heatSource(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true,
+    use_QFlowInput=false)
+    "Heat source for fluid volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=270,
+                origin={0,60})));
+
+  //
+  // Definition of heat transfer models
+  //
+  SorpLib.Components.HeatTransfer.TubeInsideHeatTransfer heatTransfer(
+    redeclare model HeatTransferCoefficient =
+        HeatTransferCoefficientCorrelations.TubeInside.Schmidt,
+    fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=liquidVolume.fluidProperties.p,
+      T=liquidVolume.fluidProperties.T,
+      rho=1/liquidVolume.fluidProperties.v,
+      cp=liquidVolume.fluidProperties.cp,
+      eta=liquidVolume.fluidProperties.eta,
+      lambda=liquidVolume.fluidProperties.lambda),
+    m_hyd_xMinus=liquidVolume.fluidProperties.mc_flow_xMinus,
+    m_hyd_xPlus=liquidVolume.fluidProperties.mc_flow_xPlus)
+    "Heat transfer model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,40})));
+
+  //
+  // Definition of liquid volume models
+  //
+  SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume liquidVolume(
+    T_initial=348.15,
+    geometry(V=Modelica.Constants.pi/4*0.01^2*1),
+    type_energyBalance=SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    calculateAdditionalProperties=true,
+    type_overallMassBalance=SorpLib.Choices.BalanceEquations.SteadyStateFreeInitial,
+    redeclare final package Medium = Medium,
+    nPorts_cfp_xMinus=1,
+    nPorts_cfp_xPlus=1)
+    "Model of a liquid volume"
+    annotation (Placement(transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=0,
+        origin={0,0})));
+
+  //
+  // Definition of fluid boundaries
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_mFlow_inlet(
+    amplitude=10,
+    f=1/250,
+    startTime=50)
+    "Input for mass flow rate at inlet port"
+    annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=0,
+        origin={-80,0})));
+
+  //
+  // Definition of thermal boundaries
+  //
+  Modelica.Blocks.Sources.Ramp input_T(
+    height=-75,
+    duration=1500,
+    offset=273.15 + 75,
+    startTime=500)
+    "Input for temperature"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={0,80})));
+
+equation
+  //
+  // Connections
+  //
+  connect(inlet.port, liquidVolume.cfp_xMinus[1]) annotation (Line(
+      points={{-50,0},{-40,0},{-40,3.6},{-8.4,3.6}},
+      color={28,108,200},
+      thickness=1));
+  connect(outlet.port, liquidVolume.cfp_xPlus[1]) annotation (Line(
+      points={{50,0},{40,0},{40,3.6},{15.6,3.6}},
+      color={28,108,200},
+      thickness=1));
+  connect(heatSource.port, heatTransfer.hp_b[1]) annotation (Line(
+      points={{0,60},{0,48}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer.hp_a[1], liquidVolume.hp_yPlus) annotation (Line(
+      points={{0,32},{0,12}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_mFlow_inlet.y, inlet.m_flow_input) annotation (Line(points={{-69,
+          0},{-60,0},{-60,-2},{-51.2,-2}}, color={0,0,127}));
+  connect(input_T.y, heatSource.T_input) annotation (Line(points={{0,69},{0,64},
+          {5.2,64},{5.2,61}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the convective heat transfer within tubes.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 19, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_TubeInsideHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/Tester/package.mo b/SorpLib/Components/HeatTransfer/Tester/package.mo
new file mode 100644
index 0000000..3ae82b5
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.HeatTransfer;
+package Tester "Models to test and varify heat transfer models"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented heat transfer 
+models. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructering the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/HeatTransfer/Tester/package.order b/SorpLib/Components/HeatTransfer/Tester/package.order
new file mode 100644
index 0000000..b5330fa
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/Tester/package.order
@@ -0,0 +1,8 @@
+Test_GenericHeatTransfer
+Test_ConductionHeatTransfer
+Test_RadiationHeatTransfer
+Test_PoolBoilingHeatTransfer
+Test_PoolCondensationHeatTransfer
+Test_TubeInsideHeatTransfer
+Test_ClosedAdsorberHeatTransfer
+Test_OpenAdsorberHeatTransfer
diff --git a/SorpLib/Components/HeatTransfer/Testers/TestHeatTransfer1.mo b/SorpLib/Components/HeatTransfer/Testers/TestHeatTransfer1.mo
deleted file mode 100644
index 49cde34..0000000
--- a/SorpLib/Components/HeatTransfer/Testers/TestHeatTransfer1.mo
+++ /dev/null
@@ -1,27 +0,0 @@
-within SorpLib.Components.HeatTransfer.Testers;
-model TestHeatTransfer1
-
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary
-    annotation (Placement(transformation(extent={{-44,-6},{-36,6}})));
-  TIL.OtherComponents.Thermal.MultiPortHeatBoundary multiPortHeatBoundary(nPorts=10, TFixed=
-        373.15)
-    annotation (Placement(transformation(extent={{36,-6},{44,6}})));
-  HeatTransfer heatTransfer(n=10,
-    useAlphaAInput=false,
-    redeclare model HeatTransfer = HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=100))
-    annotation (Placement(transformation(extent={{-8,-4},{8,4}},
-        rotation=0,
-        origin={0,0})));
-equation
-  connect(heatBoundary.heatPort, heatTransfer.heatPortA) annotation (Line(
-      points={{-40,0},{-8,0}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(multiPortHeatBoundary.heatPorts, heatTransfer.heatPortB[1:10])
-    annotation (Line(
-      points={{40,0},{8,0},{8,0.9}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (experiment(StopTime=500, Interval=1));
-end TestHeatTransfer1;
diff --git a/SorpLib/Components/HeatTransfer/Testers/TestHeatTransfer2.mo b/SorpLib/Components/HeatTransfer/Testers/TestHeatTransfer2.mo
deleted file mode 100644
index 1c47b8e..0000000
--- a/SorpLib/Components/HeatTransfer/Testers/TestHeatTransfer2.mo
+++ /dev/null
@@ -1,35 +0,0 @@
-within SorpLib.Components.HeatTransfer.Testers;
-model TestHeatTransfer2
-
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary
-    annotation (Placement(transformation(extent={{-44,-6},{-36,6}})));
-  TIL.OtherComponents.Thermal.MultiPortHeatBoundary multiPortHeatBoundary(nPorts=10, TFixed=
-        373.15)
-    annotation (Placement(transformation(extent={{36,-6},{44,6}})));
-  HeatTransfer heatTransfer(
-    useAlphaAInput=true,
-    redeclare model HeatTransfer = HeatTransferPhenomena.ConstantAlpha,
-    n=10)
-    annotation (Placement(transformation(extent={{-8,-4},{8,4}})));
-  Modelica.Blocks.Sources.Step step(
-    height=200,
-    offset=100,
-    startTime=150)
-    annotation (Placement(transformation(extent={{-6,-6},{6,6}},
-        rotation=270,
-        origin={0,18})));
-equation
-  connect(heatBoundary.heatPort, heatTransfer.heatPortA) annotation (Line(
-      points={{-40,0},{-8,0}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(step.y, heatTransfer.alphaAInput)
-    annotation (Line(points={{0,11.4},{0,6},{0,3.6}},
-                                                color={0,0,127}));
-  connect(heatTransfer.heatPortB[1:10], multiPortHeatBoundary.heatPorts)
-    annotation (Line(
-      points={{8,0.9},{8,0},{40,0}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (experiment(StopTime=500, Interval=1));
-end TestHeatTransfer2;
diff --git a/SorpLib/Components/HeatTransfer/Testers/package.mo b/SorpLib/Components/HeatTransfer/Testers/package.mo
deleted file mode 100644
index 6bc6bd7..0000000
--- a/SorpLib/Components/HeatTransfer/Testers/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.HeatTransfer;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-end Testers;
diff --git a/SorpLib/Components/HeatTransfer/Testers/package.order b/SorpLib/Components/HeatTransfer/Testers/package.order
deleted file mode 100644
index 92d5c5d..0000000
--- a/SorpLib/Components/HeatTransfer/Testers/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-TestHeatTransfer1
-TestHeatTransfer2
diff --git a/SorpLib/Components/HeatTransfer/TubeInsideHeatTransfer.mo b/SorpLib/Components/HeatTransfer/TubeInsideHeatTransfer.mo
new file mode 100644
index 0000000..135f914
--- /dev/null
+++ b/SorpLib/Components/HeatTransfer/TubeInsideHeatTransfer.mo
@@ -0,0 +1,115 @@
+within SorpLib.Components.HeatTransfer;
+model TubeInsideHeatTransfer
+  "Model calculating a heat transfer describing convective heat transfer within tubes"
+  extends BaseClasses.PartialHeatTransfer(
+    final exponetTemperature=1,
+    redeclare replaceable model HeatTransferCoefficient =
+      SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.ConstantAlpha
+      constrainedby
+      SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient(
+      fluidProperties=fluidProperties,
+      m_hyd_xMinus=m_hyd_xMinus,
+      m_hyd_xPlus=m_hyd_xPlus,
+      geometry=geometry));
+
+  //
+  // Definition of parameters
+  //
+  replaceable parameter SorpLib.Components.HeatTransfer.Records.GeometryTube geometry
+    constrainedby SorpLib.Components.HeatTransfer.Records.GeometryTube
+    "Geometry of the tube"
+    annotation(Dialog(tab = "General", group = "Heat Transfer Coefficient",
+               enable=false));
+
+  //
+  // Definitions of inputs
+  //
+  input SorpLib.Components.HeatTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties (i.e., fluid properties of the fluid volume)"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Modelica.Units.SI.MassFlowRate m_hyd_xMinus
+    "Hydraulic mass flow rate at design inlet"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+  input Modelica.Units.SI.MassFlowRate m_hyd_xPlus
+    "Hydraulic mass flow rate at design outlet"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The heat transfer model is used to describe convective heat transfer within a tube,
+which is the heat transfer between the heat transfer fluid and tube wall. Thus, 
+the pool condensation heat transfer model represents a thermal resistance betweed 
+two models. Depending on the attached temperatures (i.e., attached potential) 
+and the chosen transport phenomena, this model determines the heat flow rate 
+between the connected models. 
+<br/><br/>
+The model has two heat ports, which sizes can be defined via a parameter. The 
+scalable heat ports enable the connection of various models. For example, this 
+enables to connect a discretized model to a lumped model, or two different
+disretized models.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has steady-state energy balance:
+</p>
+<pre>
+    0 = &sum; (hp_a.Q_flow) + &sum; (hp_b.Q_flow);
+</pre>
+<p>
+The heat flow rate <i>Q_flow</i> is proportional to the driving temperature
+difference <i>&Delta;T = hp_a.T - hp_b.T</i> and the production of heat transfer
+coefficient and area <i>&alpha;A</i>, which can be formulated as thermal resistance
+<i>R<sub>tubeInside</sub></i>. This product can be given as an input or calculated using 
+models describing heat transfer coefficient correlations.
+</p>
+<pre>
+    hp_a.Q_flow = &alpha;A * &Delta;T = 1 / R<sub>tubeInside</sub> * (hp_a.T - hp_b.T);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  The number of ports a and b must be an even integer multiple of each other.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The (pool) condensation heat transfer is typically used to desribe the heat transfer 
+within tubes, covering laminar and turbulent flow regimes.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useAlphaAInput</i>:
+  Defines if the product of heat transfer coefficient and area is given via
+  an input or calculated using an approproate correlation model for the heat
+  transfer coefficient.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 19, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Text(
+          extent={{-60,20},{60,-20}},
+          lineColor={0,0,0},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={238,46,47},
+          textString="Q_flow = 1/R_tubeInside * DT")}));
+end TubeInsideHeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/package.mo b/SorpLib/Components/HeatTransfer/package.mo
index 76a8063..3781629 100644
--- a/SorpLib/Components/HeatTransfer/package.mo
+++ b/SorpLib/Components/HeatTransfer/package.mo
@@ -1,7 +1,54 @@
 within SorpLib.Components;
-package HeatTransfer
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
+package HeatTransfer "Models and correlations to calculate heat transfers"
+  extends SorpLib.Icons.HeatTransfersPackage;
 
+  annotation (Documentation(info="<html>
+<p>
+This package includes various heat transfer models to calculate the heat transfer
+between different components:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.GenericHeatTransfer\">GenericHeatTransfer</a>: 
+  Calculates a gneric heat transfer between components.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.ConductionHeatTransfer\">ConductionHeatTransfer</a>: 
+  Calculates conductive heat transfer within volume models.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.RadiationHeatTransfer\">RadiationHeatTransfer</a>: 
+  Calculates radiation heat transfer between components.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.PoolBoilingHeatTransfer\">PoolBoilingHeatTransfer</a>: 
+  Calculates pool boiling heat transfer within evaporators.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.PoolCondensationHeatTransfer\">PoolCondensationHeatTransfer</a>: 
+  Calculates (pool) condensation heat transfer within condensers.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.TubeInsideHeatTransfer\">TubeInsideHeatTransfer</a>: 
+  Calculates convective heat transfer within tubes.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.ClosedAdsorberHeatTransfer\">ClosedAdsorberHeatTransfer</a>: 
+  Calculates the heat transfer between sorbent and heat exchanger within closed
+  adsorbers.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.HeatTransfer.OpenAdsorberHeatTransfer\">OpenAdsorberHeatTransfer</a>: 
+  Calculates the heat transfer between gas and sorbent/casing within closed
+  adsorbers.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
 end HeatTransfer;
diff --git a/SorpLib/Components/HeatTransfer/package.order b/SorpLib/Components/HeatTransfer/package.order
index 724e858..1580af1 100644
--- a/SorpLib/Components/HeatTransfer/package.order
+++ b/SorpLib/Components/HeatTransfer/package.order
@@ -1,3 +1,12 @@
-HeatTransfer
-HeatTransferPhenomena
-Testers
+BaseClasses
+Records
+HeatTransferCoefficientCorrelations
+GenericHeatTransfer
+ConductionHeatTransfer
+RadiationHeatTransfer
+PoolBoilingHeatTransfer
+PoolCondensationHeatTransfer
+TubeInsideHeatTransfer
+ClosedAdsorberHeatTransfer
+OpenAdsorberHeatTransfer
+Tester
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransfer.mo b/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransfer.mo
new file mode 100644
index 0000000..2c5c67a
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransfer.mo
@@ -0,0 +1,351 @@
+within SorpLib.Components.MassTransfer.BaseClasses;
+partial model PartialMassTransfer
+  "Base model for all mass transfer models"
+
+  //
+  // Definition of parameters describing the kind of valve
+  //
+  parameter Boolean canBeActivated = false
+    "= true, if mass transfer can be activated or deactiavted"
+    annotation (Dialog(tab="General",group="Calculation Setup"),
+                Evaluate = true,
+                HideResult=true);
+  parameter Boolean isFlapValve = false
+    "= true, if mass transfer behaves like a flap valve"
+    annotation (Dialog(tab="General",group="Calculation Setup"),
+                Evaluate = true,
+                HideResult=true);
+  parameter Boolean isFlowAB = true
+    "= true, if flow direction is from port a->b; otherwise, flow direction is
+    from port b->a"
+    annotation (Dialog(tab="General",group="Calculation Setup",
+                enable = isFlapValve),
+                Evaluate = true,
+                HideResult=true);
+  parameter Modelica.Units.SI.PressureDifference offset_dp = 0
+    "Optional offset for pressure difference (i.e., dp + offset_dp) to accout for,
+    e.g., hydostatic pressure differences when controlling flap valve status"
+    annotation (Dialog(tab="General",group="Calculation Setup",
+                enable = isFlapValve));
+
+  //
+  // Definition of parameters regarding the mass transfer coefficient
+  //
+  parameter Boolean useBetaInput = false
+    " = true, if beta is given by input; otherwise, beta is calculated by
+    selected model"
+    annotation (Dialog(tab="General", group="Mass Transfer Coefficient"),
+                Evaluate = true,
+                HideResult=true);
+  parameter Boolean calculateFluidProperties = false
+    "= true, to calculate instreaming fluid properties at port a and b"
+    annotation (Dialog(tab="General", group="Mass Transfer Coefficient",
+                enable = not useBetaInput),
+                Evaluate = true,
+                HideResult=true);
+  parameter SorpLib.Choices.MassTransferFluidProperties fluidPropertyPosition=
+    SorpLib.Choices.MassTransferFluidProperties.AverageInstreaming
+    "Defines the calculation approach of fluid properties if needed"
+    annotation (Dialog(tab="General", group="Mass Transfer Coefficient",
+                enable = not useBetaInput),
+                Evaluate = true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="Medium", group="Fluid"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean limitPressureForCalculations = true
+    "= true, if pressure is limited while fluid property calculations"
+    annotation (Dialog(tab = "Advanced", group = "Limiter",
+                enable=calculateFluidProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Modelica.Units.SI.Pressure p_min = 1000
+    "Minimal pressure for fluid property calculation"
+    annotation (Dialog(tab = "Advanced", group = "Limiter",
+                enable=calculateFluidProperties and limitPressureForCalculations),
+                Evaluate=true,
+                HideResult = true);
+
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Boolean avoid_events_activating = avoid_events
+    "= true, if events are avoid by using noEvent()-operator for activating/deactivating
+    the mass transfer"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput activated_input(final unit="1") if
+    canBeActivated
+    " > 0.75, if mass transfer is activated; < 0.25, if mass transfer is decactivated;
+    otherwise, smooth transiton regime"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}},
+                rotation=90,origin={10,-60}), iconTransformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={10,-60})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealOutput activated_fixed(final unit="1") = 1 if
+    not canBeActivated
+    "Needed for connecting to conditional connector";
+
+  Modelica.Blocks.Interfaces.RealInput activated_internal(final unit="1")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of variables
+  //
+public
+  Modelica.Units.SI.PressureDifference dp
+    "Pressure difference between port a and b";
+
+equation
+  //
+  // Connectors
+  //
+  connect(activated_internal, activated_input);
+  connect(activated_internal, activated_fixed);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all mass transfers. It defines 
+fundamental parameters and variables required by all mass transfers. Models 
+that inherit properties from this partial model have to add a mass transfer
+coefficient model. In this context, records may be added that contain geometry
+and fluid property data.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Pressure difference <i>dp</i> between port a and b.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revision and added documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Major revisions (e.g., object-oriented approach) after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Ellipse(
+          extent={{80,62},{-40,-58}},
+          lineColor={0,0,0},
+          fillColor={175,175,175},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-12,56},{-8,48},{-8,40},{-6,34},{-2,28},{6,18},{20,16},{52,16},
+              {50,10},{40,10},{18,12},{16,8},{24,4},{40,2},{46,-2},{48,-8},{46,-18},
+              {42,-24},{38,-32},{28,-36},{18,-38},{12,-38},{2,-34},{4,-30},{10,-34},
+              {18,-34},{26,-32},{32,-26},{38,-20},{40,-12},{38,-6},{32,-4},{26,-2},
+              {22,0},{16,2},{12,6},{14,0},{20,-6},{26,-14},{20,-14},{16,-6},{10,
+              0},{8,4},{10,10},{6,14},{0,18},{-4,20},{-4,16},{-6,12},{-4,10},{-4,
+              4},{-4,2},{-4,0},{-2,-2},{0,-4},{4,-10},{-4,-4},{-4,-8},{-4,-10},{
+              -4,-18},{-10,-24},{-8,-8},{-6,-2},{-10,0},{-24,2},{-30,6},{-28,8},
+              {-16,4},{-8,2},{-8,8},{-10,12},{-14,14},{-22,22},{-28,32},{-22,28},
+              {-10,16},{-8,22},{-10,28},{-14,34},{-10,42},{-12,56}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          smooth=Smooth.Bezier),
+        Text(
+          extent={{-40,80},{-20,60}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.None,
+          textString="D",
+          textStyle={TextStyle.Italic}),
+        Line(
+          points={{-24,66},{-18,62},{-12,54}},
+          color={0,140,72},
+          smooth=Smooth.Bezier,
+          arrow={Arrow.None,Arrow.Filled},
+          thickness=0.5),
+        Line(
+          points={{-10,52},{-10,44},{-6,30},{4,18},{14,10},{20,2},{34,-2},{44,-10},
+              {40,-22},{28,-34},{12,-36},{4,-32}},
+          color={0,140,72},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.None,Arrow.Filled}),
+        Ellipse(
+          extent={{-12,54},{-10,52}},
+          lineColor={0,140,72},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,-30},{6,-32}},
+          lineColor={0,140,72},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-68,52},{-60,60}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-60,40},{-52,48}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-74,32},{-66,40}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-60,20},{-52,28}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-72,12},{-64,20}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-60,2},{-52,10}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-84,20},{-76,28}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-84,44},{-76,52}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-56,62},{-48,70}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-80,64},{-72,72}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,74},{-58,82}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-82,0},{-74,8}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,-6},{-62,2}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-56,-18},{-48,-10}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-74,-22},{-66,-14}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-86,-34},{-78,-26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-64,-34},{-56,-26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-48,-40},{-40,-32}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-76,-50},{-68,-42}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-60,-52},{-52,-44}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-86,-64},{-78,-56}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid)}));
+end PartialMassTransfer;
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficient.mo b/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficient.mo
new file mode 100644
index 0000000..fef5ebb
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficient.mo
@@ -0,0 +1,66 @@
+within SorpLib.Components.MassTransfer.BaseClasses;
+partial model PartialMassTransferCoefficient
+  "Base model for all models calculating the mass transfer coefficient"
+
+  //
+  // Definition of parameters regarding the mass transfer coefficient
+  //
+  parameter Boolean computeTransportProperties = false
+    "= true, if fluid transport properties are required and must be calculated"
+    annotation (Dialog(tab = "General", group = "Mass Transfer"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of outputs
+  //
+  Modelica.Blocks.Interfaces.RealOutput beta
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(graphics={Ellipse(
+          extent={{100,100},{-100,-100}},
+          lineColor={0,0,0},
+          fillColor={0,255,255},
+          fillPattern=FillPattern.Solid)}),
+                              Documentation(revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the mass transfer
+coefficient <i>&beta;</i>. It defines fundamental parameters and variables required
+by all mass transfer coefficient models. Models that inherit properties from this 
+partial model have to add an equation for calculating the mass transfer coefficient.
+In this context, records may be added that containg geometry and fluid property data.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Meat transfer coefficient <i>beta</i>.
+  </li>
+</ul>
+</html>"));
+end PartialMassTransferCoefficient;
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficientClosedAdsorberDP.mo b/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficientClosedAdsorberDP.mo
new file mode 100644
index 0000000..0e7e5ba
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficientClosedAdsorberDP.mo
@@ -0,0 +1,68 @@
+within SorpLib.Components.MassTransfer.BaseClasses;
+partial model PartialMassTransferCoefficientClosedAdsorberDP
+  "Base model for all models calculating the pressure-driven mass transfer coefficient of closed adsorbers"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficient(
+    beta(unit="m.s"));
+
+  //
+  // Definition of inputs
+  //
+  replaceable parameter SorpLib.Components.MassTransfer.Records.GeometryClosedAdsorber geometry
+    constrainedby
+    SorpLib.Components.MassTransfer.Records.GeometryClosedAdsorber
+    "Geometry of the closed adsorber"
+    annotation (Dialog(tab="General", group="Mass Transfer", enable=false));
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Components.MassTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties that may be needed for calculations"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Icon(graphics={Ellipse(
+          extent={{100,100},{-100,-100}},
+          lineColor={0,0,0},
+          fillColor={0,255,255},
+          fillPattern=FillPattern.Solid), Text(
+          extent={{-80,80},{80,-80}},
+          lineColor={0,0,0},
+          fillColor={0,255,255},
+          fillPattern=FillPattern.Solid,
+          textString="DP")}), Documentation(revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the presure-driven
+mass transfer coefficient <i>&beta;</i>. It defines fundamental parameters and 
+variables required by all mass transfer coefficient models. Models that inherit 
+properties from this partial model have to add an equation for calculating the mass 
+transfer coefficient. In this context, records may be added that containg geometry 
+and fluid property data.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Meat transfer coefficient <i>beta</i>.
+  </li>
+</ul>
+</html>"));
+end PartialMassTransferCoefficientClosedAdsorberDP;
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficientClosedAdsorberDX.mo b/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficientClosedAdsorberDX.mo
new file mode 100644
index 0000000..b7f8b99
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/PartialMassTransferCoefficientClosedAdsorberDX.mo
@@ -0,0 +1,68 @@
+within SorpLib.Components.MassTransfer.BaseClasses;
+partial model PartialMassTransferCoefficientClosedAdsorberDX
+  "Base model for all models calculating the loading-driven mass transfer coefficient"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficient(
+    beta(unit="kg/s"));
+
+  //
+  // Definition of inputs
+  //
+  replaceable parameter SorpLib.Components.MassTransfer.Records.GeometryClosedAdsorber geometry
+    constrainedby
+    SorpLib.Components.MassTransfer.Records.GeometryClosedAdsorber
+    "Geometry of the closed adsorber"
+    annotation (Dialog(tab="General", group="Mass Transfer", enable=false));
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Components.MassTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties that may be needed for calculations"
+    annotation (Dialog(tab="General", group="Inputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Icon(graphics={Ellipse(
+          extent={{100,100},{-100,-100}},
+          lineColor={0,0,0},
+          fillColor={0,255,255},
+          fillPattern=FillPattern.Solid), Text(
+          extent={{-80,80},{80,-80}},
+          lineColor={0,0,0},
+          fillColor={0,255,255},
+          fillPattern=FillPattern.Solid,
+          textString="DX")}), Documentation(revisions="<html>
+<ul>
+  <li>
+  January 25, 2024, by Mirko Engelpracht:<br/>
+  Minor adaptations and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the base model for all models calculating the loading-driven
+mass transfer coefficient <i>&beta;</i>. It defines fundamental parameters and 
+variables required by all mass transfer coefficient models. Models that inherit 
+properties from this partial model have to add an equation for calculating the mass 
+transfer coefficient. In this context, records may be added that containg geometry 
+and fluid property data.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Meat transfer coefficient <i>beta</i>.
+  </li>
+</ul>
+</html>"));
+end PartialMassTransferCoefficientClosedAdsorberDX;
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransfer.mo b/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransfer.mo
new file mode 100644
index 0000000..1d02abd
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransfer.mo
@@ -0,0 +1,434 @@
+within SorpLib.Components.MassTransfer.BaseClasses;
+partial model PartialPureMassTransfer
+  "Base model for all mass transfer models describing pure component adsorption"
+  extends SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransfer;
+
+  //
+  // Definition of parameters regarding the mass transfer coefficient
+  //
+  replaceable model MassTransferCoefficient =
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficient
+    constrainedby
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficient
+    "Model calculating the mass transfer coefficient"
+    annotation (Dialog(tab="General", group="Mass Transfer Coefficient",
+                enable=not useBetaInput),
+                choicesAllMatching=true,
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition or advanced parameters
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_small = 1e-4
+    "Regularization mass flow rate"
+    annotation (Dialog(tab="Advanced", group="Numerics"));
+  parameter Integer noDiff = 2
+    "Specification how often transition functions can be differentiated"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput beta_input if useBetaInput
+    "Mass transport coefficient given by input"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}},
+                rotation=90,origin={30,-60}), iconTransformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={30,-60})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealOutput dummyT(final unit="K") = 0 if
+    not calculateFluidProperties
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealOutput dummyD(final unit="kg/m3") = 0 if
+    not calculateFluidProperties
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealOutput dummyEta(final unit="Pa.s") = 0 if
+    not calculateFluidProperties
+    "Needed for connecting to conditional connector";
+
+  Modelica.Blocks.Interfaces.RealInput beta_internal
+    "Needed for connecting to conditional connector";
+
+  Modelica.Blocks.Interfaces.RealInput T_adsorbate_internal(final unit="K")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput T_adsorptiveA_internal(final unit="K")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput T_adsorptiveB_internal(final unit="K")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput d_adsorptiveA_internal(final unit="kg/m3")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput d_adsorptiveB_internal(final unit="kg/m3")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput eta_adsorptiveA_internal(final unit="Pa.s")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput eta_adsorptiveB_internal(final unit="Pa.s")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of ports
+  //
+public
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-88,-10},{-68,10}}),
+                iconTransformation(extent={{-88,-10},{-68,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid ports b"
+    annotation (Placement(transformation(extent={{70,-10},{90,10}}),
+                iconTransformation(extent={{70,-10},{90,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of models
+  //
+  MassTransferCoefficient massTransferCoefficient if not useBetaInput
+    "Model calculating the mass transfer coefficient";
+
+  //
+  // Definition of variables
+  //
+  Real drivingForce
+    "Driving force for mass transfer: Either dp or dx";
+  Real drivingForce_status
+    "Status of mass transfer according to driving force and flap valve 
+    behaivior: > 0.75, if mass transfer is activated; < 0.25, if mass transfer is 
+    decactivated; otherwise, smooth transiton regime";
+
+  Real activated = activated_internal * drivingForce_status
+    "Current status of mass transfer accounting for driving force and external 
+    signal: > 0.75, if mass transfer is activated; < 0.25, if mass transfer is 
+    decactivated; otherwise, smooth transiton regime";
+
+protected
+  Real drivingForce_internal
+    "Internal value of driving force: Required to pass either pressure or
+    loading difference in extended models";
+
+  SorpLib.Components.MassTransfer.Records.FluidProperties fluidProperties
+    "Fluid properties if needed for transport phenomena";
+
+equation
+  //
+  // Assertions
+  //
+  assert(no_components == 1,
+    "Mass transfer model is only valid for pure component adsorption!",
+    level = AssertionLevel.error);
+
+  //
+  // Connectors
+  //
+  connect(beta_internal, beta_input);
+  connect(beta_internal, massTransferCoefficient.beta);
+
+  connect(T_adsorbate_internal, dummyT);
+  connect(T_adsorptiveA_internal, dummyT);
+  connect(T_adsorptiveB_internal, dummyT);
+  connect(d_adsorptiveA_internal, dummyD);
+  connect(d_adsorptiveB_internal, dummyD);
+  connect(eta_adsorptiveA_internal, dummyEta);
+  connect(eta_adsorptiveB_internal, dummyEta);
+
+  //
+  // Momentum balance
+  //
+  dp = port_a.p - port_b.p
+    "Pressure drop dp required for flap valve behaiviour and/or pressure driven
+     mass transfer";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + port_b.m_flow
+    "Trivial equation: No change of mass";
+
+  port_a.Xi_outflow = inStream(port_b.Xi_outflow)
+    "Trivial equation: No change of transported substances";
+  port_b.Xi_outflow = inStream(port_a.Xi_outflow)
+    "Trivial equation: No change of transported substances";
+
+  if avoid_events_activating then
+    port_a.m_flow = (1 - SorpLib.Numerics.smoothTransition_noEvent(
+      x=activated,
+      transitionPoint=0.5,
+      transitionLength=0.25,
+      noDiff=noDiff)) * beta_internal * drivingForce
+      "Mass flow rate depends on status of mass transfer";
+
+  else
+    port_a.m_flow = (1 - SorpLib.Numerics.smoothTransition(
+      x=activated,
+      transitionPoint=0.5,
+      transitionLength=0.25,
+      noDiff=noDiff)) * beta_internal * drivingForce
+      "Mass flow rate depends on status of mass transfer";
+
+  end if;
+
+  //
+  // Energy balance
+  //
+  port_a.h_outflow = inStream(port_b.h_outflow)
+    "Trivial equation: No change of energy";
+  port_b.h_outflow = inStream(port_a.h_outflow)
+    "Trivial equation: No change of energy";
+
+  //
+  // Limit driving force and determine status of driving force
+  //
+  if isFlapValve then
+    //
+    // Flap valve: Driving force depends on flow direction
+    //
+    drivingForce = if isFlowAB then max(drivingForce_internal, 0)
+      else min(drivingForce_internal, 0)
+      "Flow from a->b: Values at port a must be greater than at port b; flow
+      from b->a: vice versa";
+
+    if isFlowAB then
+      if avoid_events then
+        drivingForce_status = (1 - SorpLib.Numerics.smoothTransition_noEvent(
+          x=dp + offset_dp,
+          transitionPoint=0,
+          transitionLength=5,
+          noDiff=noDiff))
+          "Flow from a->b: Values at port a must be greater than at port b";
+
+      else
+        drivingForce_status = (1 - SorpLib.Numerics.smoothTransition(
+          x=dp + offset_dp,
+          transitionPoint=0,
+          transitionLength=5,
+          noDiff=noDiff))
+          "Flow from a->b: Values at port a must be greater than at port b";
+
+      end if;
+
+    else
+      if avoid_events then
+        drivingForce_status = SorpLib.Numerics.smoothTransition_noEvent(
+          x=dp + offset_dp,
+          transitionPoint=0,
+          transitionLength=5,
+          noDiff=noDiff)
+          "Flow from b->a: Values at port b must be greater than at port a";
+
+      else
+        drivingForce_status = SorpLib.Numerics.smoothTransition(
+          x=dp + offset_dp,
+          transitionPoint=0,
+          transitionLength=5,
+          noDiff=noDiff)
+          "Flow from b->a: Values at port b must be greater than at port a";
+
+      end if;
+    end if;
+
+  else
+    //
+    // No flap valve behaiviour: Use driving force as given and set status to 1
+    //
+    drivingForce = drivingForce_internal
+      "Driving force depends on kind of mass tranfer: Pressure- or loading-driven 
+      mass transfer";
+    drivingForce_status = 1
+      "No flap valve behaiviour: Mass transfer is always activated w.r.t. driving 
+      force";
+
+  end if;
+
+  //
+  // Calculate fluid properties if required for mass transport phenomena
+  //
+  if calculateFluidProperties and not useBetaInput then
+    //
+    // Calculate fluid properties
+    //
+    fluidProperties.T_adsorbate = T_adsorbate_internal
+      "Temperature at the adsorbate state";
+
+    if fluidPropertyPosition==
+      SorpLib.Choices.MassTransferFluidProperties.PortAInlet then
+      fluidProperties.p_adsorptive = port_a.p
+        "Pressure at the adsorptive state";
+      fluidProperties.T_adsorptive = T_adsorptiveA_internal
+        "Temperature at the adsorptive state";
+      fluidProperties.d_adsorptive = d_adsorptiveA_internal
+        "Density at the adsorptive state";
+      fluidProperties.eta_adsorptive = eta_adsorptiveA_internal
+        "Dynamic viscosity at the adsorptive state";
+
+    elseif fluidPropertyPosition==
+      SorpLib.Choices.MassTransferFluidProperties.PortBInlet then
+      fluidProperties.p_adsorptive = port_b.p
+        "Pressure at the adsorptive state";
+      fluidProperties.T_adsorptive = T_adsorptiveB_internal
+        "Temperature at the adsorptive state";
+      fluidProperties.d_adsorptive = d_adsorptiveB_internal
+        "Density at the adsorptive state";
+      fluidProperties.eta_adsorptive = eta_adsorptiveB_internal
+        "Dynamic viscosity at the adsorptive state";
+
+    elseif fluidPropertyPosition==
+      SorpLib.Choices.MassTransferFluidProperties.ActualInlet then
+      if avoid_events then
+        fluidProperties.p_adsorptive = SorpLib.Numerics.regStep_noEvent(
+          x=port_a.m_flow,
+          y1=port_a.p,
+          y2=port_b.p,
+          x_small=m_flow_small)
+          "Pressure at the adsorptive state";
+        fluidProperties.T_adsorptive = SorpLib.Numerics.regStep_noEvent(
+          x=port_a.m_flow,
+          y1=T_adsorptiveA_internal,
+          y2=T_adsorptiveB_internal,
+          x_small=m_flow_small)
+          "Temperature at the adsorptive state";
+        fluidProperties.d_adsorptive = SorpLib.Numerics.regStep_noEvent(
+          x=port_a.m_flow,
+          y1=d_adsorptiveA_internal,
+          y2=d_adsorptiveB_internal,
+          x_small=m_flow_small)
+          "Density at the adsorptive state";
+        fluidProperties.eta_adsorptive = SorpLib.Numerics.regStep_noEvent(
+          x=port_a.m_flow,
+          y1=eta_adsorptiveA_internal,
+          y2=eta_adsorptiveB_internal,
+          x_small=m_flow_small)
+          "Dynamic viscosity at the adsorptive state";
+
+     else
+        fluidProperties.p_adsorptive = SorpLib.Numerics.regStep(
+          x=port_a.m_flow,
+          y1=port_a.p,
+          y2=port_b.p,
+          x_small=m_flow_small)
+          "Pressure at the adsorptive state";
+        fluidProperties.T_adsorptive = SorpLib.Numerics.regStep(
+          x=port_a.m_flow,
+          y1=T_adsorptiveA_internal,
+          y2=T_adsorptiveB_internal,
+          x_small=m_flow_small)
+          "Temperature at the adsorptive state";
+        fluidProperties.d_adsorptive = SorpLib.Numerics.regStep(
+          x=port_a.m_flow,
+          y1=d_adsorptiveA_internal,
+          y2=d_adsorptiveB_internal,
+          x_small=m_flow_small)
+          "Density at the adsorptive state";
+        fluidProperties.eta_adsorptive = SorpLib.Numerics.regStep(
+          x=port_a.m_flow,
+          y1=eta_adsorptiveA_internal,
+          y2=eta_adsorptiveB_internal,
+          x_small=m_flow_small)
+          "Dynamic viscosity at the adsorptive state";
+
+      end if;
+
+    else
+      fluidProperties.p_adsorptive =
+        (port_a.p+port_b.p)/2
+        "Pressure at the adsorptive state";
+      fluidProperties.T_adsorptive =
+        (T_adsorptiveA_internal+T_adsorptiveB_internal)/2
+        "Temperature at the adsorptive state";
+      fluidProperties.d_adsorptive =
+        (d_adsorptiveA_internal+d_adsorptiveB_internal)/2
+          "Density at the adsorptive state";
+      fluidProperties.eta_adsorptive =
+        (eta_adsorptiveA_internal+eta_adsorptiveB_internal)/2
+          "Dynamic viscosity at the adsorptive state";
+
+    end if;
+
+  else
+    //
+    // Fluid properties are not needed: Set dummy values
+    //
+    fluidProperties.T_adsorbate = 0
+      "Pressure at the adsorbate state";
+    fluidProperties.p_adsorptive = 0
+      "Pressure at the adsorptive state";
+    fluidProperties.T_adsorptive = 0
+      "Temperature at the adsorptive state";
+    fluidProperties.d_adsorptive = 0
+      "Density at the adsorptive state";
+    fluidProperties.eta_adsorptive = 0
+      "Dynamic viscosity at the adsorptive state";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all mass transfers of pure component
+adsorption. It defines fundamental parameters and variables required by all mass
+transfers. Models that inherit properties from this partial model have to redeclare 
+the fluid ports. Moreover, these models must redeclare and constrain the model 
+calculating the mass transfer coefficient and area. In this context, records may 
+be added that containg geometry and fluid property data. Furtheremore, the driving 
+force must be defined.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Driving force <i>drivingForce_internal</i>.
+  </li>
+  <li>
+  Temperature at adsorbate state <i>T_adsorbate_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive temperature at port a <i>T_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive temperature at port b <i>T_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive density at port a <i>d_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive density at port b <i>d_adsorptiveB_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive dynamic viscosity at port a <i>eta_adsorptiveB_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive dynamic viscosity at port b <i>eta_adsorptiveA_internal</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Major revisions (e.g., object-oriented approach) after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end PartialPureMassTransfer;
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransferDP.mo b/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransferDP.mo
new file mode 100644
index 0000000..aade14c
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransferDP.mo
@@ -0,0 +1,73 @@
+within SorpLib.Components.MassTransfer.BaseClasses;
+partial model PartialPureMassTransferDP
+  "Base model for all pressure-driven mass transfer models describing pure component adsorption"
+  extends SorpLib.Components.MassTransfer.BaseClasses.PartialPureMassTransfer;
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealOutput T_adsorbate_calc(final unit="K") = 0 if
+    calculateFluidProperties
+    "Needed for connecting to conditional connector: Value is not needed";
+
+equation
+  //
+  // Connectors
+  //
+  connect(T_adsorbate_internal, T_adsorbate_calc);
+
+  //
+  // Set driving potential
+  //
+  drivingForce_internal = port_a.p - port_b.p
+    "Pressure driven mass flow rate";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all pressure-driven mass transfers of 
+pure component adsorption. It defines fundamental parameters and variables required 
+by all mass transfers. Models that inherit properties from this partial model have 
+to redeclare the fluid ports. Moreover, these models must redeclare and constrain 
+the model calculating the mass transfer coefficient and area. In this context, records 
+may be added that containg geometry and fluid property data. Furtheremore, the driving 
+force must be defined.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Instreaming adsorptive temperature at port a <i>T_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive temperature at port b <i>T_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive density at port a <i>d_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive density at port b <i>d_adsorptiveB_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive dynamic viscosity at port a <i>eta_adsorptiveB_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive dynamic viscosity at port b <i>eta_adsorptiveA_internal</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureMassTransferDP;
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransferDX.mo b/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransferDX.mo
new file mode 100644
index 0000000..c89645c
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/PartialPureMassTransferDX.mo
@@ -0,0 +1,119 @@
+within SorpLib.Components.MassTransfer.BaseClasses;
+partial model PartialPureMassTransferDX
+  "Base model for all loading-driven mass transfer models describing pure component adsorption"
+  extends SorpLib.Components.MassTransfer.BaseClasses.PartialPureMassTransfer;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake x_adsorpt_input
+    "Actual adsorpt loading (i.e., loading at pot b)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt_input
+    "Actual adsorpt temperature (i.e., temperature at port b)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable model WorkingPair =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+    constrainedby
+    SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs(
+      stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+      calcCaloricProperties=false,
+      calcEntropicProperties=false,
+      calcDerivativesIsotherm=false,
+      calcDerivativesMassEnergyBalance=false,
+      calcDerivativesEntropyBalance=false)
+    "Working pair model"
+    annotation (Dialog(tab="Medium", group="Working Pair"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealOutput T_adsorbate_calc(final unit="K")=
+    T_adsorpt_input if calculateFluidProperties
+    "Needed for connecting to conditional connector";
+
+  //
+  // Instantiation of models
+  //
+public
+  WorkingPair workingPair_a_theoretical(
+    final p_adsorpt=port_a.p,
+    final T_adsorpt=T_adsorpt_input,
+    final x_adsorpt=x_adsorpt_theoretical)
+    "Working pair model to calculate equilibrium properties at port a";
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Units.Uptake x_adsorpt_theoretical
+    "Theoretical equilibrium loading of adsorbate at port a (i.e., 
+    vapor/gas phase)";
+
+equation
+  //
+  // Connectors
+  //
+  connect(T_adsorbate_internal, T_adsorbate_calc);
+
+  //
+  // Set driving potential
+  //
+  drivingForce_internal = x_adsorpt_theoretical - x_adsorpt_input
+    "Loading driven mass flow rate";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all pressure-driven mass transfers of 
+pure component adsorption. It defines fundamental parameters and variables required 
+by all mass transfers. Models that inherit properties from this partial model have 
+to redeclare the fluid ports. Moreover, these models must redeclare and constrain 
+the model calculating the mass transfer coefficient and area as well as the working
+pair In this context, records may be added that containg geometry and fluid property 
+data. Furtheremore, the driving force must be defined.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Instreaming adsorptive temperature at port a <i>T_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive temperature at port b <i>T_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive density at port a <i>d_adsorptiveA_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive density at port b <i>d_adsorptiveB_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive dynamic viscosity at port a <i>eta_adsorptiveB_internal</i>.
+  </li>
+  <li>
+  Instreaming adsorptive dynamic viscosity at port b <i>eta_adsorptiveA_internal</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 25, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureMassTransferDX;
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/package.mo b/SorpLib/Components/MassTransfer/BaseClasses/package.mo
new file mode 100644
index 0000000..57dc508
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Components.MassTransfer;
+package BaseClasses "Base models and functions for all mass transfers"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial mass transfer and mass transfer coefficient models, 
+containing fundamental definitions of parameters and variables. The content of 
+this package is only of interest when adding new mass transfer and mass transfer
+coefficient models to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/MassTransfer/BaseClasses/package.order b/SorpLib/Components/MassTransfer/BaseClasses/package.order
new file mode 100644
index 0000000..4b00c32
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/BaseClasses/package.order
@@ -0,0 +1,7 @@
+PartialMassTransfer
+PartialPureMassTransfer
+PartialPureMassTransferDP
+PartialPureMassTransferDX
+PartialMassTransferCoefficient
+PartialMassTransferCoefficientClosedAdsorberDP
+PartialMassTransferCoefficientClosedAdsorberDX
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/ConstantCoefficient.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/ConstantCoefficient.mo
new file mode 100644
index 0000000..81621ec
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/ConstantCoefficient.mo
@@ -0,0 +1,68 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven;
+model ConstantCoefficient
+  "Generic mass transfer correlation with constant mass transfer coefficient"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDX(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real constantCoefficient(final unit="kg/s")= 1e-7
+    "Constant mass transfer coefficient for loading-driven mass transfer"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes * constantCoefficient /
+    geometry.no_sorbentVolumes
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of mass transfer coefficient and
+area assuming a constant mass transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+assuming a constant mass transfer coefficient <i>&beta;</i> and area <i>A</i>:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> * &beta;A / no<sub>sorbent volumes</sub> = const.;
+</pre>
+<p>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This simple mass transfer correlation model is typically used if the mass transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 25, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end ConstantCoefficient;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/ConstantSpecificCoefficient.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/ConstantSpecificCoefficient.mo
new file mode 100644
index 0000000..eebcc38
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/ConstantSpecificCoefficient.mo
@@ -0,0 +1,71 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven;
+model ConstantSpecificCoefficient
+  "Generic mass transfer correlation with constant product of specific mass transfer coefficient and area"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDX(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real constantSpecificCoefficient(final unit="kg/(s.m2)")= 1e-7
+    "Constant specific mass transfer coefficient for loading-driven mass transfer"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Area A = 1
+    "Mass transfer area"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes * constantSpecificCoefficient * A /
+    geometry.no_sorbentVolumes
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of mass transfer coefficient and
+area assuming a constant mass transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+assuming a constant mass transfer coefficient <i>&beta;</i> and area <i>A</i>:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> * &beta; * A / no<sub>sorbent volumes</sub> = const.;
+</pre>
+<p>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This simple mass transfer correlation model is typically used if the mass transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 25, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end ConstantSpecificCoefficient;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/Glueckauf.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/Glueckauf.mo
new file mode 100644
index 0000000..01ef19e
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/Glueckauf.mo
@@ -0,0 +1,84 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven;
+model Glueckauf
+  "Mass transfer correlation describing mass transfer according to Glueckauf"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDX(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Radius r_sorbent = geometry.d_particle/2
+    "Radius of sorbent material"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Mass m_sorbent = 2.5
+    "Mass of dry sorbent material"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real D(unit="m2/s") = 1e-10
+    "Diffusion coefficient"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes / geometry.no_sorbentVolumes *
+    15 * m_sorbent * D / r_sorbent^2
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area according to Glueckauf.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+according to:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * 15 * D / r<sub>particle</sub>^2 * m<sub>sorbent</sub>;
+</pre>
+<p>
+Herein, <i>D</i> is the diffusion coefficient, <i>r<sub>particle</sub></i> is the 
+radius of the particle, and <i>m<sub>sorbent</sub></i> is the sorbent mass.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+within closed adsorbers.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Glueckauf, E. (1955). Theory of Chromatography. Part 10: Formulae for Diffusion into Spheres and their Application to Chromatography. Transactions of the Faraday Society, 51(11), 1540-1551.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 25, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end Glueckauf;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/GlueckaufArrhenius.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/GlueckaufArrhenius.mo
new file mode 100644
index 0000000..2ee17ad
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/GlueckaufArrhenius.mo
@@ -0,0 +1,95 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven;
+model GlueckaufArrhenius
+  "Mass transfer correlation describing mass transfer according to Glueckauf with a temperature depandancy"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDX(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Radius r_sorbent = geometry.d_particle/2
+    "Radius of sorbent material"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Mass m_sorbent = 2.5
+    "Mass of dry sorbent material"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real D(unit="m2/s") = 1e-10
+    "Diffusion coefficient"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.SpecificEnergy E_activation = 2.33e6
+    "Activation energy"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.MolarMass M_adsorptive = 0.001801528
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes / geometry.no_sorbentVolumes *
+    15 * m_sorbent * D / r_sorbent^2 * exp(-E_activation /
+    ((Modelica.Constants.R/M_adsorptive) * fluidProperties.T_adsorbate))
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area according to Glueckauf.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+according to:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * 15 * D / r<sub>particle</sub>^2 * m<sub>sorbent</sub> * <strong>exp</strong>(-E<sub>activation</sub> / (R / M<sub>adsorptive</sub> * T<sub>adsorbate</sub>));
+</pre>
+<p>
+Herein, <i>D</i> is the diffusion coefficient, <i>r<sub>particle</sub></i> is the 
+radius of the particle, and <i>m<sub>sorbent</sub></i> is the sorbent mass,
+<i>E<sub>activation</sub></i> is the activation energy, <i>M<sub>adsorptive</sub></i>
+is the molar mass of the adsorptive, <i>T<sub>adsorbate</sub></i> is the adsorbate 
+temperature.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+within closed adsorbers.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Glueckauf, E. (1955). Theory of Chromatography. Part 10: Formulae for Diffusion into Spheres and their Application to Chromatography. Transactions of the Faraday Society, 51(11), 1540-1551.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 25, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end GlueckaufArrhenius;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/package.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/package.mo
new file mode 100644
index 0000000..bded4e1
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/package.mo
@@ -0,0 +1,38 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber;
+package LoadingDriven "Correlations for loading-driven mass transfer coefficients describing the mass transfer within closed adsorbers"
+extends Modelica.Icons.FunctionsPackage;
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for mass transfer coefficients describing
+the loading-driven mass transfer within closed adsorbers:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.ConstantCoefficient\">ConstantCoefficient</a>: 
+  Generic mass transfer correlation with constant mass transfer coefficient.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.ConstantSpecificCoefficient\">ConstantSpecificCoefficient</a>: 
+  Generic mass transfer correlation with constant product of specific mass 
+  transfer coefficient and area
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.Glueckauf\">Glueckauf</a>: 
+  Mass transfer correlation according to Glueckauf.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.GlueckaufArrhenius\">GlueckaufArrhenius</a>: 
+  Mass transfer correlation according to Glueckauf with temperature dependancy.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LoadingDriven;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/package.order b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/package.order
new file mode 100644
index 0000000..e6ea8b1
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/LoadingDriven/package.order
@@ -0,0 +1,4 @@
+ConstantCoefficient
+ConstantSpecificCoefficient
+Glueckauf
+GlueckaufArrhenius
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/ConstantCoefficient.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/ConstantCoefficient.mo
new file mode 100644
index 0000000..6a3c55f
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/ConstantCoefficient.mo
@@ -0,0 +1,68 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model ConstantCoefficient
+  "Generic mass transfer correlation with constant mass transfer coefficient"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real constantCoefficient(final unit="m.s")= 1e-7
+    "Constant mass transfer coefficient for pressure-driven mass transfer"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes * constantCoefficient /
+    geometry.no_sorbentVolumes
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of mass transfer coefficient and
+area assuming a constant mass transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+assuming a constant mass transfer coefficient <i>&beta;</i> and area <i>A</i>:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> * &beta;A / no<sub>sorbent volumes</sub> = const.;
+</pre>
+<p>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This simple mass transfer correlation model is typically used if the mass transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end ConstantCoefficient;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/ConstantSpecificCoefficient.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/ConstantSpecificCoefficient.mo
new file mode 100644
index 0000000..1000eb3
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/ConstantSpecificCoefficient.mo
@@ -0,0 +1,71 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model ConstantSpecificCoefficient
+  "Generic mass transfer correlation with constant product of specific mass transfer coefficient and area"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+     final computeTransportProperties=false,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real constantSpecificCoefficient(final unit="m.s/m2")= 1e-7
+    "Constant specific mass transfer coefficient for pressure-driven mass transfer"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Area A = 1
+    "Mass transfer area"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes * constantSpecificCoefficient * A /
+    geometry.no_sorbentVolumes
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This simple transfer model calculates the product of mass transfer coefficient and
+area assuming a constant mass transfer coefficient and area.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+assuming a constant mass transfer coefficient <i>&beta;</i> and area <i>A</i>:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> * &beta; * A / no<sub>sorbent volumes</sub> = const.;
+</pre>
+<p>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This simple mass transfer correlation model is typically used if the mass transfer
+conditions do not greatly change and a very simple models is required.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end ConstantSpecificCoefficient;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPackedBedSpheres.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPackedBedSpheres.mo
new file mode 100644
index 0000000..6ad96d7
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPackedBedSpheres.mo
@@ -0,0 +1,90 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model DarcyPackedBedSpheres
+  "Mass transfer correlation describing mass transfer through a packed bed for spherical particles"
+  extends
+    SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.DarcyPorousMedia(
+     final permeability = (d_particle^2 * psi_bed^3) / (150 * (1 - psi_bed)^2));
+
+  //
+  // Definition of parameters
+  //
+  parameter Real psi_bed(final unit="1") = geometry.psi_particles
+    "Void fraction of the bed"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Diameter d_particle = geometry.d_particle
+    "Diameter of the particles"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area describing the convective flow throug porous media according to Darcy's law
+for spherical particles.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+according to:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * &Kappa; / &eta; * A<sub>cross,bed</sub> * &rho; * l<sub>bed</sub> / 2;
+</pre>
+<p>
+Herein, <i>&Kappa;</i> is the permeability of the bed, <i>A<sub>cross,bed</sub></i> 
+is the cross-sectional area of the bed, <i>l<sub>bed</sub></i> is the total length 
+of the bed, <i>&rho;</i> is the densiy of the adsorptive, and <i>&eta;</i> is the 
+dynamic viscosity of the adsorptive. The permeability <i>&Kappa;</i> is calculated from
+the particle diameter <i>d<sub>particle</sub></i> and void fraction of the bed 
+<i>&psi;<sub>bed</sub></i>:
+</p>
+<pre>
+    &Kappa;= (d<sub>particle</sub>^2 * &psi;<sub>bed</sub>^3) / (150 * (1 - &psi;<sub>bed</sub>)^2);
+</pre>
+<p>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+through a packed bed with spherical particles.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  DBejan, A. (2013). Convection heat transfer. 4th ed. Hoboken, N.J.: Wiley. ISBN: 1118519760.
+  </li>
+  <li>
+  Ergun, S. (1952). Fluid flow through packed columns. Chem. Eng. Prog., 48(2), 89-94.
+  </li>
+  <li>
+  Darcy, H.P.G. (1856). Les Fontaines Publiques de la villa de Dijon. Paris.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end DarcyPackedBedSpheres;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow.mo
new file mode 100644
index 0000000..916ed80
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow.mo
@@ -0,0 +1,184 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow
+  "Mass transfer correlation describing mass transfer through a packed bed followed trough a particle due to Knudsen diffusion and Poiseuille flow"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+     final computeTransportProperties=true,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction_bed = 1
+    "Fitting factor for the bed resistance"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real f_particle = 0.5 * geometry.no_particles *
+    geometry.V_particle / ((4/3) * Modelica.Constants.pi * (d_pore/2)^3)
+    "Fitting factor for the particle resistance"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Length l_bed = 0.025
+    "Total length the adsorptive has to flow through the bed"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Area A_bed = 0.5
+    "Cross-sectional area of the bed that the adsorptive has to pass"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real psi_bed(final unit="1") = geometry.psi_particles
+    "Void fraction of the bed"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  final parameter Real permeability(final unit="m2")=
+    (d_particle^2 * psi_bed^3) / (150 * (1 - psi_bed)^2)
+    "Permeability of the bed"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+
+  parameter Real tortuosity_Knudsen(final unit="m") = 5^1.7
+    "Tortuosity for Knudsen diffusion"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real tortuosity_Poiseuille(final unit="m") = 5^2.6
+    "Tortuosity for Poiseuille flow"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Diameter d_particle = geometry.d_particle
+    "Diameter of one particle"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Diameter d_pore = 25e-9
+    "Average diameter of the pores"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Area A_pore=
+    Modelica.Constants.pi/4 * d_pore^2
+    "Cross-sectional area of one pore"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.MolarMass M_adsorptive = 0.001801528
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  //
+  // Definition of variables
+  //
+  Real R_bed
+    "Mass transport resistance for the bed (i.e., Darcy's law)";
+  Real R_particle
+    "Mass transport resistance for the particle";
+
+  Real D_Knudsen
+    "Diffusion coefficient according to Knudsen diffusin";
+  Real D_Poiseuille
+    "Diffusion coefficient according to Poiseuille flow";
+
+equation
+  //
+  // Calculate diffusion coefficients
+  //
+  R_bed = 1 / (f_correction_bed * (permeability / fluidProperties.eta_adsorptive) *
+    (2 / l_bed) * A_bed * fluidProperties.d_adsorptive)
+    "Mass transport resistance for the bed (i.e., Darcy's law)";
+  R_particle = 1 / (f_particle * (D_Knudsen + D_Poiseuille))
+    "Mass transport resistance for the particle";
+
+  D_Knudsen = 4/3 * d_pore / tortuosity_Knudsen *  A_pore / (d_particle/2) *
+    sqrt(M_adsorptive / (2 * Modelica.Constants.pi * Modelica.Constants.R *
+    fluidProperties.T_adsorptive))
+    "Diffusion coefficient according to Knudsen diffusin";
+  D_Poiseuille =  1/32 * fluidProperties.p_adsorptive * d_pore^2 /
+    fluidProperties.eta_adsorptive / tortuosity_Poiseuille * A_pore / (d_particle/2) *
+    M_adsorptive / (Modelica.Constants.R * fluidProperties.T_adsorptive)
+    "Diffusion coefficient according to Poiseuille flow";
+
+  //
+  // Calculate overall mass transfer coefficient
+  //
+  beta = geometry.no_hydraulicParallelTubes / geometry.no_sorbentVolumes /
+    (R_bed + R_particle)
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area describing the mass transfer through a packed bed according to Darcy's law
+followed by a mass transfer through a particle due to a combination of Knudsen 
+diffusion and Poiseuille flow.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> results from a
+serial connection of mass transfer through the bed <i>D<sub>bed</sub></i> and the
+particle <i>D<sub>particle</sub></i>, with the latter being a parallel connection 
+of the Knudsen diffusion <i>D<sub>Knudsen</sub></i> and Poiseuille flow 
+<i>D<sub>Poiseuille</sub></i>:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * 1 / [1/(f<sub>correction,bed</sub> * D<sub>bed</sub>) + 1 / (f<sub>correction,particle</sub> * (D<sub>Knudsen</sub> + D<sub>Poiseuille</sub>))];
+</pre> 
+<p>
+with:
+</p>
+<pre>
+    D<sub>bed</sub> = &Kappa; / &eta; * A<sub>cross,bed</sub> * &rho; * l<sub>bed</sub> / 2;
+
+    D<sub>Knudsen</sub> = 4/3 * d<sub>pore</sub> / &theta; * A<sub>pore</sub> / (d<sub>particle</sub>/2) * <strong>sqrt</strong>(M<sub>adsorptive</sub> / (2 * &pi; * R * T<sub>adsorptive</sub>));
+
+    D<sub>Poiseuille</sub> = 1/32 * p<sub>adsorptive</sub> * d<sub>pore</sub>^2  / &eta; / &theta; * A<sub>pore</sub> / (d<sub>particle</sub>/2) * M<sub>adsorptive</sub> / (R * T<sub>adsorptive</sub>);
+</pre> 
+<p>
+and:
+</p>
+<pre>
+    &Kappa;= (d<sub>particle</sub>^2 * &psi;<sub>bed</sub>^3) / (150 * (1 - &psi;<sub>bed</sub>)^2);
+</pre>
+<p>
+Herein, <i>f<sub>correction,i</sub></i> is a correction factor, <i>d<sub>pore</sub></i>
+is the average pore diameter, <i>A<sub>pore</sub></i> is the average cross-sectional
+area of one pore, <i>d<sub>particle</sub></i> is the average particle diameter, 
+<i>&Kappa;</i> is the permeability of the bed, <i>A<sub>cross,bed</sub></i> 
+is the cross-sectional area of the bed, <i>l<sub>bed</sub></i> is the total length 
+of the bed, <i>&theta;<sub>Knudsen</sub></i> is the tortuosity factor for Knudsen diffucsion, 
+<i>&theta;<sub>Poiseuille</sub></i> is the tortuosity factor for Knudsen diffucsion,
+<i>M<sub>adsorptive</sub></i> is the molar mass, <i>R</i> is the ideal gas constant, 
+<i>p<sub>adsorptive</sub></i> is the adsorptive pressure, <i>T<sub>adsorptive</sub></i> 
+is the adsorptive temperature, <i>&rho;</i> is the densiy of the adsorptive, and <i>&eta;</i> 
+is the dynamic viscosity of the adsorptive
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+through a packed bed according to Darcy's law followed by a mass transfer through a 
+particle due to a combination of Knudsen diffusion and Poiseuille flow.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Kast, W. (1998). Adsorption aus der Gasphase: Ingenieurwissenschaftliche Grundlagen und technische Verfahren (in German). VCH Verlagsgesellschaft, Weinheim, Basel, Cambridge, New York. DOI:  https://doi.org/10.1002/bbpc.19900940122.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  June 06, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPorousMedia.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPorousMedia.mo
new file mode 100644
index 0000000..ef6963b
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/DarcyPorousMedia.mo
@@ -0,0 +1,90 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model DarcyPorousMedia
+  "Mass transfer correlation describing mass transfer through a packed bed"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+     final computeTransportProperties=true,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Length l_bed = 1
+    "Total length the adsorptive has to flow through the bed"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Area A_bed = Modelica.Constants.pi/4 * 0.01^2
+    "Cross-sectional area of the bed that the adsorptive has to pass"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real permeability(final unit="m2") = 0.32
+    "Permeability of the bed"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes / geometry.no_sorbentVolumes *
+    (permeability / fluidProperties.eta_adsorptive) * (2 / l_bed) * A_bed *
+    fluidProperties.d_adsorptive
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area describing the convective flow throug porous media according to Darcy's law.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+according to:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * &Kappa; / &eta; * A<sub>cross,bed</sub> * &rho; * l<sub>bed</sub> / 2;
+</pre>
+<p>
+Herein, <i>&Kappa;</i> is the permeability of the bed, <i>A<sub>cross,bed</sub></i> 
+is the cross-sectional area of the bed, <i>l<sub>bed</sub></i> is the total length 
+of the bed, <i>&rho;</i> is the densiy of the adsorptive, and <i>&eta;</i> is the 
+dynamic viscosity of the adsorptive.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+through a packed bed.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  DBejan, A. (2013). Convection heat transfer. 4th ed. Hoboken, N.J.: Wiley. ISBN: 1118519760.
+  </li>
+  <li>
+  Darcy, H.P.G. (1856). Les Fontaines Publiques de la villa de Dijon. Paris.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end DarcyPorousMedia;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/KnudsenDiffusion.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/KnudsenDiffusion.mo
new file mode 100644
index 0000000..b07829a
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/KnudsenDiffusion.mo
@@ -0,0 +1,104 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model KnudsenDiffusion
+  "Mass transfer correlation describing mass transfer through a particle due to Knudsen diffusion"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+     final computeTransportProperties=true,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 0.5 * geometry.no_particles *
+    geometry.V_particle / ((4/3) * Modelica.Constants.pi * (d_pore/2)^3)
+    "Fitting factor to account for a whole bed (i.e., can be considered as number
+    of porese"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real tortuosity(final unit="m") = 5^1.7
+    "Tortuosity for Knudsen diffusion"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Diameter d_particle = geometry.d_particle
+    "Diameter of one particle"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Diameter d_pore = 25e-9
+    "Average diameter of the pores"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Area A_pore=
+    Modelica.Constants.pi/4 * d_pore^2
+    "Cross-sectional area of one pore"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.MolarMass M_adsorptive = 0.001801528
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes / geometry.no_sorbentVolumes *
+    f_correction * 4/3 * d_pore / tortuosity *  A_pore / (d_particle/2) *
+    sqrt(M_adsorptive / (2 * Modelica.Constants.pi * Modelica.Constants.R *
+    fluidProperties.T_adsorptive))
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area describing the mass transfer through a particle due to Knudsen diffusion.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+according to:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * f<sub>correction</sub> * 4/3 * d<sub>pore</sub> / &theta; * A<sub>pore</sub> / (d<sub>particle</sub>/2) * <strong>sqrt</strong>(M<sub>adsorptive</sub> / (2 * &pi; * R * T<sub>adsorptive</sub>));
+</pre> 
+<p>
+Herein, <i>f<sub>correction</sub></i> is a correction factor, <i>d<sub>pore</sub></i>
+is the average pore diameter, <i>A<sub>pore</sub></i> is the average cross-sectional
+area of one pore, <i>d<sub>particle</sub></i> is the average particle diameter,
+<i>&theta;</i> is the tortuosity factor, <i>M<sub>adsorptive</sub></i> is the molar 
+mass, <i>R</i> is the ideal gas constant, and <i>T<sub>adsorptive</sub></i> is the 
+adsorptive temperature.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+through a particle that is dominated by Knudsen diffusion.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Kast, W. (1998). Adsorption aus der Gasphase: Ingenieurwissenschaftliche Grundlagen und technische Verfahren (in German). VCH Verlagsgesellschaft, Weinheim, Basel, Cambridge, New York. DOI:  https://doi.org/10.1002/bbpc.19900940122.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  June 06, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end KnudsenDiffusion;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/KnudsenDiffusionPoiseuilleFlow.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/KnudsenDiffusionPoiseuilleFlow.mo
new file mode 100644
index 0000000..b5cc6b8
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/KnudsenDiffusionPoiseuilleFlow.mo
@@ -0,0 +1,141 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model KnudsenDiffusionPoiseuilleFlow
+  "Mass transfer correlation describing mass transfer through a particle due to Knudsen diffusion and Poiseuille flow"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+     final computeTransportProperties=true,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 0.5 * geometry.no_particles *
+    geometry.V_particle / ((4/3) * Modelica.Constants.pi * (d_pore/2)^3)
+    "Fitting factor to account for a whole bed (i.e., can be considered as number
+    of pores per particle"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real tortuosity_Knudsen(final unit="m") = 5^1.7
+    "Tortuosity for Knudsen diffusion"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real tortuosity_Poiseuille(final unit="m") = 5^2.6
+    "Tortuosity for Poiseuille flow"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Diameter d_particle = geometry.d_particle
+    "Diameter of one particle"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Diameter d_pore = 25e-9
+    "Average diameter of the pores"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Area A_pore=
+    Modelica.Constants.pi/4 * d_pore^2
+    "Cross-sectional area of one pore"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.MolarMass M_adsorptive = 0.001801528
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  //
+  // Definition of variables
+  //
+  Real D_Knudsen
+    "Diffusion coefficient according to Knudsen diffusin";
+  Real D_Poiseuille
+    "Diffusion coefficient according to Poiseuille flow";
+
+equation
+  //
+  // Calculate diffusion coefficients
+  //
+  D_Knudsen = 4/3 * d_pore / tortuosity_Knudsen *  A_pore / (d_particle/2) *
+    sqrt(M_adsorptive / (2 * Modelica.Constants.pi * Modelica.Constants.R *
+    fluidProperties.T_adsorptive))
+    "Diffusion coefficient according to Knudsen diffusin";
+  D_Poiseuille =  1/32 * fluidProperties.p_adsorptive * d_pore^2 /
+    fluidProperties.eta_adsorptive / tortuosity_Poiseuille * A_pore / (d_particle/2) *
+    M_adsorptive / (Modelica.Constants.R * fluidProperties.T_adsorptive)
+    "Diffusion coefficient according to Poiseuille flow";
+
+  //
+  // Calculate overall mass transfer coefficient
+  //
+  beta = geometry.no_hydraulicParallelTubes / geometry.no_sorbentVolumes *
+    f_correction * (D_Knudsen + D_Poiseuille)
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area describing the mass transfer through a particle due to a combination of Knudsen 
+diffusion and Poiseuille flow.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> results from a 
+parallel connection of the Knudsen diffusion <i>D<sub>Knudsen</sub></i> and Poiseuille 
+flow <i>D<sub>Poiseuille</sub></i> to
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * f<sub>correction</sub> * (D<sub>Knudsen</sub> + D<sub>Poiseuille</sub>);
+</pre> 
+<p>
+with:
+</p>
+<pre>
+    D<sub>Knudsen</sub> = 4/3 * d<sub>pore</sub> / &theta; * A<sub>pore</sub> / (d<sub>particle</sub>/2) * <strong>sqrt</strong>(M<sub>adsorptive</sub> / (2 * &pi; * R * T<sub>adsorptive</sub>));
+
+    D<sub>Poiseuille</sub> = 1/32 * p<sub>adsorptive</sub> * d<sub>pore</sub>^2  / &eta; / &theta; * A<sub>pore</sub> / (d<sub>particle</sub>/2) * M<sub>adsorptive</sub> / (R * T<sub>adsorptive</sub>);
+</pre> 
+<p>
+Herein, <i>f<sub>correction</sub></i> is a correction factor, <i>d<sub>pore</sub></i>
+is the average pore diameter, <i>A<sub>pore</sub></i> is the average cross-sectional
+area of one pore, <i>d<sub>particle</sub></i> is the average particle diameter,
+<i>&theta;<sub>Knudsen</sub></i> is the tortuosity factor for Knudsen diffucsion, 
+<i>&theta;<sub>Poiseuille</sub></i> is the tortuosity factor for Knudsen diffucsion,
+<i>M<sub>adsorptive</sub></i> is the molar mass, <i>R</i> is the ideal gas constant, 
+<i>p<sub>adsorptive</sub></i> is the adsorptive pressure, and <i>T<sub>adsorptive</sub></i> 
+is the adsorptive temperature.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+through a particle that is dominated by a combination of Knudsen diffusion and 
+Poiseuille flow.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Kast, W. (1998). Adsorption aus der Gasphase: Ingenieurwissenschaftliche Grundlagen und technische Verfahren (in German). VCH Verlagsgesellschaft, Weinheim, Basel, Cambridge, New York. DOI:  https://doi.org/10.1002/bbpc.19900940122.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  June 06, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end KnudsenDiffusionPoiseuilleFlow;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/LaminarConnections.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/LaminarConnections.mo
new file mode 100644
index 0000000..4699726
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/LaminarConnections.mo
@@ -0,0 +1,86 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model LaminarConnections
+  "Mass transfer correlation describing mass transfer through connections for the lamianr flow regime"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+     final computeTransportProperties=true,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real zeta_lam(min=1) = 1
+    "Additional factor to account for nonideal connections"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Length l_connection = 0.5
+    "Length of the connection"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Diameter d_connection = 0.04
+    "Hydraulic diameter of the connection"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Area A_connection=
+    Modelica.Constants.pi/4 * d_connection^2
+    "Inner cross-sectional area of the connection"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = A_connection^2 / (8 * Modelica.Constants.pi * l_connection) *
+    fluidProperties.d_adsorptive / fluidProperties.eta_adsorptive *
+    1/zeta_lam
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area describing the mass transport through a connection for the laminar flow
+regime.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+according to:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * A<sub>connection</sub>^2 / (8 * &pi; * l<sub>connection</sub>) * &rho / &eta; * 1/&zeta;;
+</pre>
+<p>
+Herein, <i>A<sub>connection</sub></i> is the cross-sectional area of the connection,
+<i>l<sub>connection</sub></i> is the total length of the connection, <i>&rho;</i> is
+the densiy of the adsorptive, <i>&eta;</i> is the dynamic viscosity of the adsorptive,
+and <i>&zeta;</i> is a loss factor.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+through connections, such as valves between the evaporator and adsorber.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Lanzerath, F. and Bau, U. and Seiler, J. and Bardow, A. (2015). Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 21(3), 248-257. DOI: https://doi.org/10.1080/10789669.2014.990337.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  Minor revisions after restructuring of the library.
+  </li>
+  <li>
+  November 30, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end LaminarConnections;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/PoiseuilleFlow.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/PoiseuilleFlow.mo
new file mode 100644
index 0000000..9d0fbc6
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/PoiseuilleFlow.mo
@@ -0,0 +1,104 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven;
+model PoiseuilleFlow
+  "Mass transfer correlation describing mass transfer through a particle due to Poiseuille flow"
+  extends
+    SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+     final computeTransportProperties=true,
+     final avoid_events=false);
+
+  //
+  // Definition of parameters
+  //
+  parameter Real f_correction = 0.5 * geometry.no_particles *
+    geometry.V_particle / ((4/3) * Modelica.Constants.pi * (d_pore/2)^3)
+    "Fitting factor to account for a whole bed (i.e., can be considered as number
+    of pores per particle"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Real tortuosity(final unit="m") = 5^2.6
+    "Tortuosity for Poiseuille flow"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Diameter d_particle = geometry.d_particle
+    "Diameter of one particle"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+  parameter Modelica.Units.SI.Diameter d_pore = 25e-9
+    "Average diameter of the pores"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.Area A_pore=
+    Modelica.Constants.pi/4 * d_pore^2
+    "Cross-sectional area of one pore"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+  parameter Modelica.Units.SI.MolarMass M_adsorptive = 0.001801528
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Mass Transfer"));
+
+equation
+  beta = geometry.no_hydraulicParallelTubes / geometry.no_sorbentVolumes *
+    f_correction * 1/32 * fluidProperties.p_adsorptive * d_pore^2 /
+    fluidProperties.eta_adsorptive / tortuosity * A_pore / (d_particle/2) *
+    M_adsorptive / (Modelica.Constants.R * fluidProperties.T_adsorptive)
+    "Mass transfer coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model calculates the product of mass transfer coefficient and
+area describing the the mass transfer through a particle due to Poiseuille flow.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The product of mass transfer coefficient and area <i>&beta;A</i> is calculated 
+according to:
+</p>
+<pre>
+    &beta;A = no<sub>parallel flows</sub> / no<sub>sorbent volumes</sub> * f<sub>correction</sub> * 1/32 * p<sub>adsorptive</sub> * d<sub>pore</sub>^2  / &eta; / &theta; * A<sub>pore</sub> / (d<sub>particle</sub>/2) * M<sub>adsorptive</sub> / (R * T<sub>adsorptive</sub>);
+</pre> 
+<p>
+Herein, <i>f<sub>correction</sub></i> is a correction factor, <i>d<sub>pore</sub></i>
+is the average pore diameter, <i>A<sub>pore</sub></i> is the average cross-sectional
+area of one pore, <i>d<sub>particle</sub></i> is the average particle diameter,
+<i>&theta;</i> is the tortuosity factor, <i>M<sub>adsorptive</sub></i> is the molar 
+mass, <i>R</i> is the ideal gas constant, <i>p<sub>adsorptive</sub></i> is the 
+adsorptive pressure, and <i>T<sub>adsorptive</sub></i> is the adsorptive temperature.
+<br/><br/>
+The product is enlarged by the number of hydrualic parallel flows 
+<i>no<sub>parallel flows</sub></i> to account for parallel flows modeled by just 
+one flow. The area <i>A</i> accounts for the disretization due to the division by
+the discretization number of the sorbent volumes. Accordingly, the total product 
+of mass transfer coefficient and area <i>&beta;A</i> describes on heat exchanger
+tube.
+</p>
+  
+<h4>Typical use</h4>
+<p>
+This mass transfer correlation model is typically used to describe the mass transfer
+through a particle that is dominated by a Poiseuille flow.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Kast, W. (1998). Adsorption aus der Gasphase: Ingenieurwissenschaftliche Grundlagen und technische Verfahren (in German). VCH Verlagsgesellschaft, Weinheim, Basel, Cambridge, New York. DOI:  https://doi.org/10.1002/bbpc.19900940122.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  June 06, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PoiseuilleFlow;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/package.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/package.mo
new file mode 100644
index 0000000..e270d3b
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/package.mo
@@ -0,0 +1,65 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber;
+package PressureDriven "Correlations for pressure-driven mass transfer coefficients describing the mass transfer within closed adsorbers"
+extends Modelica.Icons.FunctionsPackage;
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for mass transfer coefficients describing
+the pressure-driven mass transfer within closed adsorbers:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.ConstantCoefficient\">ConstantCoefficient</a>: 
+  Generic mass transfer correlation with constant mass transfer coefficient.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.ConstantSpecificCoefficient\">ConstantSpecificCoefficient</a>: 
+  Generic mass transfer correlation with constant product of specific mass 
+  transfer coefficient and area
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.DarcyPorousMedia\">DarcyPorousMedia</a>: 
+  Mass transfer correlation describing the mass transfer through a packed bed.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.DarcyPackedBedSpheres\">DarcyPackedBedSpheres</a>: 
+  Mass transfer correlation describing the mass transfer through a packed bed.
+  with spherical particles.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.KnudsenDiffusion\">KnudsenDiffusion</a>: 
+  Mass transfer correlation describing the mass transfer through a particle due
+  to Knudsen diffusion.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.PoiseuilleFlow\">PoiseuilleFlow</a>: 
+  Mass transfer correlation describing the mass transfer through a particle due
+  to a Poiseuille flow.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.KnudsenDiffusionPoiseuilleFlow\">KnudsenDiffusionPoiseuilleFlow</a>: 
+  Mass transfer correlation describing the mass transfer through a particle due
+  to Knudsen diffusion and a Poiseuille flow.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow\">DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow</a>: 
+  Mass transfer correlation describing the mass transfer through a packed bed
+  with spherical particles and through the particles due to Knudsen diffusion and 
+  a Poiseuille flow.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.LaminarConnections\">LaminarConnections</a>: 
+  Mass transfer correlation describing the mass transfer as laminar flow through
+  fittings.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PressureDriven;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/package.order b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/package.order
new file mode 100644
index 0000000..a889854
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/PressureDriven/package.order
@@ -0,0 +1,9 @@
+ConstantCoefficient
+ConstantSpecificCoefficient
+DarcyPorousMedia
+DarcyPackedBedSpheres
+KnudsenDiffusion
+PoiseuilleFlow
+KnudsenDiffusionPoiseuilleFlow
+DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow
+LaminarConnections
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/package.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/package.mo
new file mode 100644
index 0000000..d038058
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/package.mo
@@ -0,0 +1,30 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations;
+package ClosedAdsorber "Correlations for mass transfer coefficients describing the mass transfer within closed adsorbers"
+extends Modelica.Icons.FunctionsPackage;
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for mass transfer coefficients describing
+the mass transfer within closed adsorbers. The correlations are either valid for
+pressure- or loading-driven mass transfers:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven\">PressureDriven</a>: 
+  Correlations for pressure-driven mass transfers.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven\">LoadingDriven</a>: 
+  Correlations for loading-driven mass transfers.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ClosedAdsorber;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/package.order b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/package.order
new file mode 100644
index 0000000..ebeabb2
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/ClosedAdsorber/package.order
@@ -0,0 +1,2 @@
+PressureDriven
+LoadingDriven
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/OpenAdsorber/package.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/OpenAdsorber/package.mo
new file mode 100644
index 0000000..fba80f4
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/OpenAdsorber/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations;
+package OpenAdsorber "Correlations for mass transfer coefficients describing the mass transfer within open adsorbers"
+extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains correlations for mass transfer coefficients describing
+the mass transfer between gwithin open adsorbers.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end OpenAdsorber;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/OpenAdsorber/package.order b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/OpenAdsorber/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/package.mo b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/package.mo
new file mode 100644
index 0000000..9ba7260
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/package.mo
@@ -0,0 +1,30 @@
+within SorpLib.Components.MassTransfer;
+package MassTransferCoefficientCorrelations "Package containing correlations for mass transfer coefficients"
+extends Modelica.Icons.FunctionsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains correlations for mass transfer coefficients that can be used 
+within mass transfer models. The correlations calculate the mass transfer coefficient
+as a function of fluid property data, gemeotry, and flow regime. Correlations for mass
+transfer coefficients are implemented for the following components:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber\">ClosedAdsorber</a>: 
+  Correlations for closed adsorbers.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.OpenAdsorber\">OpenAdsorber</a>: 
+  Correlations for open adsorbers.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructering the library.
+  </li>
+</ul>
+</html>"));
+end MassTransferCoefficientCorrelations;
diff --git a/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/package.order b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/package.order
new file mode 100644
index 0000000..c9cfef3
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/MassTransferCoefficientCorrelations/package.order
@@ -0,0 +1,2 @@
+ClosedAdsorber
+OpenAdsorber
diff --git a/SorpLib/Components/MassTransfer/MassTransferDiffusion.mo b/SorpLib/Components/MassTransfer/MassTransferDiffusion.mo
deleted file mode 100644
index ae54ccb..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferDiffusion.mo
+++ /dev/null
@@ -1,137 +0,0 @@
-within SorpLib.Components.MassTransfer;
-model MassTransferDiffusion
-  extends Partial.PartialMassTransfer(final computeTransportProperties=massTransfer_diffusion_dp.computeTransportProperties or massTransfer_diffusion_dx.computeTransportProperties);
-
-  /************************* VLE models ************************************/
-
-  TILMedia.VLEFluid_ph vleFluidAds(
-    p=vlePortB.p,
-    final vleFluidType=vleFluidType,
-    computeTransportProperties=false,
-    computeSurfaceTension=false,
-    h=inStream(vlePortB.h_outflow),
-    xi=inStream(vlePortB.xi_outflow)) annotation (Placement(transformation(
-          extent={{56,-40},{76,-20}}, rotation=0)));
-
-  /********************* AdsorbentAdsorbate ***********************************/
-
-  replaceable model AdsorbentAdsorbate =
-      SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater
-    constrainedby
-    SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater
-    annotation (choicesAllMatching=true, Dialog(group="Adsorbent / Adsorbate"));
-
-  AdsorbentAdsorbate adsorbentAdsorbateA(x=xA_eq, T=T) annotation (Placement(
-        transformation(extent={{-100,-40},{-80,-20}},rotation=0)));
-
-  AdsorbentAdsorbate adsorbentAdsorbateB(x=xB, T=T) annotation (Placement(
-        transformation(extent={{80,-40},{100,-20}},rotation=0)));
-
-  /***************************** Mass Transfer model **************************/
-
-  replaceable model MassTransfer_diffusion_dp =
-      MassTransferPhenomena.ConstantCoefficient_dp
-    constrainedby MassTransferPhenomena.Partial.PartialMassTransfer_dp
-    "Mass Transfer Model" annotation (Placement(transformation(extent={{-32,-70},
-            {-12,-50}})), choices(choice(redeclare model
-                MassTransfer_diffusion_dp =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dp),
-            choice(redeclare model MassTransfer_diffusion_dp =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantSpecificCoefficient_dp)),
-    Dialog(enable=inputChoice == "dp", group="Diffusion"));
-
-  MassTransfer_diffusion_dp massTransfer_diffusion_dp
-    "Mass Transfer model for diffusion resistance";
-
-  replaceable model MassTransfer_diffusion_dx =
-      MassTransferPhenomena.ConstantCoefficient_dx
-    constrainedby MassTransferPhenomena.Partial.PartialMassTransfer_dx
-    "Mass Transfer Model" annotation (Placement(transformation(extent={{-32,-70},
-            {-12,-50}})), choices(choice(redeclare model
-                MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dx),
-            choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantSpecificCoefficient_dx),
-            choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.Glueckauf_dx "Glückauf-approach dx"),
-            choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.GlueckaufArrhenius_dx
-                                                                                        "Glückauf-approach with temperature dependance dx"),
-            choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_Zeolite13X_des
-                                                                                                      "Diffusion coefficient and particle diameter for Zeolith 13X desorption (Lanzerath 2015)"),
-            choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_Zeolite13X_ads
-                                                                                                      "Diffusion coefficient and particle diameter for Zeolith 13X adsorption (Lanzerath 2015)"),
-            choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_SilicaGel
-                                                                                                 "Diffusion coefficient and particle diameter for Silica Gel 123 (Lanzerath 2015)"),
-            choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.Record.DiffusionCoefficients.SakodaSuzuki1984_SilicaGel
-                                                                                                    "Diffusion coefficient and particle diameter for Silica-gel Fuji-A-type (Sakoda Suzuki 1984)")),
-    Dialog(enable=inputChoice == "dx", group="Diffusion"));
-
-  MassTransfer_diffusion_dx massTransfer_diffusion_dx
-    "Mass Transfer model for diffusion resistance";
-
-  /****************** General parameters *******************/
-
-  parameter String inputChoice="dp" "Driving force of diffusion"
-    annotation (choices(choice="dp", choice="dx"));
-
-  /************************* Additional variables ***************/
-protected
-  inner Modelica.SIunits.Temperature T "Temperature of adsorbent";
-  Real xB "Loading of adsorbent";
-  Real xA_eq "Equilibrium loading of adsorbent given portA.p and T";
-
-equation
-  adsorbentAdsorbateB.p = vlePortB.p;
-  adsorbentAdsorbateA.p = vlePortA.p;
-  T = vleFluidAds.T;
-
-  if noEvent(valveOpen) and inputChoice == "dp" then
-    vlePortA.m_flow = massTransfer_diffusion_dp.beta*(vlePortA.p - vlePortB.p);
-  elseif noEvent(valveOpen) and inputChoice == "dx" then
-    vlePortA.m_flow = massTransfer_diffusion_dx.beta*(xA_eq - xB);
-  else
-    vlePortA.m_flow = 0;
-  end if;
-
-  annotation (Icon(graphics={Bitmap(
-          extent={{-80,-60},{82,70}},
-          imageSource="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"
-               + "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"
-               + "2enq14vuXb169VuiewCj0fdD3xNP1O7CSY1e5foCSB4AAAAkQfiI7gGMwI4/0PeCqB0geQAAAJAm2fON7t27d880k2CxD3lsoqLzXzWsRO0AyQMAAIC0C9+60xGw427WYoWPCB/kTOyI2gGSBwAAAJmRvSVnYdtwL3g1aF1t4tV4AuGDtKMZkkPEru10yCxyPQAkDwAAALIsfE2ED7Igdj4NVBA7QPIAAAAgt8Kn+r3KMOFTk4r3798jE5AoXr9+jdgBIHkAAAAwq/CJlZUVMyT63bt3SAZEjoaUb29vd+7cuWMeQCB2AEgeAAAAzC58p17hU/REdU9K6/z666+REAgtWvfgwYPOjRs3vFLXcR5E7CB2AEgeAAAAzCZ8i84Mvpp7LIN7Fl+1WiXKB2FG686dLrFl1ZTyvQRA8gAAACBY6St22RoV5dNi/fDwEHmBoajWU9HgCaJ1zLEDQPIAAAAgQuEbGeVTK/vbt2+bSJ+6ICI3+UWRXsm/Gvpcv37dT+qI1gEgeQAAAJBA6Ss6tXwHftJn0zvVxEXDquncmU00gkNS/+jRIyP5PumXVuoOnagw0ToAJA8AAABSIn3LTqRvz69rp1CqnlI8nz9/bsSAGX3pQ8dN4zaUeimJ9zvOXVpOxFeRugLfDwAkDwAAALIhfQtd1rpsO1GcCz8hUG3frVu3TCRIdVtv375FphKA6iwVgdVxUYOUIbV0loZznNeV1sv5D4DkAQAAQH7ETymem86ss8Yw8bPz+lTTJclQi311ZES+wmmKouicaikVZR0RnXML3Z6TqkvqJQCSBwAAADAgfsuuiN++XydPb8qnIn9KF5QAKtpE6udoFB21dXOqkdT+m0DmWk69pY3QkXYJgOQBAAAAzCV/ivqVXOme7TFS0mv2YtM/heRGZHXMgyKc9mdUraNNr9Q+GNIExcuZK92yTHQOAMkDAAAAiFr+bOSv7Ir+NYZ1+ByGJMhy//79nhSq9b+VJjdhRAo1asDvvZSeaj+PUNqq+/NO83M6KbENV1Su4uw/InMASB4AAABAKiSw6EhMxRUFbIyrAUwxDRfbzpiCNSJyAEgeAAAAQN5k0EYE15yas20XBx55spwGLGjNIe9z6Pk8JddnJQIHAIb/P9KYNmyq3IR9AAAAAElFTkSuQmCC",
-          fileName="modelica://SorpLib/Resources/Images/MassTransferDiffusion.png")}),
-      Documentation(info="<html>
-  <p>
-    The Mass Transfer Diffusion model extends the <a href=\"modelica://SorpLib.Components.MassTransfer.Partial.PartialMassTransfer\">SorpLib.Components.MassTransfer.Partial.PartialMassTransfer</a>.<br>
-    The Mass Transfer Diffusion model describes the mass transfer resistance caused by intra-particle resistances.<br>
-    The Mass Transfer Diffusion model can be used to model an effective mass transfer resistance (e.g. LDF approach) but also to model detailled diffusion process (e.g., Knudsen diffsion or surface diffusion) 
-    with spatial distribution of the particle using a finite volume approach. 
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    The mass flow <code>m&#775;</code> can be proportional to a pressure drop <code>&Delta;</code>p or to a loading difference (<i>x</i>-<i>x</i><sub>eq</sub>):
-    <p align=\"center\"><i><code>m&#775;</code></i><sub>in</sub> = <i><code>&beta;</code></i> <i><code>&Delta;</code>p</i></p>
-    <p align=\"center\"><i><code>m&#775;</code></i><sub>in</sub> = <i><code>&beta;</code></i> (<i>x</i>-<i>x</i><sub>eq</sub>)</p>
-    For the mass transfer coefficient <i><code>&beta;</code></i>, different correlations are implemented based on the partial models
-    <a href=\"modelica://SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp\">SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp</a>
-    and <a href=\"modelica://SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dx\">SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dx</a>.
-  </p>
- <h4>Implementation</h4>
-  <p>
-    Two adsorbent/adsorbate equilibrium models are used in Mass Transfer Diffusion model to determine the loading <i>x</i> and the equilibirum loading <i>x</i><sub>eq</sub>.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>November 30, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>
-"));
-end MassTransferDiffusion;
diff --git a/SorpLib/Components/MassTransfer/MassTransferDiffusionFlow.mo b/SorpLib/Components/MassTransfer/MassTransferDiffusionFlow.mo
deleted file mode 100644
index a306038..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferDiffusionFlow.mo
+++ /dev/null
@@ -1,185 +0,0 @@
-within SorpLib.Components.MassTransfer;
-model MassTransferDiffusionFlow
-  extends Partial.PartialMassTransfer(final computeTransportProperties=
-        massTransfer_diffusion_dp.computeTransportProperties or
-        massTransfer_diffusion_dx.computeTransportProperties or
-        massTransfer_flow.computeTransportProperties);
-
-  /************************* VLE models ************************************/
-
-  TILMedia.VLEFluid_ph vleFluidAds(
-    p=vlePortB.p,
-    final vleFluidType=vleFluidType,
-    computeTransportProperties=false,
-    computeSurfaceTension=false,
-    h=inStream(vlePortB.h_outflow),
-    xi=inStream(vlePortB.xi_outflow)) annotation (Placement(transformation(
-          extent={{56,-40},{76,-20}}, rotation=0)));
-
-  /********************* AdsorbentAdsorbate ***********************************/
-
-  replaceable model AdsorbentAdsorbate =
-      SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater
-    constrainedby
-    SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater annotation (
-      choicesAllMatching=true, Dialog(group="Adsorbent / Adsorbate"));
-
-  AdsorbentAdsorbate adsorbentAdsorbateStar(x=xStar_eq, T=T) annotation (
-      Placement(transformation(extent={{-40,-40},{-20,-20}}, rotation=0)));
-
-  AdsorbentAdsorbate adsorbentAdsorbateB(x=xB, T=T) annotation (Placement(
-        transformation(extent={{80,-40},{100,-20}}, rotation=0)));
-
-  /***************************** Mass Transfer model **************************/
-
-  replaceable model MassTransfer_flow =
-      SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp
-    constrainedby
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp
-    "Mass Transfer Model" annotation (
-    Placement(transformation(extent={{-32,-70},{-12,-50}})),
-    choices(
-      choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dp),
-      choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantSpecificCoefficient_dp),
-      choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.Laminar_dp),
-      choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.DarcyPorousMedia_dp
-          "Mass transfer in porous media following Darcy's law"),
-      choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_des
-          "Coefficients Flow Resistance adsorber -> condenser (Lanzerath 2015)"),
-      choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_ads
-          "Coefficients flow resistance evaporator -> adsorber (Lanzerath 2015)")),
-    Dialog(group="Flow"));
-
-  MassTransfer_flow massTransfer_flow "Mass Transfer model for flow resistance";
-
-  parameter String inputChoice="dp" "Driving force of diffusion"
-    annotation (Dialog(group="Diffusion"), choices(choice="dp", choice="dx"));
-
-  replaceable model MassTransfer_diffusion_dp =
-      MassTransferPhenomena.ConstantCoefficient_dp constrainedby
-    MassTransferPhenomena.Partial.PartialMassTransfer_dp "Mass Transfer Model"
-    annotation (
-    Placement(transformation(extent={{-32,-70},{-12,-50}})),
-    choices(choice(redeclare model MassTransfer_diffusion_dp =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dp),
-        choice(redeclare model MassTransfer_diffusion_dp =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantSpecificCoefficient_dp)),
-    Dialog(enable=inputChoice == "dp", group="Diffusion"));
-
-  MassTransfer_diffusion_dp massTransfer_diffusion_dp
-    "Mass Transfer model for diffusion resistance";
-
-  replaceable model MassTransfer_diffusion_dx =
-      MassTransferPhenomena.ConstantCoefficient_dx constrainedby
-    MassTransferPhenomena.Partial.PartialMassTransfer_dx "Mass Transfer Model"
-    annotation (
-    Placement(transformation(extent={{-32,-70},{-12,-50}})),
-    choices(
-      choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dx),
-      choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantSpecificCoefficient_dx),
-      choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.Glueckauf_dx
-          "Glückauf-approach dx"),
-      choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.GlueckaufArrhenius_dx
-          "Glückauf-approach with temperature dependance dx"),
-      choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_Zeolite13X_des
-          "Diffusion coefficient and particle diameter for Zeolith 13X desorption (Lanzerath 2015)"),
-      choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_Zeolite13X_ads
-          "Diffusion coefficient and particle diameter for Zeolith 13X adsorption (Lanzerath 2015)"),
-      choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.Record.DiffusionCoefficients.Lanzerath2015_SilicaGel
-          "Diffusion coefficient and particle diameter for Silica Gel 123 (Lanzerath 2015)"),
-      choice(redeclare model MassTransfer_diffusion_dx =
-            SorpLib.Components.MassTransfer.Record.DiffusionCoefficients.SakodaSuzuki1984_SilicaGel
-          "Diffusion coefficient and particle diameter for Silica-gel Fuji-A-type (Sakoda Suzuki 1984)")),
-    Dialog(enable=inputChoice == "dx", group="Diffusion"));
-
-
-
-  MassTransfer_diffusion_dx massTransfer_diffusion_dx
-    "Mass Transfer model for diffusion resistance";
-
-  /****************** General parameters *******************/
-
-
-  Modelica.SIunits.Pressure dp_AStar
-    "calculated pressure drop between A and Star";
-  Modelica.SIunits.Pressure dp_StarB
-    "calculated pressure drop between Star and B";
-
-
-  /************************* Additional variables ***************/
-  Modelica.SIunits.Pressure pStar
-    "Pressure after valve before adsorber (flow resistance)";
-
-  inner Modelica.SIunits.Temperature T "Temperature of adsorbent";
-  Real xB "Loading of adsorbent given pads and Tads";
-  Real xStar_eq "Equilibrium loading of adsorbent given pStar and Tads";
-
-equation
-  adsorbentAdsorbateB.p = vlePortB.p;
-  adsorbentAdsorbateStar.p = pStar;
-  T = vleFluidAds.T;
-
-  dp_AStar = vlePortA.p - pStar;
-  dp_StarB = pStar - vlePortB.p;
-
-  if noEvent(valveOpen) and inputChoice == "dp" then
-    vlePortA.m_flow = massTransfer_flow.beta*(vlePortA.p - pStar);
-    vlePortA.m_flow = massTransfer_diffusion_dp.beta*(pStar - vlePortB.p);
-    adsorbentAdsorbateStar.p = pStar;
-  elseif noEvent(valveOpen) and inputChoice == "dx" then
-    vlePortA.m_flow = massTransfer_flow.beta*(vlePortA.p - pStar);
-    vlePortA.m_flow = massTransfer_diffusion_dx.beta*(xStar_eq - xB);
-  else
-    vlePortA.m_flow = 0;
-    pStar = vlePortB.p;
-  end if;
-
-  annotation (Icon(graphics={Bitmap(
-          extent={{-90,-64},{84,72}},
-          imageSource=
-              "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"
-               +
-              "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"
-               +
-              "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",
-          fileName=
-              "modelica://SorpLib/Resources/Images/MassTransferDiffusionFlow.png"),
-          Line(
-          points={{-50,0},{-50,-44}},
-          color={0,0,0},
-          thickness=0.5,
-          enable=inputChoice == "dx")}), Documentation(info="<html>
-  <p>
-    The Mass Transfer Diffusion Flow model connects the flow and the diffusion resistance in series.<br>
-    The Mass Transfer Diffusion Flow model is a combination of 
-    <a href=\"modelica://SorpLib.Components.MassTransfer.MassTransferFlow\">SorpLib.Components.MassTransfer.MassTransferFlow</a> and
-    <a href=\"modelica://SorpLib.Components.MassTransfer.MassTransferDiffusion\">SorpLib.Components.MassTransfer.MassTransferDiffusion</a>
-  </p>
-  <h4>Assumptions and limitations</h4>
-  <p>
-    The model has no storage volume.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>November 30, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>
-"));
-end MassTransferDiffusionFlow;
diff --git a/SorpLib/Components/MassTransfer/MassTransferFlow.mo b/SorpLib/Components/MassTransfer/MassTransferFlow.mo
deleted file mode 100644
index c1cb6ab..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferFlow.mo
+++ /dev/null
@@ -1,68 +0,0 @@
-within SorpLib.Components.MassTransfer;
-model MassTransferFlow
-  extends Partial.PartialMassTransfer(final computeTransportProperties=massTransfer_flow.computeTransportProperties);
-
-  /***************************** Mass Transfer model ******************************************/
-
-  replaceable model MassTransfer_flow =
-      SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp
-    constrainedby
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp
-    "Mass Transfer Model" annotation (Placement(transformation(extent={{-32,-70},
-            {-12,-50}})),  choices(choice(redeclare model
-                MassTransfer_flow =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dp),
-            choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantSpecificCoefficient_dp),
-            choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.Laminar_dp),
-            choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.DarcyPorousMedia_dp
-                                                                                      "Mass transfer in porous media following Darcy's law"),
-            choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_des
-                                                                                          "Coefficients Flow Resistance adsorber -> condenser (Lanzerath 2015)"),
-            choice(redeclare model MassTransfer_flow =
-            SorpLib.Components.MassTransfer.Record.FlowCoefficients.FlowRes_Lanzerath_ads
-                                                                                          "Coefficients flow resistance evaporator -> adsorber (Lanzerath 2015)")),
-    Dialog(group="Mass transfer model"));
-
-  MassTransfer_flow massTransfer_flow "Mass Transfer model for flow resistance";
-
-equation
-
-  if noEvent(valveOpen) then
-      vlePortA.m_flow = massTransfer_flow.beta*(vlePortA.p - vlePortB.p);
-   else
-      vlePortA.m_flow = 0;
-   end if;
-
-  annotation (Icon(graphics={Line(
-          points={{0,-2},{0,-46}},
-          color={0,0,0},
-          thickness=0.5),
-          Bitmap(extent={{-81,-46},{81,84}}, fileName=
-          "modelica://SorpLib/Resources/Images/MassTransfer.png")}),
-      Documentation(info="<html>
-  <p>
-    The Mass Transfer Flow model extends the <a href=\"modelica://SorpLib.Components.MassTransfer.Partial.PartialMassTransfer\">SorpLib.Components.MassTransfer.Partial.PartialMassTransfer</a>.<br>
-    The Mass Transfer Flow model describes the mass transfer resistance caused by friction in tubes and connections or an inter-particle mass transfer within the packed bed.
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    The mass flow <code>m&#775;</code> is proportional to a pressure drop <code>&Delta;</code>p:
-    <p align=\"center\"><i><code>m&#775;</code></i><sub>in</sub> = <i><code>&beta;</code></i> <i><code>&Delta;</code>p</i></p>
-    For the mass transfer coefficient <i><code>&beta;</code></i>, different correlations are implemented based on the partial model 
-    <a href=\"modelica://SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp\">SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp</a>.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>November 30, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>
-"));
-end MassTransferFlow;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantCoefficient_dp.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantCoefficient_dp.mo
deleted file mode 100644
index 4d2f828..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantCoefficient_dp.mo
+++ /dev/null
@@ -1,34 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model ConstantCoefficient_dp
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp(
-      final computeTransportProperties=false);
-
-  parameter Real constantCoefficient(final unit="m.s")=1e-7
-    "Constant mass transfer coefficient (dp)";
-equation
-  beta = constantCoefficient;
-  annotation (Documentation(info="<html>
-<p>
-  This simple transfer model calculates the mass flow based on the pressure differnce with a constant transfer coefficient.
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"><i><code>m&#775;</code></i> = <i><code>&beta;</code></i> <i><code>&Delta;</code>p</i></p>
-  <p>where <i><code>&beta;</code></i> is a constant parameter</p>
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    In general, the mass transfer coefficient depends on fluid properties. Thus, a constant coefficient is only an approximation.
-  </p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ConstantCoefficient_dp;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantCoefficient_dx.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantCoefficient_dx.mo
deleted file mode 100644
index b69ec29..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantCoefficient_dx.mo
+++ /dev/null
@@ -1,31 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model ConstantCoefficient_dx
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dx(
-      final computeTransportProperties=false);
-
-  parameter Real constantCoefficient(final unit="kg/s")= 1e-7
-    "Constant mass transfer coefficient (dx)";
-equation
-  beta = constantCoefficient;
-  annotation (Documentation(info="<html>
-<p>
-  This simple mass transfer model provides a constant mass transfer coefficient.
-</p>
-<h4>Main equations</h4>
-<p>
-  The mass transfer according to the Linear Driving Force apporach is determined by the following equation:
-  <p align=\"center\"> <i><code>m&#775;</code></i> = <code>&beta;</code> (<i>x</i> - <i>x</i><sub>eq</sub>) </p>
-  where <code>&beta;</code> is a constant mass transfer coefficient.<br>
-</p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ConstantCoefficient_dx;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantSpecificCoefficient_dp.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantSpecificCoefficient_dp.mo
deleted file mode 100644
index d199fe9..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantSpecificCoefficient_dp.mo
+++ /dev/null
@@ -1,34 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model ConstantSpecificCoefficient_dp
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp(
-      final computeTransportProperties=false);
-
-  parameter Real constantCoefficient(final unit="m.s")=1e-7
-    "Constant mass transfer coefficient (dp)";
-equation
-  beta = constantCoefficient;
-  annotation (Documentation(info="<html>
-<p>
-  This simple transfer model calculates the mass flow based on the pressure differnce with a constant transfer coefficient.
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"><i><code>m&#775;</code></i> = <i><code>&beta;</code></i> <i>A</i> <i><code>&Delta;</code>p</i></p>
-  <p>where <code>&beta;</code> is a constant specific mass transfer coefficient and <i>A</i> is the mass transfer area.</p>
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    In general, the mass transfer coefficient depends on fluid properties. Thus, a constant coefficient is only an approximation.
-  </p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ConstantSpecificCoefficient_dp;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantSpecificCoefficient_dx.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantSpecificCoefficient_dx.mo
deleted file mode 100644
index de2e406..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/ConstantSpecificCoefficient_dx.mo
+++ /dev/null
@@ -1,33 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model ConstantSpecificCoefficient_dx
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dx(
-      final computeTransportProperties=false);
-
-  parameter Real specific_linear_Coefficient(final unit="kg/(s.m2)", start = 1e-7)
-    "Specific linear mass transfer coefficient (dx)";
-
-  parameter Modelica.SIunits.Area area(start=1) "Mass transfer area";
-equation
-  beta = specific_linear_Coefficient*area;
-  annotation (Documentation(info="<html>
-<p>
-  This simple mass transfer model provides a constant specific mass transfer coefficient.
-</p>
-<h4>Main equations</h4>
-<p>
-  The mass transfer according to the Linear Driving Force apporach is determined by the following equation:
-  <p align=\"center\"> <i><code>m&#775;</code></i> = <code>&beta;</code> <i>A</i> (<i>x</i> - <i>x</i><sub>eq</sub>) </p>
-  where <code>&beta;</code> is a constant specific mass transfer coefficient and <i>A</i> is the mass transfer area.<br>
-</p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end ConstantSpecificCoefficient_dx;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/DarcyPackedBed_Spheres_dp.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/DarcyPackedBed_Spheres_dp.mo
deleted file mode 100644
index f1b4c6d..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/DarcyPackedBed_Spheres_dp.mo
+++ /dev/null
@@ -1,51 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model DarcyPackedBed_Spheres_dp
-  "Mass transfer in a packed bed with spheres following Darcy's law"
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp(
-      final computeTransportProperties=true);
-
-  outer TILMedia.Internals.PropertyRecord properties "Property record";
-
-  parameter Real eps_b(start=0.32) "Bed porosity";
-  parameter Modelica.SIunits.Area area "Mass transfer area";
-  parameter Modelica.SIunits.Length Dp "Diameter of spheres";
-  parameter Modelica.SIunits.Length dx "Bed thickness";
-  final parameter Real k_D( final unit="m2") = (Dp^2 * eps_b^3)/(150 * (1-eps_b)^2)
-    "Permeability of bed";
-equation
-  beta = (k_D/properties.transp.eta)*(2/dx)*area*properties.d;
-  annotation (Documentation(info="<html>
-<p>
-  For a packed bed of spheres, the convective flow in a porous media can be described by Darcy's law (1856) with a correlation for the permeability proposed by Ergun (1952).
-</p>
-<h4>Main equations</h4>
-<p>
-  The convective flow can be expressed as:
-  <p align=\"center\"> <i>v</i> = - <i>K</i> / <code>&eta;</code> d<i>p</i>/d<i>x</i>. </p>
-  where <i>v</i> is the flow velocity, <i>K</i> is the permeability, <code>&eta;</code> is the dynamic viscosity and d<i>p</i>/d<i>x</i> is the pressure gradient, <br>
-  This can be translated in the following equation for the mass flow:
-  <p align=\"center\"> <i><code>m&#775;</code></i> = <i>K</i> / <code>&eta;</code> * <i>A</i> * <code>&rho;</code> / (<code>&Delta;</code><i>x</i> / 2) * <code>&Delta;</code><i>p</i>, </p>
-  where <i>A</i> is the cross-sectional area, <code>&rho;</code> is the density, and <code>&Delta;</code><i>x</i> is the total bed length.<br>
-  For packed bed of spheres, the permeability <i>K</i> can be expressed as:
-  <p align=\"center\"> <i>K</i> = <i>d</i><sup>2</sup>  <code>&Phi;</code><sup>3</sup> / [150 (1 - <code>&Phi;</code><sup>2</sup>],</p>
-  where <i>d</i> is the diameter of the spheres and <code>&Phi;</code> is the bed porosity.<br>
-  For more information see also Bejan (2013).
-</p>
-<h4>References</h4>
-<ul>
-  <li>Darcy, H.P.G. Les Fontaines Publiques de la villa de Dijon. Paris, 1856.</li>
-  <li>Ergun, S. Fluid flow through packed columns. Chem. Eng. Prog., 1952, 48(2), 89-94.</li>
-  <li>Bejan, A. Convection heat transfer. 4th ed. Hoboken, N.J.: Wiley, 2013. ISBN 1118519760.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end DarcyPackedBed_Spheres_dp;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/DarcyPorousMedia_dp.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/DarcyPorousMedia_dp.mo
deleted file mode 100644
index abcca47..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/DarcyPorousMedia_dp.mo
+++ /dev/null
@@ -1,43 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model DarcyPorousMedia_dp "Mass transfer in porous media following Darcy's law"
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp(
-      final computeTransportProperties=true);
-
-  outer TILMedia.Internals.PropertyRecord properties "Property record";
-
-  parameter Modelica.SIunits.Area area "Mass transfer area";
-  parameter Modelica.SIunits.Length dx "Bed thickness";
-  parameter Real k( final unit="m2",start=1) "Permeability of bed";
-equation
-  beta = (k/properties.transp.eta)*(2/dx)*area*properties.d;
-  annotation (Documentation(info="<html>
-<p>
-  The convective flow in a porous media can be described by Darcy's law (1856).
-</p>
-<h4>Main equations</h4>
-<p>
-  The convective flow can be expressed as:
-  <p align=\"center\"> <i>v</i> = - <i>K</i> / <code>&eta;</code> d<i>p</i>/d<i>x</i> </p>
-  where <i>v</i> is the flow velocity, <i>K</i> is the permeability, <code>&eta;</code> is the dynamic viscosity and d<i>p</i>/d<i>x</i> is the pressure gradient. <br>
-  This can be translated in the following equation for the mass flow:
-  <p align=\"center\"> <i><code>m&#775;</code></i> = <i>K</i> / <code>&eta;</code> * <i>A</i> * <code>&rho;</code> / (<code>&Delta;</code><i>x</i> / 2) * <code>&Delta;</code><i>p</i> </p>
-  where <i>A</i> is the cross-sectional area, <code>&rho;</code> is the density, and <code>&Delta;</code> <i>x</i> is the total bed length.<br>
-  For more information see also Bejan (2013).
-</p>
-<h4>References</h4>
-<ul>
-  <li>Darcy, H.P.G. Les Fontaines Publiques de la villa de Dijon. Paris, 1856.</li>
-  <li>Bejan, A. Convection heat transfer. 4th ed. Hoboken, N.J.: Wiley, 2013. ISBN 1118519760.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end DarcyPorousMedia_dp;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/GlueckaufArrhenius_dx.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/GlueckaufArrhenius_dx.mo
deleted file mode 100644
index 98901b2..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/GlueckaufArrhenius_dx.mo
+++ /dev/null
@@ -1,52 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model GlueckaufArrhenius_dx "Glückauf-approach with temperature dependance dx"
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dx(
-      final computeTransportProperties=false);
-
-  parameter Modelica.SIunits.Mass m_ads(start=2) "Mass of sorbent material";
-  parameter Real Dso(final unit="m2/s", start = 2.54e-4) "Diffusion coefficient";
-  parameter Modelica.SIunits.Length r(start=0.001) "Radius of adsorbent grains";
-  parameter Modelica.SIunits.SpecificEnergy Ea(start=2.33e6) "Activation energy";
-  parameter Modelica.SIunits.MolarMass M(start=0.018) "Molar mass of fluid";
-  final parameter Modelica.SIunits.SpecificHeatCapacity Rm=Modelica.Constants.R/M
-    "Specific gas constant of fluid [J/kg K]";
-
-  outer Modelica.SIunits.Temperature T "Adsorbent temperature";
-
-equation
-  beta = 15*m_ads*Dso/r^2*exp(-Ea/(Rm*T));
-  annotation (Documentation(info="<html>
-<p>
-  This mass transfer model derived by Glueckauf (1955) for spheres is enhanced by an Arrhenius approach to determine the mass diffusion coefficient <i>D</i>.
-</p>
-<h4>Main equations</h4>
-<p>
-  The mass transfer according to the Linear Driving Force apporach is determined by the following equation:
-  <p align=\"center\"> <i><code>m&#775;</code></i> = 15 <i>D</i> / <i>r</i><sup>2</sup> * <i>m</i><sub>sor</sub> (<i>x</i> - <i>x</i><sub>eq</sub>) </p>
-  where <i>D</i> is the diffusion coefficient and <i>r</i> is the particle radius.<br>
-  Using the Arrhenius approach, the diffusion coefficient can be determined by the following temperature dependent correlation:
-  <p align=\"center\"> <i>D</i> = <i>D</i><sub>s,0</sub>  exp ( -<i>E</i><sub>a</sub> / (<i>R T</i>) ) </p>
-  where <i>D</i><sub>s,0</sub> is a pre-exponent constant, <i>E</i><sub>a</sub> is the activation energy, <i>R</i> is the gas constant, and <i>T</i> is the temperature.
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    This correlation can be used when Knudsen diffusion is the dominant mass transfer regime Ruthven (1984). <br>
-    For silica-gel, this approach is used by Sakoda and Suzuki (1984) and by many studies referring to it. 
-  </p>
-<h4>References</h4>
-<ul>
-  <li>Ruthven, D.M. Principles of adsorption and adsorption processes. New York: Wiley, 1984. ISBN 0471866067.</li>
-  <li>Sakoda, A.; Suzuki, M. Fundamental study on a solar powered adsorption cooling system. Journal of Chemical Engineering of Japan, 1984, 17(1), 52-57.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end GlueckaufArrhenius_dx;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Glueckauf_dx.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Glueckauf_dx.mo
deleted file mode 100644
index 2849c7d..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Glueckauf_dx.mo
+++ /dev/null
@@ -1,41 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model Glueckauf_dx "Glückauf-approach dx"
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dx(
-      final computeTransportProperties=false);
-
-  parameter Modelica.SIunits.Mass m_ads(start=2) "Mass of adsorbent material";
-  parameter Real D(final unit="m2/s", start = 1e-10) "Diffusion coefficient";
-  parameter Modelica.SIunits.Length r(start=0.002) "Radius of adsorbent grains";
-
-equation
-  beta = 15*m_ads*D/r^2;
-  annotation (Documentation(info="<html>
-<p>
-  This mass transfer model was derived by Glueckauf (1955) for spheres.
-</p>
-<h4>Main equations</h4>
-<p>
-  The mass transfer according to the Linear Driving Force apporach is determined by the following equation:
-  <p align=\"center\"> <i><code>m&#775;</code></i> = 15 <i>D</i> / <i>r</i><sup>2</sup> * <i>m</i><sub>sor</sub> (<i>x</i> - <i>x</i><sub>eq</sub>) </p>
-  where <i>D</i> is the diffusion coefficient and <i>r</i> is the particle radius.<br>
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    This correlation is derived for spheres.
-  </p>
-<h4>References</h4>
-<ul>
-  <li>Glueckauf, E. Theory of Chromatography. Part 10: Formulae for Diffusion into Spheres and their Application to Chromatography. Transactions of the Faraday Society, 1955, 51(11), 1540-1551.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end Glueckauf_dx;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Laminar_dp.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Laminar_dp.mo
deleted file mode 100644
index b9c7957..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Laminar_dp.mo
+++ /dev/null
@@ -1,50 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-model Laminar_dp
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp(
-      final computeTransportProperties=true);
-
-  outer TILMedia.Internals.PropertyRecord properties "Property record";
-
-  parameter Real zeta_lam(min=1)=1 "Additional factor to account for nonideal tube";
-  parameter Modelica.SIunits.Length L(start=0.4) "Length of valve";
-  parameter Modelica.SIunits.Diameter d(start=0.3) "Inner diameter of valve";
-  final parameter Modelica.SIunits.Area A=Modelica.Constants.pi*(d/2)^2
-    "Inner Cross sectional area";
-
-equation
-
-  beta = A^2/(8*Modelica.Constants.pi*L)*properties.d/properties.transp.eta
-    *1/zeta_lam;
-  annotation (Documentation(info="<html>
-<p>
-  This laminar transfer model calculates the mass flow based on the pressure differnce according to the VDI Wärmeatlas (2013).
-</p>
-<h4>Main equations</h4>
-<p>
-  For a laminar flow, the correlation between mass flow and pressure drop can be expressed as:
-  <p align=\"center\"> <i><code>&Delta;</code>p</i> = <code>&zeta;</code></i><sub>lam</sub> * 8 <code>&pi;</code> <i>L</i> / <i>A</i><sup>2</sup> * <code>&eta;</code> / <code>&rho;</code> <i><code>m&#775;</code></i> </p>
-  where <i>A</i> is the cross-sectional area, <code>&eta;</code> is the viscosity, <code>&rho;</code> is the density and <code>&zeta;</code></i><sub>lam</sub> is an additional factor to account for a non-ideal tube.<br>
-  This correlation is implemented as:
-  <p align=\"center\"><i><code>m&#775;</code></i> = <i>A</i><sup>2</sup> / (8 <code>&pi;</code> <i>L</i>) * <code>&rho;</code> / <code>&eta;</code> * 1 / <code>&zeta;</code></i><sub>lam</sub> <i><code>&Delta;</code>p</i></p>
-</p>
-<h4>Assumptions and limitations</h4>
-  <p>
-    The additional factor <code>&zeta;</code></i><sub>lam</sub> can be experimentally determined as done by Lanzerath (2015).
-  </p>
-<h4>References</h4>
-<ul>
-  <li>VDI e.V., VDI Wärmeatlas 11., bearbeitete und erweiterte Auflage, Chapter L1, Darmstadt: Springer Berlin Heidelberg, 2011. </li>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257. </li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end Laminar_dp;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/PartialMassTransfer_dp.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/PartialMassTransfer_dp.mo
deleted file mode 100644
index bf24e8e..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/PartialMassTransfer_dp.mo
+++ /dev/null
@@ -1,28 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial;
-partial model PartialMassTransfer_dp
-
-  Real beta(final unit="m.s") "Mass transfer coefficient (dp)";
-
-  constant Boolean computeTransportProperties = false;
-
-  annotation (Icon(graphics={Bitmap(
-          extent={{-111,-100},{111,100}},
-          imageSource="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",
-          fileName="modelica://SorpLib/Resources/Images/beta.png")}),
-      Documentation(info="<html>
-<p>
-  This partial model is the basis for the mass transfer correlation models based on the loading difference <i><code>&Delta;</code>p</i>. <br>
-</p>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-
-end PartialMassTransfer_dp;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/PartialMassTransfer_dx.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/PartialMassTransfer_dx.mo
deleted file mode 100644
index 9e256ca..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/PartialMassTransfer_dx.mo
+++ /dev/null
@@ -1,33 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial;
-partial model PartialMassTransfer_dx
-
-  Real beta(final unit="kg/s")
-    "Mass transfer coefficient (dx)";
-
-  constant Boolean computeTransportProperties = false;
-
-
-
-  annotation (Icon(graphics={Bitmap(
-          extent={{-111,-100},{111,100}},
-          imageSource=
-              "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",
-          fileName=
-              "modelica://SorpLib/Resources/Images/beta.png")}),
-      Documentation(info="<html>
-<p>
-  This partial model is the basis for the mass transfer correlation models based on the loading difference <i><code>&Delta;</code>x</i>. <br>
-</p>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-
-end PartialMassTransfer_dx;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/package.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/package.mo
deleted file mode 100644
index 467644e..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena;
-package Partial
-extends SorpLib.Internals.ClassTypes.PartialPackage;
-
-
-end Partial;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/package.order b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/package.order
deleted file mode 100644
index 3b73eff..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Partial/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-PartialMassTransfer_dp
-PartialMassTransfer_dx
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_SilicaGel.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_SilicaGel.mo
deleted file mode 100644
index 29261b7..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_SilicaGel.mo
+++ /dev/null
@@ -1,26 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Records.DiffusionCoefficients;
-model Lanzerath2015_SilicaGel
-  "Diffusion coefficient and particle diameter for Silica Gel 123 (Lanzerath 2015)"
-  extends Glueckauf_dx(
-    final D=1.8e-10,
-    final r=0.00045,
-    m_ads=2.236);
-  annotation (Documentation(info="<html>
-<p>
-  The diffusion coefficients in this record were determined by Lanzerath et. al. (2015) for silica-gel 123 particles.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end Lanzerath2015_SilicaGel;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_Zeolite13X_ads.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_Zeolite13X_ads.mo
deleted file mode 100644
index 40a4337..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_Zeolite13X_ads.mo
+++ /dev/null
@@ -1,26 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Records.DiffusionCoefficients;
-model Lanzerath2015_Zeolite13X_ads
-  "Diffusion coefficient and particle diameter for Zeolith 13X adsorption (Lanzerath 2015)"
-  extends Glueckauf_dx(
-    final D=3.416e-10,
-    final r=0.0007,
-    m_ads=1.833);
-  annotation (Documentation(info="<html>
-<p>
-  The diffusion coefficients in this record were determined by Lanzerath et. al. (2015) for Zeolite 13X particles during adsorption.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end Lanzerath2015_Zeolite13X_ads;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_Zeolite13X_des.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_Zeolite13X_des.mo
deleted file mode 100644
index 0d241a6..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/Lanzerath2015_Zeolite13X_des.mo
+++ /dev/null
@@ -1,26 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Records.DiffusionCoefficients;
-model Lanzerath2015_Zeolite13X_des
-  "Diffusion coefficient and particle diameter for Zeolith 13X desorption (Lanzerath 2015)"
-  extends Glueckauf_dx(
-    final D=3.055e-9,
-    final r=0.0007,
-    m_ads=1.833);
-  annotation (Documentation(info="<html>
-<p>
-  The diffusion coefficients in this record were determined by Lanzerath et. al. (2015) for Zeolite 13X particles during desorption.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end Lanzerath2015_Zeolite13X_des;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/SakodaSuzuki1984_SilicaGel.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/SakodaSuzuki1984_SilicaGel.mo
deleted file mode 100644
index ce17c47..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/SakodaSuzuki1984_SilicaGel.mo
+++ /dev/null
@@ -1,26 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Records.DiffusionCoefficients;
-model SakodaSuzuki1984_SilicaGel
-  "Diffusion coefficient and particle diameter for Silica-gel Fuji-A-type (Sakoda Suzuki 1984)"
-  extends GlueckaufArrhenius_dx(
-    final Dso=3.055e-9,
-    final r=0.0007,
-    m_ads=1.833);
-  annotation (Documentation(info="<html>
-<p>
-  The diffusion coefficients in this record were determined by Sakoda and Suzuki (1984) for silica-gel fuji A.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Sakoda, A.; Suzuki, M. Fundamental study on a solar powered adsorption cooling system. Journal of Chemical Engineering of Japan, 1984, 17(1), 52-57.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end SakodaSuzuki1984_SilicaGel;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/package.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/package.mo
deleted file mode 100644
index 80fcd4c..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Records;
-package DiffusionCoefficients
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-
-
-end DiffusionCoefficients;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/package.order b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/package.order
deleted file mode 100644
index 65473a9..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/DiffusionCoefficients/package.order
+++ /dev/null
@@ -1,4 +0,0 @@
-Lanzerath2015_Zeolite13X_des
-Lanzerath2015_Zeolite13X_ads
-Lanzerath2015_SilicaGel
-SakodaSuzuki1984_SilicaGel
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/FlowRes_Lanzerath_ads.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/FlowRes_Lanzerath_ads.mo
deleted file mode 100644
index 433ede4..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/FlowRes_Lanzerath_ads.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Records.FlowCoefficients;
-model FlowRes_Lanzerath_ads
-  "Coefficients flow resistance evaporator -> adsorber (Lanzerath 2013)"
-  extends Laminar_dp(
-    final zeta_lam=14.8,
-    final L=0.455,
-    final d=0.0382);
-end FlowRes_Lanzerath_ads;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/FlowRes_Lanzerath_des.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/FlowRes_Lanzerath_des.mo
deleted file mode 100644
index 9d05faa..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/FlowRes_Lanzerath_des.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Records.FlowCoefficients;
-model FlowRes_Lanzerath_des
-  "Coefficients Flow Resistance adsorber -> condenser (Lanzerath 2013)"
-  extends Laminar_dp(
-    final zeta_lam=30.1,
-    final L=0.38,
-    final d=0.0345);
-end FlowRes_Lanzerath_des;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/package.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/package.mo
deleted file mode 100644
index 8631734..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.MassTransfer.MassTransferPhenomena.Records;
-package FlowCoefficients
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-end FlowCoefficients;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/package.order b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/package.order
deleted file mode 100644
index d6a83ba..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/FlowCoefficients/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-FlowRes_Lanzerath_des
-FlowRes_Lanzerath_ads
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/package.order b/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/package.order
deleted file mode 100644
index 44b738a..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/Records/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-DiffusionCoefficients
-FlowCoefficients
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/package.mo b/SorpLib/Components/MassTransfer/MassTransferPhenomena/package.mo
deleted file mode 100644
index 50b60c8..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/package.mo
+++ /dev/null
@@ -1,14 +0,0 @@
-within SorpLib.Components.MassTransfer;
-package MassTransferPhenomena
-extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-
-
-
-
-
-
-
-end MassTransferPhenomena;
diff --git a/SorpLib/Components/MassTransfer/MassTransferPhenomena/package.order b/SorpLib/Components/MassTransfer/MassTransferPhenomena/package.order
deleted file mode 100644
index 0ae71e8..0000000
--- a/SorpLib/Components/MassTransfer/MassTransferPhenomena/package.order
+++ /dev/null
@@ -1,10 +0,0 @@
-ConstantCoefficient_dp
-ConstantSpecificCoefficient_dp
-Laminar_dp
-DarcyPorousMedia_dp
-DarcyPackedBed_Spheres_dp
-ConstantCoefficient_dx
-ConstantSpecificCoefficient_dx
-Glueckauf_dx
-GlueckaufArrhenius_dx
-Partial
diff --git a/SorpLib/Components/MassTransfer/Partial/PartialMassTransfer.mo b/SorpLib/Components/MassTransfer/Partial/PartialMassTransfer.mo
deleted file mode 100644
index 7a07c0a..0000000
--- a/SorpLib/Components/MassTransfer/Partial/PartialMassTransfer.mo
+++ /dev/null
@@ -1,185 +0,0 @@
-within SorpLib.Components.MassTransfer.Partial;
-partial model PartialMassTransfer
-
-  /*********************** SIM ***********************************/
-
-  parameter TILMedia.VLEFluidTypes.BaseVLEFluid vleFluidType=sim.vleFluidType1
-    "VLE fluid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.vleFluidType1 "VLE fluid 1 as defined in SIM",
-      choice=sim.vleFluidType2 "VLE fluid 2 as defined in SIM",
-      choice=sim.vleFluidType3 "VLE fluid 3 as defined in SIM"));
-protected
-  outer TIL.SystemInformationManager sim "System information manager";
-
-  /******************** Connectors *****************************/
-
-public
-  TIL.Connectors.VLEFluidPort vlePortA(
-    p(final start=pStart),
-    m_flow(final start=m_flowStart),
-    final vleFluidType=vleFluidType) annotation (Placement(transformation(
-          extent={{-102,-10},{-82,10}}, rotation=0), iconTransformation(extent={
-            {-101,-10},{-81,10}})));
-  TIL.Connectors.VLEFluidPort vlePortB(
-    p(final start=pStart),
-    m_flow(final start=-m_flowStart),
-    final vleFluidType=vleFluidType) annotation (Placement(transformation(
-          extent={{82,-10},{102,10}}, rotation=0), iconTransformation(extent={{82,
-            -10},{102,10}})));
-
-  /*********************** VLEFluid ***************************/
-
-  TILMedia.VLEFluid_ph vleFluidA(
-    p=vlePortA.p,
-    h=noEvent(actualStream(vlePortA.h_outflow)),
-    xi=noEvent(actualStream(vlePortA.xi_outflow)),
-    final vleFluidType=vleFluidType,
-    computeTransportProperties=true) annotation (Placement(transformation(
-          extent={{-100,20},{-80,40}}, rotation=0)));
-
-  TILMedia.VLEFluid_ph vleFluidB(
-    p=vlePortB.p,
-    h=noEvent(actualStream(vlePortB.h_outflow)),
-    xi=noEvent(actualStream(vlePortB.xi_outflow)),
-    final vleFluidType=vleFluidType,
-    computeTransportProperties=true) annotation (Placement(transformation(
-          extent={{80,20},{100,40}}, rotation=0)));
-
-
-  /****************** Additional inner and outer objects *******************/
-
-  Modelica.SIunits.Pressure dp "Total pressure drop";
-
-  inner Modelica.SIunits.MassFlowRate mdotHydraulic=vlePortA.m_flow
-    "Hydraulic mass flow rate";
-
-  inner TILMedia.Internals.PropertyRecord properties=
-      TILMedia.Internals.PropertyRecord(
-      d=(vleFluidA.d + vleFluidB.d)/2,
-      h=(vleFluidA.h + vleFluidB.h)/2,
-      p=(vleFluidA.p + vleFluidA.p)/2,
-      s=(vleFluidA.s + vleFluidB.s)/2,
-      T=(vleFluidA.T + vleFluidB.T)/2,
-      cp=(vleFluidA.cp + vleFluidB.cp)/2,
-      q=(vleFluidA.q + vleFluidB.q)/2,
-      transp=TILMedia.Internals.TransportPropertyRecord(
-        Pr=(vleFluidA.transp.Pr + vleFluidB.transp.Pr)/2,
-        lambda=(vleFluidA.transp.lambda + vleFluidA.transp.lambda)/2,
-        eta=(vleFluidA.transp.eta + vleFluidB.transp.eta)/2,
-        sigma=(vleFluidA.transp.sigma + vleFluidB.transp.sigma)/2),
-      VLE=vleFluidA.VLE,
-      VLETransp=vleFluidA.VLETransp,
-      crit=vleFluidA.crit);
-
-   parameter Boolean computeTransportProperties=false "If true, tranport propertie are calculated in the vle object";
-
-  /****************** Start values *******************/
-
-  parameter Modelica.SIunits.Pressure pStart=1.013e5
-    annotation (Dialog(group="Start Values", tab="Start and Initialization"));
-
-  parameter Modelica.SIunits.MassFlowRate m_flowStart=0.01
-    annotation (Dialog(group="Start Values", tab="Start and Initialization"));
-
-  /******* Parameters and connectors for active closing and flap valve*********/
-
-  parameter Boolean isClosable=false
-    "true = activly closable, false = not activly closable" annotation (Dialog(
-        group="Valve type"), choices(choice=true "activly closable", choice=false
-        "not activly closable"));
-  parameter Boolean isFlap=false "true = flap valve, false = no flap valve"
-    annotation (Dialog(group="Valve type"), choices(choice=true
-        "flap valve (opens only one in one direction)", choice=false
-        "opens in both directions"));
-  parameter Boolean openingDirection=true "true = A --> B, false = B --> A"
-    annotation (Dialog(enable=isFlap, group="Valve type"), choices(choice=true
-        "A --> B", choice=false "B --> A"));
-
-  Boolean valveOpen;
-
-public
-  Modelica.Blocks.Interfaces.BooleanInput open if isClosable annotation (
-      Placement(transformation(
-        extent={{-17,-17},{17,17}},
-        rotation=90,
-        origin={0,-61})));
-
-protected
-  Modelica.Blocks.Interfaces.BooleanOutput getOpen annotation (Placement(
-        transformation(
-        extent={{-10,-10},{10,10}},
-        rotation=90,
-        origin={16,-22})));
-  Modelica.Blocks.Interfaces.BooleanInput open_=true if   not isClosable
-    annotation (Placement(transformation(
-        extent={{-16,-16},{16,16}},
-        rotation=90,
-        origin={32,-60})));
-
-equation
-  if not getOpen or (isFlap and openingDirection and vlePortA.p <= vlePortB.p)
-       or (isFlap and not openingDirection and vlePortB.p <= vlePortA.p) then
-    valveOpen = false;
-  else
-    valveOpen = true;
-  end if;
-
-  vlePortA.m_flow + vlePortB.m_flow = 0;
-  vlePortA.xi_outflow = inStream(vlePortB.xi_outflow);
-  vlePortB.xi_outflow = inStream(vlePortA.xi_outflow);
-
-  vlePortA.h_outflow = inStream(vlePortB.h_outflow);
-  vlePortB.h_outflow = inStream(vlePortA.h_outflow);
-
-  dp = vlePortA.p - vlePortB.p;
-
-  // no limiter used
-  vlePortA.h_limit = -1e6;
-  vlePortB.h_limit = -1e6;
-
-  connect(open, getOpen) annotation (Line(points={{0,-61},{0,-61},{0,-36},{16,
-          -36},{16,-22}},     color={255,0,255}));
-  connect(open_, getOpen) annotation (Line(points={{32,-60},{32,-60},{32,-36},{16,
-          -36},{16,-22}}, color={255,0,255}));
-  annotation (
-    Icon(coordinateSystem(extent={{-100,-60},{100,60}})),
-    Diagram(coordinateSystem(extent={{-100,-60},{100,60}})),
-    Documentation(info="<html>
-  <p>
-    The mass transfer models are used to connect the adsorbent cell to an evaporator, a condenser, or a moist air cell (or any other adsorbate source or sink). 
-    The mass transfer models are modeled as an isenthalpic valve with no volume. 
-    Depending on the chosen Transport Phenomena, the Mass Transfer model represents diffusion in the particle and also pressure drop due to friction in pipes, connceting the adsorbent to other models.
-    The partial model includes the main equations, used for all Mass Transfer models including:
-    <ul>
-      <li>2 vle ports</li>
-      <li>Parameters and connectors to model an activly closable and a flap valve (opens only in one direction)</li>
-      <li>Mass balance</li>
-      <li>Energy balance</li>
-    </ul>
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    The mass transfer model is modelled as an isenthalpic valve with no storage volume. 
-    Thus, the mass balance reads:
-    <p align=\"center\"><i><code>m&#775;</code></i><sub>in</sub> = <i><code>m&#775;</code></i><sub>out</sub> </p>
-    The energy balance boils down to equal specific enthalpies:
-    <p align=\"center\"><i>h</i><sub>in</sub> = <i>h</i><sub>out</sub> </p>
-  </p>
-  <h4>References</h4>
-  <p>
-    For more information see:
-    <ul>
-    <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257. </li>
-    </ul>
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>November 30, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>
-"));
-end PartialMassTransfer;
diff --git a/SorpLib/Components/MassTransfer/Partial/package.mo b/SorpLib/Components/MassTransfer/Partial/package.mo
deleted file mode 100644
index 87a4ed8..0000000
--- a/SorpLib/Components/MassTransfer/Partial/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.MassTransfer;
-package Partial
-extends SorpLib.Internals.ClassTypes.PartialPackage;
-
-end Partial;
diff --git a/SorpLib/Components/MassTransfer/Partial/package.order b/SorpLib/Components/MassTransfer/Partial/package.order
deleted file mode 100644
index b906271..0000000
--- a/SorpLib/Components/MassTransfer/Partial/package.order
+++ /dev/null
@@ -1 +0,0 @@
-PartialMassTransfer
diff --git a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_SilicaGel.mo b/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_SilicaGel.mo
deleted file mode 100644
index 1e2239a..0000000
--- a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_SilicaGel.mo
+++ /dev/null
@@ -1,26 +0,0 @@
-within SorpLib.Components.MassTransfer.Record.DiffusionCoefficients;
-model Lanzerath2015_SilicaGel
-  "Diffusion coefficient and particle diameter for Silica Gel 123 (Lanzerath 2015)"
-  extends MassTransfer.MassTransferPhenomena.Glueckauf_dx(
-    final D=1.8e-10,
-    final r=0.00045);
-  annotation (Documentation(info="<html>
-<p>
-  The diffusion coefficients in this record were determined by Lanzerath et. al. (2015) for silica-gel 123 particles.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-
-end Lanzerath2015_SilicaGel;
diff --git a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_Zeolite13X_ads.mo b/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_Zeolite13X_ads.mo
deleted file mode 100644
index 22aa5bd..0000000
--- a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_Zeolite13X_ads.mo
+++ /dev/null
@@ -1,27 +0,0 @@
-within SorpLib.Components.MassTransfer.Record.DiffusionCoefficients;
-model Lanzerath2015_Zeolite13X_ads
-  "Diffusion coefficient and particle diameter for Zeolith 13X adsorption (Lanzerath 2015)"
-  extends MassTransfer.MassTransferPhenomena.Glueckauf_dx(
-    final D=3.416e-10,
-    final r=0.0007);
-
-  annotation (Documentation(info="<html>
-<p>
-  The diffusion coefficients in this record were determined by Lanzerath et. al. (2015) for Zeolite 13X particles during adsorption.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-
-end Lanzerath2015_Zeolite13X_ads;
diff --git a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_Zeolite13X_des.mo b/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_Zeolite13X_des.mo
deleted file mode 100644
index 378a0ae..0000000
--- a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/Lanzerath2015_Zeolite13X_des.mo
+++ /dev/null
@@ -1,25 +0,0 @@
-within SorpLib.Components.MassTransfer.Record.DiffusionCoefficients;
-model Lanzerath2015_Zeolite13X_des
-  "Diffusion coefficient and particle diameter for Zeolith 13X desorption (Lanzerath 2015)"
-  extends MassTransfer.MassTransferPhenomena.Glueckauf_dx(
-    final D=3.055e-9,
-    final r=0.0007);
-  annotation (Documentation(info="<html>
-<p>
-  The diffusion coefficients in this record were determined by Lanzerath et. al. (2015) for Zeolite 13X particles during desorption.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Lanzerath, F.; Bau, U.; Seiler, J.; Bardow, A. Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 2015, 21(3), 248-257.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end Lanzerath2015_Zeolite13X_des;
diff --git a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/SakodaSuzuki1984_SilicaGel.mo b/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/SakodaSuzuki1984_SilicaGel.mo
deleted file mode 100644
index bc4b40f..0000000
--- a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/SakodaSuzuki1984_SilicaGel.mo
+++ /dev/null
@@ -1,26 +0,0 @@
-within SorpLib.Components.MassTransfer.Record.DiffusionCoefficients;
-model SakodaSuzuki1984_SilicaGel
-  "Diffusion coefficient and particle diameter for Silica-gel Fuji-A-type (Sakoda Suzuki 1984)"
-  extends MassTransfer.MassTransferPhenomena.GlueckaufArrhenius_dx(
-    final Dso=3.055e-9,
-    final r=0.0007);
-  annotation (Documentation(info="<html>
-<p>
-  The diffusion coefficients in this record were determined by Sakoda and Suzuki (1984) for silica-gel fuji A.
-</p>
-<h4>References</h4>
-<ul>
-  <li>Sakoda, A.; Suzuki, M. Fundamental study on a solar powered adsorption cooling system. Journal of Chemical Engineering of Japan, 1984, 17(1), 52-57.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 30, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-
-end SakodaSuzuki1984_SilicaGel;
diff --git a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/package.mo b/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/package.mo
deleted file mode 100644
index b2a502c..0000000
--- a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.MassTransfer.Record;
-package DiffusionCoefficients
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-
-
-end DiffusionCoefficients;
diff --git a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/package.order b/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/package.order
deleted file mode 100644
index 65473a9..0000000
--- a/SorpLib/Components/MassTransfer/Record/DiffusionCoefficients/package.order
+++ /dev/null
@@ -1,4 +0,0 @@
-Lanzerath2015_Zeolite13X_des
-Lanzerath2015_Zeolite13X_ads
-Lanzerath2015_SilicaGel
-SakodaSuzuki1984_SilicaGel
diff --git a/SorpLib/Components/MassTransfer/Record/FlowCoefficients/FlowRes_Lanzerath_ads.mo b/SorpLib/Components/MassTransfer/Record/FlowCoefficients/FlowRes_Lanzerath_ads.mo
deleted file mode 100644
index 6e15d48..0000000
--- a/SorpLib/Components/MassTransfer/Record/FlowCoefficients/FlowRes_Lanzerath_ads.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.MassTransfer.Record.FlowCoefficients;
-model FlowRes_Lanzerath_ads
-  "Coefficients flow resistance evaporator -> adsorber (Lanzerath 2015)"
-  extends MassTransfer.MassTransferPhenomena.Laminar_dp(
-    final zeta_lam=14.8,
-    final L=0.455,
-    final d=0.0382);
-end FlowRes_Lanzerath_ads;
diff --git a/SorpLib/Components/MassTransfer/Record/FlowCoefficients/FlowRes_Lanzerath_des.mo b/SorpLib/Components/MassTransfer/Record/FlowCoefficients/FlowRes_Lanzerath_des.mo
deleted file mode 100644
index 71fa65f..0000000
--- a/SorpLib/Components/MassTransfer/Record/FlowCoefficients/FlowRes_Lanzerath_des.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.MassTransfer.Record.FlowCoefficients;
-model FlowRes_Lanzerath_des
-  "Coefficients Flow Resistance adsorber -> condenser (Lanzerath 2015)"
-  extends MassTransfer.MassTransferPhenomena.Laminar_dp(
-    final zeta_lam=30.1,
-    final L=0.38,
-    final d=0.0345);
-end FlowRes_Lanzerath_des;
diff --git a/SorpLib/Components/MassTransfer/Record/FlowCoefficients/package.mo b/SorpLib/Components/MassTransfer/Record/FlowCoefficients/package.mo
deleted file mode 100644
index a22d344..0000000
--- a/SorpLib/Components/MassTransfer/Record/FlowCoefficients/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.MassTransfer.Record;
-package FlowCoefficients
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-end FlowCoefficients;
diff --git a/SorpLib/Components/MassTransfer/Record/FlowCoefficients/package.order b/SorpLib/Components/MassTransfer/Record/FlowCoefficients/package.order
deleted file mode 100644
index d6a83ba..0000000
--- a/SorpLib/Components/MassTransfer/Record/FlowCoefficients/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-FlowRes_Lanzerath_des
-FlowRes_Lanzerath_ads
diff --git a/SorpLib/Components/MassTransfer/Record/package.mo b/SorpLib/Components/MassTransfer/Record/package.mo
deleted file mode 100644
index 3a80320..0000000
--- a/SorpLib/Components/MassTransfer/Record/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.MassTransfer;
-package Record
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-end Record;
diff --git a/SorpLib/Components/MassTransfer/Record/package.order b/SorpLib/Components/MassTransfer/Record/package.order
deleted file mode 100644
index 44b738a..0000000
--- a/SorpLib/Components/MassTransfer/Record/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-DiffusionCoefficients
-FlowCoefficients
diff --git a/SorpLib/Components/MassTransfer/Records/FluidProperties.mo b/SorpLib/Components/MassTransfer/Records/FluidProperties.mo
new file mode 100644
index 0000000..b0c5863
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/Records/FluidProperties.mo
@@ -0,0 +1,36 @@
+within SorpLib.Components.MassTransfer.Records;
+record FluidProperties
+  "This record contains fluid properties required for heat transfer coefficients"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of variables describing fluid properties
+  //
+  Modelica.Units.SI.Temperature T_adsorbate
+    "Temperature at the adsorbate state";
+
+  Modelica.Units.SI.Pressure p_adsorptive
+    "Pressure at the adsorptive state";
+  Modelica.Units.SI.Temperature T_adsorptive
+    "Temperature at the adsorptive state";
+  Modelica.Units.SI.Density d_adsorptive
+    "Density at the adsorptive state";
+  Modelica.Units.SI.DynamicViscosity eta_adsorptive
+    "Dynamic viscosity at the adsorptive state";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains fluid properties required for mass transfer coefficients.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end FluidProperties;
diff --git a/SorpLib/Components/MassTransfer/Records/GeometryClosedAdsorber.mo b/SorpLib/Components/MassTransfer/Records/GeometryClosedAdsorber.mo
new file mode 100644
index 0000000..f0055d7
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/Records/GeometryClosedAdsorber.mo
@@ -0,0 +1,22 @@
+within SorpLib.Components.MassTransfer.Records;
+record GeometryClosedAdsorber
+  "This record contains the geometry required for mass transfer coefficients of closed adsorbers"
+  extends SorpLib.Components.HeatExchanger.Records.GeometryClosedAdsorber;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by models calculating the mass
+transfer coefficients in closed adsorbers.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryClosedAdsorber;
diff --git a/SorpLib/Components/MassTransfer/Records/GeometryOpenAdsorber.mo b/SorpLib/Components/MassTransfer/Records/GeometryOpenAdsorber.mo
new file mode 100644
index 0000000..ab7a1f5
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/Records/GeometryOpenAdsorber.mo
@@ -0,0 +1,222 @@
+within SorpLib.Components.MassTransfer.Records;
+record GeometryOpenAdsorber
+  "This record contains the geometry required for mass transfer coefficients of open adsorbers"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters regarding the disretization
+  //
+  parameter Integer no_volumes(min=1) = 1
+    "Number of discretization volumes in flow direction"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+
+  //
+  // Definition of parameters regarding the geometry of the casing
+  //
+  parameter Modelica.Units.SI.Length l_cas = 1
+    "Length of the casing"
+    annotation (Dialog(tab="Casing", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_inner_cas = 0.15
+    "Inner diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer_cas = 0.16
+    "Outer diameter of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+  parameter Modelica.Units.SI.Thickness t_wall_cas=
+    (d_outer_cas - d_inner_cas) / 2
+    "Wall thickness of the casing"
+    annotation (Dialog(tab="Casing", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_crossInner_cas=
+    Modelica.Constants.pi/4 * d_inner_cas^2
+    "Inner cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter_cas=
+    Modelica.Constants.pi/4 * d_outer_cas^2
+    "Outer cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall_cas=
+    A_crossOuter_cas - A_crossInner_cas
+    "Wall cross-sectional area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferInner_cas=
+    Modelica.Constants.pi * d_inner_cas * l_cas
+    "Inner heat transfer area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter_cas=
+    Modelica.Constants.pi * d_outer_cas * l_cas
+    "Outer heat transfer area of the casing"
+    annotation (Dialog(tab="Casing", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_inner_cas=
+    Modelica.Constants.pi/4 * d_inner_cas * l_cas
+    "Inner volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer_cas=
+    Modelica.Constants.pi/4 * d_outer_cas * l_cas
+    "Outer volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall_cas=
+    V_outer_cas - V_inner_cas
+    "Wall volume of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_free_cas=
+    V_inner_cas - V_inner_hx - V_outer_hx - V_sorbent_hx
+    "Free volume (i.e., gas/vapor volume) of the casing"
+    annotation (Dialog(tab="Casing", group="Volumes"));
+
+  //
+  // Definition of parameters regarding the general geometry of the heat exchanger
+  //
+  parameter Integer no_hydraulicParallelTubes(min=1) = 1
+    "Number of hydraulically parallel tubes"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+
+  parameter Modelica.Units.SI.Length l_hx = 0
+    "Length of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+
+  parameter Modelica.Units.SI.Length roughness_hx = 0
+    "Absolute roughness of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="General"));
+
+  //
+  // Definition of parameters regarding diameters of the heat exchanger
+  //
+  parameter Modelica.Units.SI.Diameter d_inner_hx = 0
+    "Inner diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer_hx = 0
+    "Outer diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+
+  parameter Modelica.Units.SI.Diameter d_hydInner_hx = d_inner_hx
+    "Hydraulic inner diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydOuter_hx = d_outer_hx
+    "Hydraulic outer diameter of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+
+  parameter Modelica.Units.SI.Thickness t_wall_hx=
+    (d_outer_hx - d_inner_hx) / 2
+    "Wall thickness of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Diameters"));
+
+  //
+  // Definition of parameters regarding areas of the heat exchanger
+  //
+  parameter Modelica.Units.SI.Area A_crossInner_hx=
+    Modelica.Constants.pi/4 * d_inner_hx^2
+    "Inner cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter_hx=
+    Modelica.Constants.pi/4 * d_outer_hx^2
+    "Outer cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall_hx=
+    A_crossOuter_hx - A_crossInner_hx
+    "Wall cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  parameter Modelica.Units.SI.Area A_hydCrossInner_hx = A_crossInner_hx
+    "Hydraulic inner cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossOuter_hx = A_crossOuter_hx
+    "Hydraulic outer cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossWall_hx=
+    A_hydCrossOuter_hx - A_hydCrossInner_hx
+    "Hydraulic wall cross-sectional area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  parameter Modelica.Units.SI.Area A_heatTransferInner_hx=
+    Modelica.Constants.pi * d_inner_hx * l_hx
+    "Total inner heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter_hx=
+    Modelica.Constants.pi * d_outer_hx * l_hx
+    "Total outer heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  parameter Real f_finAreaRatioInner_hx(min=0, max=1) = 0
+    "Ratio of total inner fin area to total inner heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+  parameter Real f_finAreaRatioOuter_hx(min=0, max=1) = 0
+    "Ratio of total outer fin area to total outer heat transfer area of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Areas"));
+
+  //
+  // Definition of parameters regarding volumes of the heat exchanger
+  //
+  parameter Modelica.Units.SI.Volume V_inner_hx = A_crossInner_hx * l_hx
+    "Total inner volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer_hx = A_crossOuter_hx * l_hx
+    "Total outer volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall_hx = V_outer_hx - V_inner_hx
+    "Total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_sorbent_hx=
+    2.5 * V_wall_hx
+    "Available volume for sorbent particles of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+
+  parameter Real f_finVolumeRatioInner_hx(min=0, max=1) = 0
+    "Ratio of total inner fin volume to total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+  parameter Real f_finVolumeRatioOuter_hx(min=0, max=1) = 0
+    "Ratio of total outer fin volume to total wall volume of the tube"
+    annotation (Dialog(tab="Heat Exchanger", group="Volumes"));
+
+  //
+  // Definition of parameters regarding the sorbent gemeotry
+  //
+  parameter Real no_particles = (1-psi_particles) * V_inner_cas / V_particle
+    "Number of particles"
+    annotation (Dialog(tab="Sorbent", group="General"));
+  parameter Real psi_particles(unit="1") = 1 - 0.74
+    "Void fraction of the adsorber (i.e., ratio of the free fluid volume to
+    the total inner volume)"
+    annotation (Dialog(tab="Sorbent", group="General"));
+
+  parameter Modelica.Units.SI.Diameter d_particle = 0.7 / 1000
+    "Average diameter of the adsorbent particles"
+    annotation (Dialog(tab="Sorbent", group="Diameters"));
+
+  parameter Modelica.Units.SI.Area A_cross_particle=
+    Modelica.Constants.pi/4 * d_particle^2
+    "Average cross-sectional area of the particle"
+    annotation (Dialog(tab="Sorbent", group="Areas"));
+  parameter Modelica.Units.SI.Area A_surface_particle=
+    Modelica.Constants.pi * d_particle^2
+    "Average suraface area of the particle"
+    annotation (Dialog(tab="Sorbent", group="Areas"));
+
+  parameter Modelica.Units.SI.Volume V_particle=
+    Modelica.Constants.pi/6 * d_particle^3
+    "Average volume of the particle"
+    annotation (Dialog(tab="Sorbent", group="Volumes"));
+  parameter Modelica.Units.SI.Volume V_particles=
+    no_particles * V_particle
+    "Average volume of all particles"
+    annotation (Dialog(tab="Sorbent", group="Volumes"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by models calculating the mass
+transfer coefficients in open adsorbers.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryOpenAdsorber;
diff --git a/SorpLib/Components/MassTransfer/Records/package.mo b/SorpLib/Components/MassTransfer/Records/package.mo
new file mode 100644
index 0000000..1558ae8
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/Records/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.MassTransfer;
+package Records "Package containing records"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records. These records are used to cluster 
+variables and tidy up the model output.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Components/MassTransfer/Records/package.order b/SorpLib/Components/MassTransfer/Records/package.order
new file mode 100644
index 0000000..72a79bf
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/Records/package.order
@@ -0,0 +1,3 @@
+FluidProperties
+GeometryClosedAdsorber
+GeometryOpenAdsorber
diff --git a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusion1.mo b/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusion1.mo
deleted file mode 100644
index 93fed9b..0000000
--- a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusion1.mo
+++ /dev/null
@@ -1,54 +0,0 @@
-within SorpLib.Components.MassTransfer.Testers;
-model TesterMassTransferDiffusion1
-
-  MassTransferDiffusion  massTransfer(
-    pStart(displayUnit="kPa") = 1200,
-    inputChoice="dx",
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    vleFluidType=sim.vleFluidType1,
-    isClosable=false,
-    isFlap=true,
-    openingDirection=false,
-    redeclare model MassTransfer_diffusion_dx =
-        MassTransferPhenomena.Glueckauf_dx (
-        m_ads=2,
-        D=1.8e-8,
-        r(displayUnit="mm") = 0.0007))
-    annotation (Placement(transformation(extent={{-12,13},{12,27}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1750.51,
-    hFixed=2.8e6,
-    use_pressureInput=true)
-    annotation (Placement(transformation(extent={{-36,10},{-28,30}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    boundaryType="p",
-    hFixed=2.8e6,
-    pFixed(displayUnit="kPa") = 1900)
-    annotation (Placement(transformation(extent={{22,10},{30,30}})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  Modelica.Blocks.Sources.Step step(
-    startTime=250,
-    height=300,
-    offset=1800)
-    annotation (Placement(transformation(extent={{-52,14},{-40,26}})));
-equation
-
-  connect(vleBoundary1.port, massTransfer.vlePortA) annotation (Line(
-      points={{-32,20},{-10.92,20}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(massTransfer.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{11.04,20},{26,20}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(step.y, vleBoundary1.p_in) annotation (Line(points={{-39.4,20},{-38,
-          20},{-38,26},{-36,26}}, color={0,0,127}));
-  annotation (experiment(StopTime=500, Interval=1));
-end TesterMassTransferDiffusion1;
diff --git a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow1.mo b/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow1.mo
deleted file mode 100644
index 9bff252..0000000
--- a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow1.mo
+++ /dev/null
@@ -1,60 +0,0 @@
-within SorpLib.Components.MassTransfer.Testers;
-model TesterMassTransferDiffusionFlow1
-
-  MassTransferDiffusionFlow
-                         massTransfer(
-    pStart(displayUnit="kPa") = 1200,
-    vleFluidType=sim.vleFluidType1,
-    openingDirection=false,
-    isFlap=false,
-    inputChoice="dx",
-    isClosable=false,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_flow =
-        MassTransferPhenomena.DarcyPorousMedia_dp (
-        area=1,
-        dx=0.05,
-        k=2e-9),
-    redeclare model MassTransfer_diffusion_dx =
-        MassTransferPhenomena.Glueckauf_dx (
-        m_ads=2,
-        D=1.8e-8,
-        r(displayUnit="mm") = 0.0007))
-    annotation (Placement(transformation(extent={{-12,13},{12,27}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1750.51,
-    hFixed=2.8e6,
-    use_pressureInput=true)
-    annotation (Placement(transformation(extent={{-36,10},{-28,30}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    boundaryType="p",
-    hFixed=2.8e6,
-    pFixed(displayUnit="kPa") = 1900)
-    annotation (Placement(transformation(extent={{22,10},{30,30}})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  Modelica.Blocks.Sources.Step step(
-    startTime=250,
-    height=300,
-    offset=1800)
-    annotation (Placement(transformation(extent={{-52,14},{-40,26}})));
-equation
-
-  connect(vleBoundary1.port, massTransfer.vlePortA) annotation (Line(
-      points={{-32,20},{-10.92,20}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(massTransfer.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{11.04,20},{26,20}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(step.y, vleBoundary1.p_in) annotation (Line(points={{-39.4,20},{-38,
-          20},{-38,26},{-36,26}}, color={0,0,127}));
-  annotation (experiment(StopTime=500, Interval=1));
-end TesterMassTransferDiffusionFlow1;
diff --git a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow2.mo b/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow2.mo
deleted file mode 100644
index b0cc398..0000000
--- a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow2.mo
+++ /dev/null
@@ -1,66 +0,0 @@
-within SorpLib.Components.MassTransfer.Testers;
-model TesterMassTransferDiffusionFlow2
-
-  MassTransferDiffusionFlow
-                         massTransfer(
-    pStart(displayUnit="kPa") = 1200,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_diffusion_dp =
-        MassTransferPhenomena.ConstantCoefficient_dp,
-    vleFluidType=sim.vleFluidType1,
-    openingDirection=false,
-    isFlap=false,
-    redeclare model MassTransfer_flow =
-        Record.FlowCoefficients.FlowRes_Lanzerath_des,
-    inputChoice="dx",
-    isClosable=true,
-    redeclare model MassTransfer_diffusion_dx =
-        MassTransferPhenomena.Glueckauf_dx (
-        m_ads=2,
-        D=1.8e-8,
-        r(displayUnit="mm") = 0.0007))
-    annotation (Placement(transformation(extent={{-12,13},{12,27}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1750.51,
-    hFixed=2.8e6,
-    use_pressureInput=true)
-    annotation (Placement(transformation(extent={{-36,10},{-28,30}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    boundaryType="p",
-    hFixed=2.8e6,
-    pFixed(displayUnit="kPa") = 1900)
-    annotation (Placement(transformation(extent={{22,10},{30,30}})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  Modelica.Blocks.Sources.BooleanStep booleanStep(startTime=150) annotation (
-      Placement(transformation(
-        extent={{-5,-5},{5,5}},
-        rotation=90,
-        origin={-6,-3})));
-  Modelica.Blocks.Sources.Step step(
-    startTime=250,
-    height=300,
-    offset=1800)
-    annotation (Placement(transformation(extent={{-52,14},{-40,26}})));
-equation
-
-  connect(vleBoundary1.port, massTransfer.vlePortA) annotation (Line(
-      points={{-32,20},{-10.92,20}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(massTransfer.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{11.04,20},{26,20}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(booleanStep.y, massTransfer.open) annotation (Line(points={{-6,2.5},{
-          -6,12.8833},{0,12.8833}},
-                               color={255,0,255}));
-  connect(step.y, vleBoundary1.p_in) annotation (Line(points={{-39.4,20},{-38,
-          20},{-38,26},{-36,26}}, color={0,0,127}));
-end TesterMassTransferDiffusionFlow2;
diff --git a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow3.mo b/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow3.mo
deleted file mode 100644
index 8f1dd9c..0000000
--- a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferDiffusionFlow3.mo
+++ /dev/null
@@ -1,58 +0,0 @@
-within SorpLib.Components.MassTransfer.Testers;
-model TesterMassTransferDiffusionFlow3
-
-  MassTransferDiffusionFlow
-                         massTransfer(
-    pStart(displayUnit="kPa") = 1200,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model MassTransfer_diffusion_dp =
-        MassTransferPhenomena.ConstantCoefficient_dp,
-    vleFluidType=sim.vleFluidType1,
-    openingDirection=false,
-    redeclare model MassTransfer_flow =
-        Record.FlowCoefficients.FlowRes_Lanzerath_des,
-    inputChoice="dx",
-    isClosable=false,
-    isFlap=true,
-    redeclare model MassTransfer_diffusion_dx =
-        MassTransferPhenomena.Glueckauf_dx (
-        m_ads=2,
-        D=1.8e-8,
-        r=0.0007))
-    annotation (Placement(transformation(extent={{-12,13},{12,27}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1750.51,
-    hFixed=2.8e6,
-    use_pressureInput=true)
-    annotation (Placement(transformation(extent={{-36,10},{-28,30}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    boundaryType="p",
-    hFixed=2.8e6,
-    pFixed(displayUnit="kPa") = 1900)
-    annotation (Placement(transformation(extent={{22,10},{30,30}})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  Modelica.Blocks.Sources.Step step(
-    startTime=250,
-    height=300,
-    offset=1800)
-    annotation (Placement(transformation(extent={{-52,14},{-40,26}})));
-equation
-
-  connect(vleBoundary1.port, massTransfer.vlePortA) annotation (Line(
-      points={{-32,20},{-10.92,20}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(massTransfer.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{11.04,20},{26,20}},
-      color={153,204,0},
-      thickness=0.5,
-      smooth=Smooth.None));
-  connect(step.y, vleBoundary1.p_in) annotation (Line(points={{-39.4,20},{-38,
-          20},{-38,26},{-36,26}}, color={0,0,127}));
-end TesterMassTransferDiffusionFlow3;
diff --git a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow1.mo b/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow1.mo
deleted file mode 100644
index 05cd0f5..0000000
--- a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow1.mo
+++ /dev/null
@@ -1,54 +0,0 @@
-within SorpLib.Components.MassTransfer.Testers;
-model TesterMassTransferFlow1
-
-  MassTransferFlow massTransfer(
-    pStart(displayUnit="kPa") = 1200,
-    openingDirection=true,
-    vleFluidType=sim.vleFluidType1,
-    isFlap=false,
-    redeclare model MassTransfer_flow =
-        MassTransferPhenomena.Laminar_dp (
-        L=0.4,
-        zeta_lam=20,
-        d=0.03),
-    isClosable=false)
-    annotation (Placement(transformation(extent={{-10,-7},{10,7}},
-        rotation=0,
-        origin={0,20})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1750.51,
-    use_pressureInput=true,
-    vleFluidType=sim.vleFluidType1,
-    hFixed=2800000)
-    annotation (Placement(transformation(extent={{-36,10},{-28,30}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    m_flowFixed=-0.2,
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1927.6,
-    vleFluidType=sim.vleFluidType1,
-    hFixed=2800000)
-    annotation (Placement(transformation(extent={{22,10},{30,30}})));
-  Modelica.Blocks.Sources.Step step(
-    startTime=250,
-    height=300,
-    offset=1800)
-    annotation (Placement(transformation(extent={{-58,14},{-46,26}})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-equation
-
-  connect(step.y, vleBoundary1.p_in) annotation (Line(points={{-45.4,20},{-42,
-          20},{-42,26},{-36,26}}, color={0,0,127}));
-  connect(vleBoundary1.port, massTransfer.vlePortA) annotation (Line(
-      points={{-32,20},{-16,20},{-9.1,20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(massTransfer.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{9.2,20},{9.2,20},{26,20}},
-      color={153,204,0},
-      thickness=0.5));
-  annotation (experiment(StopTime=500, Interval=1));
-end TesterMassTransferFlow1;
diff --git a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow2.mo b/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow2.mo
deleted file mode 100644
index 8dcbfb3..0000000
--- a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow2.mo
+++ /dev/null
@@ -1,46 +0,0 @@
-within SorpLib.Components.MassTransfer.Testers;
-model TesterMassTransferFlow2
-
-  MassTransferFlow massTransfer(
-    pStart(displayUnit="kPa") = 1200,
-    openingDirection=true,
-    isClosable=false,
-    vleFluidType=sim.vleFluidType1,
-    isFlap=false,
-    redeclare model MassTransfer_flow =
-        Record.FlowCoefficients.FlowRes_Lanzerath_des)
-    annotation (Placement(transformation(extent={{-10,13},{10,27}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1750.51,
-    use_pressureInput=true,
-    hFixed=2.8e6)
-    annotation (Placement(transformation(extent={{-36,10},{-28,30}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    pFixed(displayUnit="kPa") = 2227.6,
-    boundaryType="m_flow",
-    hFixed=2.8e6,
-    m_flowFixed=-0.001)
-    annotation (Placement(transformation(extent={{22,10},{30,30}})));
-  Modelica.Blocks.Sources.Step step(
-    height=1000,
-    offset=1700,
-    startTime=250)
-    annotation (Placement(transformation(extent={{-58,14},{-46,26}})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-equation
-
-  connect(step.y, vleBoundary1.p_in) annotation (Line(points={{-45.4,20},{-42,
-          20},{-42,26},{-36,26}}, color={0,0,127}));
-  connect(vleBoundary1.port, massTransfer.vlePortA) annotation (Line(
-      points={{-32,20},{-9.1,20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(massTransfer.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{9.2,20},{9.2,20},{26,20}},
-      color={153,204,0},
-      thickness=0.5));
-end TesterMassTransferFlow2;
diff --git a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow3.mo b/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow3.mo
deleted file mode 100644
index 74fa658..0000000
--- a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow3.mo
+++ /dev/null
@@ -1,50 +0,0 @@
-within SorpLib.Components.MassTransfer.Testers;
-model TesterMassTransferFlow3
-
-  MassTransferFlow massTransfer(
-    pStart(displayUnit="kPa") = 1200,
-    openingDirection=true,
-    vleFluidType=sim.vleFluidType1,
-    redeclare model MassTransfer_flow =
-        MassTransferPhenomena.Laminar_dp (
-        L=0.4,
-        zeta_lam=20,
-        d=0.03),
-    isFlap=false,
-    isClosable=false)
-    annotation (Placement(transformation(extent={{-10,13},{10,27}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    pFixed(displayUnit="kPa") = 1750.51,
-    boundaryType="m_flow",
-    use_pressureInput=false,
-    use_massFlowRateInput=true,
-    hFixed=2.8e6)
-    annotation (Placement(transformation(extent={{-36,10},{-28,30}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    pFixed(displayUnit="kPa") = 2227.6,
-    m_flowFixed=-0.2,
-    boundaryType="p",
-    hFixed=2.8e6)
-    annotation (Placement(transformation(extent={{22,10},{30,30}})));
-  Modelica.Blocks.Sources.Step step(
-    startTime=250,
-    offset=-0.0005,
-    height=0.001)
-    annotation (Placement(transformation(extent={{-58,14},{-46,26}})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-equation
-
-  connect(massTransfer.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{9.2,20},{9.2,20},{26,20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(step.y, vleBoundary1.m_flow_in) annotation (Line(points={{-45.4,20},{
-          -42,20},{-42,22},{-36,22}}, color={0,0,127}));
-  connect(vleBoundary1.port, massTransfer.vlePortA) annotation (Line(
-      points={{-32,20},{-9.1,20}},
-      color={153,204,0},
-      thickness=0.5));
-end TesterMassTransferFlow3;
diff --git a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow4.mo b/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow4.mo
deleted file mode 100644
index 2b191c0..0000000
--- a/SorpLib/Components/MassTransfer/Testers/TesterMassTransferFlow4.mo
+++ /dev/null
@@ -1,56 +0,0 @@
-within SorpLib.Components.MassTransfer.Testers;
-model TesterMassTransferFlow4
-
-  MassTransferFlow massTransfer(
-    pStart(displayUnit="kPa") = 1200,
-    openingDirection=true,
-    vleFluidType=sim.vleFluidType1,
-    redeclare model MassTransfer_flow =
-        MassTransferPhenomena.Laminar_dp (
-        L=0.4,
-        zeta_lam=20,
-        d=0.03),
-    isClosable=true,
-    isFlap=true)
-    annotation (Placement(transformation(extent={{-10,13},{10,27}})));
-
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary1(
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1750.51,
-    use_pressureInput=true,
-    hFixed=2.8e6)
-    annotation (Placement(transformation(extent={{-36,10},{-28,30}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundary2(
-    m_flowFixed=-0.2,
-    boundaryType="p",
-    pFixed(displayUnit="kPa") = 1927.6,
-    hFixed=2.8e6)
-    annotation (Placement(transformation(extent={{22,10},{30,30}})));
-  Modelica.Blocks.Sources.Step step(
-    startTime=250,
-    height=300,
-    offset=1800)
-    annotation (Placement(transformation(extent={{-58,14},{-46,26}})));
-  Modelica.Blocks.Sources.BooleanStep booleanStep(startTime=150) annotation (
-      Placement(transformation(
-        extent={{-5,-5},{5,5}},
-        rotation=90,
-        origin={0,-5})));
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-equation
-
-  connect(step.y, vleBoundary1.p_in) annotation (Line(points={{-45.4,20},{-42,
-          20},{-42,26},{-36,26}}, color={0,0,127}));
-  connect(vleBoundary1.port, massTransfer.vlePortA) annotation (Line(
-      points={{-32,20},{-9.1,20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(massTransfer.vlePortB, vleBoundary2.port) annotation (Line(
-      points={{9.2,20},{9.2,20},{26,20}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(booleanStep.y, massTransfer.open) annotation (Line(points={{
-          4.44089e-016,0.5},{0,0.5},{0,12.8833}}, color={255,0,255}));
-end TesterMassTransferFlow4;
diff --git a/SorpLib/Components/MassTransfer/Testers/package.mo b/SorpLib/Components/MassTransfer/Testers/package.mo
deleted file mode 100644
index 13ff9fb..0000000
--- a/SorpLib/Components/MassTransfer/Testers/package.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Components.MassTransfer;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-
-
-
-
-
-end Testers;
diff --git a/SorpLib/Components/MassTransfer/Testers/package.order b/SorpLib/Components/MassTransfer/Testers/package.order
deleted file mode 100644
index 4aac1e2..0000000
--- a/SorpLib/Components/MassTransfer/Testers/package.order
+++ /dev/null
@@ -1,8 +0,0 @@
-TesterMassTransferFlow1
-TesterMassTransferFlow2
-TesterMassTransferFlow3
-TesterMassTransferFlow4
-TesterMassTransferDiffusion1
-TesterMassTransferDiffusionFlow1
-TesterMassTransferDiffusionFlow2
-TesterMassTransferDiffusionFlow3
diff --git a/SorpLib/Components/MassTransfer/VLEMassTransfers/ClosedAdsorberMassTransferDP.mo b/SorpLib/Components/MassTransfer/VLEMassTransfers/ClosedAdsorberMassTransferDP.mo
new file mode 100644
index 0000000..c5e2623
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/VLEMassTransfers/ClosedAdsorberMassTransferDP.mo
@@ -0,0 +1,226 @@
+within SorpLib.Components.MassTransfer.VLEMassTransfers;
+model ClosedAdsorberMassTransferDP
+  "Pressure-driven mass transfer models describing pure component adsorption in closed adsorbern"
+  extends SorpLib.Components.MassTransfer.BaseClasses.PartialPureMassTransferDP(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    final no_components=Medium.nX,
+    redeclare replaceable model MassTransferCoefficient =
+    SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.ConstantCoefficient
+      constrainedby
+      SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDP(
+        fluidProperties=fluidProperties));
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="Medium", group="Fluid"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of state records
+  //
+  Medium.ThermodynamicState stateAIn = if calculateFluidProperties and not
+    fluidPropertyPosition == SorpLib.Choices.MassTransferFluidProperties.PortBInlet
+    then Medium.setState_phX(
+      p = if limitPressureForCalculations then max(port_a.p, p_min) else port_a.p,
+      h = inStream(port_a.h_outflow),
+      X = inStream(port_a.Xi_outflow))
+    else Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+    "Instreaming state properties at port a";
+
+  Medium.ThermodynamicState stateBIn = if calculateFluidProperties and not
+    fluidPropertyPosition == SorpLib.Choices.MassTransferFluidProperties.PortAInlet
+    then Medium.setState_phX(
+      p = if limitPressureForCalculations then max(port_b.p, p_min) else port_b.p,
+      h = inStream(port_b.h_outflow),
+      X = inStream(port_b.Xi_outflow))
+    else Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+    "Instreaming state properties at port b";
+
+  //
+  // Definition of connectors for conditional removed models / variables
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput T_adsorptiveA_calc(final unit="K")=
+    Medium.temperature(state=stateAIn) if
+    calculateFluidProperties
+    "Temperature of adsorptive at port a";
+  Modelica.Blocks.Interfaces.RealInput T_adsorptiveB_calc(final unit="K")=
+    Medium.temperature(state=stateBIn) if
+    calculateFluidProperties
+    "Temperature of adsorptive at port b";
+
+  Modelica.Blocks.Interfaces.RealInput d_adsorptiveA_calc(final unit="kg/m3")=
+    Medium.density(state=stateAIn) if
+    calculateFluidProperties
+    "Density of adsorptive at port a";
+  Modelica.Blocks.Interfaces.RealInput d_adsorptiveB_calc(final unit="kg/m3")=
+    Medium.density(state=stateBIn) if
+    calculateFluidProperties
+    "Density of adsorptive at port b";
+
+  Modelica.Blocks.Interfaces.RealInput eta_adsorptiveA_calc(final unit="Pa.s")=
+    Medium.dynamicViscosity(state=stateAIn) if
+    calculateFluidProperties
+    "Dynamic viscosity of adsorptive at port a";
+  Modelica.Blocks.Interfaces.RealInput eta_adsorptiveB_calc(final unit="Pa.s")=
+    Medium.dynamicViscosity(state=stateBIn) if
+    calculateFluidProperties
+    "Dynamic viscosity of adsorptive at port b";
+
+equation
+  //
+  // Connections
+  //
+  connect(T_adsorptiveA_internal, T_adsorptiveA_calc);
+  connect(T_adsorptiveB_internal, T_adsorptiveB_calc);
+
+  connect(d_adsorptiveA_internal, d_adsorptiveA_calc);
+  connect(d_adsorptiveB_internal, d_adsorptiveB_calc);
+
+  connect(eta_adsorptiveA_internal, eta_adsorptiveA_calc);
+  connect(eta_adsorptiveB_internal, eta_adsorptiveB_calc);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model is used to connect adsorbate volumes with a VLE volume,
+evaporator, condenser, or other adsorbate volumes. Thus, the mass heat transfer 
+model represents a hydraulic resistance between two models. Depending on the 
+driving potential (i.e., pressure difference) and the chosen transport phenomena, 
+this model determines the mass flow rate between the connected models. Note that
+port b is located at the adsorbate volume by design.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has a steady-state energy balance
+</p>
+<pre>
+    0 = port_a.m_flow + port_b.m_flow;
+</pre>
+<p>
+and a steady-state energy balance
+</p>
+<pre>
+    port_a.h_outflow = port_b.h_outflow;
+</pre>
+<p>
+The mass flow rate <i>port_a.m_flow</i> is calculated linearly dependent on the
+pressure difference <i>&Delta;p = port_a.p - port_b.p</i>:
+</p>
+<pre>
+    port_a.m_flow = &beta; * &Delta;p = &beta; * (port_a.p - port_b.p);
+</pre>
+<p>
+The mass transport coefficient is calculated according to the selected corrlation.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  Linear driving force approach
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This mass transfer model is used to describe the mass transfer between an
+adsorbate volume and VLE volume or evaporator/condenser within closed adosrbers.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>canBeActivated</i>:
+  Defines if the mass transfer can activaly be activated or deactivated via an
+  input signal.
+  </li>
+  <li>
+  <i>isFlapValve</i>:
+  Defines if the mass transfer model behaves like a flap valve.
+  </li>
+  <li>
+  <i>isFlowAB</i>:
+  Defines the flow direction if the mass transfer models behaves like a flap
+  valve.
+  </li>
+  <li>
+  <i>offset_dp</i>:
+  Defines an optional offset for pressure difference if the mass transfer behaves
+  likes a flap valve.
+  </li>
+  <br>
+  <li>
+  <i>useBetaInput</i>:
+  Defines if mass transfer coefficient is given via an input.
+  </li>
+  <li>
+  <i>calculateFluidProperties</i>:
+  Defines if fluid properties are required to calculate the mass transfer coefficient.
+  </li>
+  <li>
+  <i>fluidPropertyPosition</i>:
+  Defines the position of the fluid properties used for calculations.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+  <li>
+  <i>avoid_events_activating</i>:
+  Defines if events shall be avoided via the noEvent()-operator when activating/
+  deactivating the mass transfer.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Lanzerath, F. and Bau, U. and Seiler, J. and Bardow, A. (2015). Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 21(3), 248-257. DOI: https://doi.org/10.1080/10789669.2014.990337.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ClosedAdsorberMassTransferDP;
diff --git a/SorpLib/Components/MassTransfer/VLEMassTransfers/ClosedAdsorberMassTransferDX.mo b/SorpLib/Components/MassTransfer/VLEMassTransfers/ClosedAdsorberMassTransferDX.mo
new file mode 100644
index 0000000..3357788
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/VLEMassTransfers/ClosedAdsorberMassTransferDX.mo
@@ -0,0 +1,240 @@
+within SorpLib.Components.MassTransfer.VLEMassTransfers;
+model ClosedAdsorberMassTransferDX
+  "Loading-driven mass transfer models describing pure component adsorption in closed adsorbern"
+  extends SorpLib.Components.MassTransfer.BaseClasses.PartialPureMassTransferDX(
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    redeclare final SorpLib.Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    final no_components=Medium.nX,
+    redeclare replaceable model MassTransferCoefficient =
+    SorpLib.Components.MassTransfer.MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.ConstantCoefficient
+      constrainedby
+      SorpLib.Components.MassTransfer.BaseClasses.PartialMassTransferCoefficientClosedAdsorberDX(
+        fluidProperties=fluidProperties),
+    redeclare replaceable model WorkingPair =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+        redeclare replaceable package Medium = Medium,
+        stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+        calcCaloricProperties=false,
+        calcEntropicProperties=false,
+        calcDerivativesIsotherm=false,
+        calcDerivativesMassEnergyBalance=false,
+        calcDerivativesEntropyBalance=false));
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="Medium", group="Fluid"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of state records
+  //
+  Medium.ThermodynamicState stateAIn = if calculateFluidProperties and not
+    fluidPropertyPosition == SorpLib.Choices.MassTransferFluidProperties.PortBInlet
+    then Medium.setState_phX(
+      p = if limitPressureForCalculations then max(port_a.p, p_min) else port_a.p,
+      h = inStream(port_a.h_outflow),
+      X = inStream(port_a.Xi_outflow))
+    else Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+    "Instreaming state properties at port a";
+
+  Medium.ThermodynamicState stateBIn = if calculateFluidProperties and not
+    fluidPropertyPosition == SorpLib.Choices.MassTransferFluidProperties.PortAInlet
+    then Medium.setState_phX(
+      p = if limitPressureForCalculations then max(port_b.p, p_min) else port_b.p,
+      h = inStream(port_b.h_outflow),
+      X = inStream(port_b.Xi_outflow))
+    else Medium.setState_phX(
+        p=Medium.p_default,
+        h=Medium.specificEnthalpy_pTX(
+          p=Medium.p_default,
+          T=Medium.T_default,
+          X=Medium.X_default),
+        X=Medium.X_default)
+    "Instreaming state properties at port b";
+
+  //
+  // Definition of connectors for conditional removed models / variables
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput T_adsorptiveA_calc(final unit="K")=
+    Medium.temperature(state=stateAIn) if
+    calculateFluidProperties
+    "Temperature of adsorptive at port a";
+  Modelica.Blocks.Interfaces.RealInput T_adsorptiveB_calc(final unit="K")=
+    Medium.temperature(state=stateBIn) if
+    calculateFluidProperties
+    "Temperature of adsorptive at port b";
+
+  Modelica.Blocks.Interfaces.RealInput d_adsorptiveA_calc(final unit="kg/m3")=
+    Medium.density(state=stateAIn) if
+    calculateFluidProperties
+    "Density of adsorptive at port a";
+  Modelica.Blocks.Interfaces.RealInput d_adsorptiveB_calc(final unit="kg/m3")=
+    Medium.density(state=stateBIn) if
+    calculateFluidProperties
+    "Density of adsorptive at port b";
+
+  Modelica.Blocks.Interfaces.RealInput eta_adsorptiveA_calc(final unit="Pa.s")=
+    Medium.dynamicViscosity(state=stateAIn) if
+    calculateFluidProperties
+    "Dynamic viscosity of adsorptive at port a";
+  Modelica.Blocks.Interfaces.RealInput eta_adsorptiveB_calc(final unit="Pa.s")=
+    Medium.dynamicViscosity(state=stateBIn) if
+    calculateFluidProperties
+    "Dynamic viscosity of adsorptive at port b";
+
+equation
+  //
+  // Connections
+  //
+  connect(T_adsorptiveA_internal, T_adsorptiveA_calc);
+  connect(T_adsorptiveB_internal, T_adsorptiveB_calc);
+
+  connect(d_adsorptiveA_internal, d_adsorptiveA_calc);
+  connect(d_adsorptiveB_internal, d_adsorptiveB_calc);
+
+  connect(eta_adsorptiveA_internal, eta_adsorptiveA_calc);
+  connect(eta_adsorptiveB_internal, eta_adsorptiveB_calc);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass transfer model is used to connect adsorbate volumes with a VLE volume,
+evaporator, condenser, or other adsorbate volumes. Thus, the mass heat transfer 
+model represents a hydraulic resistance between two models. Depending on the 
+driving potential (i.e., loading difference) and the chosen transport phenomena, 
+this model determines the mass flow rate between the connected models. Note that
+port b is located at the adsorbate volume by design.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The model has a steady-state energy balance
+</p>
+<pre>
+    0 = port_a.m_flow + port_b.m_flow;
+</pre>
+<p>
+and a steady-state energy balance
+</p>
+<pre>
+    port_a.h_outflow = port_b.h_outflow;
+</pre>
+<p>
+The mass flow rate <i>port_a.m_flow</i> is calculated linearly dependent on the
+loading difference <i>&Delta;x = port_a.x - port_b.x</i>:
+</p>
+<pre>
+    port_a.m_flow = &beta; * &Delta;x = &beta; * (port_a.x - port_b.x);
+</pre>
+<p>
+Note that the loading at port p corresponds to the loading of the connect adsorbate
+volume and is given via an input. The loading at port a is calculated loading using
+the pressure at port a and the actual adorpt temperature (i.e., temperature at port
+b given via an input). The mass transport coefficient is calculated according to the 
+selected corrlation.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  Linear driving force approach
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This mass transfer model is used to describe the mass transfer between an
+adsorbate volume and VLE volume or evaporator/condenser within closed adosrbers.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>canBeActivated</i>:
+  Defines if the mass transfer can activaly be activated or deactivated via an
+  input signal.
+  </li>
+  <li>
+  <i>isFlapValve</i>:
+  Defines if the mass transfer model behaves like a flap valve.
+  </li>
+  <li>
+  <i>isFlowAB</i>:
+  Defines the flow direction if the mass transfer models behaves like a flap
+  valve.
+  </li>
+  <li>
+  <i>offset_dp</i>:
+  Defines an optional offset for pressure difference if the mass transfer behaves
+  likes a flap valve.
+  </li>
+  <br>
+  <li>
+  <i>useBetaInput</i>:
+  Defines if mass transfer coefficient is given via an input.
+  </li>
+  <li>
+  <i>calculateFluidProperties</i>:
+  Defines if fluid properties are required to calculate the mass transfer coefficient.
+  </li>
+  <li>
+  <i>fluidPropertyPosition</i>:
+  Defines the position of the fluid properties used for calculations.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+  <li>
+  <i>avoid_events_activating</i>:
+  Defines if events shall be avoided via the noEvent()-operator when activating/
+  deactivating the mass transfer.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Lanzerath, F. and Bau, U. and Seiler, J. and Bardow, A. (2015). Optimal design of adsorption chillers based on a validated dynamic object-oriented model. Science and Technology for the Built Environment, 21(3), 248-257. DOI: https://doi.org/10.1080/10789669.2014.990337.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 25, 2024, by Mirko Engelpracht:<br/>
+  Minor revisions and documentation.
+  </li>
+  <li>
+  January 18, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ClosedAdsorberMassTransferDX;
diff --git a/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/Test_ClosedAdsorberMassTransferDP.mo b/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/Test_ClosedAdsorberMassTransferDP.mo
new file mode 100644
index 0000000..b47bd36
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/Test_ClosedAdsorberMassTransferDP.mo
@@ -0,0 +1,169 @@
+within SorpLib.Components.MassTransfer.VLEMassTransfers.Tester;
+model Test_ClosedAdsorberMassTransferDP
+  "Tester for the pressure-driven mass transfer model used within closed adsorbers describing pure component adsorption"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource fluidSource(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare package Medium = Medium)
+    "Fluid source" annotation (Placement(
+        transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={-40,60})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource heatSource(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true)
+    "Heat source for fluid volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=270,
+                origin={40,60})));
+
+  //
+  // Definition of heat and mass transfer models
+  //
+  SorpLib.Components.MassTransfer.VLEMassTransfers.ClosedAdsorberMassTransferDP
+    massTransfer(
+    calculateFluidProperties=true,
+    fluidPropertyPosition=SorpLib.Choices.MassTransferFluidProperties.AverageInstreaming,
+    p_min(displayUnit="Pa") = 1000,
+    redeclare model MassTransferCoefficient =
+        MassTransferCoefficientCorrelations.ClosedAdsorber.PressureDriven.DarcyPackedBedSpheresKnudsenDiffusionPoiseuilleFlow,
+    redeclare package Medium = Medium) "Mass transfer model" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={-40,38})));
+
+  SorpLib.Components.HeatTransfer.ClosedAdsorberHeatTransfer heatTransfer(
+    redeclare model HeatTransferCoefficient =
+      HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.LinearAlphaA
+        (
+       constantAlphaA=500, b=2),
+    fluidProperties= SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=adsorbateVolume.adsorbateProperties.p,
+      T=adsorbateVolume.adsorbateProperties.T,
+      rho=1/adsorbateVolume.workingPair.medium_sorbent.state_variables.v,
+      cp=adsorbateVolume.workingPair.medium_sorbent.additional_variables.c,
+      eta=0,
+      lambda=adsorbateVolume.workingPair.medium_sorbent.additional_variables.lambda))
+    "Heat transfer model"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={40,40})));
+
+  //
+  // Definition of liquid volume models
+  //
+  Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume adsorbateVolume(
+    T_initial=373.15,
+    useHeatPorts=false,
+    useHeatPortsX=false,
+    geometry(V=Modelica.Constants.pi/4*0.1^2*1),
+    redeclare model PureWorkingPairModel =
+      Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+      approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron,
+      approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl,
+      limitLowerPressure=true,
+      limitLowerPressureAdsorptive=true),
+    x_initial=0.1,
+    redeclare final package Medium = Medium,
+    nSorptionPorts=1)
+    "Model of an adsorbate volume"
+    annotation (Placement(transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=0,
+        origin={0,0})));
+
+  //
+  // Definition of thermal boundaries
+  //
+
+protected
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=50,
+    f=1/250,
+    offset=273.15 + 75) "Input for temperature"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={40,80})));
+
+  Modelica.Blocks.Sources.Sine input_p(
+    amplitude=2.5e3,
+    f=1/250,
+    offset=5e3)
+    "Input for pressure"
+    annotation (Placement(transformation(
+        extent={{10,10},{-10,-10}},
+        rotation=90,
+        origin={-40,80})));
+
+equation
+  //
+  // Connections
+  //
+  connect(massTransfer.port_b, adsorbateVolume.fp_sorption[1]) annotation (Line(
+      points={{-40,30},{-40,20},{-3.2,20},{-3.2,8.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(fluidSource.port, massTransfer.port_a) annotation (Line(
+      points={{-40,60},{-40,45.8}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(heatSource.port, heatTransfer.hp_b[1]) annotation (Line(
+      points={{40,60},{40,48}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer.hp_a[1], adsorbateVolume.hp_sorption) annotation (Line(
+      points={{40,32},{40,28},{3.2,28},{3.2,15.2}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_p.y, fluidSource.p_input) annotation (Line(points={{-40,69},{-40,
+          64},{-45,64},{-45,61.2}}, color={0,0,127}));
+  connect(input_T.y, heatSource.T_input) annotation (Line(points={{40,69},{40,64},
+          {45.2,64},{45.2,61}},
+                              color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the pressure-driven mass transfer model used within closed 
+adsorbers describing pure component adsorption.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 24, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ClosedAdsorberMassTransferDP;
diff --git a/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/Test_ClosedAdsorberMassTransferDX.mo b/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/Test_ClosedAdsorberMassTransferDX.mo
new file mode 100644
index 0000000..b871a11
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/Test_ClosedAdsorberMassTransferDX.mo
@@ -0,0 +1,179 @@
+within SorpLib.Components.MassTransfer.VLEMassTransfers.Tester;
+model Test_ClosedAdsorberMassTransferDX
+  "Tester for the loading-driven mass transfer model used within closed adsorbers describing pure component adsorption"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model WorkingPair =
+    SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE
+    "Working pair model"
+    annotation (Dialog(tab="General", group="Media"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource fluidSource(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=323.15,
+    redeclare package Medium = Medium)
+    "Fluid source"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={-40,60})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource heatSource(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true)
+    "Heat source for fluid volume"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=270,
+                origin={40,60})));
+
+  //
+  // Definition of heat and mass transfer models
+  //
+  SorpLib.Components.MassTransfer.VLEMassTransfers.ClosedAdsorberMassTransferDX
+    massTransfer(
+    calculateFluidProperties=true,
+    fluidPropertyPosition=SorpLib.Choices.MassTransferFluidProperties.AverageInstreaming,
+    p_min(displayUnit="Pa") = 1000,
+    redeclare model MassTransferCoefficient =
+        MassTransferCoefficientCorrelations.ClosedAdsorber.LoadingDriven.GlueckaufArrhenius
+        (m_sorbent=adsorbateVolume.m_sor_initial),
+    x_adsorpt_input=adsorbateVolume.x,
+    T_adsorpt_input=adsorbateVolume.T,
+    redeclare model WorkingPair = WorkingPair,
+    redeclare package Medium = Medium) "Mass transfer model" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={-40,40})));
+
+  SorpLib.Components.HeatTransfer.ClosedAdsorberHeatTransfer heatTransfer(
+    redeclare model HeatTransferCoefficient =
+      HeatTransfer.HeatTransferCoefficientCorrelations.ClosedAdsorber.LinearAlphaA
+        (
+        constantAlphaA=500, b=2),
+    fluidProperties=SorpLib.Components.HeatTransfer.Records.FluidProperties(
+      p=adsorbateVolume.adsorbateProperties.p,
+      T=adsorbateVolume.adsorbateProperties.T,
+      rho=1/adsorbateVolume.workingPair.medium_sorbent.state_variables.v,
+      cp=adsorbateVolume.workingPair.medium_sorbent.additional_variables.c,
+      eta=0,
+      lambda=adsorbateVolume.workingPair.medium_sorbent.additional_variables.lambda))
+    "Heat transfer model"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={40,40})));
+
+  //
+  // Definition of liquid volume models
+  //
+  Basics.Volumes.AdsorbateVolumes.AdsorbatePureVLEVolume adsorbateVolume(
+    T_initial=373.15,
+    useHeatPorts=false,
+    useHeatPortsX=false,
+    geometry(V=Modelica.Constants.pi/4*0.1^2*1),
+    redeclare model PureWorkingPairModel = WorkingPair (
+      approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron,
+      approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl,
+      limitLowerPressure=true,
+      limitLowerPressureAdsorptive=true),
+    x_initial=0.1,
+    redeclare final package Medium = Medium,
+    nSorptionPorts=1)
+    "Model of an adsorbate volume"
+    annotation (Placement(transformation(
+        extent={{-20,-20},{20,20}},
+        rotation=0,
+        origin={0,0})));
+
+  //
+  // Definition of thermal boundaries
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=50,
+    f=1/250,
+    offset=273.15 + 75) "Input for temperature"
+    annotation (Placement(transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={40,80})));
+
+  Modelica.Blocks.Sources.Sine input_p(
+    amplitude=2.5e3,
+    f=1/250,
+    offset=5e3)
+    "Input for pressure"
+    annotation (Placement(transformation(
+        extent={{10,10},{-10,-10}},
+        rotation=90,
+        origin={-40,80})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fluidSource.port, massTransfer.port_a) annotation (Line(
+      points={{-40,60},{-40,47.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(massTransfer.port_b, adsorbateVolume.fp_sorption[1]) annotation (Line(
+      points={{-40,32},{-40,20},{-3.2,20},{-3.2,8.8}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(heatSource.port, heatTransfer.hp_b[1]) annotation (Line(
+      points={{40,60},{40,48}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer.hp_a[1], adsorbateVolume.hp_sorption) annotation (Line(
+      points={{40,32},{40,28},{3.2,28},{3.2,15.2}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_p.y, fluidSource.p_input) annotation (Line(points={{-40,69},{-40,
+          64},{-45,64},{-45,61.2}}, color={0,0,127}));
+  connect(input_T.y, heatSource.T_input) annotation (Line(points={{40,69},{40,64},
+          {45.2,64},{45.2,61}},
+                              color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the loading-driven mass transfer model used within closed 
+adsorbers describing pure component adsorption.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 25, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ClosedAdsorberMassTransferDX;
diff --git a/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/package.mo b/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/package.mo
new file mode 100644
index 0000000..18f9d41
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.MassTransfer.VLEMassTransfers;
+package Tester "Models to test and varify mass transfer models"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented mass transfer 
+models. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructering the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/package.order b/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/package.order
new file mode 100644
index 0000000..d5178c2
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/VLEMassTransfers/Tester/package.order
@@ -0,0 +1,2 @@
+Test_ClosedAdsorberMassTransferDP
+Test_ClosedAdsorberMassTransferDX
diff --git a/SorpLib/Components/MassTransfer/VLEMassTransfers/package.mo b/SorpLib/Components/MassTransfer/VLEMassTransfers/package.mo
new file mode 100644
index 0000000..cd28e97
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/VLEMassTransfers/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components.MassTransfer;
+package VLEMassTransfers "Mass transfer models for real fluids (i.e., with a two-phase regime)"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains mass transfer models using real fluids (i.e., with a two-
+phase regime) that are based on the open-source Modelica Standard Library (MSL).
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end VLEMassTransfers;
diff --git a/SorpLib/Components/MassTransfer/VLEMassTransfers/package.order b/SorpLib/Components/MassTransfer/VLEMassTransfers/package.order
new file mode 100644
index 0000000..8e9f26f
--- /dev/null
+++ b/SorpLib/Components/MassTransfer/VLEMassTransfers/package.order
@@ -0,0 +1,3 @@
+ClosedAdsorberMassTransferDP
+ClosedAdsorberMassTransferDX
+Tester
diff --git a/SorpLib/Components/MassTransfer/package.mo b/SorpLib/Components/MassTransfer/package.mo
index dddf08f..62e4d49 100644
--- a/SorpLib/Components/MassTransfer/package.mo
+++ b/SorpLib/Components/MassTransfer/package.mo
@@ -1,10 +1,21 @@
 within SorpLib.Components;
-package MassTransfer
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-
-
-
+package MassTransfer "Models and correlations to calculate mass transfers"
+  extends SorpLib.Icons.MassTransfersPackage;
 
+  annotation (Documentation(info="<html>
+<p>
+This package includes various mass transfer models for deal gases and real 
+substances (i.e., with a two-phase region). The mass transfer models can be
+used within closed or open adsorbers to describe the mass transfer between
+adsorbate volumes and other volumes, such as gas, VLE, or phase saparator
+volumes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
 end MassTransfer;
diff --git a/SorpLib/Components/MassTransfer/package.order b/SorpLib/Components/MassTransfer/package.order
index b106aa7..746da38 100644
--- a/SorpLib/Components/MassTransfer/package.order
+++ b/SorpLib/Components/MassTransfer/package.order
@@ -1,7 +1,4 @@
-MassTransferFlow
-MassTransferDiffusion
-MassTransferDiffusionFlow
-Partial
-MassTransferPhenomena
-Testers
-Record
+BaseClasses
+Records
+MassTransferCoefficientCorrelations
+VLEMassTransfers
diff --git a/SorpLib/Components/OpenAdsorber/Geometry/CylindricAdsorber.mo b/SorpLib/Components/OpenAdsorber/Geometry/CylindricAdsorber.mo
deleted file mode 100644
index 12e2aef..0000000
--- a/SorpLib/Components/OpenAdsorber/Geometry/CylindricAdsorber.mo
+++ /dev/null
@@ -1,29 +0,0 @@
-within SorpLib.Components.OpenAdsorber.Geometry;
-record CylindricAdsorber
-  extends GeneralAdsorberGeometry(
-            final innerVolume = length*Modelica.Constants.pi*(innerDiameter/2)^2,
-            final outerVolume = length*Modelica.Constants.pi*(outerDiameter/2)^2,
-            final innerLateralArea = Modelica.Constants.pi*innerDiameter*length,
-            final outerLateralArea = Modelica.Constants.pi*outerDiameter*length,
-            final innerCrossSection = Modelica.Constants.pi*(innerDiameter/2)^2,
-            final hydraulicDiameter = innerDiameter);
-
-  parameter Modelica.SIunits.Diameter innerDiameter=0.15
-    "Inner diameter of adsorber" annotation (Dialog(group="Geometry"));
-  parameter Modelica.SIunits.Diameter outerDiameter=0.16
-    "Outer diameter of adsorber" annotation (Dialog(group="Geometry"));
-
-  annotation (Documentation(info="<html>
-  <p>
-    This record describes a cylindric open adsorber. <br>  
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 11, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end CylindricAdsorber;
diff --git a/SorpLib/Components/OpenAdsorber/Geometry/GeneralAdsorberGeometry.mo b/SorpLib/Components/OpenAdsorber/Geometry/GeneralAdsorberGeometry.mo
deleted file mode 100644
index 77edfab..0000000
--- a/SorpLib/Components/OpenAdsorber/Geometry/GeneralAdsorberGeometry.mo
+++ /dev/null
@@ -1,61 +0,0 @@
-within SorpLib.Components.OpenAdsorber.Geometry;
-record GeneralAdsorberGeometry
-  extends SorpLib.Internals.ClassTypes.Record;
-
-  parameter Real psi(final unit="1")=0.34 "Void percentage of packed bed" annotation (Dialog(group="Packed bed"));
-
-  parameter Modelica.SIunits.Density bulkDensity=750
-    "Bulk density of packed bed" annotation (Dialog(group="Packed bed"));
-
-  parameter Modelica.SIunits.Diameter particleDiameter=0.002
-    "Diameter of particle" annotation (Dialog(group="Packed bed"));
-
-  parameter Modelica.SIunits.Length length=0.088 "Length of adsorber" annotation (Dialog(group="Geometry"));
-
-  parameter Modelica.SIunits.Volume innerVolume "Inner volume of adsorber" annotation (Dialog(group="Geometry"));
-
-  parameter Modelica.SIunits.Volume outerVolume "Outer volume of adsorber" annotation (Dialog(group="Geometry"));
-
-  parameter Modelica.SIunits.Area innerLateralArea
-    "Inner lateral area of adsorber" annotation (Dialog(group="Geometry"));
-
-  parameter Modelica.SIunits.Area outerLateralArea
-    "Outer lateral area of adsorber" annotation (Dialog(group="Geometry"));
-
-  parameter Modelica.SIunits.CrossSection innerCrossSection "Inner cross section of adsorber" annotation (Dialog(group="Geometry"));
-
-  parameter Modelica.SIunits.Diameter hydraulicDiameter "Hydraulic diameter" annotation (Dialog(group="Geometry"));
-
-  final parameter Modelica.SIunits.Diameter hydraulicDiameter_bed = (2/3)*psi/(1-psi)*particleDiameter "Hydraulic diameter of packed bed with spheric particles";
-
-  final parameter Modelica.SIunits.Mass massAdsorbent = innerVolume*bulkDensity;
-
-  final parameter Modelica.SIunits.Volume bedVolume = innerVolume*(1-psi)
-    "Volume of bed";
-
-  final parameter Modelica.SIunits.Volume wallVolume = outerVolume-innerVolume
-    "Volume of wall";
-
-  final parameter Modelica.SIunits.Volume particleVolume = (Modelica.Constants.pi/6)*(particleDiameter)^3
-    "Volume of particle";
-
-  final parameter Real particleNumber = bedVolume/particleVolume
-    "Number of particles";
-
-  final parameter Modelica.SIunits.Area particleSurface = particleNumber*Modelica.Constants.pi*(particleDiameter)^2
-    "Total surface of particles";
-
-  annotation (Documentation(info="<html>
-  <p>
-    This record containes all information necessary to describe a open adsorber geometry. <br>  
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 11, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end GeneralAdsorberGeometry;
diff --git a/SorpLib/Components/OpenAdsorber/Geometry/RectangularAdsorber.mo b/SorpLib/Components/OpenAdsorber/Geometry/RectangularAdsorber.mo
deleted file mode 100644
index 5041271..0000000
--- a/SorpLib/Components/OpenAdsorber/Geometry/RectangularAdsorber.mo
+++ /dev/null
@@ -1,30 +0,0 @@
-within SorpLib.Components.OpenAdsorber.Geometry;
-record RectangularAdsorber
-  extends GeneralAdsorberGeometry(
-            final innerVolume = length*innerCrossSection,
-            final outerVolume = length*outerCrossSection,
-            final innerLateralArea = length*2*(innerWidth+innerHeigth),
-            final outerLateralArea = length*2*(innerWidth+innerHeigth+4*wallThickness),
-            final innerCrossSection = innerWidth*innerHeigth);
-
-  parameter Modelica.SIunits.Diameter innerWidth=0.1
-    "Inner width of adsorber" annotation (Dialog(group="Geometry"));
-  parameter Modelica.SIunits.Diameter innerHeigth=0.1
-    "Inner height of adsorber" annotation (Dialog(group="Geometry"));
-  parameter Modelica.SIunits.Thickness wallThickness=0.01
-    "Wall thickness of adsorber" annotation (Dialog(group="Geometry"));
-
-  annotation (Documentation(info="<html>
-  <p>
-    This record describes a rectanular open adsorber. <br>  
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 11, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end RectangularAdsorber;
diff --git a/SorpLib/Components/OpenAdsorber/Geometry/package.mo b/SorpLib/Components/OpenAdsorber/Geometry/package.mo
deleted file mode 100644
index 8ee4c7c..0000000
--- a/SorpLib/Components/OpenAdsorber/Geometry/package.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Components.OpenAdsorber;
-package Geometry
-extends SorpLib.Internals.ClassTypes.RecordPackage;
-
-
-
-
-
-annotation (Documentation(info="<html>
-</html>"));
-end Geometry;
diff --git a/SorpLib/Components/OpenAdsorber/Geometry/package.order b/SorpLib/Components/OpenAdsorber/Geometry/package.order
deleted file mode 100644
index c8840b0..0000000
--- a/SorpLib/Components/OpenAdsorber/Geometry/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-GeneralAdsorberGeometry
-CylindricAdsorber
-RectangularAdsorber
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/HeatTransfer.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/HeatTransfer.mo
deleted file mode 100644
index 91ed4a4..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/HeatTransfer.mo
+++ /dev/null
@@ -1,20 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer;
-model HeatTransfer
-  extends SorpLib.Components.HeatTransfer.HeatTransfer;
-
-  inner input TILMedia.Internals.PropertyRecord properties_gas;
-  inner input Modelica.SIunits.MassFlowRate mdotHydraulic_gas;
-
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    Documentation(info="<html>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 11, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end HeatTransfer;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/MassTransferDiffusion.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/MassTransferDiffusion.mo
deleted file mode 100644
index 1d6bd15..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/MassTransferDiffusion.mo
+++ /dev/null
@@ -1,20 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer;
-model MassTransferDiffusion
-  extends SorpLib.Components.MassTransfer.MassTransferDiffusion;
-
-  inner input TILMedia.Internals.PropertyRecord properties_gas;
-  inner input Modelica.SIunits.MassFlowRate mdotHydraulic_gas;
-
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)),
-    Documentation(info="<html>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 11, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end MassTransferDiffusion;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedGas_HougenMarshall1947.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedGas_HougenMarshall1947.mo
deleted file mode 100644
index 988426c..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedGas_HougenMarshall1947.mo
+++ /dev/null
@@ -1,45 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.HeatTransfer;
-model PackedBedGas_HougenMarshall1947 "Heat transfer between packed bed and gas according to Hougen and Marshall (1947)"
-  extends
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer(final computeTransportProperties=true);
-
-  outer parameter Integer nCells;
-  outer parameter SorpLib.Components.OpenAdsorber.Geometry.GeneralAdsorberGeometry adsorberGeometry;
-
-  outer TILMedia.Internals.PropertyRecord properties_gas;
-  outer Modelica.SIunits.MassFlowRate mdotHydraulic_gas;
-
-  Modelica.SIunits.ReynoldsNumber Re_par "Reynolds-Number for one Particle";
-
-equation
-  Re_par = noEvent(abs(mdotHydraulic_gas))*adsorberGeometry.particleDiameter/(adsorberGeometry.innerCrossSection*properties_gas.transp.eta*adsorberGeometry.psi);
-
-  alphaA = 0.683*properties_gas.cp*mdotHydraulic_gas/(adsorberGeometry.innerCrossSection*adsorberGeometry.psi)*(Re_par+1)^(-0.51)*adsorberGeometry.particleSurface/nCells;
-
-  annotation (Documentation(info="<html>
-<p>
-  This model calculates heat transfer coefficient from gas to adsorbent for packed beds according to Hougen and Marshall (1947). The hydraulic mass flow rate, the fluid properties record, the adsorber geometry and discretization number are defined as outer objects and thus taken from the overlying model level.  
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i><code>&alpha;</code></i> = 0.683 <i>c</i><sub>p</sub> <i><code>&#7745;</code></i><sub>hydraulic</sub> / (<i>A</i><sub>cs</sub> <i><code>&psi;</code></i>) Re<sup>-0.51</sup>
-<p>where <i><code>&alpha;</code></i> is the heat transfer coefficient, <i>c</i><sub>p</sub> is the specific heat capacity,  <i><code>&#7745;</code></i><sub>hydraulic</sub> is the hydraulic mass flow, <i>A</i><sub>cs</sub> is the cross sectional area, <i><code>&psi;</code></i> is the void percentage of packed bed and Re is the Reynolds number. </p>
-<p>For detailed information we refer to Hougen and Marshall (1947).</p>
-</p>
-
-<h4>References</h4>
-<ul>
-<li>Adsorption from a Fluid Stream flowing through a stationary Granular Bed, Hougen O.A. and Marshall W.R., Chemical Engineering Progress, 1947. </li>
-</ul>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end PackedBedGas_HougenMarshall1947;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedGas_Kast1988.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedGas_Kast1988.mo
deleted file mode 100644
index ba39e40..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedGas_Kast1988.mo
+++ /dev/null
@@ -1,64 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.HeatTransfer;
-model PackedBedGas_Kast1988 "Heat transfer between packed bed and gas according to Kast (1988)"
-  extends
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer(final computeTransportProperties=true);
-
-  outer parameter Integer nCells;
-  outer parameter SorpLib.Components.OpenAdsorber.Geometry.GeneralAdsorberGeometry adsorberGeometry;
-
-  outer TILMedia.Internals.PropertyRecord properties_gas;
-  outer Modelica.SIunits.MassFlowRate mdotHydraulic_gas;
-
-  final parameter Real Nu_min=2 "For spehrical particles";
-  final parameter Real formFactor=1+1.5*(1-adsorberGeometry.psi) "For spherical particles";
-
-  Modelica.SIunits.ReynoldsNumber Re_par "Reynolds-Number for one Particle";
-  Modelica.SIunits.NusseltNumber Nu_lam "Laminar Nusselt-Number";
-  Modelica.SIunits.NusseltNumber Nu_turb "Turbulent Nusselt-Number";
-  Modelica.SIunits.NusseltNumber Nu_Par "Nusselt-Number for one Particle";
-  Modelica.SIunits.NusseltNumber Nu_Bed "Nusselt-Number for all Bed";
-
-equation
-  Re_par = noEvent(abs(mdotHydraulic_gas))*adsorberGeometry.particleDiameter/(adsorberGeometry.innerCrossSection*properties_gas.transp.eta*adsorberGeometry.psi);
-
-  Nu_lam = 0.664*(Re_par+1)^0.5*properties_gas.transp.Pr^0.5;
-
-  Nu_turb = (0.037*(Re_par+1)^0.8*properties_gas.transp.Pr)/(1 + 2.443*(Re_par+1)^(-0.8)*(properties_gas.transp.Pr^(2/3) - 1));
-
-  Nu_Par = Nu_min + (Nu_lam^2 + Nu_turb^2)^0.5;
-
-  Nu_Bed = formFactor*Nu_Par;
-
-  alphaA = Nu_Bed*properties_gas.transp.lambda/adsorberGeometry.particleDiameter*adsorberGeometry.particleSurface/nCells;
-
-  annotation (Documentation(info="<html>
-<p>
-  This model calculates heat transfer coefficient from gas to adsorbent for packed beds according to Kast (1988). The hydraulic mass flow rate, the fluid properties record, the adsorber geometry and discretization number are defined as outer objects and thus taken from the overlying model level.  
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> Nu = <i>f</i><sub>a</sub> (Nu<sub>min</sub> + <code>&radic;</code>(Nu<sub>lam</sub><sup>2</sup> + Nu<sub>turb</sub><sup>2</sup>)) </p>
-<p>where Nu is the Nusselt number and <i>f</i><sub>a</sub> is the form factor. </p>
-Nu<sub>lam</sub> and Nu<sub>turb</sub> are calculated by following correlations:
-<p align=\"center\"> Nu<sub>lam</sub> = 0.664 <code>&radic;</code>Re <code>&radic;</code>Pr </p>
-<p align=\"center\"> Nu<sub>turb</sub> = 0.037 Re<sup>0.8</sup> Pr / (1 + 2.443 Re<sup>-0.8</sup> (Pr<sup>2/3</sup> - 1)) </p>
-<p>where Re is the Reynolds number and Pr is the Prandtl number. </p>
-<p>For detailed information we refer to Kast (1988). </p>
-</p>
-
-<h4>References</h4>
-<ul>
-<li>Adsorption aus der Gasphase, Werner Kast, Darmstadt, 1988. </li>
-</ul>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end PackedBedGas_Kast1988;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedWall_Kast1988.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedWall_Kast1988.mo
deleted file mode 100644
index 4515249..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/PackedBedWall_Kast1988.mo
+++ /dev/null
@@ -1,58 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.HeatTransfer;
-model PackedBedWall_Kast1988 "Heat transfer between packed bed and wall according to Kast (1988)"
-  extends
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer(final computeTransportProperties=true);
-
-  outer parameter Integer nCells;
-  outer parameter SorpLib.Components.OpenAdsorber.Geometry.GeneralAdsorberGeometry adsorberGeometry;
-
-  outer TILMedia.Internals.PropertyRecord properties_gas;
-  outer Modelica.SIunits.MassFlowRate mdotHydraulic_gas;
-
-  final parameter Real c=12 "Parameter for particle form consideration --> 12 for spherical";
-
-  Modelica.SIunits.PecletNumber Pe
-    "Peclet number";
-
-  Modelica.SIunits.NusseltNumber Nu_lengthCorrection;
-
-  Modelica.SIunits.NusseltNumber Nu
-    "Nusselt number";
-
-  final parameter Modelica.SIunits.Length mixtureLength = 1.15*adsorberGeometry.particleDiameter "Mixture Length for spherical particles";
-
-equation
-  Pe=noEvent(abs(mdotHydraulic_gas))/(properties_gas.d*adsorberGeometry.innerCrossSection*adsorberGeometry.psi)*mixtureLength/(properties_gas.transp.lambda/properties_gas.d/properties_gas.cp);
-
-  Nu_lengthCorrection=-1.55e-6*Pe^2+0.04285*Pe+24.57 "Own fit for spherical particles from Kast (1988) p. 136";
-
-  Nu=Nu_lengthCorrection/(1+c*adsorberGeometry.length/adsorberGeometry.hydraulicDiameter/(Pe+0.1));
-
-  alphaA=Nu*properties_gas.transp.lambda/mixtureLength*adsorberGeometry.innerLateralArea/nCells;
-
-  annotation (Documentation(info="<html>
-<p>
-  This model calculates heat transfer coefficient from gas to wall for packed beds according to Kast (1988). The hydraulic mass flow rate, the fluid properties record, the adsorber geometry and discretization number are defined as outer objects and thus taken from the overlying model level. 
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> Nu (1 + <i>c</i> <i>L / D</i> / Pe) = <i>f</i>(Pe)</p>
-<p>where Nu is the Nusselt number, <i>c</i> is a constant for the particle form, <i>L</i> is the hydraulic length, <i>D</i> is the hydraulic diameter and Pe is the Peclet number. The correlation <i>f</i>(Pe) is fitted with a second order polynom according to the diagram in Kast (1988), p. 136. </p>
-</p>
-
-<h4>References</h4>
-<ul>
-<li>Adsorption aus der Gasphase, Werner Kast, Darmstadt, 1988. </li>
-</ul>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end PackedBedWall_Kast1988;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.mo
deleted file mode 100644
index 11111c2..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.mo
+++ /dev/null
@@ -1,10 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena;
-package HeatTransfer
-  extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-
-
-
-end HeatTransfer;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.order b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.order
deleted file mode 100644
index 3572765..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/HeatTransfer/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-PackedBedWall_Kast1988
-PackedBedGas_Kast1988
-PackedBedGas_HougenMarshall1947
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/PackedBedGas_HougenMarshall1947.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/PackedBedGas_HougenMarshall1947.mo
deleted file mode 100644
index 4be518f..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/PackedBedGas_HougenMarshall1947.mo
+++ /dev/null
@@ -1,48 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.MassTransfer;
-model PackedBedGas_HougenMarshall1947 "Mass transfer between packed bed and gas according to Hougen and Marshall (1947)"
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp(      final computeTransportProperties=true);
-
-  outer parameter Modelica.SIunits.MolarMass M_adsorbent "Molar mass of adsorbate";
-  outer parameter Modelica.SIunits.MolarMass M_carrier "Molar mass of carrier";
-
-  outer parameter Integer nCells;
-  outer parameter SorpLib.Components.OpenAdsorber.Geometry.GeneralAdsorberGeometry adsorberGeometry;
-
-  outer TILMedia.Internals.PropertyRecord properties_gas;
-  outer Modelica.SIunits.MassFlowRate mdotHydraulic_gas;
-
-  Modelica.SIunits.ReynoldsNumber Re_par "Reynolds number for one particle";
-
-equation
-  Re_par=noEvent(abs(mdotHydraulic_gas))*adsorberGeometry.particleDiameter/(adsorberGeometry.innerCrossSection*properties_gas.transp.eta*adsorberGeometry.psi);
-
-  beta=0.704*noEvent(abs(mdotHydraulic_gas))/(adsorberGeometry.innerCrossSection*adsorberGeometry.psi)*(Re_par+1)^(-0.51)*(M_adsorbent/M_carrier)/properties_gas.p*adsorberGeometry.particleSurface/nCells;
-
-  annotation (Documentation(info="<html>
-<p>
-  This model calculates mass transfer coefficient from gas to adsorbent for packed beds according to Hougen and Marshall (1947). The hydraulic mass flow rate, the fluid properties record, the adsorber geometry and discretization number are defined as outer objects and thus taken from the overlying model level.  
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i><code>&beta;</code></i> = 0.704 <i><code>&#7745;</code></i><sub>hydraulic</sub> / (<i>A</i><sub>cs</sub> <i><code>&psi;</code></i>) Re<sup>-0.51</sup>
-<p>where <i><code>&beta;</code></i> is the mass transfer coefficient,  <i><code>&#7745;</code></i><sub>hydraulic</sub> is the hydraulic mass flow, <i>A</i><sub>cs</sub> is the cross sectional area, <i><code>&psi;</code></i> is the void percentage of packed bed and Re is the Reynolds number. </p>
-<p>For detailed information we refer to Hougen and Marshall (1947).</p>
-</p>
-
-<h4>References</h4>
-<ul>
-<li>Adsorption from a Fluid Stream flowing through a stationary Granular Bed, Hougen O.A. and Marshall W.R., Chemical Engineering Progress, 1947. </li>
-</ul>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end PackedBedGas_HougenMarshall1947;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/PackedBedGas_Kast1988.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/PackedBedGas_Kast1988.mo
deleted file mode 100644
index 2022e3a..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/PackedBedGas_Kast1988.mo
+++ /dev/null
@@ -1,72 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.MassTransfer;
-model PackedBedGas_Kast1988 "Mass transfer between packed bed and gas according to Kast (1988)"
-  extends
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp(      final computeTransportProperties=true);
-
-  outer parameter Modelica.SIunits.MolarMass M_adsorbent "Molar mass of adsorbate";
-
-  outer parameter Integer nCells;
-  outer parameter SorpLib.Components.OpenAdsorber.Geometry.GeneralAdsorberGeometry adsorberGeometry;
-
-  outer TILMedia.Internals.PropertyRecord properties_gas;
-  outer Modelica.SIunits.MassFlowRate mdotHydraulic_gas;
-
-  final parameter Real Sh_min=2 "For spehrical particles";
-  final parameter Real formFactor=1+1.5*(1-adsorberGeometry.psi) "For spherical particles";
-
-  Modelica.SIunits.ReynoldsNumber Re_par "Reynolds number for one particle";
-  Modelica.SIunits.DiffusionCoefficient diffusionCoefficient "Diffusion coefficient in binary mixture";
-  Modelica.SIunits.SchmidtNumber Sc "Schmidt number";
-  Real Sh_lam "Laminar Sherwood-Number";
-  Real Sh_turb "Turbulent Sherwood-Number";
-  Real Sh_par "Sherwood-Number for one Particle";
-  Real Sh_bed "Sherwood-Number for entire Bed";
-
-equation
-  Re_par = noEvent(abs(mdotHydraulic_gas))*adsorberGeometry.particleDiameter/(adsorberGeometry.innerCrossSection*properties_gas.transp.eta*adsorberGeometry.psi);
-
-  diffusionCoefficient = 1.72e-7*properties_gas.T-2.438e-5;
-
-  Sc = properties_gas.transp.eta/properties_gas.d/diffusionCoefficient;
-
-  Sh_lam = 0.664*(Re_par+1)^0.5*Sc^0.5;
-
-  Sh_turb = (0.037*(Re_par+1)^0.8*Sc)/(1 + 2.443*(Re_par+1)^(-0.8)*(Sc^(2/3) - 1));
-
-  Sh_par = Sh_min + (Sh_lam^2 + Sh_turb^2)^0.5;
-
-  Sh_bed = formFactor*Sh_par;
-
-  beta = Sh_bed*diffusionCoefficient/adsorberGeometry.particleDiameter*M_adsorbent/(properties_gas.T*Modelica.Constants.R)*adsorberGeometry.particleSurface/nCells;
-
-  annotation (Documentation(info="<html>
-<p>
-  This model calculates heat mass coefficient from gas to adsorbent for packed beds according to Kast (1988). The hydraulic mass flow rate, the fluid properties record, the adsorber geometry and discretization number are defined as outer objects and thus taken from the overlying model level.  
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> Sh = <i>f</i><sub>a</sub> (Sh<sub>min</sub> + <code>&radic;</code>(Sh<sub>lam</sub><sup>2</sup> + Sh<sub>turb</sub><sup>2</sup>)) </p>
-<p>where Sh is the Sherwood number and <i>f</i><sub>a</sub> is the form factor. </p>
-Sh<sub>lam</sub> and Sh<sub>turb</sub> are calculated by following correlations:
-<p align=\"center\"> Sh<sub>lam</sub> = 0.664 <code>&radic;</code>Re <code>&radic;</code>Sc </p>
-<p align=\"center\"> Sh<sub>turb</sub> = 0.037 Re<sup>0.8</sup> Sc / (1 + 2.443 Re<sup>-0.8</sup> (Sc<sup>2/3</sup> - 1)) </p>
-<p>where Re is the Reynolds number and Sc is the Schmidt number. </p>
-<p>For detailed information we refer to Kast (1988). </p>
-</p>
-
-<h4>References</h4>
-<ul>
-<li>Adsorption aus der Gasphase, Werner Kast, Darmstadt, 1988. </li>
-</ul>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end PackedBedGas_Kast1988;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/package.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/package.mo
deleted file mode 100644
index e307e18..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena;
-package MassTransfer
-  extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-
-end MassTransfer;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/package.order b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/package.order
deleted file mode 100644
index 526b040..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/MassTransfer/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-PackedBedGas_Kast1988
-PackedBedGas_HougenMarshall1947
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/package.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/package.mo
deleted file mode 100644
index fab7cd9..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.OpenAdsorber.HeatAndMassTransfer;
-package TransportPhenomena
-    extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-end TransportPhenomena;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/package.order b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/package.order
deleted file mode 100644
index b9c86f1..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/TransportPhenomena/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-HeatTransfer
-MassTransfer
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/package.mo b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/package.mo
deleted file mode 100644
index c8ae297..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.OpenAdsorber;
-package HeatAndMassTransfer
-     extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-end HeatAndMassTransfer;
diff --git a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/package.order b/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/package.order
deleted file mode 100644
index 2917363..0000000
--- a/SorpLib/Components/OpenAdsorber/HeatAndMassTransfer/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-MassTransferDiffusion
-HeatTransfer
-TransportPhenomena
diff --git a/SorpLib/Components/OpenAdsorber/OpenAdsorber.mo b/SorpLib/Components/OpenAdsorber/OpenAdsorber.mo
deleted file mode 100644
index 409908c..0000000
--- a/SorpLib/Components/OpenAdsorber/OpenAdsorber.mo
+++ /dev/null
@@ -1,433 +0,0 @@
-within SorpLib.Components.OpenAdsorber;
-model OpenAdsorber "Open adsorption system"
-
-  /*********************** SIM ***********************************/
-
-  inner parameter TILMedia.GasTypes.BaseGas gasType=sim.gasType1 "Gas type"
-    annotation (Dialog(tab="SIM", group="SIM"), choices(choice=sim.gasType1
-        "Gas 1 as defined in SIM", choice=sim.gasType2
-        "Gas 2 as defined in SIM"));
-  parameter TILMedia.VLEFluidTypes.BaseVLEFluid vleFluidType=sim.vleFluidType1
-    "VLE fluid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.vleFluidType1 "VLE fluid 1 as defined in SIM",
-      choice=sim.vleFluidType2 "VLE fluid 2 as defined in SIM",
-      choice=sim.vleFluidType3 "VLE fluid 3 as defined in SIM"));
-
-protected
-  outer TIL.SystemInformationManager sim "System Information Manager";
-  TIL.Internals.SimPort simPort;
-
-  /************************** Connectors *********************************/
-
-public
-  TIL.Connectors.GasPort gasPortA(final gasType=gasType) annotation (Placement(transformation(extent={{-128,
-            -10},{-108,10}}),    iconTransformation(extent={{-128,-10},{-108,10}})));
-  TIL.Connectors.GasPort gasPortB(final gasType=gasType) annotation (Placement(transformation(extent={{112,-10},
-            {132,10}}),        iconTransformation(extent={{112,-10},{132,10}})));
-
-  TIL.Connectors.HeatPort[nCells] heatPort annotation (Placement(transformation(extent={{-10,130},
-            {10,150}}),         iconTransformation(extent={{-10,130},{10,150}})));
-
-  /************************** Gas inlet/outlet ****************************/
-
-  TILMedia.Gas_ph gasA(
-      final gasType=gasType,
-      final p=gasPortA.p,
-      final h=noEvent(actualStream(gasPortA.h_outflow)),
-      each final xi=noEvent(actualStream(gasPortA.xi_outflow)))
-    annotation (Placement(transformation(extent={{-60,60},{-40,80}})));
-
-  TILMedia.Gas_ph gasB(
-      final gasType=gasType,
-      final p=gasPortB.p,
-      final h=noEvent(actualStream(gasPortB.h_outflow)),
-      each final xi=noEvent(actualStream(gasPortB.xi_outflow)))
-    annotation (Placement(transformation(extent={{40,60},{60,80}})));
-
-  /***********************Geometry characteristics******************************/
-
-  inner parameter Integer nCells(min=1) = 1
-    "Number of cells in adsorber for discretization" annotation (Dialog(group="Discretization"));
-
-  inner replaceable parameter Geometry.GeneralAdsorberGeometry adsorberGeometry
-    constrainedby Geometry.GeneralAdsorberGeometry "Adsorber geometry"
-    annotation (Dialog(group="Adsorber geometry"),
-    choicesAllMatching=true, Placement(transformation(extent={{58,-138},{78,
-            -118}})));
-
-
-  /*************************** Components *********************************/
-
-  /************************** Gas volume **********************************/
-
-  Cells.Gas.Gas[nCells] gas(
-    each final cellGeometry(
-      length=adsorberGeometry.length/nCells,
-      hydraulicDiameter=adsorberGeometry.particleDiameter,
-      flowCrossSection=adsorberGeometry.innerCrossSection,
-      psi=adsorberGeometry.psi),
-    each final gasType=gasType,
-    each final vleFluidType=vleFluidType,
-    each final generateEventsAtFlowReversal=generateEventsAtFlowReversal,
-    each final computeTransportProperties=computeTransportProperties,
-    each final HydraulicMassFlowPosition=HydraulicMassFlowPosition,
-    each final TInitial=TInitialGas,
-    each final xiInitial=xiInitial,
-    each final pInitial=pInitial,
-    each final m_flowStart=m_flowStart,
-    redeclare each final model PressureDropModel = PressureDropModel,
-    final fixedInitialPressure=cat(1, {fixedInitialPressure_firstCell}, {fixedInitialPressure for i in 2:nCells}))
-    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
-
-  replaceable model PressureDropModel =
-      SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial.PartialPressureDrop
-    constrainedby
-    SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial.PartialPressureDrop
-    "Pressure drop model for gas cell" annotation (Dialog(group="Pressure drop model"),choices(choice(redeclare
-          model PressureDropModel =
-            SorpLib.Components.Cells.Gas.PressureDropCorrelations.ZeroPressureDrop),
-            choice(redeclare model PressureDropModel =
-            SorpLib.Components.Cells.Gas.PressureDropCorrelations.ConstantResistanceCoefficient),
-            choice(redeclare model PressureDropModel =
-            SorpLib.Components.OpenAdsorber.PressureDropCorrelations.PackedBed_Kast1988
-                                                                                        "Pressure drop in packed bed according to Kast (1988)")));
-
-  /************************** Adsorbent volume **********************************/
-
-  SorpLib.Components.Cells.Adsorbent.Adsorbent[nCells] adsorbent(
-    each final vleFluidType=vleFluidType,
-    each final massAdsorbent=adsorberGeometry.massAdsorbent/nCells,
-    each final generateEventsAtFlowReversal=generateEventsAtFlowReversal,
-    each final TInitial=TInitialAdsorbent,
-    each final xInitial=xInitial,
-    each final initial_x=true,
-    redeclare each final model AdsorbentAdsorbateModel=AdsorbentAdsorbate)
-    annotation (Placement(transformation(extent={{-10,-120},{10,-100}})));
-
-  replaceable model AdsorbentAdsorbate =
-      SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater
-      constrainedby
-    SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater
-    "Adsorbent adsorbate model" annotation (Dialog(group="Adsorbent model"),choicesAllMatching=true);
-
-  /************************** Wall volume **********************************/
-
-  Cells.Wall.Wall[nCells] wall(
-    each final volume=adsorberGeometry.wallVolume/nCells,
-    each final TInitial=TInitialWall,
-    redeclare each final model WallMaterial=WallMaterial)
-    annotation (Placement(transformation(extent={{-8,76},{8,84}})));
-
-  replaceable model WallMaterial = TILMedia.SolidTypes.BaseSolid  constrainedby
-    TILMedia.SolidTypes.BaseSolid "Wall material model"
-                      annotation (Dialog(group="Wall material"),choicesAllMatching=true);
-
-  /*********************** Heat and mass transfer models ****************************/
-
-  HeatAndMassTransfer.HeatTransfer[             nCells] heatTransfer_gasWall(
-    each final n=1,
-    each final useAlphaAInput=false,
-    redeclare each final model HeatTransfer = HeatTransfer_gasWall,
-    final properties_gas=gas.properties,
-    final mdotHydraulic_gas=gas.mdotHydraulic) annotation (
-     Placement(transformation(
-        extent={{-8,-4},{8,4}},
-        rotation=90,
-        origin={0,44})));
-
-  replaceable model HeatTransfer_gasWall =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "Heat Transfer Model between gas and wall" annotation(Dialog(group="Heat transfer"), choices(choice(redeclare
-          model HeatTransfer_gasWall =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha),
-            choice(redeclare model HeatTransfer_gasWall =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA),
-            choice(redeclare model HeatTransfer_gasWall =
-            SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedWall_Kast1988
-                                                                                                                       "Heat transfer between packed bed and wall according to Kast (1988)")));
-
-  HeatAndMassTransfer.HeatTransfer[nCells] heatTransfer_gasAdsorbent(
-    each final n=1,
-    each final useAlphaAInput=false,
-    redeclare each final model HeatTransfer = HeatTransfer_gasAdsorbent,
-    final properties_gas=gas.properties,
-    final mdotHydraulic_gas=gas.mdotHydraulic) annotation (
-     Placement(transformation(
-        extent={{8,-4},{-8,4}},
-        rotation=90,
-        origin={40,-56})));
-
-  replaceable model HeatTransfer_gasAdsorbent =
-      SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    constrainedby
-    SorpLib.Components.HeatTransfer.HeatTransferPhenomena.Partial.PartialHeatTransfer
-    "Heat Transfer Model between gas and adsorbent"
-    annotation(Dialog(group="Heat transfer"), choices(choice(redeclare model
-          HeatTransfer_gasAdsorbent =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlpha),
-            choice(redeclare model HeatTransfer_gasAdsorbent =
-            SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA),
-            choice(redeclare model HeatTransfer_gasAdsorbent =
-            SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedGas_Kast1988
-                                                                                                                      "Heat transfer between packed bed and gas according to Kast (1988)"),
-            choice(redeclare model HeatTransfer_gasAdsorbent =
-            SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedGas_HougenMarshall1947
-                                                                                                                                "Heat transfer between packed bed and gas according to Hougen and Marshall (1947)")));
-
-  HeatAndMassTransfer.MassTransferDiffusion[             nCells] massTransferDiffusion(
-    each final vleFluidType=vleFluidType,
-    each final isClosable=false,
-    each final isFlap=false,
-    each final inputChoice=inputChoice,
-    redeclare each final model AdsorbentAdsorbate = AdsorbentAdsorbate,
-    redeclare each final model MassTransfer_diffusion_dp =
-        MassTransfer_diffusion_dp,
-    redeclare each final model MassTransfer_diffusion_dx =
-        MassTransfer_diffusion_dx,
-    final properties_gas=gas.properties,
-    final mdotHydraulic_gas=gas.mdotHydraulic) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=-90,
-        origin={-40,-56})));
-
-  replaceable model MassTransfer_diffusion_dp =
-      SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dp
-    constrainedby
-    SorpLib.Components.MassTransfer.MassTransferPhenomena.Partial.PartialMassTransfer_dp
-    "Mass Transfer Model" annotation (Placement(transformation(extent={{-32,-70},
-            {-12,-50}})), Dialog(enable=inputChoice == "dp", group="Diffusion"),
-            choices(choice(redeclare model MassTransfer_diffusion_dp =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dp),
-            choice(redeclare model MassTransfer_diffusion_dp =
-            SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantSpecificCoefficient_dp),
-            choice(redeclare model MassTransfer_diffusion_dp =
-            SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.MassTransfer.PackedBedGas_Kast1988
-                                                                                                                      "Mass transfer between packed bed and gas according to Kast (1988)"),
-            choice(redeclare model MassTransfer_diffusion_dp =
-            SorpLib.Components.OpenAdsorber.HeatAndMassTransfer.TransportPhenomena.MassTransfer.PackedBedGas_HougenMarshall1947
-                                                                                                                                "Mass transfer between packed bed and gas according to Hougen and Marshall (1947)")));
-
-  final model MassTransfer_diffusion_dx =
-      SorpLib.Components.MassTransfer.MassTransferPhenomena.ConstantCoefficient_dx
-    "Mass Transfer Model" annotation (Placement(transformation(extent={{-32,-70},
-            {-12,-50}})), choicesAllMatching=true,
-    Dialog(enable=inputChoice == "dx", group="Diffusion"));
-
-  /********************* General Parameters ************************************/
-
-  final parameter Boolean computeTransportProperties=heatTransfer_gasWall[1].computeTransportProperties or heatTransfer_gasAdsorbent[1].computeTransportProperties or massTransferDiffusion[1].computeTransportProperties;
-
-  parameter Boolean generateEventsAtFlowReversal=false "If true, events are generated at flow reversal" annotation(Evaluate=true, Dialog(tab="Advanced", group="Event-Handling"));
-
-  parameter String HydraulicMassFlowPosition="gas port B" "Position of hydraulic mass flow of gas cell" annotation(Evaluate=true, Dialog(tab="Advanced", group="Hydraulic mass flow position"),
-    choices(
-    choice="gas port A" "hydraulic mass flow at gas port A",
-    choice="gas port B" "hydraulic mass flow at gas port B"));
-
-  final parameter String inputChoice="dp" "Driving force of diffusion";
-
-  final inner parameter Modelica.SIunits.MolarMass M_adsorbent=TILMedia.GasFunctions.molarMass_n(gasType,0) "Molar mass of adsorbate";
-
-  final inner parameter Modelica.SIunits.MolarMass M_carrier=TILMedia.GasFunctions.molarMass_n(gasType,1) "Molar mass of carrier gas";
-
-  /******************** Initialization ********************/
-
-   parameter Modelica.SIunits.Temperature TInitialGas
-    "Initial temperature of gas" annotation (Dialog(group="Gas volume", tab="Initialization"));
-   parameter Modelica.SIunits.MassFraction[gasType.nc - 1] xiInitial=gasType.defaultMixingRatio[1:end - 1]/sum(gasType.defaultMixingRatio)
-    "Initial composition of gas" annotation (Dialog(group="Gas volume", tab="Initialization"));
-   parameter Modelica.SIunits.Pressure pInitial
-    "Initial pressure in gas cell" annotation (Dialog(group="Gas volume", tab="Initialization"));
-   parameter Boolean fixedInitialPressure=true
-    "If true, initial pressure is fixed" annotation (Dialog(group="Gas volume", tab="Initialization"));
-   parameter Boolean fixedInitialPressure_firstCell=true
-    "Use false, if two pressure boundaries are connected" annotation (Dialog(group="Gas volume", tab="Initialization"));
-   parameter Modelica.SIunits.MassFlowRate m_flowStart=0.2
-    "Start mass flow rate for iteration" annotation (Dialog(group="Gas volume", tab="Initialization"));
-   parameter Modelica.SIunits.Temperature TInitialAdsorbent
-     "Initial temperature of adsorbent" annotation (Dialog(group="Adsorbent volume", tab="Initialization"));
-   parameter Real xInitial(unit="kg/kg",start=0.2) "Initial loading of adsorbent" annotation (Dialog(group="Adsorbent volume", tab="Initialization"));
-
-   parameter Modelica.SIunits.Temperature TInitialWall "Initial Temperature of wall" annotation (Dialog(group="Wall volume", tab="Initialization"));
-
-    /************************** Summary ************************************/
-
-  inner parameter Boolean includeSummaryArrays=true
-    "include array entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-  inner parameter Boolean includeDefaultSummary=true
-    "include default entries in summary"
-    annotation (Dialog(tab="Advanced", group="Summary"));
-
-protected
-   record Summary
-    extends TIL.Internals.ClassTypes.Record;
-
-    Modelica.SIunits.MassFlowRate m_flow_A if include;
-    Modelica.SIunits.MassFlowRate m_flow_B if include;
-
-    Modelica.SIunits.HeatFlowRate Q_flow_gasWall if include;
-    Modelica.SIunits.HeatFlowRate Q_flow_gasSorbent if include;
-    Modelica.SIunits.HeatFlowRate Q_flow_wallAmbient if include;
-
-    Modelica.SIunits.Temperature T_A if include;
-    Modelica.SIunits.Temperature T_B if include;
-    Modelica.SIunits.Pressure p_A if include;
-    Modelica.SIunits.Pressure p_B if include;
-    Modelica.SIunits.Pressure delta_p if include;
-    Modelica.SIunits.MassFraction xi_A[gasType.nc-1] if include;
-    Modelica.SIunits.MassFraction xi_B[gasType.nc-1] if include;
-    TILMedia.Internals.Units.RelativeHumidity phi_A if include;
-    TILMedia.Internals.Units.RelativeHumidity phi_B if include;
-    Modelica.SIunits.MassFlowRate m_flow_ads if include;
-    Modelica.SIunits.Mass m_adsorbent if include;
-    Modelica.SIunits.Mass m_adsorbate if include;
-    Real x_avg if include;
-
-  protected
-    outer parameter Boolean includeDefaultSummary;
-    parameter Boolean include=includeDefaultSummary;
-    outer parameter TILMedia.GasTypes.BaseGas gasType;
-
-  public
-    replaceable Arrays arrays;
-
-  protected
-    record Arrays
-      parameter Integer n if includeCross;
-
-      Modelica.SIunits.Temperature[n] T_gas if includeCross;
-      Modelica.SIunits.Temperature[n] T_sorbent if includeCross;
-      Modelica.SIunits.Temperature[n] T_wall if includeCross;
-      Modelica.SIunits.Pressure[n] p_gas if includeCross;
-      Modelica.SIunits.Pressure[n] delta_p if includeCross;
-      Modelica.SIunits.Pressure[n] p_sorbent if includeCross;
-      Modelica.SIunits.MassFraction[n,gasType.nc-1] xi if includeCross;
-      TILMedia.Internals.Units.RelativeHumidity[n] phi if includeCross;
-      Modelica.SIunits.Mass[n] m_adsorbent if includeCross;
-      Modelica.SIunits.Mass[n] m_adsorbate if includeCross;
-      Real[n] x if includeCross;
-
-    protected
-      outer parameter Boolean includeSummaryArrays;
-      parameter Boolean includeCross = includeSummaryArrays;
-      outer parameter TILMedia.GasTypes.BaseGas gasType;
-    end Arrays;
-
-   end Summary;
-
-   replaceable record SummaryClass = Summary;
-
-public
-  SummaryClass summary(
-    m_flow_A=gasPortA.m_flow,
-    m_flow_B=gasPortB.m_flow,
-    Q_flow_gasWall=-sum(gas.heatPortB.Q_flow),
-    Q_flow_gasSorbent=-sum(gas.heatPortA.Q_flow),
-    Q_flow_wallAmbient=-sum(wall.heatPortB.Q_flow),
-    T_A=gasA.T,
-    T_B=gasB.T,
-    p_A=gasPortA.p,
-    p_B=gasPortB.p,
-    delta_p=gasPortA.p-gasPortB.p,
-    xi_A=gasA.xi,
-    xi_B=gasB.xi,
-    phi_A=gasA.phi,
-    phi_B=gasB.phi,
-    m_flow_ads=-sum(gas.vlePort.m_flow),
-    m_adsorbent=adsorberGeometry.massAdsorbent,
-    m_adsorbate=sum(adsorbent.massVLEFluid),
-    x_avg=sum(adsorbent.x)/nCells,
-    arrays(n=nCells,
-      T_gas=gas.properties.T,
-      T_sorbent=adsorbent.T,
-      T_wall=wall.T,
-      p_gas=gas.properties.p,
-      delta_p=gas.gasPortA.p-gas.gasPortB.p,
-      p_sorbent=adsorbent.p,
-      xi=gas.gas.xi,
-      phi=gas.gas.phi,
-      m_adsorbent=adsorbent.massAdsorbent,
-      m_adsorbate=adsorbent.massVLEFluid,
-      x=adsorbent.x));
-equation
-
-  connect(wall.heatPortB, heatPort) annotation (Line(
-      points={{0,83.8},{0,140}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(wall.heatPortA, heatTransfer_gasWall.heatPortB[1]) annotation (Line(
-      points={{0,76},{0,52}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer_gasWall.heatPortA, gas.heatPortB) annotation (Line(
-      points={{0,36},{0,10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer_gasAdsorbent.heatPortA, gas.heatPortA) annotation (Line(
-      points={{40,-48},{40,-20},{0,-20},{0,-10}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer_gasAdsorbent.heatPortB[1], adsorbent.heatPortB)
-    annotation (Line(
-      points={{40,-64},{40,-90},{0,-90},{0,-104}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(gas.vlePort, massTransferDiffusion.vlePortA) annotation (Line(
-      points={{-6,-10},{-6,-20},{-40,-20},{-40,-46.9}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(massTransferDiffusion.vlePortB, adsorbent.vlePortA) annotation (Line(
-      points={{-40,-65.2},{-40,-90},{-7.2,-90},{-7.2,-110}},
-      color={153,204,0},
-      thickness=0.5));
-
-  connect(gasPortA, gas[1].gasPortA) annotation (Line(
-      points={{-118,0},{-10,0}},
-      color={255,153,0},
-      thickness=0.5));
-
-  for i in 1:(nCells-1) loop
-    connect(gas[i].gasPortB, gas[i+1].gasPortA);
-  end for;
-
-  connect(gas[nCells].gasPortB, gasPortB) annotation (Line(
-      points={{9.8,0},{122,0}},
-      color={255,153,0},
-      thickness=0.5));
-   annotation (
-    Icon(coordinateSystem(preserveAspectRatio=false,extent={{-120,-140},{120,
-            140}}),
-        graphics={Bitmap(extent={{-246,-140},{232,142}}, fileName=
-              "modelica://SorpLib/Resources/Images/OpenAdsorber.png")}),
-    Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-120,-140},{
-            120,140}})),
-    Dialog(tab="SIM", group="SIM"),
-    Line(
-      points={{-40,0},{-4,0}},
-      color={255,153,0},
-      pattern=LinePattern.None,
-      thickness=0.5,
-      smooth=Smooth.None),
-    Line(
-      points={{4,0},{40,0}},
-      color={255,153,0},
-      pattern=LinePattern.None,
-      thickness=0.5,
-      smooth=Smooth.None),
-    Documentation(info="<html>
-  <p>
-    This model represents an packed bed open adsorption system, which can be used for desiccant applications. The model consists of a gas cell, an adsorbent cell and a wall cell connected by heat and mass transfer resistances. Some transfer correlation are implemented from literature. The model can be descretized in flow direction to build up a finite volume model.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 11, 2017, by Andrej Gibelhaus:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end OpenAdsorber;
diff --git a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/PackedBed_Kast1988.mo b/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/PackedBed_Kast1988.mo
deleted file mode 100644
index 13c4b5d..0000000
--- a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/PackedBed_Kast1988.mo
+++ /dev/null
@@ -1,52 +0,0 @@
-within SorpLib.Components.OpenAdsorber.PressureDropCorrelations;
-model PackedBed_Kast1988
-  "Pressure drop correlation for packed beds according to Kast (1988)"
-  extends
-    SorpLib.Components.Cells.Gas.PressureDropCorrelations.Partial.PartialPressureDrop(
-     final computeTransportProperties=true);
-
-  outer parameter Cells.Gas.Geometry.CellGeometry cellGeometry "cell geometry";
-
-  outer TILMedia.Internals.PropertyRecord properties;
-  outer Modelica.SIunits.MassFlowRate mdotHydraulic
-    "Hydraulic mass flow rate";
-
-  Real zeta(final unit="1") "Pressure drop coefficient";
-  Modelica.SIunits.ReynoldsNumber Re "Reynolds number";
-
-equation
-  Re=noEvent(abs(mdotHydraulic))*cellGeometry.hydraulicDiameter/(cellGeometry.flowCrossSection*properties.transp.eta*cellGeometry.psi);
-
-  zeta=2.2*(64/(Re+1)+1.8/(Re+1)^0.1);
-
-  pressureDrop=(cellGeometry.length/cellGeometry.hydraulicDiameter)/(2*properties.d*cellGeometry.flowCrossSection^2*cellGeometry.psi^2)*zeta*TIL.Utilities.Numerics.squareFunction(mdotHydraulic);
-
-  annotation (Documentation(info="<html>
-<p>
-  This model calculates the pressure drop for packed beds according to Kast (1988). The sign of the pressure drop is automatically determined by the sign of the hydraulic mass flow rate. The hydraulic mass flow rate, the fluid properties record, the adsorber geometry and discretization number are defined as outer objects and thus taken from the overlying model level. 
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i><code>&Delta;</code>p</i> = sgn(<i><code>&#7745;</code></i><sub>hydraulic</sub>) <i>L</i> / <i>D</i> <i>f</i> / (2 <i><code>&rho;</code></i> <i>A</i><sup>2</sup> <i><code>&psi;</code></i><sup>2</sup>) <i><code>&#7745;</code></i><sub>hydraulic</sub><sup>2</sup> </p>
-<p>where <i><code>&Delta;</code>p</i> is the pressure drop, <i><code>&#7745;</code></i><sub>hydraulic</sub> is the hydraulic mass flow rate, <i>L</i> is the hydraulic length, <i>D</i> is the hydraulic diameter, <i>f</i> is the resistance coefficient, <i><code>&rho;</code></i> is the fluid density, <i>A</i> is the cross sectional area and <i><code>&psi;</code></i> is the void percentage of packed bed. </p>
-The resistance coefficient <i>f</i> is calculated by
-<p align=\"center\"> <i>f</i> = 2.2 (64/Re + 1.8/Re<sup>0.1</sup>)</p>
-where Re is the Reynolds number.
-</p>
-
-<h4>References</h4>
-<ul>
-<li>Adsorption aus der Gasphase, Werner Kast, Darmstadt, 1988. </li>
-</ul>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 11, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end PackedBed_Kast1988;
diff --git a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/Partial/PartialPressureDrop.mo b/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/Partial/PartialPressureDrop.mo
deleted file mode 100644
index 0bd4baf..0000000
--- a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/Partial/PartialPressureDrop.mo
+++ /dev/null
@@ -1,29 +0,0 @@
-within SorpLib.Components.OpenAdsorber.PressureDropCorrelations.Partial;
-partial model PartialPressureDrop
-
-  Modelica.SIunits.Pressure pressureDrop;
-
-  parameter Boolean computeTransportProperties;
-
-  annotation (Icon(graphics={Bitmap(extent={{-100,-100},{100,100}},
-          imageSource=
-              "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",
-          fileName=
-              "modelica://SorpLib/Resources/Images/DeltaP.png")}),
-      Documentation(info="<html>
-<p>
-  This partial model is the basis for the pressure drop correlation models. <br>
-</p>
-
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 28, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-
-end PartialPressureDrop;
diff --git a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/Partial/package.order b/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/Partial/package.order
deleted file mode 100644
index 1b8a13e..0000000
--- a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/Partial/package.order
+++ /dev/null
@@ -1 +0,0 @@
-PartialPressureDrop
diff --git a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/package.mo b/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/package.mo
deleted file mode 100644
index 72c1b92..0000000
--- a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/package.mo
+++ /dev/null
@@ -1,8 +0,0 @@
-within SorpLib.Components.OpenAdsorber;
-package PressureDropCorrelations
-  extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-
-end PressureDropCorrelations;
diff --git a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/package.order b/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/package.order
deleted file mode 100644
index 5d63ff1..0000000
--- a/SorpLib/Components/OpenAdsorber/PressureDropCorrelations/package.order
+++ /dev/null
@@ -1 +0,0 @@
-PackedBed_Kast1988
diff --git a/SorpLib/Components/OpenAdsorber/Testers/TestOpenAdsorber.mo b/SorpLib/Components/OpenAdsorber/Testers/TestOpenAdsorber.mo
deleted file mode 100644
index d6e3839..0000000
--- a/SorpLib/Components/OpenAdsorber/Testers/TestOpenAdsorber.mo
+++ /dev/null
@@ -1,62 +0,0 @@
-within SorpLib.Components.OpenAdsorber.Testers;
-model TestOpenAdsorber
-
-  inner TIL.SystemInformationManager sim(
-    redeclare TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1,
-    redeclare TILMedia.LiquidTypes.TILMedia_Water liquidType1,
-    redeclare TILMedia.GasTypes.TILMedia_MoistAir gasType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryA(
-    phiFixed=80,
-    boundaryType="m_flow",
-    gasType=sim.gasType1,
-    m_flowFixed=-2,
-    streamVariablesInputTypeConcentration="xi",
-    TFixed=353.15)
-    annotation (Placement(transformation(extent={{-44,-10},{-36,10}})));
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryB(
-    phiFixed=80,
-    boundaryType="p",
-    streamVariablesInputTypeConcentration="xi",
-    TFixed=373.15,
-    pFixed=100000)
-    annotation (Placement(transformation(extent={{36,-10},{44,10}})));
-
-  OpenAdsorber openAdsorber(
-    redeclare Geometry.CylindricAdsorber adsorberGeometry,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    nCells=5,
-    redeclare model HeatTransfer_gasAdsorbent =
-        HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedGas_Kast1988,
-    redeclare model MassTransfer_diffusion_dp =
-        HeatAndMassTransfer.TransportPhenomena.MassTransfer.PackedBedGas_Kast1988,
-    HydraulicMassFlowPosition="gas port B",
-    xInitial=0.3,
-    redeclare model WallMaterial = TILMedia.SolidTypes.TILMedia_St35_8,
-    redeclare model HeatTransfer_gasWall =
-        HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedWall_Kast1988,
-    fixedInitialPressure=true,
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.PackedBed_Kast1988,
-    TInitialGas=293.15,
-    pInitial=100000,
-    TInitialAdsorbent=293.15,
-    TInitialWall=293.15)
-    annotation (Placement(transformation(extent={{-8,-14},{16,14}})));
-
-equation
-  connect(openAdsorber.gasPortB, gasBoundaryB.port) annotation (Line(
-      points={{16.2,0},{24,0},{40,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(openAdsorber.gasPortA, gasBoundaryA.port) annotation (Line(
-      points={{-7.8,0},{-24,0},{-40,0}},
-      color={255,153,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-            -100},{100,100}})),
-    experiment(StopTime=200),
-    __Dymola_experimentSetupOutput);
-end TestOpenAdsorber;
diff --git a/SorpLib/Components/OpenAdsorber/Testers/TestOpenAdsorber2.mo b/SorpLib/Components/OpenAdsorber/Testers/TestOpenAdsorber2.mo
deleted file mode 100644
index 47952cc..0000000
--- a/SorpLib/Components/OpenAdsorber/Testers/TestOpenAdsorber2.mo
+++ /dev/null
@@ -1,83 +0,0 @@
-within SorpLib.Components.OpenAdsorber.Testers;
-model TestOpenAdsorber2
-
-  inner TIL.SystemInformationManager sim(
-    redeclare TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1,
-    redeclare TILMedia.LiquidTypes.TILMedia_Water liquidType1,
-    redeclare TILMedia.GasTypes.TILMedia_MoistAir gasType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryB(
-    phiFixed=80,
-    boundaryType="p",
-    streamVariablesInputTypeConcentration="xi",
-    TFixed=373.15,
-    pFixed=100000)
-    annotation (Placement(transformation(extent={{36,-10},{44,10}})));
-
-  OpenAdsorber openAdsorber(
-    redeclare Geometry.CylindricAdsorber adsorberGeometry,
-    redeclare model AdsorbentAdsorbate =
-        Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe,
-    redeclare model WallMaterial = TILMedia.SolidTypes.TILMedia_Steel,
-    nCells=5,
-    redeclare model HeatTransfer_gasAdsorbent =
-        HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedGas_Kast1988,
-    HydraulicMassFlowPosition="gas port B",
-    redeclare model HeatTransfer_gasWall =
-        HeatAndMassTransfer.TransportPhenomena.HeatTransfer.PackedBedWall_Kast1988,
-    xInitial=0.025,
-    generateEventsAtFlowReversal=false,
-    fixedInitialPressure=true,
-    fixedInitialPressure_firstCell=false,
-    redeclare model MassTransfer_diffusion_dp =
-        HeatAndMassTransfer.TransportPhenomena.MassTransfer.PackedBedGas_Kast1988,
-    redeclare model PressureDropModel =
-        PressureDropCorrelations.PackedBed_Kast1988,
-    TInitialGas=353.15,
-    pInitial=100000,
-    TInitialAdsorbent=353.15,
-    TInitialWall=353.15)
-    annotation (Placement(transformation(extent={{-13,-14},{13,14}})));
-
-  TIL.GasComponents.Boundaries.Boundary gasBoundaryA(
-    phiFixed=80,
-    boundaryType="p",
-    streamVariablesInputTypeConcentration="xi",
-    mixingRatioFixed={0.01,1},
-    TFixed=303.15,
-    pFixed=150000)
-    annotation (Placement(transformation(extent={{-44,-10},{-36,10}})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary(TFixed=303.15)
-    annotation (Placement(transformation(
-        extent={{-4,-6},{4,6}},
-        rotation=-90,
-        origin={0,44})));
-  HeatTransfer.HeatTransfer heatTransfer(n=openAdsorber.nCells, redeclare model
-      HeatTransfer = HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=100)) annotation (Placement(transformation(
-        extent={{-8,-4},{8,4}},
-        rotation=-90,
-        origin={0,28})));
-equation
-  connect(openAdsorber.gasPortB, gasBoundaryB.port) annotation (Line(
-      points={{13.2167,0},{13.2167,0},{40,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(gasBoundaryA.port, openAdsorber.gasPortA) annotation (Line(
-      points={{-40,0},{-12.7833,0}},
-      color={255,153,0},
-      thickness=0.5));
-  connect(openAdsorber.heatPort, heatTransfer.heatPortB) annotation (Line(
-      points={{0,14},{0,14},{0,20}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer.heatPortA, heatBoundary.heatPort) annotation (Line(
-      points={{0,36},{0,44}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (Diagram(coordinateSystem(preserveAspectRatio=false, extent={{-100,
-            -100},{100,100}})),
-    experiment(StopTime=200),
-    __Dymola_experimentSetupOutput);
-end TestOpenAdsorber2;
diff --git a/SorpLib/Components/OpenAdsorber/Testers/package.mo b/SorpLib/Components/OpenAdsorber/Testers/package.mo
deleted file mode 100644
index 4f9323e..0000000
--- a/SorpLib/Components/OpenAdsorber/Testers/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.OpenAdsorber;
-package Testers
-  extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-end Testers;
diff --git a/SorpLib/Components/OpenAdsorber/Testers/package.order b/SorpLib/Components/OpenAdsorber/Testers/package.order
deleted file mode 100644
index 3789a52..0000000
--- a/SorpLib/Components/OpenAdsorber/Testers/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-TestOpenAdsorber
-TestOpenAdsorber2
diff --git a/SorpLib/Components/OpenAdsorber/package.mo b/SorpLib/Components/OpenAdsorber/package.mo
deleted file mode 100644
index 255df93..0000000
--- a/SorpLib/Components/OpenAdsorber/package.mo
+++ /dev/null
@@ -1,13 +0,0 @@
-within SorpLib.Components;
-package OpenAdsorber
-
-
-   extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-
-
-
-
-  annotation (Icon(graphics));
-end OpenAdsorber;
diff --git a/SorpLib/Components/OpenAdsorber/package.order b/SorpLib/Components/OpenAdsorber/package.order
deleted file mode 100644
index b9483c6..0000000
--- a/SorpLib/Components/OpenAdsorber/package.order
+++ /dev/null
@@ -1,5 +0,0 @@
-OpenAdsorber
-Geometry
-HeatAndMassTransfer
-PressureDropCorrelations
-Testers
diff --git a/SorpLib/Components/Pumps/AffinityPump.mo b/SorpLib/Components/Pumps/AffinityPump.mo
new file mode 100644
index 0000000..b21eb51
--- /dev/null
+++ b/SorpLib/Components/Pumps/AffinityPump.mo
@@ -0,0 +1,132 @@
+within SorpLib.Components.Pumps;
+model AffinityPump "Model of a pump based on affinity laws"
+  extends BaseClasses.PartialAffinityPump(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculation of fluid properties
+  //
+  rho = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1, inStream(port_a.Xi_outflow), {1-sum(inStream(port_a.Xi_outflow))}))
+    "Instreaming density";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The affinity pump can be used to prescribe the mass or volume flow rate in hydraulic
+components, such as tubes or heat exchangers. The model assumes a non-constant pump
+efficiency that depends on the volume flow rate. Changes compared to a nominal operating
+point are considered by affinity laws.
+
+<h4>Main equations</h4>
+<p>
+The model calculates the hydraulic, shaft, and drive power transmitted to the fluid
+or required to drive the pump. The hydraulic power <i>P<sub>hydraulic</sub></i> 
+transmitted to the fluid is defined as:
+</p>
+<pre>
+    P<sub>hydraulic</sub> = m&#x307; / &rho;<sub>in</sub> * &Delta;p;
+</pre>
+<p>
+Herein, <i>m&#x307;</i> is the mass flow rate, <i>&rho;<sub>in</sub></i> describes the 
+fluid density at the inlet, and <i>&Delta;p = p<sub>b</sub> - p<sub>a</sub></i> is the 
+pressure difference between port b and a. The mass flow rate <i>m&#x307;</i> follows
+from the volume flow rate <i>V<sub>flow</sub></i> that depends on the rotational speed
+<i>n</i>, the nominal volume flow rate <i>V<sub>flow,ref</sub></i>, and the nominal
+rotational speed <i>n<sub>ref</sub></i>:
+</p>
+<pre>
+    V<sub>flow</sub> = m&#x307; / &rho;<sub>in</sub> = V<sub>flow,ref</sub> * n / n<sub>ref</sub>;
+</pre>
+<p>
+The shaft power <i>P<sub>shaft</sub></i> depends on the pump efficiency 
+<i>&eta;<sub>pump</sub></i> and is defined as:
+</p>
+<pre>
+    P<sub>shaft</sub> = P<sub>hydraulic</sub> / &eta;<sub>pump</sub>;
+</pre>
+<p>
+with
+</p>
+<pre>
+    &eta;<sub>pump</sub> = &eta;<sub>pump,ref</sub> * (1 - f<sub>loss</sub> * ((m&#x307; / &rho;<sub>in</sub>) / V<sub>flow,ref</sub> - 1) ^ 2);
+</pre>
+<p>
+Herein, <i>f<sub>loss</sub></i> is a loss factor describing the dependency on the volume 
+flow rate, <i>&eta;<sub>pump,ref</sub></i> is the efficiency at the nominal operating point, 
+and <i>V<sub>flow,ref</sub></i> is the nominal volume flow rate. The shaft power is completly 
+transmitted to the fluid, thus increasing the outflowing specific enthalpy of the fluid.
+<br/><br/>
+The drive power <i>P<sub>drive</sub></i> is required to drive the pump, depends on the
+drive efficienciy <i>&eta;<sub>drive</sub></i>, and is defined as:
+</p>
+<pre>
+    P<sub>drive</sub> = P<sub>shaft</sub> / &eta;<sub>drive</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No flow reversal
+  </li>
+  <li>
+  Affinity laws apply to describe changes in operating conditions
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The affinity pump is typically used to prescripe the mass or volume flow rate
+in hydraulic components, such as tubes or heat exchangers, if process controlelrs
+are investigated and the flow rate changes.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>assumeIsenthalpicPump</i>:
+  Defines if the hydraulic losses are considered in the energy balance.
+  </li>
+  <li>
+  <i>calculateDrivePower</i>:
+  Defines if the driving power is calculates within the model.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 9, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AffinityPump;
diff --git a/SorpLib/Components/Pumps/BaseClasses/PartialAffinityPump.mo b/SorpLib/Components/Pumps/BaseClasses/PartialAffinityPump.mo
new file mode 100644
index 0000000..3388bae
--- /dev/null
+++ b/SorpLib/Components/Pumps/BaseClasses/PartialAffinityPump.mo
@@ -0,0 +1,142 @@
+within SorpLib.Components.Pumps.BaseClasses;
+partial model PartialAffinityPump
+  "Base model for all pumps using affinity laws"
+  extends SorpLib.Components.Pumps.BaseClasses.PartialPump;
+
+  //
+  // Definition of paramteres describring the pump's characteristics
+  //
+  parameter Modelica.Units.SI.Frequency n_ref = 50
+    "Nominal rotational speed"
+    annotation (Dialog(tab="General", group="Pump Characteristics - Nominal point"));
+  parameter Modelica.Units.SI.VolumeFlowRate V_flow_ref = 10/1000/60
+    "Nominal volume flow rate"
+    annotation (Dialog(tab="General", group="Pump Characteristics - Nominal point"));
+  parameter Modelica.Units.SI.Efficiency eta_pump_ref = 0.4
+    "Nominal pump efficiency"
+    annotation (Dialog(tab="General", group="Pump Characteristics - Nominal point"));
+  parameter Real f_loss = 0.3
+    "Loss factor describing the pump efficiency"
+    annotation (Dialog(tab="General", group="Pump Characteristics - Nominal point"));
+
+  //
+  // Definition of parameters describing the inputs
+  //
+  parameter Boolean use_nInput = false
+    "=true, if n is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Inputs"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Frequency n_fixed = 50
+    "Fixed rotational speed"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=not use_nInput));
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput n_input(final unit="1/s") if
+    use_nInput
+    "Input for rotational speed"
+    annotation (Placement(transformation(extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={0,-90}),
+      iconTransformation(extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,-80})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput n_internal(final unit="1/s")
+    "Needed for connecting to conditional connector";
+
+  //
+  // Definition of variables
+  //
+public
+  Modelica.Units.SI.Efficiency eta_pump
+    "Pump efficiency";
+
+equation
+  //
+  // Assertions
+  //
+  assert(n_internal >= 0,
+         "Rotational speed cannot be negative!",
+         level=AssertionLevel.error);
+
+  //
+  // Connectors
+  //
+  connect(n_internal, n_input);
+
+  if not use_nInput then
+    n_internal = n_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Mass balance
+  //
+  m_flow = V_flow * rho
+    "Mass flow rate at port a";
+  V_flow = V_flow_ref * (n_internal / n_ref)
+    "Volume flow rate at port a (affinity law)";
+
+  //
+  // Energy balance
+  //
+  if assumeIsenthalpicPump then
+    port_a.h_outflow = inStream(port_b.h_outflow)
+      "Stream variable: Trivial equation since no change of energy due to
+      forbidden flow revesal";
+    port_b.h_outflow = inStream(port_a.h_outflow) + (1/eta_pump - 1) * dp / rho
+      "Increase of specific enthalpy due to internal losses of the pump";
+
+  else
+    port_a.h_outflow = inStream(port_b.h_outflow)
+      "Stream variable: Trivial equation since no change of energy";
+    port_b.h_outflow = inStream(port_a.h_outflow)
+      "Stream variable: Trivial equation since no change of energy";
+
+  end if;
+
+  //
+  // Power calculations
+  //
+  eta_pump = eta_pump_ref * (1 - f_loss * (V_flow / V_flow_ref - 1) ^ 2)
+    "Efficiency ot the pump dependent on the volume flow rate";
+
+  P_shaft = P_hydraulic / eta_pump
+    "Shaft power consumption of pump";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all pumps using affinity laws and volume-
+flow-dependent efficiencies. It defines fundamental parameters and variables required 
+by all affinity pumps. Models that inherit properties from this partial model have 
+to redeclare the fluid ports. Moreover, the instreaming density must be calculated. 
+In this context, appropriate fluid property models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Instreaming density <i>rho</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 9, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialAffinityPump;
diff --git a/SorpLib/Components/Pumps/BaseClasses/PartialPump.mo b/SorpLib/Components/Pumps/BaseClasses/PartialPump.mo
new file mode 100644
index 0000000..bfbe364
--- /dev/null
+++ b/SorpLib/Components/Pumps/BaseClasses/PartialPump.mo
@@ -0,0 +1,185 @@
+within SorpLib.Components.Pumps.BaseClasses;
+partial model PartialPump "Base model for all pumps"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of paramteres describring the pump's characteristics
+  //
+  parameter Boolean assumeIsenthalpicPump = false
+    " = true, if internal losses do not influence the energy balance"
+    annotation (Dialog(tab="General", group="Pump Characteristics"));
+  parameter Boolean calculateDrivePower = true
+    " = true, if drive power is calcualted"
+    annotation (Dialog(tab="General", group="Pump Characteristics"));
+
+  parameter Modelica.Units.SI.Efficiency eta_drive = 0.9
+    "Efficiency of drive that is used to calculate drive power"
+    annotation (Dialog(tab="General", group="Pump Characteristics",
+                enable=calculateDrivePower));
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-90,-10},{-70,10}}),
+                iconTransformation(extent={{-90,-10},{-70,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{70,-10},{90,10}}),
+                iconTransformation(extent={{70,-10},{90,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Density rho
+    "Instreaming density";
+
+  Modelica.Units.SI.PressureDifference dp
+    "Pressure difference between port a and b";
+  Modelica.Units.SI.MassFlowRate m_flow
+    "Mass flow rate";
+  Modelica.Units.SI.VolumeFlowRate V_flow
+    "Volume flow rate";
+
+  Modelica.Units.SI.Power P_hydraulic
+    "Hydraulic power consumption of the pump";
+  Modelica.Units.SI.Power P_shaft
+    "Shaft power consumption of the pump";
+  Modelica.Units.SI.Power P_drive
+    "Drive power consumption of the pump";
+  Modelica.Units.SI.Power P_loss_internal
+    "Internal power losses of the pump (i.e., increase of outflowing specific 
+    enthalpy)";
+
+equation
+  //
+  // Assertions
+  //
+  assert(m_flow >= 0,
+         "Pump model cannot handle flow reversal!",
+         level=AssertionLevel.error);
+
+  //
+  // Momentum balance
+  //
+  dp = port_b.p - port_a.p
+    "Pressure difference between port b and a";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + port_b.m_flow
+    "Steady-state mass balance";
+
+  port_a.Xi_outflow = inStream(port_b.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+  port_b.Xi_outflow = inStream(port_a.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+
+  port_a.m_flow = m_flow
+    "Mass flow rate at port a";
+
+  //
+  // Power calculations
+  //
+  P_hydraulic = V_flow * dp
+    "Hydraulic power consumption of the pump";
+  P_drive = if calculateDrivePower then P_shaft / eta_drive else 0
+    "Drive power consumption of pump";
+  P_loss_internal = P_shaft - P_hydraulic
+    "Internal power losses of pump (i.e., increase outflowing specific enthalpy)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all pumps. It defines fundamental 
+parameters and variables required by all pumps. Models that inherit properties 
+from this partial model have to redeclare the fluid ports. Moreover, the mass
+and energy balances must be completed, and the power calculations must be added.
+In this context, appropriate fluid property models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Instreaming density <i>rho</i>.
+  </li>
+  <br/>
+  <li>
+  Mass flow rate <i>m_flow</i> at port a.
+  </li>
+  <li>
+  Volume flow rate <i>V_flow</i> at port a.
+  </li>
+  <br/>
+  <li>
+  Outflowing specific enthalpy <i>port_a.h_outflow</i> at port a.
+  </li>
+  <li>
+  Outflowing specific enthalpy <i>port_b.h_outflow</i> at port b.
+  </li>
+  <br/>
+  <li>
+  Shaft power <i>P_shaft</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 8, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Ellipse(
+          extent={{-80,-80},{80,80}},
+          lineColor={28,108,200},
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Sphere),
+        Polygon(
+          points={{-68,42},{-68,-42},{80,0},{-68,42}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Line(
+          points={{40,0},{-50,0}},
+          color={0,0,0},
+          arrow={Arrow.Filled,Arrow.None})}));
+end PartialPump;
diff --git a/SorpLib/Components/Pumps/BaseClasses/PartialSimplePump.mo b/SorpLib/Components/Pumps/BaseClasses/PartialSimplePump.mo
new file mode 100644
index 0000000..09f91dc
--- /dev/null
+++ b/SorpLib/Components/Pumps/BaseClasses/PartialSimplePump.mo
@@ -0,0 +1,173 @@
+within SorpLib.Components.Pumps.BaseClasses;
+partial model PartialSimplePump
+  "Base model for all simple pumps with constant efficiencies"
+  extends SorpLib.Components.Pumps.BaseClasses.PartialPump(
+    final calculateDrivePower=true);
+
+  //
+  // Definition of paramteres describring the pump's characteristics
+  //
+  parameter Modelica.Units.SI.Efficiency eta_pump = 0.4
+    "Efficiency of pump that is used to calculate shaft power"
+    annotation (Dialog(tab="General", group="Pump Characteristics"));
+
+  //
+  // Definition of parameters describing the inputs
+  //
+  parameter SorpLib.Choices.PrescripedPumpVariable prescribedInput=
+    SorpLib.Choices.PrescripedPumpVariable.V_flow
+    "Prescribed input variable"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  parameter Boolean use_mFlowInput = false
+    "=true, if m_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=(prescribedInput ==
+                SorpLib.Choices.PrescripedPumpVariable.m_flow)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_fixed = 0.1
+    "Fixed mass flow rate"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=(prescribedInput ==
+                SorpLib.Choices.PrescripedPumpVariable.m_flow)
+                and not use_mFlowInput));
+
+  parameter Boolean use_VFlowInput = false
+    "=true, if V_flow is defined by input; otherwise, fixed value is used"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=(prescribedInput ==
+                SorpLib.Choices.PrescripedPumpVariable.V_flow)),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.VolumeFlowRate V_flow_fixed = 10/1000/60
+    "Fixed volume flow rate"
+    annotation (Dialog(tab="General",group="Inputs",
+                enable=(prescribedInput ==
+                SorpLib.Choices.PrescripedPumpVariable.V_flow)
+                and not use_VFlowInput));
+
+  //
+  // Definition of connectors
+  //
+  Modelica.Blocks.Interfaces.RealInput m_flow_input(final unit="kg/s") if
+    (prescribedInput == SorpLib.Choices.PrescripedPumpVariable.m_flow and
+    use_mFlowInput)
+    "Input for mass flow rate"
+    annotation (Placement(transformation(extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={0,-90}),
+      iconTransformation(extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,-80})));
+
+  Modelica.Blocks.Interfaces.RealInput V_flow_input(final unit="m3/s") if
+    (prescribedInput == SorpLib.Choices.PrescripedPumpVariable.V_flow and
+    use_VFlowInput)
+    "Input for volume flow rate"
+    annotation (Placement(transformation(extent={{-20,-20},{20,20}},
+        rotation=90,
+        origin={30,-90}),
+      iconTransformation(extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={30,-80})));
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput m_flow_internal(final unit="kg/s")
+    "Needed for connecting to conditional connector";
+  Modelica.Blocks.Interfaces.RealInput V_flow_internal(final unit="m3/s")
+    "Needed for connecting to conditional connector";
+
+equation
+  //
+  // Connectors
+  //
+  connect(m_flow_internal, m_flow_input);
+  connect(V_flow_internal, V_flow_input);
+
+  if not use_mFlowInput then
+    m_flow_internal = m_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+  if not use_VFlowInput then
+    V_flow_internal = V_flow_fixed
+      "Needed for connecting to conditional connector";
+  end if;
+
+  //
+  // Mass balance
+  //
+  if prescribedInput == SorpLib.Choices.PrescripedPumpVariable.m_flow then
+    m_flow = m_flow_internal
+      "Mass flow rate at port a";
+    V_flow = m_flow_internal / rho
+      "Volume flow rate at port a";
+
+  elseif prescribedInput == SorpLib.Choices.PrescripedPumpVariable.V_flow then
+    m_flow = V_flow_internal * rho
+      "Mass flow rate at port a";
+    V_flow = V_flow_internal
+      "Volume flow rate at port a";
+
+  end if;
+
+  //
+  // Energy balance
+  //
+  if assumeIsenthalpicPump then
+    port_a.h_outflow = inStream(port_b.h_outflow)
+      "Stream variable: Trivial equation since no change of energy due to
+      forbidden flow revesal";
+    port_b.h_outflow = inStream(port_a.h_outflow) + (1/eta_pump - 1) * dp / rho
+      "Increase of specific enthalpy due to internal losses of the pump";
+
+  else
+    port_a.h_outflow = inStream(port_b.h_outflow)
+      "Stream variable: Trivial equation since no change of energy";
+    port_b.h_outflow = inStream(port_a.h_outflow)
+      "Stream variable: Trivial equation since no change of energy";
+
+  end if;
+
+  //
+  // Power calculations
+  //
+  P_shaft = P_hydraulic / eta_pump
+    "Shaft power consumption of pump";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all simple pumps with constant efficiencies.
+It defines fundamental parameters and variables required by all simple pumps. Models 
+that inherit properties from this partial model have to redeclare the fluid ports. 
+Moreover, the instreaming density must be calculated. In this context, appropriate 
+fluid property models are required.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Instreaming density <i>rho</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 8, 2024, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialSimplePump;
diff --git a/SorpLib/Components/Pumps/BaseClasses/package.mo b/SorpLib/Components/Pumps/BaseClasses/package.mo
new file mode 100644
index 0000000..89baf30
--- /dev/null
+++ b/SorpLib/Components/Pumps/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Pumps;
+package BaseClasses "Base models and functions for all pumps"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial pump models, containing fundamental definitions for 
+pumps. The content of this package is only of interest when adding new pumps to 
+the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/Pumps/BaseClasses/package.order b/SorpLib/Components/Pumps/BaseClasses/package.order
new file mode 100644
index 0000000..c6c3711
--- /dev/null
+++ b/SorpLib/Components/Pumps/BaseClasses/package.order
@@ -0,0 +1,3 @@
+PartialPump
+PartialSimplePump
+PartialAffinityPump
diff --git a/SorpLib/Components/Pumps/SimplePump.mo b/SorpLib/Components/Pumps/SimplePump.mo
new file mode 100644
index 0000000..527c17c
--- /dev/null
+++ b/SorpLib/Components/Pumps/SimplePump.mo
@@ -0,0 +1,120 @@
+within SorpLib.Components.Pumps;
+model SimplePump "Model of a simple pump with constant efficiencies"
+  extends BaseClasses.PartialSimplePump(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculation of fluid properties
+  //
+  rho = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1, inStream(port_a.Xi_outflow), {1-sum(inStream(port_a.Xi_outflow))}))
+    "Instreaming density";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The simple pump can be used to prescribe the mass or volume flow rate in hydraulic
+components, such as tubes or heat exchangers. The model assumes constant efficiencies
+and can be used for (ideal) liquids.
+
+<h4>Main equations</h4>
+<p>
+The model calculates the hydraulic, shaft, and drive power transmitted to the fluid
+or required to drive the pump. The hydraulic power <i>P<sub>hydraulic</sub></i> 
+transmitted to the fluid is defined as:
+</p>
+<pre>
+    P<sub>hydraulic</sub> = m&#x307; / &rho;<sub>in</sub> * &Delta;p;
+</pre>
+<p>
+Herein, <i>m&#x307;</i> is the mass flow rate, <i>&rho;<sub>in</sub></i> describes the 
+fluid density at the inlet, and <i>&Delta;p = p<sub>b</sub> - p<sub>a</sub></i> is the 
+pressure difference between port b and a.
+<br/><br/>
+The shaft power <i>P<sub>shaft</sub></i> depends on the pump efficiency 
+<i>&eta;<sub>pump</sub></i> and is defined as:
+</p>
+<pre>
+    P<sub>shaft</sub> = P<sub>hydraulic</sub> / &eta;<sub>pump</sub>;
+</pre>
+<p>
+The shaft power is completly transmitted to the fluid, thus increasing the outflowing
+specific enthalpy of the fluid.
+<br/><br/>
+The drive power <i>P<sub>drive</sub></i> is required to drive the pump, depends on the
+drive efficienciy <i>&eta;<sub>drive</sub></i>, and is defined as:
+</p>
+<pre>
+    P<sub>drive</sub> = P<sub>shaft</sub> / &eta;<sub>drive</sub>;
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Steady-state process
+  </li>
+  <li>
+  No flow reversal
+  </li>
+  <li>
+  Constant efficiencies
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The simple pump is typically used to prescripe the mass or volume flow rate
+in hydraulic components, such as tubes or heat exchangers.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>prescribedInput</i>:
+  Defines the variable that is prescribed (i.e., mass flow rate or volume
+  flow rate).
+  </li>
+  <li>
+  <i>assumeIsenthalpicPump</i>:
+  Defines if the hydraulic losses are considered in the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 8, 2024, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SimplePump;
diff --git a/SorpLib/Components/Pumps/Tester/Test_AffinityPump.mo b/SorpLib/Components/Pumps/Tester/Test_AffinityPump.mo
new file mode 100644
index 0000000..aa49ea7
--- /dev/null
+++ b/SorpLib/Components/Pumps/Tester/Test_AffinityPump.mo
@@ -0,0 +1,100 @@
+within SorpLib.Components.Pumps.Tester;
+model Test_AffinityPump "Tester for the affinity pump"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Pumps.AffinityPump pump(
+    use_nInput=true,
+    redeclare final package Medium = Medium) "Affinity pump"
+    annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
+
+  SorpLib.Components.Fittings.Resistors.LiquidTubeResistance pressureLoss(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.PortAInlet,
+    frictionPressureLoss=true,
+    fittingPressureLosss=false,
+    redeclare model PressureLossModel =
+        Fittings.PressureLossCorrelations.TubeInside.Blasius,
+    redeclare final package Medium = Medium) "Pressure loss model"
+    annotation (Placement(transformation(extent={{20,-10},{40,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_n(
+    amplitude=50,
+    f=1/250,
+    offset=50)
+    "Input signal for the rotational speed"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, pump.port_a) annotation (Line(
+      points={{-60,0},{-38,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(pressureLoss.port_a, pump.port_b) annotation (Line(
+      points={{22,0},{-22,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, pressureLoss.port_b) annotation (Line(
+      points={{60,0},{38,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_n.y, pump.n_input)
+    annotation (Line(points={{-59,-30},{-30,-30},{-30,-8}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the affinity pump.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 9, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AffinityPump;
diff --git a/SorpLib/Components/Pumps/Tester/Test_SimplePump.mo b/SorpLib/Components/Pumps/Tester/Test_SimplePump.mo
new file mode 100644
index 0000000..847aa84
--- /dev/null
+++ b/SorpLib/Components/Pumps/Tester/Test_SimplePump.mo
@@ -0,0 +1,104 @@
+within SorpLib.Components.Pumps.Tester;
+model Test_SimplePump "Tester for the simple pump"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of multi ports
+  //
+  SorpLib.Components.Pumps.SimplePump pump(
+    use_VFlowInput=true,
+    redeclare final package Medium = Medium) "Simple pump"
+    annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
+
+  SorpLib.Components.Fittings.Resistors.LiquidTubeResistance pressureLoss(
+    positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.PortAInlet,
+    frictionPressureLoss=true,
+    fittingPressureLosss=false,
+    redeclare model PressureLossModel =
+        Fittings.PressureLossCorrelations.TubeInside.Blasius,
+    redeclare final package Medium = Medium) "Pressure loss model"
+    annotation (Placement(transformation(extent={{20,-10},{40,10}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_VFlow(
+    amplitude=10/1000/60,
+    f=1/250,
+    offset=10/1000/60)
+    "Input signal for volume flow rate"
+    annotation (Placement(transformation(extent={{-80,-40},{-60,-20}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, pump.port_a) annotation (Line(
+      points={{-60,0},{-38,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(pressureLoss.port_a, pump.port_b) annotation (Line(
+      points={{22,0},{-22,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, pressureLoss.port_b) annotation (Line(
+      points={{60,0},{38,0}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(input_VFlow.y, pump.V_flow_input)
+    annotation (Line(points={{-59,-30},{-27,-30},{-27,-8}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the simple pump.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 8, 2024, by Mirko Engelpracht:<br/>
+  Adaptations due to restructering the library and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_SimplePump;
diff --git a/SorpLib/Components/Pumps/Tester/package.mo b/SorpLib/Components/Pumps/Tester/package.mo
new file mode 100644
index 0000000..1eeb651
--- /dev/null
+++ b/SorpLib/Components/Pumps/Tester/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Pumps;
+package Tester "Models to test and varify pump models"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented pumps. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Pumps/Tester/package.order b/SorpLib/Components/Pumps/Tester/package.order
new file mode 100644
index 0000000..6fed2df
--- /dev/null
+++ b/SorpLib/Components/Pumps/Tester/package.order
@@ -0,0 +1,2 @@
+Test_SimplePump
+Test_AffinityPump
diff --git a/SorpLib/Components/Pumps/package.mo b/SorpLib/Components/Pumps/package.mo
new file mode 100644
index 0000000..19a5915
--- /dev/null
+++ b/SorpLib/Components/Pumps/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components;
+package Pumps "Pumps to move fluids"
+  extends SorpLib.Icons.PumpsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains pumps. Ready-to-use models are based on the Modelica 
+Standard library (MSL). Pumps are used to prescripe a mass or volume flow rate
+to a hydraulic fluid.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Pumps;
diff --git a/SorpLib/Components/Pumps/package.order b/SorpLib/Components/Pumps/package.order
new file mode 100644
index 0000000..8a485fb
--- /dev/null
+++ b/SorpLib/Components/Pumps/package.order
@@ -0,0 +1,4 @@
+BaseClasses
+SimplePump
+AffinityPump
+Tester
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/DensitySensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/DensitySensor.mo
new file mode 100644
index 0000000..659482c
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/DensitySensor.mo
@@ -0,0 +1,70 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model DensitySensor "Density sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialAbsoluteFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=1e3);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = Medium.density_phX(
+    p=port.p,
+    h=inStream(port.h_outflow),
+    X=cat(1,inStream(port.Xi_outflow),{1-sum(inStream(port.Xi_outflow))}))
+    "Density";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This density sensor reads the density in kg/m<sup>3</sup>. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,74},{50,-26}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="ρ"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value,significantDigits=3) + " kg/m³")}));
+end DensitySensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFlowRateSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFlowRateSensor.mo
new file mode 100644
index 0000000..d1af3a7
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFlowRateSensor.mo
@@ -0,0 +1,82 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model MassFlowRateSensor "Mass flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialFlowFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=0.1);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the sensor setup
+  //
+  parameter Boolean flowDirectionAB = true
+    " = true, if mass flows from port a to b (i.e., positive value); otherwise,
+    mass flows from port b to a"
+    annotation (Dialog(tab="General", group="Sensor Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = if flowDirectionAB then port_a.m_flow else port_b.m_flow
+    "Mass flow rate";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass flow rate sensor reads the mass flow rate in kg/s. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  Added functionality and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,64},{50,-36}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="ṁ"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value,significantDigits=3) + " kg/s")}));
+end MassFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFractionSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFractionSensor.mo
new file mode 100644
index 0000000..cdbbd49
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFractionSensor.mo
@@ -0,0 +1,78 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model MassFractionSensor "Mass fraction sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialAbsoluteFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=0.1);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the sensor setup
+  //
+  parameter Integer ind_component(min=1, max=no_components) = 1
+    "Index of the component to read"
+    annotation (Dialog(tab="General", group="Sensor Setup",
+                enable=(Medium.nX>1)),
+                Evaluate=true,
+                HideResult=true);
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = if ind_component < Medium.nX then
+    inStream(port.Xi_outflow[ind_component]) else 1-sum(inStream(port.Xi_outflow))
+    "Mass fraction";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fraction sensor reads the mass fraction of the specified component in 
+kg/kg. It is possible to select that the sensor value <i>value</i> is delayed by 
+using a time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="xi"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value,significantDigits=3) + " kg/kg")}));
+end MassFractionSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFractionsSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFractionsSensor.mo
new file mode 100644
index 0000000..30a8c52
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/MassFractionsSensor.mo
@@ -0,0 +1,175 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model MassFractionsSensor
+  "Mass fractions sensor"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  final parameter Integer no_components = Medium.nX
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of setup parameters
+  //
+  parameter Boolean useTimeConstant = false
+    " = true, if time constant is used (i.e., sensor value is returned delayed)"
+    annotation (Dialog(tab="General", group="Sensor Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Modelica.Units.SI.Time tau = 1
+    "Time constant for delay"
+    annotation (Dialog(tab="General", group="Sensor Setup",
+                enable=useTimeConstant));
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Integer initialisationType(min=1, max=3) = 1
+    "Initialisation type: Fixed, steady-state, or free"
+    annotation (Dialog(tab="Initialisation", group="Type",
+                enable=useTimeConstant),
+                choices(
+                  choice=1 "Fixed",
+                  choice=2 "Steady-state",
+                  choice=3 "Free"));
+
+  parameter Real[no_components] value_initial=
+    fill(1/no_components, no_components)
+    "Initial values of sensor value if it is delayed"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=useTimeConstant));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of outputs
+  //
+  Modelica.Blocks.Interfaces.RealOutput[no_components] value(
+    start=value_initial)
+    "Sensor values that might be delayed by a time constant"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,68}), iconTransformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,68})));
+
+  //
+  // Definition of variables
+  //
+  Real[no_components] valueNonDelayed
+    "Non-delayed sensor values";
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port"
+    annotation (Placement(transformation(extent={{-10,-90},{10,-70}}),
+                iconTransformation(extent={{-10,-90},{10,-70}})),
+                choicesAllMatching=true);
+
+initial equation
+  if useTimeConstant then
+    if initialisationType==1 then
+      value = value_initial
+        "Fixed intial values";
+
+    elseif initialisationType==2 then
+      der(value) = zeros(no_components)
+        "Steady-state initialisations";
+
+    end if;
+  end if;
+
+equation
+  //
+  // Delay sensor value if necessary
+  //
+  if useTimeConstant then
+    der(value) = (valueNonDelayed .- value) ./ tau
+      "Delayed sensor values";
+
+  else
+    value = valueNonDelayed
+      "Non-delayed sensor values";
+
+  end if;
+
+  //
+  // Set port values
+  //
+  port.m_flow = 0
+    "Mass flow rate";
+  port.h_outflow = 0
+    "Specific enthalpy leaving the port: Dummy value";
+  port.Xi_outflow = fill(1/no_components, no_components-1)
+    "Independent mass fractions leaving the port: Dummy value";
+
+  valueNonDelayed =
+    cat(1, inStream(port.Xi_outflow), {1-sum(inStream(port.Xi_outflow))})
+    "Mass fractions";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fractions sensor reads all mass fractions in kg/kg. It is possible to 
+select that the sensor values <i>value</i> are delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces dynamic states variable, it can be used to break 
+algebraic loops. The non-delayed sensor values can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Ellipse(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          lineThickness=0.5), Text(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="xi")}));
+end MassFractionsSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/PressureDifferenceSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/PressureDifferenceSensor.mo
new file mode 100644
index 0000000..94a6095
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/PressureDifferenceSensor.mo
@@ -0,0 +1,80 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model PressureDifferenceSensor "Pressure difference sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialFlowFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=0);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the sensor setup
+  //
+  parameter Boolean flowDirectionAB = true
+    " = true, pressure difference is calculated between port a and b (i.e., 
+    positive value); otherwise, pressure difference is claculated between port
+    b and a"
+    annotation (Dialog(tab="General", group="Sensor Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = if flowDirectionAB then port_a.p-port_b.p else
+    port_b.p-port_a.p
+    "Pressure difference";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure difference sensor reads the pressure difference in Pa. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-40,64},{40,-36}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="Δp"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value/100,significantDigits=3) + " mbar")}));
+end PressureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/PressureSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/PressureSensor.mo
new file mode 100644
index 0000000..2498694
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/PressureSensor.mo
@@ -0,0 +1,67 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model PressureSensor "Pressure sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialAbsoluteFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=1e5);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Set port values
+  //
+  port.p = valueNonDelayed
+    "Pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure sensor reads the absolute pressure in Pa. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,72},{50,-28}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="p"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value/100,significantDigits=3) + " mbar")}));
+end PressureSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/SpecificEnthalpySensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/SpecificEnthalpySensor.mo
new file mode 100644
index 0000000..d1d44e0
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/SpecificEnthalpySensor.mo
@@ -0,0 +1,67 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model SpecificEnthalpySensor "Specific enthalpy sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialAbsoluteFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=1e5);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = inStream(port.h_outflow)
+    "Specific enthalpy";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific enthalpy sensor reads the specific enthalpy in J/kg. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="h"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value/1000,significantDigits=3) + " kJ/kg")}));
+end SpecificEnthalpySensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/SpecificEntropySensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/SpecificEntropySensor.mo
new file mode 100644
index 0000000..1258956
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/SpecificEntropySensor.mo
@@ -0,0 +1,70 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model SpecificEntropySensor "Specific entropy sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialAbsoluteFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=1e3);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = Medium.specificEntropy(Medium.setState_phX(
+    p=port.p,
+    h=inStream(port.h_outflow),
+    X=cat(1,inStream(port.Xi_outflow),{1-sum(inStream(port.Xi_outflow))})))
+    "Specific entropy";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific entropy sensor reads the specific entropy in J/kg/K. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,66},{50,-34}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="s"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value,significantDigits=3) + " J/kg/K")}));
+end SpecificEntropySensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/TemperatureDifferenceSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/TemperatureDifferenceSensor.mo
new file mode 100644
index 0000000..d7c282a
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/TemperatureDifferenceSensor.mo
@@ -0,0 +1,95 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model TemperatureDifferenceSensor
+  "Temperature difference sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialFlowFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=0);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the sensor setup
+  //
+  parameter Boolean flowDirectionAB = true
+    " = true, temperature difference is calculated between port a and b (i.e., 
+    positive value); otherwise, temperature difference is claculated between port
+    b and a"
+    annotation (Dialog(tab="General", group="Sensor Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Temperature T_a = Medium.temperature_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Temperature at port a";
+  Modelica.Units.SI.Temperature T_b = Medium.temperature_phX(
+    p=port_b.p,
+    h=inStream(port_b.h_outflow),
+    X=cat(1,inStream(port_b.Xi_outflow),{1-sum(inStream(port_b.Xi_outflow))}))
+    "Temperature at port b";
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = if flowDirectionAB then T_a-T_b else T_b-T_a
+    "Temperature difference";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature difference sensor reads the temperature difference in K. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-40,64},{40,-36}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="ΔT"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value,significantDigits=3) + " K")}));
+end TemperatureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/TemperatureSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/TemperatureSensor.mo
new file mode 100644
index 0000000..cefb49e
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/TemperatureSensor.mo
@@ -0,0 +1,70 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model TemperatureSensor "Temperature sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialAbsoluteFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=298.15);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = Medium.temperature_phX(
+    p=port.p,
+    h=inStream(port.h_outflow),
+    X=cat(1,inStream(port.Xi_outflow),{1-sum(inStream(port.Xi_outflow))}))
+    "Temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature sensor reads the absolute temperature in K. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="T"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value-273.15,significantDigits=3) + " °C")}));
+end TemperatureSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/ThermodynamicStateSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/ThermodynamicStateSensor.mo
new file mode 100644
index 0000000..be8feac
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/ThermodynamicStateSensor.mo
@@ -0,0 +1,137 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model ThermodynamicStateSensor
+  "Thermodynamic state sensor"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  final parameter Integer no_components = Medium.nX
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+  Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy";
+  Modelica.Units.SI.SpecificInternalEnergy u
+    "Specific internal energy";
+  Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy";
+  Modelica.Units.SI.SpecificGibbsFreeEnergy  g
+    "Specific free enthalpy (i.e., Gibbs free energy)";
+  Modelica.Units.SI.SpecificHelmholtzFreeEnergy  a
+    "Specific free energy (i.e., Helmholts free energy)";
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port"
+    annotation (Placement(transformation(extent={{-10,-90},{10,-70}}),
+                iconTransformation(extent={{-10,-90},{10,-70}})),
+                choicesAllMatching=true);
+
+  //
+  // Definitio of protected variables
+  //
+protected
+  Medium.ThermodynamicState state = Medium.setState_phX(
+    p=p,
+    h=h,
+    X=cat(1,inStream(port.Xi_outflow),{1-sum(inStream(port.Xi_outflow))}))
+    "State record";
+
+equation
+  //
+  // Set port values
+  //
+  port.m_flow = 0
+    "Mass flow rate";
+  port.h_outflow = 0
+    "Specific enthalpy leaving the port: Dummy value";
+  port.Xi_outflow = fill(1/no_components, no_components-1)
+    "Independent mass fractions leaving the port: Dummy value";
+
+  //
+  // Calculate state variables
+  //
+  p = port.p
+    "Pressure";
+  T = Medium.temperature(state=state)
+    "Temperature";
+  v = 1/Medium.density(state=state)
+    "Specific volume";
+  h = inStream(port.h_outflow)
+    "Specific enthalpy";
+  u = h - p*v
+    "Specific internal energy";
+  s = Medium.specificEntropy(state=state)
+    "Specific entropy";
+  g = h - T*s
+    "Specific free enthalpy (i.e., Gibbs free energy)";
+  a = u - T*s
+    "Specific free energy (i.e., Helmholts free energy)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This thermodynamic state sensor reads all thermodynamic state variables. I.e.,
+pressure <i>p</i>, temperature <i>T</i>, specific volume <i>v</i>, specific
+enthalpy <i>h</i>, specific internal energy <i>u</i>, specific entropy <i>s</i>,
+specific free enthalpy (i.e., Gibbs free energy <i>g</i>, and specific free 
+energy (i.e., Helmholts free energy) <i>a</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Ellipse(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          lineThickness=0.5), Text(
+          extent={{-40,60},{40,-40}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="state")}));
+end ThermodynamicStateSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/VolumeFlowRateSensor.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/VolumeFlowRateSensor.mo
new file mode 100644
index 0000000..ccde68b
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/VolumeFlowRateSensor.mo
@@ -0,0 +1,115 @@
+within SorpLib.Components.Sensors.BaseClasses.FluidMSL;
+partial model VolumeFlowRateSensor "Volume flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialFlowFluidSensor(
+    final no_components=Medium.nX,
+    value_initial=10/60000);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters regarding the sensor setup
+  //
+  parameter Boolean flowDirectionAB = true
+    " = true, if mass flows from port a to b (i.e., positive value); otherwise,
+    mass flows from port b to a"
+    annotation (Dialog(tab="General", group="Sensor Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Modelica.Units.SI.MassFlowRate m_flow_small = 1e-5
+    "Mass flow rate used to regulate flow-dependent properties (i.e., density)"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Density rho_a = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Density at port a";
+  Modelica.Units.SI.Density rho_b = Medium.density_phX(
+    p=port_b.p,
+    h=inStream(port_b.h_outflow),
+    X=cat(1,inStream(port_b.Xi_outflow),{1-sum(inStream(port_b.Xi_outflow))}))
+    "Density at port b";
+  Modelica.Units.SI.Density rho = if avoid_events then
+    SorpLib.Numerics.regStep_noEvent(
+      x=port_a.m_flow,
+      y1=rho_a,
+      y2=rho_b,
+      x_small=m_flow_small) else
+    SorpLib.Numerics.regStep(
+      x=port_a.m_flow,
+      y1=rho_a,
+      y2=rho_b,
+      x_small=m_flow_small)
+    "Actual density";
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = if flowDirectionAB then port_a.m_flow/rho else
+    port_b.m_flow/rho
+    "Volume flow rate";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This volume flow rate sensor reads the volume flow rate in m<sup>3</sup>/s. It 
+is possible to select that the sensor value <i>value</i> is delayed by using a 
+time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,54},{50,-46}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="V̇"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value*60000,significantDigits=3) + " l/min")}));
+end VolumeFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/package.mo b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/package.mo
new file mode 100644
index 0000000..41da62d
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Components.Sensors.BaseClasses;
+package FluidMSL "Base models for all fluid sensors based on the MSL"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial fluid sensors, containing fundamental 
+definitions for sensors. These fluid sensors are based on the open-
+source Modelica Standard Library (MSL). The content of this package 
+is only of interest when adding new sensors to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end FluidMSL;
diff --git a/SorpLib/Components/Sensors/BaseClasses/FluidMSL/package.order b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/package.order
new file mode 100644
index 0000000..c462676
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/FluidMSL/package.order
@@ -0,0 +1,12 @@
+PressureSensor
+TemperatureSensor
+DensitySensor
+SpecificEnthalpySensor
+SpecificEntropySensor
+MassFractionSensor
+MassFractionsSensor
+ThermodynamicStateSensor
+MassFlowRateSensor
+VolumeFlowRateSensor
+PressureDifferenceSensor
+TemperatureDifferenceSensor
diff --git a/SorpLib/Components/Sensors/BaseClasses/PartialAbsoluteFluidSensor.mo b/SorpLib/Components/Sensors/BaseClasses/PartialAbsoluteFluidSensor.mo
new file mode 100644
index 0000000..cbbb805
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/PartialAbsoluteFluidSensor.mo
@@ -0,0 +1,72 @@
+within SorpLib.Components.Sensors.BaseClasses;
+partial model PartialAbsoluteFluidSensor
+  "Base model for all fluid-based absolute sensors"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  extends SorpLib.Components.Sensors.BaseClasses.PartialSensor;
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port"
+    annotation (Placement(transformation(extent={{-10,-90},{10,-70}}),
+                iconTransformation(extent={{-10,-90},{10,-70}})),
+                choicesAllMatching=true);
+
+equation
+  //
+  // Set port values
+  //
+  port.m_flow = 0
+    "Mass flow rate";
+  port.h_outflow = 0
+    "Specific enthalpy leaving the port: Dummy value";
+  port.Xi_outflow = fill(1/no_components, no_components-1)
+    "Independent mass fractions leaving the port: Dummy value";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model is the base model for all fluid-based absolute sensors. It defines 
+fundamental parameters and variables required by all sensors. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Ellipse(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          lineThickness=0.5), Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1)}));
+end PartialAbsoluteFluidSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/PartialFlowFluidSensor.mo b/SorpLib/Components/Sensors/BaseClasses/PartialFlowFluidSensor.mo
new file mode 100644
index 0000000..8265ecb
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/PartialFlowFluidSensor.mo
@@ -0,0 +1,80 @@
+within SorpLib.Components.Sensors.BaseClasses;
+partial model PartialFlowFluidSensor
+  "Base model for all fluid-based flow sensors"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  extends SorpLib.Components.Sensors.BaseClasses.PartialSensor;
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-60,-90},{-40,-70}}),
+                iconTransformation(extent={{-60,-90},{-40,-70}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{40,-90},{60,-70}}),
+                iconTransformation(extent={{40,-90},{60,-70}})),
+                choicesAllMatching=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(port_a, port_b)
+    annotation (Line(points={{-50,-80},{50,-80}}, color={0,0,0}));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model is the base model for all fluid-based flow sensors. It defines 
+fundamental parameters and variables required by all sensors. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  Added functionality and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Ellipse(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          lineThickness=0.5), Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1)}));
+end PartialFlowFluidSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/PartialRelativeFluidSensor.mo b/SorpLib/Components/Sensors/BaseClasses/PartialRelativeFluidSensor.mo
new file mode 100644
index 0000000..ee61b63
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/PartialRelativeFluidSensor.mo
@@ -0,0 +1,88 @@
+within SorpLib.Components.Sensors.BaseClasses;
+partial model PartialRelativeFluidSensor
+  "Base model for all fluid-based relative sensors"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  extends SorpLib.Components.Sensors.BaseClasses.PartialSensor;
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-60,-90},{-40,-70}}),
+                iconTransformation(extent={{-60,-90},{-40,-70}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components)
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{40,-90},{60,-70}}),
+                iconTransformation(extent={{40,-90},{60,-70}})),
+                choicesAllMatching=true);
+
+equation
+  //
+  // Set port values
+  //
+  port_a.m_flow = 0
+    "Mass flow rate";
+  port_b.m_flow = 0
+    "Mass flow rate";
+
+  port_a.h_outflow = 0
+    "Specific enthalpy leaving the port: Dummy value";
+  port_b.h_outflow = 0
+    "Specific enthalpy leaving the port: Dummy value";
+
+  port_a.Xi_outflow = fill(1/no_components, no_components-1)
+    "Independent mass fractions leaving the port: Dummy value";
+  port_b.Xi_outflow = fill(1/no_components, no_components-1)
+    "Independent mass fractions leaving the port: Dummy value";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model is the base model for all fluid-based relative sensors. It defines 
+fundamental parameters and variables required by all sensors. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Ellipse(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          lineThickness=0.5), Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1)}));
+end PartialRelativeFluidSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/PartialSensor.mo b/SorpLib/Components/Sensors/BaseClasses/PartialSensor.mo
new file mode 100644
index 0000000..7f852a2
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/PartialSensor.mo
@@ -0,0 +1,126 @@
+within SorpLib.Components.Sensors.BaseClasses;
+partial model PartialSensor
+  "Base model for all sensors"
+
+  //
+  // Definition of setup parameters
+  //
+  parameter Boolean useTimeConstant = false
+    " = true, if time constant is used (i.e., sensor value is returned delayed)"
+    annotation (Dialog(tab="General", group="Sensor Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Modelica.Units.SI.Time tau = 1
+    "Time constant for delay"
+    annotation (Dialog(tab="General", group="Sensor Setup",
+                enable=useTimeConstant));
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Integer initialisationType(min=1, max=3) = 1
+    "Initialisation type: Fixed, steady-state, or free"
+    annotation (Dialog(tab="Initialisation", group="Type",
+                enable=useTimeConstant),
+                choices(
+                  choice=1 "Fixed",
+                  choice=2 "Steady-state",
+                  choice=3 "Free"));
+
+  parameter Real value_initial = 1
+    "Initial value of sensor value if it is delayed"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=useTimeConstant));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of outputs
+  //
+  Modelica.Blocks.Interfaces.RealOutput value(
+    start=value_initial)
+    "Sensor value that might be delayed by a time constant"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,68}), iconTransformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,68})));
+
+  //
+  // Definition of variables
+  //
+  Real valueNonDelayed
+    "Non-delayed sensor value";
+
+initial equation
+  if useTimeConstant then
+    if initialisationType==1 then
+      value = value_initial
+        "Fixed intial value";
+
+    elseif initialisationType==2 then
+      der(value) = 0
+        "Steady-state initialisation";
+
+    end if;
+  end if;
+
+equation
+  //
+  // Delay sensor value if necessary
+  //
+  if useTimeConstant then
+    der(value) = (valueNonDelayed - value) / tau
+      "Delayed sensor value";
+
+  else
+    value = valueNonDelayed
+      "Non-delayed sensor value";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model is the base model for all sensors. It defines fundamental parameters
+and variables required by all sensors. It is possible to select that the sensor 
+value <i>value</i> is delayed by using a time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Ellipse(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          lineThickness=0.5), Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1)}));
+end PartialSensor;
diff --git a/SorpLib/Components/Sensors/BaseClasses/package.mo b/SorpLib/Components/Sensors/BaseClasses/package.mo
new file mode 100644
index 0000000..568f0d0
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Sensors;
+package BaseClasses "Base models for all sensors"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial sensors, containing fundamental definitions 
+for sensors. The content of this package is only of interest when adding 
+new sensors to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/Sensors/BaseClasses/package.order b/SorpLib/Components/Sensors/BaseClasses/package.order
new file mode 100644
index 0000000..cca0fc7
--- /dev/null
+++ b/SorpLib/Components/Sensors/BaseClasses/package.order
@@ -0,0 +1,5 @@
+PartialSensor
+PartialAbsoluteFluidSensor
+PartialRelativeFluidSensor
+PartialFlowFluidSensor
+FluidMSL
diff --git a/SorpLib/Components/Sensors/GasSensors/DensitySensor.mo b/SorpLib/Components/Sensors/GasSensors/DensitySensor.mo
new file mode 100644
index 0000000..060e68d
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/DensitySensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.GasSensors;
+model DensitySensor "Density sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.DensitySensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+      redeclare replaceable package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+        constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This density sensor reads the density in kg/m<sup>3</sup>. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DensitySensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/MassFlowRateSensor.mo b/SorpLib/Components/Sensors/GasSensors/MassFlowRateSensor.mo
new file mode 100644
index 0000000..bdffbaf
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/MassFlowRateSensor.mo
@@ -0,0 +1,42 @@
+within SorpLib.Components.Sensors.GasSensors;
+model MassFlowRateSensor "Mass flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFlowRateSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+      constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass flow rate sensor reads the mass flow rate in kg/s. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  Added functionality and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={244,125,35},
+          thickness=1)}));
+end MassFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/MassFractionSensor.mo b/SorpLib/Components/Sensors/GasSensors/MassFractionSensor.mo
new file mode 100644
index 0000000..0464baf
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/MassFractionSensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.GasSensors;
+model MassFractionSensor "Mass fraction sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFractionSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+      constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fraction sensor reads the mass fraction of the specified component in 
+kg/kg. It is possible to select that the sensor value <i>value</i> is delayed by 
+using a time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MassFractionSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/MassFractionsSensor.mo b/SorpLib/Components/Sensors/GasSensors/MassFractionsSensor.mo
new file mode 100644
index 0000000..b354fe0
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/MassFractionsSensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.GasSensors;
+model MassFractionsSensor "Mass fractions sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFractionsSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+      constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fractions sensor reads all mass fractions in kg/kg. It is possible to 
+select that the sensor values <i>value</i> are delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces dynamic states variable, it can be used to break 
+algebraic loops. The non-delayed sensor values can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MassFractionsSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/PressureDifferenceSensor.mo b/SorpLib/Components/Sensors/GasSensors/PressureDifferenceSensor.mo
new file mode 100644
index 0000000..59cc748
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/PressureDifferenceSensor.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.Sensors.GasSensors;
+model PressureDifferenceSensor "Pressure difference sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.PressureDifferenceSensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+      redeclare replaceable package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+        constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure difference sensor reads the pressure difference in Pa. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={244,125,35},
+          thickness=1)}));
+end PressureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/PressureSensor.mo b/SorpLib/Components/Sensors/GasSensors/PressureSensor.mo
new file mode 100644
index 0000000..4b728c9
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/PressureSensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.GasSensors;
+model PressureSensor "Pressure sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.PressureSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+      constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure sensor reads the pressure temperature in Pa. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PressureSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/SpecificEnthalpySensor.mo b/SorpLib/Components/Sensors/GasSensors/SpecificEnthalpySensor.mo
new file mode 100644
index 0000000..814720e
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/SpecificEnthalpySensor.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Sensors.GasSensors;
+model SpecificEnthalpySensor "Specific enthalpy sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.SpecificEnthalpySensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+      redeclare replaceable package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+        constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific enthalpy sensor reads the specific enthalpy in J/kg. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificEnthalpySensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/SpecificEntropySensor.mo b/SorpLib/Components/Sensors/GasSensors/SpecificEntropySensor.mo
new file mode 100644
index 0000000..db16007
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/SpecificEntropySensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.GasSensors;
+model SpecificEntropySensor "Specific entropy sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.SpecificEntropySensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+      constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific entropy sensor reads the specific entropy in J/kg/K. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificEntropySensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/TemperatureDifferenceSensor.mo b/SorpLib/Components/Sensors/GasSensors/TemperatureDifferenceSensor.mo
new file mode 100644
index 0000000..247b47a
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/TemperatureDifferenceSensor.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.Sensors.GasSensors;
+model TemperatureDifferenceSensor "Temperature difference sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.TemperatureDifferenceSensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+      redeclare replaceable package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+        constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature difference sensor reads the temperature difference in K. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={244,125,35},
+          thickness=1)}));
+end TemperatureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/TemperatureSensor.mo b/SorpLib/Components/Sensors/GasSensors/TemperatureSensor.mo
new file mode 100644
index 0000000..59396f5
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/TemperatureSensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.GasSensors;
+model TemperatureSensor "Temperature sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.TemperatureSensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+      redeclare replaceable package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+        constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature sensor reads the absolute temperature in K. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TemperatureSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/Tester/Test_GasSensors.mo b/SorpLib/Components/Sensors/GasSensors/Tester/Test_GasSensors.mo
new file mode 100644
index 0000000..0821f84
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/Tester/Test_GasSensors.mo
@@ -0,0 +1,218 @@
+within SorpLib.Components.Sensors.GasSensors.Tester;
+model Test_GasSensors "Tester for gas / gas mixture sensors"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true) "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasSource fs_b(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    use_TInput=true) "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of sensors
+  //
+  SorpLib.Components.Sensors.GasSensors.PressureSensor pSensor
+    "Pressure sensor"
+    annotation (Placement(transformation(extent={{-50,-2},{-30,18}})));
+  SorpLib.Components.Sensors.GasSensors.TemperatureSensor TSensor_a
+    "Temperature sensor at port a"
+    annotation (Placement(transformation(extent={{-50,58},{-30,78}})));
+  SorpLib.Components.Sensors.GasSensors.TemperatureSensor TSensor_b(
+      useTimeConstant=true, tau=10) "Temperature sensor at port b"
+    annotation (Placement(transformation(extent={{30,-82},{50,-62}})));
+  SorpLib.Components.Sensors.GasSensors.DensitySensor rhoSensor_a
+    "Density sensor at port a"
+    annotation (Placement(transformation(extent={{-30,58},{-10,78}})));
+  SorpLib.Components.Sensors.GasSensors.DensitySensor rhoSensor_b(
+      useTimeConstant=true, tau=10) "Density sensor at port b"
+    annotation (Placement(transformation(extent={{10,-82},{30,-62}})));
+  SorpLib.Components.Sensors.GasSensors.SpecificEnthalpySensor hSensor_a
+    "Specific enthalpy sensor at port a"
+    annotation (Placement(transformation(extent={{-10,58},{10,78}})));
+  SorpLib.Components.Sensors.GasSensors.SpecificEnthalpySensor hSensor_b(
+      useTimeConstant=true, tau=10) "Specific enthalpy sensor at port b"
+    annotation (Placement(transformation(extent={{-10,-82},{10,-62}})));
+  SorpLib.Components.Sensors.GasSensors.SpecificEntropySensor sSensor_a
+    "Specific entropy sensor at port a"
+    annotation (Placement(transformation(extent={{10,58},{30,78}})));
+  SorpLib.Components.Sensors.GasSensors.SpecificEntropySensor sSensor_b(
+      useTimeConstant=true, tau=10) "Specific entropy sensor at port b"
+    annotation (Placement(transformation(extent={{-30,-82},{-10,-62}})));
+  SorpLib.Components.Sensors.GasSensors.MassFractionsSensor xiSensor_a
+    "Mass fractions sensor at port a"
+    annotation (Placement(transformation(extent={{30,58},{50,78}})));
+  SorpLib.Components.Sensors.GasSensors.MassFractionsSensor xiSensor_b(
+      useTimeConstant=true, tau=10) "Mass fractions sensor at port b"
+    annotation (Placement(transformation(extent={{-50,-82},{-30,-62}})));
+  SorpLib.Components.Sensors.GasSensors.ThermodynamicStateSensor stateSensor_a
+    "Thermodynamic state sensor at port a"
+    annotation (Placement(transformation(extent={{50,58},{70,78}})));
+  SorpLib.Components.Sensors.GasSensors.ThermodynamicStateSensor stateSensor_b
+    "Thermodynamic state sensor at port b"
+    annotation (Placement(transformation(extent={{-70,-82},{-50,-62}})));
+
+  SorpLib.Components.Sensors.GasSensors.MassFlowRateSensor mFlowSensor
+    "Mass flow rate sensor"
+    annotation (Placement(transformation(extent={{-30,-2},{-10,18}})));
+  SorpLib.Components.Sensors.GasSensors.VolumeFlowRateSensor VFlowSensor
+    "Volume flow rate sensor"
+    annotation (Placement(transformation(extent={{-10,-2},{10,18}})));
+  SorpLib.Components.Sensors.GasSensors.PressureDifferenceSensor dpSensor
+    "Pressure difference sensor"
+    annotation (Placement(transformation(extent={{10,-2},{30,18}})));
+  SorpLib.Components.Sensors.GasSensors.TemperatureDifferenceSensor dTSensor
+    "Temperature difference sensor"
+    annotation (Placement(transformation(extent={{30,-2},{50,18}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_mFlowVar(
+    height=60/60,
+    duration=2500,
+    offset=-30/60,
+    startTime=0)
+    "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{-100,10},{-80,30}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_TVar_a(
+    height=80,
+    duration=2500,
+    offset=293.15,
+    startTime=0)
+    "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,-30}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=-(10e5 - 1e3),
+    duration=2500,
+    offset=10e5,
+    startTime=0)
+    "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{100,10},{80,30}})),
+    HideResult=true);
+  Modelica.Blocks.Sources.Sine input_TVar_b(
+    amplitude=25,
+    f=1/250,
+    offset=273.15 + 50)
+    "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{100,-10},{80,-30}})),
+    HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(input_mFlowVar.y, fs_a.m_flow_input) annotation (Line(points={{-79,20},
+          {-70,20},{-70,2},{-61.2,2}}, color={0,0,127}));
+  connect(input_TVar_a.y, fs_a.T_input) annotation (Line(points={{-79,-20},{-70,
+          -20},{-70,-2},{-61.2,-2}}, color={0,0,127}));
+  connect(input_pVar.y, fs_b.p_input) annotation (Line(points={{79,20},{70,20},{
+          70,5},{61.2,5}}, color={0,0,127}));
+  connect(input_TVar_b.y, fs_b.T_input) annotation (Line(points={{79,-20},{70,-20},
+          {70,-2},{61.2,-2}}, color={0,0,127}));
+
+  connect(fs_a.port, TSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{-40,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, rhoSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{-20,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, hSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{0,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, sSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{20,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, xiSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{40,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, stateSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{60,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, TSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{40,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, rhoSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{20,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, hSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{0,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, sSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-20,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, xiSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-40,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, stateSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-60,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, pSensor.port) annotation (Line(
+      points={{-60,0},{-40,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(pSensor.port, mFlowSensor.port_a) annotation (Line(
+      points={{-40,0},{-25,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(mFlowSensor.port_b, VFlowSensor.port_a) annotation (Line(
+      points={{-15,0},{-5,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(VFlowSensor.port_b, dpSensor.port_a) annotation (Line(
+      points={{5,0},{15,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(dpSensor.port_b, dTSensor.port_a) annotation (Line(
+      points={{25,0},{35,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(dTSensor.port_b, fs_b.port) annotation (Line(
+      points={{45,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks all gas / gas mixture sensors.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasSensors;
diff --git a/SorpLib/Components/Sensors/GasSensors/Tester/package.mo b/SorpLib/Components/Sensors/GasSensors/Tester/package.mo
new file mode 100644
index 0000000..303659c
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Sensors.GasSensors;
+package Tester "Models to test and varify models for gas / gas mixture sensors"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented gas / gas
+mixture sensors. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Sensors/GasSensors/Tester/package.order b/SorpLib/Components/Sensors/GasSensors/Tester/package.order
new file mode 100644
index 0000000..242ac2d
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/Tester/package.order
@@ -0,0 +1 @@
+Test_GasSensors
diff --git a/SorpLib/Components/Sensors/GasSensors/ThermodynamicStateSensor.mo b/SorpLib/Components/Sensors/GasSensors/ThermodynamicStateSensor.mo
new file mode 100644
index 0000000..c3bad45
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/ThermodynamicStateSensor.mo
@@ -0,0 +1,29 @@
+within SorpLib.Components.Sensors.GasSensors;
+model ThermodynamicStateSensor "Thermodynamic state sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.ThermodynamicStateSensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+      redeclare replaceable package Medium =
+        SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+        constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This thermodynamic state sensor reads all thermodynamic state variables. I.e.,
+pressure <i>p</i>, temperature <i>T</i>, specific volume <i>v</i>, specific
+enthalpy <i>h</i>, specific internal energy <i>u</i>, specific entropy <i>s</i>,
+specific free enthalpy (i.e., Gibbs free energy <i>g</i>, and specific free 
+energy (i.e., Helmholts free energy) <i>a</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ThermodynamicStateSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/VolumeFlowRateSensor.mo b/SorpLib/Components/Sensors/GasSensors/VolumeFlowRateSensor.mo
new file mode 100644
index 0000000..5af0e0f
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/VolumeFlowRateSensor.mo
@@ -0,0 +1,38 @@
+within SorpLib.Components.Sensors.GasSensors;
+model VolumeFlowRateSensor "Volume flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.VolumeFlowRateSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O
+      constrainedby Modelica.Media.Interfaces.PartialMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This volume flow rate sensor reads the volume flow rate in m<sup>3</sup>/s. It 
+is possible to select that the sensor value <i>value</i> is delayed by using a 
+time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={244,125,35},
+          thickness=1)}));
+end VolumeFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/GasSensors/package.mo b/SorpLib/Components/Sensors/GasSensors/package.mo
new file mode 100644
index 0000000..b1c4f23
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Components.Sensors;
+package GasSensors "Gas / Gas mixture sensors"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains gas / gas mixture sensors based on the open-source Modelica 
+Standard Library (MSL). It implements absolute sensors, which are only connected to  
+one fluid port, as well as relative and flow sensors, which are connected between 
+two fluid ports.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasSensors;
diff --git a/SorpLib/Components/Sensors/GasSensors/package.order b/SorpLib/Components/Sensors/GasSensors/package.order
new file mode 100644
index 0000000..675912c
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasSensors/package.order
@@ -0,0 +1,13 @@
+PressureSensor
+TemperatureSensor
+DensitySensor
+SpecificEnthalpySensor
+SpecificEntropySensor
+MassFractionSensor
+MassFractionsSensor
+ThermodynamicStateSensor
+MassFlowRateSensor
+VolumeFlowRateSensor
+PressureDifferenceSensor
+TemperatureDifferenceSensor
+Tester
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/DensitySensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/DensitySensor.mo
new file mode 100644
index 0000000..3ee4d4b
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/DensitySensor.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model DensitySensor "Density sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.DensitySensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+      redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This density sensor reads the density in kg/m<sup>3</sup>. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DensitySensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFlowRateSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFlowRateSensor.mo
new file mode 100644
index 0000000..ae09764
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFlowRateSensor.mo
@@ -0,0 +1,43 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model MassFlowRateSensor "Mass flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFlowRateSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass flow rate sensor reads the mass flow rate in kg/s. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  Added functionality and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={244,125,35},
+          thickness=1)}));
+end MassFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFractionSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFractionSensor.mo
new file mode 100644
index 0000000..c1928ba
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFractionSensor.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model MassFractionSensor "Mass fraction sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFractionSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fraction sensor reads the mass fraction of the specified component in 
+kg/kg. It is possible to select that the sensor value <i>value</i> is delayed by 
+using a time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MassFractionSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFractionsSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFractionsSensor.mo
new file mode 100644
index 0000000..dd24d3c
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/MassFractionsSensor.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model MassFractionsSensor "Mass fractions sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFractionsSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fractions sensor reads all mass fractions in kg/kg. It is possible to 
+select that the sensor values <i>value</i> are delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces dynamic states variable, it can be used to break 
+algebraic loops. The non-delayed sensor values can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MassFractionsSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/PressureDifferenceSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/PressureDifferenceSensor.mo
new file mode 100644
index 0000000..754abec
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/PressureDifferenceSensor.mo
@@ -0,0 +1,40 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model PressureDifferenceSensor "Pressure difference sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.PressureDifferenceSensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+      redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure difference sensor reads the pressure difference in Pa. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={244,125,35},
+          thickness=1)}));
+end PressureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/PressureSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/PressureSensor.mo
new file mode 100644
index 0000000..50c9365
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/PressureSensor.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model PressureSensor "Pressure sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.PressureSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure sensor reads the pressure temperature in Pa. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PressureSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/RelativeHumiditySensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/RelativeHumiditySensor.mo
new file mode 100644
index 0000000..90ebd8f
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/RelativeHumiditySensor.mo
@@ -0,0 +1,77 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model RelativeHumiditySensor "Relative humidity sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialAbsoluteFluidSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    final no_components=Medium.nX,
+    value_initial=0.1);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby
+    SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+protected
+  Medium.ThermodynamicState state = Medium.setState_phX(
+    p=port.p,
+    h=inStream(port.h_outflow),
+    X=cat(1,inStream(port.Xi_outflow),{1-sum(inStream(port.Xi_outflow))}))
+    "State record";
+
+equation
+  //
+  // Calculate properties
+  //
+  valueNonDelayed = Medium.relativeHumidity(state=state)
+     "Relative humidity";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This relative humidity sensor reads the relative humidity quality in 0-1. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time 
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,74},{50,-26}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="φ"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value*100,significantDigits=3) + " %%rF")}));
+end RelativeHumiditySensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/SpecificEnthalpySensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/SpecificEnthalpySensor.mo
new file mode 100644
index 0000000..f11f808
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/SpecificEnthalpySensor.mo
@@ -0,0 +1,36 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model SpecificEnthalpySensor "Specific enthalpy sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.SpecificEnthalpySensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+      redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific enthalpy sensor reads the specific enthalpy in J/kg. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificEnthalpySensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/SpecificEntropySensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/SpecificEntropySensor.mo
new file mode 100644
index 0000000..88600a5
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/SpecificEntropySensor.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model SpecificEntropySensor "Specific entropy sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.SpecificEntropySensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific entropy sensor reads the specific entropy in J/kg/K. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificEntropySensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/TemperatureDifferenceSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/TemperatureDifferenceSensor.mo
new file mode 100644
index 0000000..4d10c74
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/TemperatureDifferenceSensor.mo
@@ -0,0 +1,40 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model TemperatureDifferenceSensor "Temperature difference sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.TemperatureDifferenceSensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+      redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature difference sensor reads the temperature difference in K. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={244,125,35},
+          thickness=1)}));
+end TemperatureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/TemperatureSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/TemperatureSensor.mo
new file mode 100644
index 0000000..13a9458
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/TemperatureSensor.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model TemperatureSensor "Temperature sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.TemperatureSensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+      redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature sensor reads the absolute temperature in K. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TemperatureSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/Test_GasSensors.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/Test_GasSensors.mo
new file mode 100644
index 0000000..23fab99
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/Test_GasSensors.mo
@@ -0,0 +1,232 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors.Tester;
+model Test_GasSensors "Tester for gas / gas mixture sensors"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true) "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource fs_b(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    use_TInput=true) "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of sensors
+  //
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.PressureSensor pSensor
+    "Pressure sensor"
+    annotation (Placement(transformation(extent={{-50,-2},{-30,18}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.TemperatureSensor TSensor_a
+    "Temperature sensor at port a"
+    annotation (Placement(transformation(extent={{-50,58},{-30,78}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.TemperatureSensor TSensor_b(
+      useTimeConstant=true, tau=10) "Temperature sensor at port b"
+    annotation (Placement(transformation(extent={{30,-82},{50,-62}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.DensitySensor rhoSensor_a
+    "Density sensor at port a"
+    annotation (Placement(transformation(extent={{-30,58},{-10,78}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.DensitySensor rhoSensor_b(
+      useTimeConstant=true, tau=10) "Density sensor at port b"
+    annotation (Placement(transformation(extent={{10,-82},{30,-62}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.SpecificEnthalpySensor hSensor_a
+    "Specific enthalpy sensor at port a"
+    annotation (Placement(transformation(extent={{-10,58},{10,78}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.SpecificEnthalpySensor hSensor_b(
+      useTimeConstant=true, tau=10) "Specific enthalpy sensor at port b"
+    annotation (Placement(transformation(extent={{-10,-82},{10,-62}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.SpecificEntropySensor sSensor_a
+    "Specific entropy sensor at port a"
+    annotation (Placement(transformation(extent={{10,58},{30,78}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.SpecificEntropySensor sSensor_b(
+      useTimeConstant=true, tau=10) "Specific entropy sensor at port b"
+    annotation (Placement(transformation(extent={{-30,-82},{-10,-62}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.MassFractionsSensor xiSensor_a
+    "Mass fractions sensor at port a"
+    annotation (Placement(transformation(extent={{30,58},{50,78}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.MassFractionsSensor xiSensor_b(
+      useTimeConstant=true, tau=10) "Mass fractions sensor at port b"
+    annotation (Placement(transformation(extent={{-50,-82},{-30,-62}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.RelativeHumiditySensor phiSensor_a
+    "Relative humidity sensor at port a"
+    annotation (Placement(transformation(extent={{50,58},{70,78}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.RelativeHumiditySensor phiSensor_b(
+      useTimeConstant=true, tau=10) "Relative humidity sensor at port b"
+    annotation (Placement(transformation(extent={{-70,-82},{-50,-62}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.ThermodynamicStateSensor stateSensor_a
+    "Thermodynamic state sensor at port a"
+    annotation (Placement(transformation(extent={{70,58},{90,78}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.ThermodynamicStateSensor stateSensor_b
+    "Thermodynamic state sensor at port b"
+    annotation (Placement(transformation(extent={{-90,-82},{-70,-62}})));
+
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.MassFlowRateSensor mFlowSensor
+    "Mass flow rate sensor"
+    annotation (Placement(transformation(extent={{-30,-2},{-10,18}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.VolumeFlowRateSensor VFlowSensor
+    "Volume flow rate sensor"
+    annotation (Placement(transformation(extent={{-10,-2},{10,18}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.PressureDifferenceSensor dpSensor
+    "Pressure difference sensor"
+    annotation (Placement(transformation(extent={{10,-2},{30,18}})));
+  SorpLib.Components.Sensors.GasVaporMixtureSenors.TemperatureDifferenceSensor dTSensor
+    "Temperature difference sensor"
+    annotation (Placement(transformation(extent={{30,-2},{50,18}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_mFlowVar(
+    height=60/60,
+    duration=2500,
+    offset=-30/60,
+    startTime=0)
+    "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{-100,10},{-80,30}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_TVar_a(
+    height=80,
+    duration=2500,
+    offset=293.15,
+    startTime=0)
+    "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,-30}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=-(10e5 - 1e3),
+    duration=2500,
+    offset=10e5,
+    startTime=0)
+    "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{100,10},{80,30}})),
+    HideResult=true);
+  Modelica.Blocks.Sources.Sine input_TVar_b(
+    amplitude=25,
+    f=1/250,
+    offset=273.15 + 50)
+    "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{100,-10},{80,-30}})),
+    HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(input_mFlowVar.y, fs_a.m_flow_input) annotation (Line(points={{-79,20},
+          {-70,20},{-70,2},{-61.2,2}}, color={0,0,127}));
+  connect(input_TVar_a.y, fs_a.T_input) annotation (Line(points={{-79,-20},{-70,
+          -20},{-70,-2},{-61.2,-2}}, color={0,0,127}));
+  connect(input_pVar.y, fs_b.p_input) annotation (Line(points={{79,20},{70,20},{
+          70,5},{61.2,5}}, color={0,0,127}));
+  connect(input_TVar_b.y, fs_b.T_input) annotation (Line(points={{79,-20},{70,-20},
+          {70,-2},{61.2,-2}}, color={0,0,127}));
+
+  connect(fs_a.port, TSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{-40,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, rhoSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{-20,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, hSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{0,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, sSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{20,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, xiSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{40,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, stateSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{80,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, TSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{40,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, rhoSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{20,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, hSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{0,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, sSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-20,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, xiSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-40,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, stateSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-80,-80}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, pSensor.port) annotation (Line(
+      points={{-60,0},{-40,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(pSensor.port, mFlowSensor.port_a) annotation (Line(
+      points={{-40,0},{-25,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(mFlowSensor.port_b, VFlowSensor.port_a) annotation (Line(
+      points={{-15,0},{-5,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(VFlowSensor.port_b, dpSensor.port_a) annotation (Line(
+      points={{5,0},{15,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(dpSensor.port_b, dTSensor.port_a) annotation (Line(
+      points={{25,0},{35,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(dTSensor.port_b, fs_b.port) annotation (Line(
+      points={{45,0},{60,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a.port, phiSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{60,60}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b.port, phiSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-60,-80}},
+      color={244,125,35},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks all gas-vapor mixture sensors.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_GasSensors;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/package.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/package.mo
new file mode 100644
index 0000000..84ce374
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+package Tester "Models to test and varify models for gas / gas mixture sensors"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented gas / gas
+mixture sensors. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/package.order b/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/package.order
new file mode 100644
index 0000000..242ac2d
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/Tester/package.order
@@ -0,0 +1 @@
+Test_GasSensors
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/ThermodynamicStateSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/ThermodynamicStateSensor.mo
new file mode 100644
index 0000000..ee9491b
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/ThermodynamicStateSensor.mo
@@ -0,0 +1,43 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model ThermodynamicStateSensor "Thermodynamic state sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.ThermodynamicStateSensor(
+      redeclare final Basics.Interfaces.FluidPorts.GasPort_in port,
+      redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Definition of variables
+  //
+  Real phi(min=0, max=1)
+     "Relative humidity";
+
+equation
+  //
+  // Calculate properties
+  //
+  phi = Medium.relativeHumidity(state=state)
+     "Relative humidity";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This thermodynamic state sensor reads all thermodynamic state variables. I.e.,
+pressure <i>p</i>, temperature <i>T</i>, specific volume <i>v</i>, specific
+enthalpy <i>h</i>, specific internal energy <i>u</i>, specific entropy <i>s</i>,
+specific free enthalpy (i.e., Gibbs free energy <i>g</i>, and specific free 
+energy (i.e., Helmholts free energy) <i>a</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ThermodynamicStateSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/VolumeFlowRateSensor.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/VolumeFlowRateSensor.mo
new file mode 100644
index 0000000..599a6af
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/VolumeFlowRateSensor.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.Sensors.GasVaporMixtureSenors;
+model VolumeFlowRateSensor "Volume flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.VolumeFlowRateSensor(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+      constrainedby
+      SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This volume flow rate sensor reads the volume flow rate in m<sup>3</sup>/s. It 
+is possible to select that the sensor value <i>value</i> is delayed by using a 
+time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={244,125,35},
+          thickness=1)}));
+end VolumeFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/package.mo b/SorpLib/Components/Sensors/GasVaporMixtureSenors/package.mo
new file mode 100644
index 0000000..2f06401
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Components.Sensors;
+package GasVaporMixtureSenors "Gas-vapor mixture sensors"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains gas-vapor mixture sensors based on the open-source Modelica 
+Standard Library (MSL). It implements absolute sensors, which are only connected to  
+one fluid port, as well as relative and flow sensors, which are connected between 
+two fluid ports.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GasVaporMixtureSenors;
diff --git a/SorpLib/Components/Sensors/GasVaporMixtureSenors/package.order b/SorpLib/Components/Sensors/GasVaporMixtureSenors/package.order
new file mode 100644
index 0000000..80ca3f3
--- /dev/null
+++ b/SorpLib/Components/Sensors/GasVaporMixtureSenors/package.order
@@ -0,0 +1,14 @@
+PressureSensor
+TemperatureSensor
+DensitySensor
+SpecificEnthalpySensor
+SpecificEntropySensor
+MassFractionSensor
+MassFractionsSensor
+RelativeHumiditySensor
+ThermodynamicStateSensor
+MassFlowRateSensor
+VolumeFlowRateSensor
+PressureDifferenceSensor
+TemperatureDifferenceSensor
+Tester
diff --git a/SorpLib/Components/Sensors/LiquidSensors/DensitySensor.mo b/SorpLib/Components/Sensors/LiquidSensors/DensitySensor.mo
new file mode 100644
index 0000000..e444ef0
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/DensitySensor.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model DensitySensor "Density sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.DensitySensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This density sensor reads the density in kg/m<sup>3</sup>. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DensitySensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/MassFlowRateSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/MassFlowRateSensor.mo
new file mode 100644
index 0000000..250bfb3
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/MassFlowRateSensor.mo
@@ -0,0 +1,41 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model MassFlowRateSensor "Mass flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFlowRateSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass flow rate sensor reads the mass flow rate in kg/s. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  Added functionality and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={28,108,200},
+          thickness=1)}));
+end MassFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/MassFractionSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/MassFractionSensor.mo
new file mode 100644
index 0000000..b106a02
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/MassFractionSensor.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model MassFractionSensor "Mass fraction sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFractionSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fraction sensor reads the mass fraction of the specified component in 
+kg/kg. It is possible to select that the sensor value <i>value</i> is delayed by 
+using a time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MassFractionSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/MassFractionsSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/MassFractionsSensor.mo
new file mode 100644
index 0000000..bd03ffb
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/MassFractionsSensor.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model MassFractionsSensor "Mass fractions sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFractionsSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fractions sensor reads all mass fractions in kg/kg. It is possible to 
+select that the sensor values <i>value</i> are delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces dynamic states variable, it can be used to break 
+algebraic loops. The non-delayed sensor values can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MassFractionsSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/PressureDifferenceSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/PressureDifferenceSensor.mo
new file mode 100644
index 0000000..fdd25db
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/PressureDifferenceSensor.mo
@@ -0,0 +1,38 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model PressureDifferenceSensor "Pressure difference sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.PressureDifferenceSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure difference sensor reads the pressure difference in Pa. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={28,108,200},
+          thickness=1)}));
+end PressureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/PressureSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/PressureSensor.mo
new file mode 100644
index 0000000..8fa4104
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/PressureSensor.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model PressureSensor "Pressure sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.PressureSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure sensor reads the pressure temperature in Pa. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PressureSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/SpecificEnthalpySensor.mo b/SorpLib/Components/Sensors/LiquidSensors/SpecificEnthalpySensor.mo
new file mode 100644
index 0000000..ff1a37e
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/SpecificEnthalpySensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model SpecificEnthalpySensor "Specific enthalpy sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.SpecificEnthalpySensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific enthalpy sensor reads the specific enthalpy in J/kg. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificEnthalpySensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/SpecificEntropySensor.mo b/SorpLib/Components/Sensors/LiquidSensors/SpecificEntropySensor.mo
new file mode 100644
index 0000000..a7852a7
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/SpecificEntropySensor.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model SpecificEntropySensor "Specific entropy sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.SpecificEntropySensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific entropy sensor reads the specific entropy in J/kg/K. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificEntropySensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/TemperatureDifferenceSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/TemperatureDifferenceSensor.mo
new file mode 100644
index 0000000..1b3b3f3
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/TemperatureDifferenceSensor.mo
@@ -0,0 +1,38 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model TemperatureDifferenceSensor "Temperature difference sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.TemperatureDifferenceSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature difference sensor reads the temperature difference in K. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={28,108,200},
+          thickness=1)}));
+end TemperatureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/TemperatureSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/TemperatureSensor.mo
new file mode 100644
index 0000000..4833edd
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/TemperatureSensor.mo
@@ -0,0 +1,33 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model TemperatureSensor "Temperature sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.TemperatureSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature sensor reads the absolute temperature in K. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TemperatureSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/Tester/Test_LiquidSensors.mo b/SorpLib/Components/Sensors/LiquidSensors/Tester/Test_LiquidSensors.mo
new file mode 100644
index 0000000..79b4479
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/Tester/Test_LiquidSensors.mo
@@ -0,0 +1,218 @@
+within SorpLib.Components.Sensors.LiquidSensors.Tester;
+model Test_LiquidSensors "Tester for liquid sensors"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true) "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    use_TInput=true) "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of sensors
+  //
+  SorpLib.Components.Sensors.LiquidSensors.PressureSensor pSensor
+    "Pressure sensor"
+    annotation (Placement(transformation(extent={{-50,-2},{-30,18}})));
+  SorpLib.Components.Sensors.LiquidSensors.TemperatureSensor TSensor_a
+    "Temperature sensor at port a"
+    annotation (Placement(transformation(extent={{-50,58},{-30,78}})));
+  SorpLib.Components.Sensors.LiquidSensors.TemperatureSensor TSensor_b(
+      useTimeConstant=true, tau=10) "Temperature sensor at port b"
+    annotation (Placement(transformation(extent={{30,-82},{50,-62}})));
+  SorpLib.Components.Sensors.LiquidSensors.DensitySensor rhoSensor_a
+    "Density sensor at port a"
+    annotation (Placement(transformation(extent={{-30,58},{-10,78}})));
+  SorpLib.Components.Sensors.LiquidSensors.DensitySensor rhoSensor_b(
+      useTimeConstant=true, tau=10) "Density sensor at port b"
+    annotation (Placement(transformation(extent={{10,-82},{30,-62}})));
+  SorpLib.Components.Sensors.LiquidSensors.SpecificEnthalpySensor hSensor_a
+    "Specific enthalpy sensor at port a"
+    annotation (Placement(transformation(extent={{-10,58},{10,78}})));
+  SorpLib.Components.Sensors.LiquidSensors.SpecificEnthalpySensor hSensor_b(
+      useTimeConstant=true, tau=10) "Specific enthalpy sensor at port b"
+    annotation (Placement(transformation(extent={{-10,-82},{10,-62}})));
+  SorpLib.Components.Sensors.LiquidSensors.SpecificEntropySensor sSensor_a
+    "Specific entropy sensor at port a"
+    annotation (Placement(transformation(extent={{10,58},{30,78}})));
+  SorpLib.Components.Sensors.LiquidSensors.SpecificEntropySensor sSensor_b(
+      useTimeConstant=true, tau=10) "Specific entropy sensor at port b"
+    annotation (Placement(transformation(extent={{-30,-82},{-10,-62}})));
+  SorpLib.Components.Sensors.LiquidSensors.MassFractionsSensor xiSensor_a
+    "Mass fractions sensor at port a"
+    annotation (Placement(transformation(extent={{30,58},{50,78}})));
+  SorpLib.Components.Sensors.LiquidSensors.MassFractionsSensor xiSensor_b(
+      useTimeConstant=true, tau=10) "Mass fractions sensor at port b"
+    annotation (Placement(transformation(extent={{-50,-82},{-30,-62}})));
+  SorpLib.Components.Sensors.LiquidSensors.ThermodynamicStateSensor stateSensor_a
+    "Thermodynamic state sensor at port a"
+    annotation (Placement(transformation(extent={{50,58},{70,78}})));
+  SorpLib.Components.Sensors.LiquidSensors.ThermodynamicStateSensor stateSensor_b
+    "Thermodynamic state sensor at port b"
+    annotation (Placement(transformation(extent={{-70,-82},{-50,-62}})));
+
+  SorpLib.Components.Sensors.LiquidSensors.MassFlowRateSensor mFlowSensor
+    "Mass flow rate sensor"
+    annotation (Placement(transformation(extent={{-30,-2},{-10,18}})));
+  SorpLib.Components.Sensors.LiquidSensors.VolumeFlowRateSensor VFlowSensor
+    "Volume flow rate sensor"
+    annotation (Placement(transformation(extent={{-10,-2},{10,18}})));
+  SorpLib.Components.Sensors.LiquidSensors.PressureDifferenceSensor dpSensor
+    "Pressure difference sensor"
+    annotation (Placement(transformation(extent={{10,-2},{30,18}})));
+  SorpLib.Components.Sensors.LiquidSensors.TemperatureDifferenceSensor dTSensor
+    "Temperature difference sensor"
+    annotation (Placement(transformation(extent={{30,-2},{50,18}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_mFlowVar(
+    height=60/60,
+    duration=2500,
+    offset=-30/60,
+    startTime=0)
+    "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{-100,10},{-80,30}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_TVar_a(
+    height=80,
+    duration=2500,
+    offset=293.15,
+    startTime=0)
+    "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,-30}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=9e5,
+    duration=2500,
+    offset=1e5,
+    startTime=0)
+    "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{100,10},{80,30}})),
+    HideResult=true);
+  Modelica.Blocks.Sources.Sine input_TVar_b(
+    amplitude=25,
+    f=1/250,
+    offset=273.15 + 50)
+    "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{100,-10},{80,-30}})),
+    HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(input_mFlowVar.y, fs_a.m_flow_input) annotation (Line(points={{-79,20},
+          {-70,20},{-70,2},{-61.2,2}}, color={0,0,127}));
+  connect(input_TVar_a.y, fs_a.T_input) annotation (Line(points={{-79,-20},{-70,
+          -20},{-70,-2},{-61.2,-2}}, color={0,0,127}));
+  connect(input_pVar.y, fs_b.p_input) annotation (Line(points={{79,20},{70,20},{
+          70,5},{61.2,5}}, color={0,0,127}));
+  connect(input_TVar_b.y, fs_b.T_input) annotation (Line(points={{79,-20},{70,-20},
+          {70,-2},{61.2,-2}}, color={0,0,127}));
+
+  connect(fs_a.port, TSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{-40,60}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a.port, rhoSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{-20,60}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a.port, hSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{0,60}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a.port, sSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{20,60}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a.port, xiSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{40,60}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a.port, stateSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{60,60}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, TSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{40,-80}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, rhoSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{20,-80}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, hSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{0,-80}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, sSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-20,-80}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, xiSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-40,-80}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b.port, stateSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-60,-80}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a.port, pSensor.port) annotation (Line(
+      points={{-60,0},{-40,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(pSensor.port, mFlowSensor.port_a) annotation (Line(
+      points={{-40,0},{-25,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(mFlowSensor.port_b, VFlowSensor.port_a) annotation (Line(
+      points={{-15,0},{-5,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(VFlowSensor.port_b, dpSensor.port_a) annotation (Line(
+      points={{5,0},{15,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(dpSensor.port_b, dTSensor.port_a) annotation (Line(
+      points={{25,0},{35,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(dTSensor.port_b, fs_b.port) annotation (Line(
+      points={{45,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks all liquid sensors.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidSensors;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/Tester/package.mo b/SorpLib/Components/Sensors/LiquidSensors/Tester/package.mo
new file mode 100644
index 0000000..4d4d46f
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+package Tester "Models to test and varify models for liquid sensors"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented liquid
+sensors. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/Tester/package.order b/SorpLib/Components/Sensors/LiquidSensors/Tester/package.order
new file mode 100644
index 0000000..0620693
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/Tester/package.order
@@ -0,0 +1 @@
+Test_LiquidSensors
diff --git a/SorpLib/Components/Sensors/LiquidSensors/ThermodynamicStateSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/ThermodynamicStateSensor.mo
new file mode 100644
index 0000000..228c169
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/ThermodynamicStateSensor.mo
@@ -0,0 +1,28 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model ThermodynamicStateSensor "Thermodynamic state sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.ThermodynamicStateSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This thermodynamic state sensor reads all thermodynamic state variables. I.e.,
+pressure <i>p</i>, temperature <i>T</i>, specific volume <i>v</i>, specific
+enthalpy <i>h</i>, specific internal energy <i>u</i>, specific entropy <i>s</i>,
+specific free enthalpy (i.e., Gibbs free energy <i>g</i>, and specific free 
+energy (i.e., Helmholts free energy) <i>a</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ThermodynamicStateSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/VolumeFlowRateSensor.mo b/SorpLib/Components/Sensors/LiquidSensors/VolumeFlowRateSensor.mo
new file mode 100644
index 0000000..c95475b
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/VolumeFlowRateSensor.mo
@@ -0,0 +1,37 @@
+within SorpLib.Components.Sensors.LiquidSensors;
+model VolumeFlowRateSensor "Volume flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.VolumeFlowRateSensor(
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.WaterIF97_R1pT);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This volume flow rate sensor reads the volume flow rate in m<sup>3</sup>/s. It 
+is possible to select that the sensor value <i>value</i> is delayed by using a 
+time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={28,108,200},
+          thickness=1)}));
+end VolumeFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/package.mo b/SorpLib/Components/Sensors/LiquidSensors/package.mo
new file mode 100644
index 0000000..f3f590e
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Components.Sensors;
+package LiquidSensors "Liquid sensors"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains liquid sensors based on the open-source Modelica Standard
+Library (MSL). It implements absolute sensors, which are only connected to one 
+fluid port, as well as relative and flow sensors, which are connected between 
+two fluid ports.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end LiquidSensors;
diff --git a/SorpLib/Components/Sensors/LiquidSensors/package.order b/SorpLib/Components/Sensors/LiquidSensors/package.order
new file mode 100644
index 0000000..675912c
--- /dev/null
+++ b/SorpLib/Components/Sensors/LiquidSensors/package.order
@@ -0,0 +1,13 @@
+PressureSensor
+TemperatureSensor
+DensitySensor
+SpecificEnthalpySensor
+SpecificEntropySensor
+MassFractionSensor
+MassFractionsSensor
+ThermodynamicStateSensor
+MassFlowRateSensor
+VolumeFlowRateSensor
+PressureDifferenceSensor
+TemperatureDifferenceSensor
+Tester
diff --git a/SorpLib/Components/Sensors/ThermalSensors/DifferenceTemperatureSensor.mo b/SorpLib/Components/Sensors/ThermalSensors/DifferenceTemperatureSensor.mo
new file mode 100644
index 0000000..668a9f4
--- /dev/null
+++ b/SorpLib/Components/Sensors/ThermalSensors/DifferenceTemperatureSensor.mo
@@ -0,0 +1,87 @@
+within SorpLib.Components.Sensors.ThermalSensors;
+model DifferenceTemperatureSensor
+  "Difference temperature sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialSensor(
+    value_initial=0);
+
+  //
+  // Definition of parameters
+  //
+  parameter Boolean flowDirectionAB = true
+    " = true, temperature difference is calculated between port a and b (i.e., 
+    positive value); otherwise, temperature difference is claculated between port
+    b and a"
+    annotation (Dialog(tab="General", group="Sensor Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition of ports
+  //
+  Basics.Interfaces.HeatPorts.HeatPort_in port_a
+    annotation (Placement(transformation(extent={{-60,-90},{-40,-70}}),
+                iconTransformation(extent={{-60,-90},{-40,-70}})));
+
+  Basics.Interfaces.HeatPorts.HeatPort_out port_b
+    annotation (Placement(transformation(extent={{40,-90},{60,-70}}),
+                iconTransformation(extent={{40,-90},{60,-70}})));
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = if flowDirectionAB then port_a.T-port_b.T else port_b.T-port_a.T
+    "Temperature";
+
+  port_a.Q_flow = 0
+    "Heat flow rate";
+  port_b.Q_flow = 0
+    "Heat flow rate";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This difference temperature sensor reads the difference temperature between port
+a and b or b and a in K. It is possible to select that the sensor value <i>value</i> 
+is delayed by using a time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-40,60},{40,-40}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="ΔT"),    Line(
+          points={{-52,-80},{50,-80}},
+          color={238,46,47},
+          thickness=1),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value,significantDigits=3) + " K")}));
+end DifferenceTemperatureSensor;
diff --git a/SorpLib/Components/Sensors/ThermalSensors/HeatFlowRateSensor.mo b/SorpLib/Components/Sensors/ThermalSensors/HeatFlowRateSensor.mo
new file mode 100644
index 0000000..f0e9524
--- /dev/null
+++ b/SorpLib/Components/Sensors/ThermalSensors/HeatFlowRateSensor.mo
@@ -0,0 +1,88 @@
+within SorpLib.Components.Sensors.ThermalSensors;
+model HeatFlowRateSensor "Heat flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialSensor(
+    value_initial=0);
+
+  //
+  // Definition of parameters
+  //
+  parameter Boolean flowDirectionAB = true
+    " = true, if heat flows from port a to b (i.e., positive value); otherwise,
+    heat flows from port b to a"
+    annotation (Dialog(tab="General", group="Sensor Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition of ports
+  //
+  Basics.Interfaces.HeatPorts.HeatPort_in port_a
+    annotation (Placement(transformation(extent={{-60,-90},{-40,-70}}),
+                iconTransformation(extent={{-60,-90},{-40,-70}})));
+
+  Basics.Interfaces.HeatPorts.HeatPort_out port_b
+    annotation (Placement(transformation(extent={{40,-90},{60,-70}}),
+                iconTransformation(extent={{40,-90},{60,-70}})));
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = if flowDirectionAB then port_a.Q_flow else port_b.Q_flow
+    "Heat flow rate";
+
+  //
+  // Connections
+  //
+  connect(port_a, port_b) annotation (Line(
+      points={{-50,-80},{50,-80}},
+      color={238,46,47},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This heat flow rate sensor reads the heat flow rate at port a or b in W. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time 
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,50},{50,-30}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="Q̇"),    Line(
+          points={{-52,-80},{50,-80}},
+          color={238,46,47},
+          thickness=1),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value,significantDigits=3) + " W")}));
+end HeatFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/ThermalSensors/TemperatureSensor.mo b/SorpLib/Components/Sensors/ThermalSensors/TemperatureSensor.mo
new file mode 100644
index 0000000..51e69dc
--- /dev/null
+++ b/SorpLib/Components/Sensors/ThermalSensors/TemperatureSensor.mo
@@ -0,0 +1,65 @@
+within SorpLib.Components.Sensors.ThermalSensors;
+model TemperatureSensor
+  "Temperature sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialSensor(
+    value_initial=298.15);
+
+  //
+  // Definition of ports
+  //
+  Basics.Interfaces.HeatPorts.HeatPort_in port
+    annotation (Placement(transformation(extent={{-10,-90},{10,-70}}),
+                iconTransformation(extent={{-10,-90},{10,-70}})));
+
+equation
+  //
+  // Set port values
+  //
+  port.T = valueNonDelayed
+    "Temperature";
+  port.Q_flow = 0
+    "Heat flow rate";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature sensor reads the absolute temperature in K. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,60},{50,-40}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="T"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value-273.15,significantDigits=3) + " °C")}));
+end TemperatureSensor;
diff --git a/SorpLib/Components/Sensors/ThermalSensors/Tester/Test_ThermalSensors.mo b/SorpLib/Components/Sensors/ThermalSensors/Tester/Test_ThermalSensors.mo
new file mode 100644
index 0000000..5a5a0c0
--- /dev/null
+++ b/SorpLib/Components/Sensors/ThermalSensors/Tester/Test_ThermalSensors.mo
@@ -0,0 +1,108 @@
+within SorpLib.Components.Sensors.ThermalSensors.Tester;
+model Test_ThermalSensors "Tester for thermal sensors"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  Basics.Sources.Thermal.HeatSource hp_TVar(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true)
+    "Heat source with variable temperature"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  Basics.Sources.Thermal.HeatSource hp_QVar(
+    boundaryType=SorpLib.Choices.BoundaryThermal.HeatFlowRate,
+    use_QFlowInput=true)
+    "Heat source with variable heat flow"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of sensors
+  //
+  TemperatureSensor TSensor_hp_TVar
+    "Temperatur sensor at thermal source 'hp_TVar'"
+    annotation (Placement(transformation(extent={{-50,-2},{-30,18}})));
+  DifferenceTemperatureSensor DTSensor "Difference temperature sensor"
+    annotation (Placement(transformation(extent={{-10,18},{10,38}})));
+  HeatFlowRateSensor QFlowSensor "Heat flow rate sensor"
+    annotation (Placement(transformation(extent={{-10,-2},{10,18}})));
+  TemperatureSensor TSensor_hp_QVar(useTimeConstant=true, tau=25,
+    value_initial=293.15)
+    "Temperatur sensor at thermal source 'hp_QVar'"
+    annotation (Placement(transformation(extent={{30,-2},{50,18}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_TVar(
+    height=80,
+    duration=2500,
+    offset=293.15,
+    startTime=0)
+    "Ramp to simulate input signal of temperrature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_QVar(
+    height=2000,
+    duration=2500,
+    offset=-1000,
+    startTime=0)
+    "Ramp to simulate input signal of heat flow"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})),
+    HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(hp_TVar.port, TSensor_hp_TVar.port) annotation (Line(
+      points={{-60,0},{-40,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(hp_QVar.port, TSensor_hp_QVar.port) annotation (Line(
+      points={{60,0},{40,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(hp_TVar.port, QFlowSensor.port_a) annotation (Line(
+      points={{-60,0},{-5,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(QFlowSensor.port_b, hp_QVar.port) annotation (Line(
+      points={{5,0},{60,0}},
+      color={238,46,47},
+      thickness=1));
+  connect(hp_TVar.port, DTSensor.port_a) annotation (Line(
+      points={{-60,0},{-22,0},{-22,20},{-5,20}},
+      color={238,46,47},
+      thickness=1));
+  connect(DTSensor.port_b, hp_QVar.port) annotation (Line(
+      points={{5,20},{20,20},{20,0},{60,0}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_TVar.y, hp_TVar.T_input) annotation (Line(points={{-79,0},{-70,0},{
+          -70,5.2},{-61,5.2}},      color={0,0,127}));
+  connect(input_QVar.y, hp_QVar.Q_flow_input) annotation (Line(points={{79,0},{70,0},
+          {70,-6},{61,-6},{61,-5}},         color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks all thermal sensors.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ThermalSensors;
diff --git a/SorpLib/Components/Sensors/ThermalSensors/Tester/package.mo b/SorpLib/Components/Sensors/ThermalSensors/Tester/package.mo
new file mode 100644
index 0000000..f8cbeb5
--- /dev/null
+++ b/SorpLib/Components/Sensors/ThermalSensors/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Sensors.ThermalSensors;
+package Tester "Models to test and varify models for thermal sensors"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented thermal
+sensors. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Sensors/ThermalSensors/Tester/package.order b/SorpLib/Components/Sensors/ThermalSensors/Tester/package.order
new file mode 100644
index 0000000..c1325a9
--- /dev/null
+++ b/SorpLib/Components/Sensors/ThermalSensors/Tester/package.order
@@ -0,0 +1 @@
+Test_ThermalSensors
diff --git a/SorpLib/Components/Sensors/ThermalSensors/package.mo b/SorpLib/Components/Sensors/ThermalSensors/package.mo
new file mode 100644
index 0000000..c05fb6d
--- /dev/null
+++ b/SorpLib/Components/Sensors/ThermalSensors/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Sensors;
+package ThermalSensors "Thermal sensors"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains thermal sensors. It implements absolute sensors, which 
+are only connected to one thermal port, as well as relative and flow sensors, 
+which are connected between two thermal ports.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ThermalSensors;
diff --git a/SorpLib/Components/Sensors/ThermalSensors/package.order b/SorpLib/Components/Sensors/ThermalSensors/package.order
new file mode 100644
index 0000000..bafaf60
--- /dev/null
+++ b/SorpLib/Components/Sensors/ThermalSensors/package.order
@@ -0,0 +1,4 @@
+TemperatureSensor
+DifferenceTemperatureSensor
+HeatFlowRateSensor
+Tester
diff --git a/SorpLib/Components/Sensors/VLESensors/DensitySensor.mo b/SorpLib/Components/Sensors/VLESensors/DensitySensor.mo
new file mode 100644
index 0000000..d639c42
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/DensitySensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.VLESensors;
+model DensitySensor "Density sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.DensitySensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This density sensor reads the density in kg/m<sup>3</sup>. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DensitySensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/MassFlowRateSensor.mo b/SorpLib/Components/Sensors/VLESensors/MassFlowRateSensor.mo
new file mode 100644
index 0000000..7df5298
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/MassFlowRateSensor.mo
@@ -0,0 +1,42 @@
+within SorpLib.Components.Sensors.VLESensors;
+model MassFlowRateSensor "Mass flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFlowRateSensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass flow rate sensor reads the mass flow rate in kg/s. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  Added functionality and documentation.
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={0,140,72},
+          thickness=1)}));
+end MassFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/MassFractionSensor.mo b/SorpLib/Components/Sensors/VLESensors/MassFractionSensor.mo
new file mode 100644
index 0000000..2396d4e
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/MassFractionSensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.VLESensors;
+model MassFractionSensor "Mass fraction sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFractionSensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fraction sensor reads the mass fraction of the specified component in 
+kg/kg. It is possible to select that the sensor value <i>value</i> is delayed by 
+using a time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MassFractionSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/MassFractionsSensor.mo b/SorpLib/Components/Sensors/VLESensors/MassFractionsSensor.mo
new file mode 100644
index 0000000..95a1a6f
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/MassFractionsSensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.VLESensors;
+model MassFractionsSensor "Mass fractions sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.MassFractionsSensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This mass fractions sensor reads all mass fractions in kg/kg. It is possible to 
+select that the sensor values <i>value</i> are delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces dynamic states variable, it can be used to break 
+algebraic loops. The non-delayed sensor values can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MassFractionsSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/PressureDifferenceSensor.mo b/SorpLib/Components/Sensors/VLESensors/PressureDifferenceSensor.mo
new file mode 100644
index 0000000..64ecafa
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/PressureDifferenceSensor.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.Sensors.VLESensors;
+model PressureDifferenceSensor "Pressure difference sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.PressureDifferenceSensor(
+      redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.StandardWater
+        constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure difference sensor reads the pressure difference in Pa. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={0,140,72},
+          thickness=1)}));
+end PressureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/PressureSensor.mo b/SorpLib/Components/Sensors/VLESensors/PressureSensor.mo
new file mode 100644
index 0000000..76ee497
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/PressureSensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.VLESensors;
+model PressureSensor "Pressure sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.PressureSensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This pressure sensor reads the pressure temperature in Pa. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PressureSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/SpecificEnthalpySensor.mo b/SorpLib/Components/Sensors/VLESensors/SpecificEnthalpySensor.mo
new file mode 100644
index 0000000..d167a6f
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/SpecificEnthalpySensor.mo
@@ -0,0 +1,35 @@
+within SorpLib.Components.Sensors.VLESensors;
+model SpecificEnthalpySensor "Specific enthalpy sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.SpecificEnthalpySensor(
+      redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.StandardWater
+        constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific enthalpy sensor reads the specific enthalpy in J/kg. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificEnthalpySensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/SpecificEntropySensor.mo b/SorpLib/Components/Sensors/VLESensors/SpecificEntropySensor.mo
new file mode 100644
index 0000000..3ffb576
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/SpecificEntropySensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.VLESensors;
+model SpecificEntropySensor "Specific entropy sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.SpecificEntropySensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This specific entropy sensor reads the specific entropy in J/kg/K. It is possible 
+to select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificEntropySensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/TemperatureDifferenceSensor.mo b/SorpLib/Components/Sensors/VLESensors/TemperatureDifferenceSensor.mo
new file mode 100644
index 0000000..760833b
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/TemperatureDifferenceSensor.mo
@@ -0,0 +1,39 @@
+within SorpLib.Components.Sensors.VLESensors;
+model TemperatureDifferenceSensor "Temperature difference sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.TemperatureDifferenceSensor(
+      redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+      redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.StandardWater
+        constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature difference sensor reads the temperature difference in K. It is 
+possible to select that the sensor value <i>value</i> is delayed by using a time  
+constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={0,140,72},
+          thickness=1)}));
+end TemperatureDifferenceSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/TemperatureSensor.mo b/SorpLib/Components/Sensors/VLESensors/TemperatureSensor.mo
new file mode 100644
index 0000000..39cff04
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/TemperatureSensor.mo
@@ -0,0 +1,34 @@
+within SorpLib.Components.Sensors.VLESensors;
+model TemperatureSensor "Temperature sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.TemperatureSensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This temperature sensor reads the absolute temperature in K. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TemperatureSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/Tester/Test_VLESensors.mo b/SorpLib/Components/Sensors/VLESensors/Tester/Test_VLESensors.mo
new file mode 100644
index 0000000..e3e9ed0
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/Tester/Test_VLESensors.mo
@@ -0,0 +1,232 @@
+within SorpLib.Components.Sensors.VLESensors.Tester;
+model Test_VLESensors "Tester for VLE sensors"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.MassFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=true,
+    use_TInput=true) "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource fs_b(
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    use_TInput=true) "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of sensors
+  //
+  SorpLib.Components.Sensors.VLESensors.PressureSensor pSensor
+    "Pressure sensor"
+    annotation (Placement(transformation(extent={{-50,-2},{-30,18}})));
+  SorpLib.Components.Sensors.VLESensors.TemperatureSensor TSensor_a
+    "Temperature sensor at port a"
+    annotation (Placement(transformation(extent={{-50,58},{-30,78}})));
+  SorpLib.Components.Sensors.VLESensors.TemperatureSensor TSensor_b(
+      useTimeConstant=true, tau=10) "Temperature sensor at port b"
+    annotation (Placement(transformation(extent={{30,-82},{50,-62}})));
+  SorpLib.Components.Sensors.VLESensors.DensitySensor rhoSensor_a
+    "Density sensor at port a"
+    annotation (Placement(transformation(extent={{-30,58},{-10,78}})));
+  SorpLib.Components.Sensors.VLESensors.DensitySensor rhoSensor_b(
+      useTimeConstant=true, tau=10) "Density sensor at port b"
+    annotation (Placement(transformation(extent={{10,-82},{30,-62}})));
+  SorpLib.Components.Sensors.VLESensors.SpecificEnthalpySensor hSensor_a
+    "Specific enthalpy sensor at port a"
+    annotation (Placement(transformation(extent={{-10,58},{10,78}})));
+  SorpLib.Components.Sensors.VLESensors.SpecificEnthalpySensor hSensor_b(
+      useTimeConstant=true, tau=10) "Specific enthalpy sensor at port b"
+    annotation (Placement(transformation(extent={{-10,-82},{10,-62}})));
+  SorpLib.Components.Sensors.VLESensors.SpecificEntropySensor sSensor_a
+    "Specific entropy sensor at port a"
+    annotation (Placement(transformation(extent={{10,58},{30,78}})));
+  SorpLib.Components.Sensors.VLESensors.SpecificEntropySensor sSensor_b(
+      useTimeConstant=true, tau=10) "Specific entropy sensor at port b"
+    annotation (Placement(transformation(extent={{-30,-82},{-10,-62}})));
+  SorpLib.Components.Sensors.VLESensors.MassFractionsSensor xiSensor_a
+    "Mass fractions sensor at port a"
+    annotation (Placement(transformation(extent={{30,58},{50,78}})));
+  SorpLib.Components.Sensors.VLESensors.MassFractionsSensor xiSensor_b(
+      useTimeConstant=true, tau=10) "Mass fractions sensor at port b"
+    annotation (Placement(transformation(extent={{-50,-82},{-30,-62}})));
+  SorpLib.Components.Sensors.VLESensors.VaporQualitySensor vaporQuality_a
+    "Vapor quality sensor at port a"
+    annotation (Placement(transformation(extent={{50,58},{70,78}})));
+  SorpLib.Components.Sensors.VLESensors.VaporQualitySensor vaporQuality_b(
+      useTimeConstant=true, tau=10) "Vapor quality sensor at port b"
+    annotation (Placement(transformation(extent={{-70,-82},{-50,-62}})));
+  SorpLib.Components.Sensors.VLESensors.ThermodynamicStateSensor stateSensor_a
+    "Thermodynamic state sensor at port a"
+    annotation (Placement(transformation(extent={{70,58},{90,78}})));
+  SorpLib.Components.Sensors.VLESensors.ThermodynamicStateSensor stateSensor_b
+    "Thermodynamic state sensor at port b"
+    annotation (Placement(transformation(extent={{-90,-82},{-70,-62}})));
+
+  SorpLib.Components.Sensors.VLESensors.MassFlowRateSensor mFlowSensor
+    "Mass flow rate sensor"
+    annotation (Placement(transformation(extent={{-30,-2},{-10,18}})));
+  SorpLib.Components.Sensors.VLESensors.VolumeFlowRateSensor VFlowSensor
+    "Volume flow rate sensor"
+    annotation (Placement(transformation(extent={{-10,-2},{10,18}})));
+  SorpLib.Components.Sensors.VLESensors.PressureDifferenceSensor dpSensor
+    "Pressure difference sensor"
+    annotation (Placement(transformation(extent={{10,-2},{30,18}})));
+  SorpLib.Components.Sensors.VLESensors.TemperatureDifferenceSensor dTSensor
+    "Temperature difference sensor"
+    annotation (Placement(transformation(extent={{30,-2},{50,18}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Ramp input_mFlowVar(
+    height=60/60,
+    duration=2500,
+    offset=-30/60,
+    startTime=0)
+    "Ramp to simulate input signal of mass flow rate"
+    annotation (Placement(transformation(extent={{-100,10},{-80,30}})),
+                HideResult=true);
+  Modelica.Blocks.Sources.Ramp input_TVar_a(
+    height=80,
+    duration=2500,
+    offset=293.15,
+    startTime=0)
+    "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,-30}})),
+                HideResult=true);
+
+  Modelica.Blocks.Sources.Ramp input_pVar(
+    height=-(10e5 - 1e3),
+    duration=2500,
+    offset=10e5,
+    startTime=0)
+    "Ramp to simulate input signal of pressure"
+    annotation (Placement(transformation(extent={{100,10},{80,30}})),
+    HideResult=true);
+  Modelica.Blocks.Sources.Sine input_TVar_b(
+    amplitude=25,
+    f=1/250,
+    offset=273.15 + 50)
+    "Ramp to simulate input signal of temperature"
+    annotation (Placement(transformation(extent={{100,-10},{80,-30}})),
+    HideResult=true);
+
+equation
+  //
+  // Connections
+  //
+  connect(input_mFlowVar.y, fs_a.m_flow_input) annotation (Line(points={{-79,20},
+          {-70,20},{-70,2},{-61.2,2}}, color={0,0,127}));
+  connect(input_TVar_a.y, fs_a.T_input) annotation (Line(points={{-79,-20},{-70,
+          -20},{-70,-2},{-61.2,-2}}, color={0,0,127}));
+  connect(input_pVar.y, fs_b.p_input) annotation (Line(points={{79,20},{70,20},{
+          70,5},{61.2,5}}, color={0,0,127}));
+  connect(input_TVar_b.y, fs_b.T_input) annotation (Line(points={{79,-20},{70,-20},
+          {70,-2},{61.2,-2}}, color={0,0,127}));
+
+  connect(fs_a.port, TSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{-40,60}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a.port, rhoSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{-20,60}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a.port, hSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{0,60}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a.port, sSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{20,60}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a.port, xiSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{40,60}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a.port, stateSensor_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{80,60}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, TSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{40,-80}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, rhoSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{20,-80}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, hSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{0,-80}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, sSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-20,-80}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, xiSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-40,-80}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, stateSensor_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-80,-80}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a.port, pSensor.port) annotation (Line(
+      points={{-60,0},{-40,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(pSensor.port, mFlowSensor.port_a) annotation (Line(
+      points={{-40,0},{-25,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(mFlowSensor.port_b, VFlowSensor.port_a) annotation (Line(
+      points={{-15,0},{-5,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(VFlowSensor.port_b, dpSensor.port_a) annotation (Line(
+      points={{5,0},{15,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(dpSensor.port_b, dTSensor.port_a) annotation (Line(
+      points={{25,0},{35,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(dTSensor.port_b, fs_b.port) annotation (Line(
+      points={{45,0},{60,0}},
+      color={0,140,72},
+      thickness=1));
+
+  //
+  // Annotations
+  //
+  connect(fs_a.port, vaporQuality_a.port) annotation (Line(
+      points={{-60,0},{-50,0},{-50,60},{60,60}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b.port, vaporQuality_b.port) annotation (Line(
+      points={{60,0},{50,0},{50,-80},{-60,-80}},
+      color={0,140,72},
+      thickness=1));
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks all VLE sensors.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_VLESensors;
diff --git a/SorpLib/Components/Sensors/VLESensors/Tester/package.mo b/SorpLib/Components/Sensors/VLESensors/Tester/package.mo
new file mode 100644
index 0000000..06b125a
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components.Sensors.VLESensors;
+package Tester "Models to test and varify models for VLE sensors"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented VLE sensors. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Sensors/VLESensors/Tester/package.order b/SorpLib/Components/Sensors/VLESensors/Tester/package.order
new file mode 100644
index 0000000..16d6c0b
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/Tester/package.order
@@ -0,0 +1 @@
+Test_VLESensors
diff --git a/SorpLib/Components/Sensors/VLESensors/ThermodynamicStateSensor.mo b/SorpLib/Components/Sensors/VLESensors/ThermodynamicStateSensor.mo
new file mode 100644
index 0000000..9c62726
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/ThermodynamicStateSensor.mo
@@ -0,0 +1,53 @@
+within SorpLib.Components.Sensors.VLESensors;
+model ThermodynamicStateSensor "Thermodynamic state sensor"
+  extends
+    SorpLib.Components.Sensors.BaseClasses.FluidMSL.ThermodynamicStateSensor(
+      redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+      redeclare replaceable package Medium =
+        Modelica.Media.Water.StandardWater
+        constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Definition of variables
+  //
+  Real q(unit="kg/kg")
+    "Vapor quality";
+
+protected
+  Medium.SaturationProperties sat = Medium.setSat_p(p=p)
+    "Saturation state";
+
+  Modelica.Units.SI.SpecificEnthalpy h_sat_liq=
+    Medium.bubbleEnthalpy(sat=sat)
+    "Specific bubble point enthalpy";
+  Modelica.Units.SI.SpecificEnthalpy h_sat_vap=
+    Medium.dewEnthalpy(sat=sat)
+    "Specific dew point enthalpy";
+
+equation
+  //
+  // Calculate properties
+  //
+  q = max(0, min((h - h_sat_liq) / (h_sat_vap - h_sat_liq), 1))
+    "Vapor quality";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This thermodynamic state sensor reads all thermodynamic state variables. I.e.,
+pressure <i>p</i>, temperature <i>T</i>, specific volume <i>v</i>, specific
+enthalpy <i>h</i>, specific internal energy <i>u</i>, specific entropy <i>s</i>,
+specific free enthalpy (i.e., Gibbs free energy <i>g</i>, and specific free 
+energy (i.e., Helmholts free energy) <i>a</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ThermodynamicStateSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/VaporQualitySensor.mo b/SorpLib/Components/Sensors/VLESensors/VaporQualitySensor.mo
new file mode 100644
index 0000000..7cdcea4
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/VaporQualitySensor.mo
@@ -0,0 +1,84 @@
+within SorpLib.Components.Sensors.VLESensors;
+model VaporQualitySensor
+  "Vapor quality (i.e., mass fraction) sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.PartialAbsoluteFluidSensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port,
+    final no_components=Medium.nX,
+    value_initial=0.1);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.SaturationProperties sat = Medium.setSat_p(p=port.p)
+    "Saturation state";
+
+  Modelica.Units.SI.SpecificEnthalpy h_sat_liq=
+    Medium.bubbleEnthalpy(sat=sat)
+    "Specific bubble point enthalpy";
+  Modelica.Units.SI.SpecificEnthalpy h_sat_vap=
+    Medium.dewEnthalpy(sat=sat)
+    "Specific dew point enthalpy";
+
+equation
+  //
+  // Set port values
+  //
+  valueNonDelayed = max(0,
+    min((inStream(port.h_outflow) - h_sat_liq) / (h_sat_vap - h_sat_liq), 1))
+    "Vapor quality";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This vapor quality sensor reads the vapor quality in kg/kg. It is possible to 
+select that the sensor value <i>value</i> is delayed by using a time constant 
+<i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={    Line(
+          points={{0,-40},{0,-80}},
+          color={0,0,0},
+          thickness=1), Text(
+          extent={{-50,74},{50,-26}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="q"),
+        Text(
+          extent={{10,80},{90,60}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString=String(value,significantDigits=3) + " kg/kg")}));
+end VaporQualitySensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/VolumeFlowRateSensor.mo b/SorpLib/Components/Sensors/VLESensors/VolumeFlowRateSensor.mo
new file mode 100644
index 0000000..235e8e7
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/VolumeFlowRateSensor.mo
@@ -0,0 +1,38 @@
+within SorpLib.Components.Sensors.VLESensors;
+model VolumeFlowRateSensor "Volume flow rate sensor"
+  extends SorpLib.Components.Sensors.BaseClasses.FluidMSL.VolumeFlowRateSensor(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This volume flow rate sensor reads the volume flow rate in m<sup>3</sup>/s. It 
+is possible to select that the sensor value <i>value</i> is delayed by using a 
+time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={Line(
+          points={{-50,-80},{50,-80}},
+          color={0,140,72},
+          thickness=1)}));
+end VolumeFlowRateSensor;
diff --git a/SorpLib/Components/Sensors/VLESensors/package.mo b/SorpLib/Components/Sensors/VLESensors/package.mo
new file mode 100644
index 0000000..44af2ff
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Components.Sensors;
+package VLESensors "VLE sensors"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains VLE sensors based on the open-source Modelica Standard
+Library (MSL). It implements absolute sensors, which are only connected to one 
+fluid port, as well as relative and flow sensors, which are connected between 
+two fluid ports.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 18, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end VLESensors;
diff --git a/SorpLib/Components/Sensors/VLESensors/package.order b/SorpLib/Components/Sensors/VLESensors/package.order
new file mode 100644
index 0000000..fcf07b9
--- /dev/null
+++ b/SorpLib/Components/Sensors/VLESensors/package.order
@@ -0,0 +1,14 @@
+PressureSensor
+TemperatureSensor
+DensitySensor
+SpecificEnthalpySensor
+SpecificEntropySensor
+MassFractionSensor
+MassFractionsSensor
+VaporQualitySensor
+ThermodynamicStateSensor
+MassFlowRateSensor
+VolumeFlowRateSensor
+PressureDifferenceSensor
+TemperatureDifferenceSensor
+Tester
diff --git a/SorpLib/Components/Sensors/package.mo b/SorpLib/Components/Sensors/package.mo
new file mode 100644
index 0000000..433ee7a
--- /dev/null
+++ b/SorpLib/Components/Sensors/package.mo
@@ -0,0 +1,203 @@
+within SorpLib.Components;
+package Sensors "Ideal sensors to extract signals from interfaces"
+extends Modelica.Icons.SensorsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains ideal sensors to measure thermal, thermo-physical, or 
+hydraulic values. The sensors are ideal, meaning that they do not influence the
+model they are connected to. There are three types of sensors. Absolute sensors 
+are connected to one port and measure state variables. Relative sensors are 
+connected to two ports and measure the difference between two state variables. 
+Flow sensors are connected to two ports and measure flow variables.
+</p>
+
+<h4>Main equations</h4>
+<p>
+It is possible to select that the sensor value <i>value</i> is delayed by using 
+a time constant <i>tau</i>:
+</p>
+<pre>
+    (dvalue/dt) = (valueNonDelayed - value) / tau;
+</pre>
+<p>
+Although this introduces a dynamic state variable, it can be used to break 
+algebraic loops. The non-delayed sensor value can be accessed via the variable
+<i>valueNonDelayed</i>.
+</p>
+
+<h4>Implemented sensors</h4>
+<p>
+Three sensors are implemented for thermal ports:
+</p>
+<ul>
+  <li>
+  <i>Temperature</i>: Measures the temperature (absolute sensor).
+  </li>
+  <li>
+  <i>Difference temperatures</i>: Measures the difference temperature between two
+  pots (relative sensor).
+  </li>
+  <li>
+  <i>Heat flow rate</i>: Measures the heat flow rate (flow sensor).
+  </li>
+</ul>
+<p>
+The following sensors are implemented for fluid ports:
+<br/>
+</p>
+<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">
+  <thead>
+    <tr>
+      <th><b>Sensor</b></th>
+      <th><b>Type</b></th>
+      <th><b>Liquid</b></th>
+      <th><b>Gas / Gas mixture</b></th>
+      <th><b>Gas-vapor mixture</b></th>
+      <th><b>VLE</b></th>
+    </tr>
+  </thead>
+  <tbody>
+    <tr>
+      <td>Pressure</td>
+      <td>Absolute</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Temperature</td>
+      <td>Absolute</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Density</td>
+      <td>Absolute</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Specific enthalpy</td>
+      <td>Absolute</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Specific entropy</td>
+      <td>Absolute</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Mass fraction</td>
+      <td>Absolute</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Mass fractions</td>
+      <td>Absolute</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Vapor quality</td>
+      <td>Absolute</td>
+      <td></td>
+      <td></td>
+      <td>X</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>Relative humidity</td>
+      <td>Absolute</td>
+      <td></td>
+      <td></td>
+      <td>X</td>
+      <td></td>
+    </tr>
+    <tr>
+      <td>Thermodynamic state</td>
+      <td>Absolute</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Mass flow rate</td>
+      <td>Flow</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Volume flow rate</td>
+      <td>Flow</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Pressure difference</td>
+      <td>Relative</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+    <tr>
+      <td>Temperature difference</td>
+      <td>Relative</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+      <td>X</td>
+    </tr>
+  </tbody>
+</table>
+
+<h4>Typical use</h4>
+<p>
+The sensors are typically used to measure quantities for controllers or 
+thermal/fluid boundaries.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useTimeConstant</i>:
+  The sensor value is returned with a delay by using a time constant.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The sensors have a dynamic state (i.e., <i>value</i> ) when a time constant is 
+used. Otherwise, there is no dynamic state.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Sensors;
diff --git a/SorpLib/Components/Sensors/package.order b/SorpLib/Components/Sensors/package.order
new file mode 100644
index 0000000..2af5697
--- /dev/null
+++ b/SorpLib/Components/Sensors/package.order
@@ -0,0 +1,6 @@
+BaseClasses
+ThermalSensors
+LiquidSensors
+GasSensors
+GasVaporMixtureSenors
+VLESensors
diff --git a/SorpLib/Components/Tubes/BaseClasses/PartialTube.mo b/SorpLib/Components/Tubes/BaseClasses/PartialTube.mo
new file mode 100644
index 0000000..a465788
--- /dev/null
+++ b/SorpLib/Components/Tubes/BaseClasses/PartialTube.mo
@@ -0,0 +1,832 @@
+within SorpLib.Components.Tubes.BaseClasses;
+partial model PartialTube "Base model for all tubes"
+
+  //
+  // Definition of general parameters
+  //
+  parameter Integer no_fluidVolumes(min=2)=10
+    "Discretization number of fluid volumes"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_wallVolumes(min=2)=no_fluidVolumes
+    "Discretization number of wall volumes (must be a factor of no_fluidVolumes)"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the geometry
+  //
+  replaceable parameter SorpLib.Components.Tubes.Records.GeometryTube geometry
+    constrainedby SorpLib.Components.Tubes.Records.GeometryTube(
+      no_fluidVolumes=no_fluidVolumes,
+      no_wallVolumes=no_wallVolumes)
+    "Geometry of the tube"
+    annotation (Dialog(tab = "General", group = "Geoemetry"),
+                choicesAllMatching = true);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of models describing transport phenomena
+  //
+  parameter Boolean useConductionPerpendicularFlowDirection = true
+    " = true, if thermal conduction perpendicular to the flow direction is
+    considered within the wall"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean useConductionFlowDirection = false
+    " = true, if thermal conduction in the flow direction is considered within 
+    the wall"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcFluidTransportProperties = true
+    " = true, if any transport model needs fluid or transport properties"
+    annotation (Dialog(tab="Transport Phenomena", group="General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer fluidPropertyPosition = 1
+    "Defines the position for fluid porperty calculation is discretization number
+    is different"
+    annotation (Dialog(tab="Transport Phenomena", group="General",
+                enable=no_fluidVolumes<>no_wallVolumes),
+                choices(choice=1 "First volume near port a",
+                        choice=2 "First volume near port b",
+                        choice=3 "Properties averaged over volumes"),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model InnerWallThermalConductionPerpendicularFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l/geometry.no_wallVolumes,
+        d_inner=geometry.d_hydInner,
+        d_outer=(geometry.d_hydInner + geometry.d_hydOuter)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction perpendicular to the
+    flow direction within the wall near the fluid"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionPerpendicularFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model OuterWallThermalConductionPerpendicularFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.CylindricalWall
+      ( l_wall=geometry.l/geometry.no_wallVolumes,
+        d_inner=(geometry.d_hydInner + geometry.d_hydOuter)/2,
+        d_outer=geometry.d_hydOuter)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction perpendicular to the
+    flow direction within the wall near the heat port"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionPerpendicularFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+  replaceable model WallThermalConductionFlowDirection =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.Conduction.PlainWall
+      (
+      A_cross=geometry.A_crossWall,
+      delta_wall=(geometry.l/geometry.no_wallVolumes)/2)
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialConductiveHeatTransferCoefficient
+    "Heat transfer correlation describing thermal conduction in the flow direction
+    within the wall"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Conduction",
+                enable = useConductionFlowDirection),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model FluidThermalConvectionTubeInside =
+    SorpLib.Components.HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.GnielinskiDittusBoelter
+    constrainedby
+    SorpLib.Components.HeatTransfer.BaseClasses.PartialTubeInsideHeatTransferCoefficient
+    "Heat transfer correlation describing thermal convection at the tube inside
+    (i.e., form the fluid to the wall)"
+    annotation (Dialog(tab="Transport Phenomena", group="Thermal Convection"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model PressureDrop =
+    SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Konakov
+    constrainedby
+    SorpLib.Components.Fittings.BaseClasses.PartialTubeInsidePressureLoss
+    "Pressure drop correlation describing the pressure drop of the fluid"
+    annotation (Dialog(tab="Transport Phenomena", group="Pressure Drop"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding start values
+  //
+  parameter Modelica.Units.SI.Pressure p_fluidAInitial = 1.25e5
+    "Initial value of fluid pressure at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+  parameter Modelica.Units.SI.Pressure p_fluidBInitial = 1e5
+    "Initial value of fluid pressure at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  parameter Modelica.Units.SI.Temperature T_fluidAInitial = 283.15
+    "Initial value of fluid temperature at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+  parameter Modelica.Units.SI.Temperature T_fluidBInitial = 303.15
+    "Initial value of fluid temperature at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  parameter Modelica.Units.SI.Temperature T_wallAInitial = T_fluidAInitial
+    "Initial value of wall temperature at port a"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+  parameter Modelica.Units.SI.Temperature T_wallBInitial = T_fluidBInitial
+    "Initial value of wall temperature at port b"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"));
+
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter SorpLib.Choices.BalanceEquations type_overallMassBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the overall mass balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BalanceEquations type_independentMassBalances=
+    type_overallMassBalance
+    "Handling of independent mass balances and corresponding initialisations"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.BalanceEquations type_energyBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial
+    "Handling of the energy balance and corresponding initialisation"
+    annotation (Dialog(tab = "Advanced", group = "Conservation Equations"),
+                Evaluate=true,
+                HideResult = true);
+
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Modelica.Units.SI.MassFlowRate m_flow_small = 1e-4
+    "Regularization mass flow rate"
+    annotation (Dialog(tab="Advanced", group="Numerics"));
+  parameter Integer noDiff = 2
+    "Specification how often transition functions can be differentiated"
+    annotation(Dialog(tab = "Advanced", group = "Numerics"),
+              Evaluate=true,
+              HideResult=true);
+
+  //
+  // Definition of protected parameters
+  //
+protected
+  final parameter Integer factorDiscretization=
+    integer(max(no_fluidVolumes,no_wallVolumes)/
+    min(no_fluidVolumes,no_wallVolumes))
+    "Discretization factor"
+    annotation (Dialog(tab = "General", group = "Discretization"),
+                Evaluate=true,
+                HideResult=true);
+
+  final parameter Modelica.Units.SI.Pressure[no_fluidVolumes] p_fluidInitial=
+    linspace(p_fluidAInitial, p_fluidBInitial, no_fluidVolumes)
+    "Initial value of fluid pressures for each volume"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"),
+                HideResult = true);
+  final parameter Modelica.Units.SI.Temperature[no_fluidVolumes] T_fluidInitial=
+    linspace(T_fluidAInitial, T_fluidBInitial, no_fluidVolumes)
+    "Initial value of fluid temperature for each fluid volume"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"),
+                HideResult = true);
+  final parameter Modelica.Units.SI.Temperature[no_wallVolumes] T_wallInitial=
+    linspace(T_wallAInitial, T_wallBInitial, no_wallVolumes)
+    "Initial value of wall temperatures for each wall volume"
+    annotation (Dialog(tab="Initialisation", group="Initial Values"),
+                HideResult = true);
+
+  //
+  // Definition of ports
+  //
+public
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort fp_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-110,-10},{-90,10}}),
+                iconTransformation(extent={{-110,-10},{-90,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort fp_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{90,-10},{110,10}}),
+                iconTransformation(extent={{90,-10},{110,10}})),
+                choicesAllMatching=true);
+
+  SorpLib.Basics.Interfaces.HeatPorts.HeatPort_in[no_wallVolumes] hp_wall
+    "Heat ports at the wall"
+    annotation (Placement(transformation(extent={{-10,30},{10,50}}),
+                iconTransformation(extent={{-10,30},{10,50}})));
+
+  //
+  // Definition and instanziation of models
+  //
+  replaceable SorpLib.Basics.Volumes.BaseClasses.PartialFluidVolume[no_fluidVolumes] fluidVolumes(
+    each independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX,
+    each final calculateAdditionalProperties=calcFluidTransportProperties,
+    each final useHeatPorts=true,
+    each final useHeatPortsX=false,
+    each final useHeatPortsY=true,
+    each final useHeatPortsZ=false,
+    final p_initial=p_fluidInitial,
+    final T_initial=T_fluidInitial,
+    each final mc_flow_initialX=m_flow_start,
+    each final type_energyBalance=type_energyBalance,
+    each final avoid_events=avoid_events,
+    each final type_overallMassBalance=type_overallMassBalance,
+    each final nPorts_cfp_xMinus=1,
+    each final nPorts_cfp_xPlus=1)
+    "Fluid volumes"
+    annotation (Placement(transformation(extent={{-10,-74},{10,-54}})));
+
+  replaceable SorpLib.Basics.Volumes.BaseClasses.PartialVolume[no_wallVolumes] wallVolumes(
+    each final useHeatPortsX=useConductionFlowDirection,
+    each final useHeatPortsY=true,
+    each final useHeatPortsZ=false,
+    each final type_energyBalance=type_energyBalance,
+    each final avoid_events=avoid_events)
+    "Wall volumes"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  SorpLib.Components.HeatTransfer.TubeInsideHeatTransfer[min(no_fluidVolumes,no_wallVolumes)] thermalConvection_fluidToWall(
+    each final n_a=if no_wallVolumes > no_fluidVolumes then 1 elseif
+        no_wallVolumes < no_fluidVolumes then factorDiscretization else 1,
+    each final n_b=if useConductionPerpendicularFlowDirection then 1 elseif
+      no_wallVolumes > no_fluidVolumes then factorDiscretization elseif
+      no_wallVolumes < no_fluidVolumes then 1 else 1,
+    each final geometry=geometry,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        FluidThermalConvectionTubeInside,
+    final fluidProperties=propertiesFluid,
+    final m_hyd_xMinus=m_flow_hyd_xMinus/geometry.no_hydraulicParallelTubes,
+    final m_hyd_xPlus=m_flow_hyd_xPlus/geometry.no_hydraulicParallelTubes)
+    "Thermal convection from fluids to walls"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=90,
+                origin={0,-42})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer[min(no_fluidVolumes,no_wallVolumes)] thermalConduction_fluidToWall(
+    each final n_a=1,
+    each final n_b=if no_wallVolumes < no_fluidVolumes then 1 elseif
+        no_wallVolumes > no_fluidVolumes then factorDiscretization else 1,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        InnerWallThermalConductionPerpendicularFlowDirection,
+    each final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes,
+    final fluidProperties=propertiesWall) if
+    useConductionPerpendicularFlowDirection
+    "Thermal conduction from fluids to walls"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=90,
+                origin={0,-22})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer[no_wallVolumes] thermalConduction_wallToHeatPort(
+    each final n_a=1,
+    each final n_b=1,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        OuterWallThermalConductionPerpendicularFlowDirection,
+    each final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    useConductionPerpendicularFlowDirection
+    "Thermal conduction from wall to heat ports"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=90,
+                origin={0,24})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer[no_wallVolumes-1] thermalConduction_wall1(
+    each final n_a=1,
+    each final n_b=1,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        WallThermalConductionFlowDirection,
+    each final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    useConductionFlowDirection
+    "Thermal conduction of the first wall halfs"
+    annotation (Placement(transformation(extent={{18,-10},{38,10}})));
+
+  SorpLib.Components.HeatTransfer.ConductionHeatTransfer[no_wallVolumes-1] thermalConduction_wall2(
+    each final n_a=1,
+    each final n_b=1,
+    each final calculateFluidProperties=calcFluidTransportProperties,
+    redeclare each final model HeatTransferCoefficient =
+        WallThermalConductionFlowDirection,
+    each final no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes) if
+    useConductionFlowDirection
+    "Thermal conduction of the second wall halfs"
+    annotation (Placement(transformation(extent={{-38,-10},{-18,10}})));
+
+  replaceable SorpLib.Components.Fittings.BaseClasses.PartialResistance[no_fluidVolumes-1] pressureDrop(
+    each final instreamingPropertiesByInput=true,
+    each final dynamicPressureLoss=false,
+    each final geodeticPressureLoss=false,
+    each final frictionPressureLoss=true,
+    final p_a=fluidVolumes[1:no_fluidVolumes-1].fluidProperties.p,
+    final T_a=fluidVolumes[1:no_fluidVolumes-1].fluidProperties.T,
+    final rho_a=1 ./ fluidVolumes[1:no_fluidVolumes-1].fluidProperties.v,
+    final eta_a=fluidVolumes[1:no_fluidVolumes-1].fluidProperties.eta,
+    final p_b_ad=fluidVolumes[2:no_fluidVolumes].fluidProperties.p,
+    final T_b_ad=fluidVolumes[2:no_fluidVolumes].fluidProperties.T,
+    final rho_b_ad=1 ./ fluidVolumes[2:no_fluidVolumes].fluidProperties.v,
+    final eta_b_ad=fluidVolumes[2:no_fluidVolumes].fluidProperties.eta,
+    each final m_flow_start=m_flow_start,
+    each final avoid_events=avoid_events,
+    each final m_flow_small=m_flow_small,
+    each positionFluidProperties=SorpLib.Choices.ResistorFluidProperties.PortAInlet,
+    each fittingPressureLosss=false)
+    "Pressure drop between fluid volumes"
+    annotation (Placement(transformation(extent={{10,-100},{-10,-80}})));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.PressureDifference dp = fp_a.p - fp_b.p
+    "Pressure difference between port a and b";
+
+  Modelica.Units.SI.MassFlowRate m_flow_a = fp_a.m_flow
+    "Mass flow rate at port a";
+  Modelica.Units.SI.MassFlowRate m_flow_b = fp_b.m_flow
+    "Mass flow rate at port b";
+
+  Modelica.Units.SI.HeatFlowRate DH_flow
+    "Difference enthalpy flow rate between port a and port b";
+  Modelica.Units.SI.HeatFlowRate Q_flow_fluidWall=
+    sum(thermalConvection_fluidToWall.Q_flow)
+    "Heat flow rate transferred from the fluid to the eall";
+  Modelica.Units.SI.HeatFlowRate Q_flow_wallHP=
+    -sum(hp_wall.Q_flow)
+    "Heat flow rate transferred from the wall to the heat port";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.Pressure[no_wallVolumes] p_wall
+    "Pressures used to calculate properteis of the wall";
+
+  Modelica.Units.SI.MassFlowRate[min(no_fluidVolumes,no_wallVolumes)] m_flow_hyd_xMinus
+    "Mass flow rates at first volume near port a";
+  Modelica.Units.SI.MassFlowRate[min(no_fluidVolumes,no_wallVolumes)] m_flow_hyd_xPlus
+    "Mass flow rates at first volume near port b";
+
+  SorpLib.Components.HeatTransfer.Records.FluidProperties[min(no_fluidVolumes,no_wallVolumes)] propertiesWall
+    "Media properties used to calcualte conductive heat transfer at fluid side";
+  SorpLib.Components.HeatTransfer.Records.FluidProperties[min(no_fluidVolumes,no_wallVolumes)] propertiesFluid
+    "Media properties used to calcualte convective heat transfer at fluid side";
+
+equation
+  //
+  // Assertations
+  //
+  if no_wallVolumes < no_fluidVolumes then
+    assert(rem(no_fluidVolumes, no_wallVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of fluid volumes!");
+
+  elseif no_wallVolumes > no_fluidVolumes then
+    assert(rem(no_wallVolumes, no_fluidVolumes) == 0,
+      "Number of wall volumes must be a factor of the number of fluid volumes!");
+
+  end if;
+
+  //
+  // Connection of fluid ports
+  //
+  connect(fp_a, fluidVolumes[1].cfp_xMinus[1]) annotation (Line(points={{-100,0},
+          {-60,0},{-60,-62.2},{-4.2,-62.2}}, color={0,0,0}));
+
+  for i in 1:no_fluidVolumes-1 loop
+    connect(pressureDrop[i].port_a, fluidVolumes[i].cfp_xPlus[1]) annotation (Line(
+          points={{8,-90},{20,-90},{20,-62.2},{7.8,-62.2}},       color={0,0,0}));
+    connect(pressureDrop[i].port_b, fluidVolumes[i+1].cfp_xMinus[1]) annotation (Line(
+          points={{-8,-90},{-20,-90},{-20,-62.2},{-4.2,-62.2}},       color={0,0,0}));
+  end for;
+
+  connect(fp_b, fluidVolumes[no_fluidVolumes].cfp_xPlus[1]) annotation (Line(points={{100,0},
+          {80,0},{80,-62.2},{7.8,-62.2}},
+                                      color={0,0,0}));
+
+  //
+  // Connection of heat ports
+  //
+  if no_fluidVolumes == no_wallVolumes then
+    //
+    // Identical discretization number
+    //
+    connect(fluidVolumes.hp_yPlus, thermalConvection_fluidToWall.hp_a[1])
+      annotation (Line(
+        points={{0,-58},{0,-50}},
+        color={238,46,47},
+        thickness=1));
+
+    if useConductionPerpendicularFlowDirection then
+      connect(thermalConvection_fluidToWall.hp_b[1],
+        thermalConduction_fluidToWall.hp_a[1]) annotation (Line(
+          points={{0,-34},{0,-30}},
+          color={238,46,47},
+          thickness=1));
+      connect(thermalConduction_fluidToWall.hp_b[1], wallVolumes.hp_yMinus)
+        annotation (Line(
+          points={{0,-14},{0,-6}},
+          color={238,46,47},
+          thickness=1));
+
+    else
+      connect(thermalConvection_fluidToWall.hp_b[1], wallVolumes.hp_yMinus);
+
+    end if;
+
+  elseif no_fluidVolumes > no_wallVolumes then
+    //
+    // More fluid volumes than wall volumes
+    //
+    for i in 1:no_wallVolumes loop
+      connect(fluidVolumes[1+(i-1)*factorDiscretization:i*factorDiscretization].hp_yPlus,
+      thermalConvection_fluidToWall[i].hp_a[1:factorDiscretization])
+        annotation (Line(
+          points={{0,-58},{0,-50}},
+          color={238,46,47},
+          thickness=1));
+    end for;
+
+    if useConductionPerpendicularFlowDirection then
+      connect(thermalConvection_fluidToWall.hp_b[1],
+        thermalConduction_fluidToWall.hp_a[1]) annotation (Line(
+          points={{0,-34},{0,-30}},
+          color={238,46,47},
+          thickness=1));
+      connect(thermalConduction_fluidToWall.hp_b[1], wallVolumes.hp_yMinus)
+        annotation (Line(
+          points={{0,-14},{0,-6}},
+          color={238,46,47},
+          thickness=1));
+
+    else
+      connect(thermalConvection_fluidToWall.hp_b[1], wallVolumes.hp_yMinus);
+
+    end if;
+
+  else
+    //
+    // More wall volumes than fluid volumes
+    //
+    connect(fluidVolumes.hp_yPlus, thermalConvection_fluidToWall.hp_a[1])
+      annotation (Line(
+        points={{0,-58},{0,-50}},
+        color={238,46,47},
+        thickness=1));
+
+    if useConductionPerpendicularFlowDirection then
+      connect(thermalConvection_fluidToWall.hp_b[1],
+        thermalConduction_fluidToWall.hp_a[1]) annotation (Line(
+          points={{0,-34},{0,-30}},
+          color={238,46,47},
+          thickness=1));
+
+      for i in 1:no_fluidVolumes loop
+        connect(thermalConduction_fluidToWall[i].hp_b[1:factorDiscretization],
+        wallVolumes[1+(i-1)*factorDiscretization:i*factorDiscretization].hp_yMinus)
+          annotation (Line(
+            points={{0,-14},{0,-6}},
+            color={238,46,47},
+            thickness=1));
+      end for;
+
+    else
+      for i in 1:no_fluidVolumes loop
+        connect(thermalConvection_fluidToWall[i].hp_b[1:factorDiscretization],
+          wallVolumes[1+(i-1)*factorDiscretization:i*factorDiscretization].hp_yMinus)
+          annotation (Line(
+            points={{0,-34},{0,-6}},
+            color={238,46,47},
+            thickness=1));
+      end for;
+    end if;
+  end if;
+
+  if useConductionPerpendicularFlowDirection then
+    connect(wallVolumes.hp_yPlus, thermalConduction_wallToHeatPort.hp_a[1])
+      annotation (Line(
+        points={{0,6},{0,16}},
+        color={238,46,47},
+        thickness=1));
+    connect(thermalConduction_wallToHeatPort.hp_b[1], hp_wall) annotation (Line(
+        points={{0,32},{0,40}},
+        color={238,46,47},
+        thickness=1));
+
+  else
+    connect(wallVolumes.hp_yPlus, hp_wall) annotation (Line(
+        points={{0,6},{0,40}},
+        color={238,46,47},
+        thickness=1));
+
+  end if;
+
+  if useConductionFlowDirection then
+    for i in 1:no_wallVolumes-1 loop
+      connect(wallVolumes[i].hp_xPlus, thermalConduction_wall1[i].hp_a[1])
+        annotation (Line(
+          points={{6,0},{20,0}},
+          color={238,46,47},
+          thickness=1));
+      connect(thermalConduction_wall1[i].hp_b[1], thermalConduction_wall2[i].hp_a[1])
+        annotation (Line(
+          points={{36,0},{40,0},{40,14},{-40,14},{-40,0},{-36,0}},
+          color={238,46,47},
+          thickness=1));
+      connect(thermalConduction_wall2[i].hp_b[1], wallVolumes[i+1].hp_xMinus)
+        annotation (Line(
+          points={{-20,0},{-6,0}},
+          color={238,46,47},
+      thickness=1));
+    end for;
+  end if;
+
+  //
+  // Calculate fluid properties
+  //
+  if no_fluidVolumes == no_wallVolumes then
+    //
+    // Identical discretization number
+    //
+    p_wall = fluidVolumes.fluidProperties.p
+      "Pressures used to calculate properteis of the wall";
+
+    m_flow_hyd_xMinus = fluidVolumes.fluidProperties.mc_flow_xMinus
+      "Mass flow rates at first volume near port a";
+    m_flow_hyd_xPlus = fluidVolumes.fluidProperties.mc_flow_xPlus
+      "Mass flow rates at first volume near port b";
+
+    propertiesFluid.p = fluidVolumes.fluidProperties.p
+      "Pressures used to calcualte convective heat transfer at fluid side";
+    propertiesFluid.T = fluidVolumes.fluidProperties.T
+      "Temperatures used to calcualte convective heat transfer at fluid side";
+    propertiesFluid.rho = 1 ./ fluidVolumes.fluidProperties.v
+      "Densities used to calcualte convective heat transfer at fluid side";
+    propertiesFluid.cp = fluidVolumes.fluidProperties.cp
+      "Specific heat capacities used to calcualte convective heat transfer at 
+      fluid side";
+    propertiesFluid.eta = fluidVolumes.fluidProperties.eta
+      "Dynamic viscosities used to calcualte convective heat transfer at 
+      fluid side";
+    propertiesFluid.lambda = fluidVolumes.fluidProperties.lambda
+      "Thermal conductivities used to calcualte convective heat transfer at 
+      fluid side";
+
+  elseif no_fluidVolumes > no_wallVolumes then
+    //
+    // More fluid volumes than wall volumes
+    //
+    if fluidPropertyPosition == 1 then
+      for i in 1:no_wallVolumes loop
+        p_wall[i] =
+          fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.p
+          "Pressures used to calculate properteis of the wall";
+
+        m_flow_hyd_xMinus[i] =
+          fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.mc_flow_xMinus
+        "Mass flow rates at first volume near port a";
+        m_flow_hyd_xMinus[i] =
+          fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.mc_flow_xPlus
+        "Mass flow rates at first volume near port b";
+
+        propertiesFluid[i].p =
+          fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.p
+          "Pressures used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].T =
+          fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.T
+          "Temperatures used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].rho =
+          1 ./ fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.v
+          "Densities used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].cp =
+          fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.cp
+          "Specific heat capacities used to calcualte convective heat transfer at 
+          fluid side";
+        propertiesFluid[i].eta =
+          fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.eta
+          "Dynamic viscosities used to calcualte convective heat transfer at 
+          fluid side";
+        propertiesFluid[i].lambda =
+          fluidVolumes[1+(i-1)*factorDiscretization].fluidProperties.lambda
+          "Thermal conductivities used to calcualte convective heat transfer at 
+          fluid side";
+      end for;
+
+    elseif fluidPropertyPosition == 2 then
+      for i in 1:no_wallVolumes loop
+        p_wall[i] =
+          fluidVolumes[i*factorDiscretization].fluidProperties.p
+          "Pressures used to calculate properteis of the wall";
+
+        m_flow_hyd_xMinus[i] =
+          fluidVolumes[i*factorDiscretization].fluidProperties.mc_flow_xMinus
+        "Mass flow rates at first volume near port a";
+        m_flow_hyd_xMinus[i] =
+          fluidVolumes[i*factorDiscretization].fluidProperties.mc_flow_xPlus
+        "Mass flow rates at first volume near port b";
+
+        propertiesFluid[i].p =
+          fluidVolumes[i*factorDiscretization].fluidProperties.p
+          "Pressures used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].T =
+          fluidVolumes[i*factorDiscretization].fluidProperties.T
+          "Temperatures used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].rho =
+          1 ./ fluidVolumes[i*factorDiscretization].fluidProperties.v
+          "Densities used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].cp =
+          fluidVolumes[i*factorDiscretization].fluidProperties.cp
+          "Specific heat capacities used to calcualte convective heat transfer at 
+          fluid side";
+        propertiesFluid[i].eta =
+          fluidVolumes[i*factorDiscretization].fluidProperties.eta
+          "Dynamic viscosities used to calcualte convective heat transfer at 
+          fluid side";
+        propertiesFluid[i].lambda =
+          fluidVolumes[i*factorDiscretization].fluidProperties.lambda
+          "Thermal conductivities used to calcualte convective heat transfer at 
+          fluid side";
+      end for;
+
+    else
+      for i in 1:no_wallVolumes loop
+        p_wall[i] = 1/factorDiscretization *
+          sum(fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.p)
+          "Pressures used to calculate properteis of the wall";
+
+        m_flow_hyd_xMinus[i] = 1/factorDiscretization *
+          sum(fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.mc_flow_xMinus)
+          "Mass flow rates at first volume near port a";
+        m_flow_hyd_xMinus[i] = 1/factorDiscretization *
+          sum(fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.mc_flow_xPlus)
+          "Mass flow rates at first volume near port b";
+
+        propertiesFluid[i].p = 1/factorDiscretization *
+          sum(fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.p)
+          "Pressures used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].T = 1/factorDiscretization *
+          sum(fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.T)
+          "Temperatures used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].rho = 1/factorDiscretization *
+          sum(1 ./ fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.v)
+          "Densities used to calcualte convective heat transfer at fluid side";
+        propertiesFluid[i].cp = 1/factorDiscretization *
+          sum(fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.cp)
+          "Specific heat capacities used to calcualte convective heat transfer at 
+          fluid side";
+        propertiesFluid[i].eta = 1/factorDiscretization *
+          sum(fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.eta)
+          "Dynamic viscosities used to calcualte convective heat transfer at 
+          fluid side";
+        propertiesFluid[i].lambda = 1/factorDiscretization *
+          sum(fluidVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].fluidProperties.lambda)
+          "Thermal conductivities used to calcualte convective heat transfer at 
+          fluid side";
+      end for;
+    end if;
+
+  else
+    //
+    // More wall volumes than fluid volumes
+    //
+    for i in 1:no_fluidVolumes loop
+      p_wall[1+(i-1)*factorDiscretization:i*factorDiscretization] =
+        fill(fluidVolumes[i].fluidProperties.p, factorDiscretization)
+        "Pressures used to calculate properteis of the wall";
+    end for;
+
+    m_flow_hyd_xMinus = fluidVolumes.fluidProperties.mc_flow_xMinus
+      "Mass flow rates at first volume near port a";
+    m_flow_hyd_xPlus = fluidVolumes.fluidProperties.mc_flow_xPlus
+      "Mass flow rates at first volume near port b";
+
+    propertiesFluid.p = fluidVolumes.fluidProperties.p
+      "Pressures used to calcualte convective heat transfer at fluid side";
+    propertiesFluid.T = fluidVolumes.fluidProperties.T
+      "Temperatures used to calcualte convective heat transfer at fluid side";
+    propertiesFluid.rho = 1 ./ fluidVolumes.fluidProperties.v
+      "Densities used to calcualte convective heat transfer at fluid side";
+    propertiesFluid.cp = fluidVolumes.fluidProperties.cp
+      "Specific heat capacities used to calcualte convective heat transfer at 
+      fluid side";
+    propertiesFluid.eta = fluidVolumes.fluidProperties.eta
+      "Dynamic viscosities used to calcualte convective heat transfer at 
+      fluid side";
+    propertiesFluid.lambda = fluidVolumes.fluidProperties.lambda
+      "Thermal conductivities used to calcualte convective heat transfer at 
+      fluid side";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for all tubes. It defines fundamental parameters,
+models, and variables required by all tubes. Models that inherit properties from this 
+partial model have to redeclare all partial models (i.e., fluid ports, wall volumes,
+fluid volumes, and resistors). Morover, the geometry of the redeclared models except
+the fluid ports must be correctly set using the geometry record. In addition, the 
+pressure drop model must be passed to the resistor model, and the inputs 'fluidProperties'
+of the conductive heat transfer models must be correctly set using properties of the
+wall volumes.
+<br/><br/>
+The following variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  Difference enthalpy flow rate between port a and port b <i>DH_flow</i>.
+  </li>
+  <li>
+  The fluid property records <i>propertiesWall</i> considering the disretization and
+  fluid property position.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 29, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Rectangle(
+          extent={{-100,40},{100,-40}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Text(
+          extent={{-60,10},{-40,-10}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.None,
+          fontSize=20,
+          textString="1"),
+        Text(
+          extent={{40,10},{60,-10}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.None,
+          fontSize=20,
+          textString="n"),
+        Line(
+          points={{0,40},{2,14},{-4,10},{2,-6},{-2,-16},{2,-32},{0,-40}},
+          color={0,0,0},
+          smooth=Smooth.Bezier)}));
+end PartialTube;
diff --git a/SorpLib/Components/Tubes/BaseClasses/package.mo b/SorpLib/Components/Tubes/BaseClasses/package.mo
new file mode 100644
index 0000000..df3bc71
--- /dev/null
+++ b/SorpLib/Components/Tubes/BaseClasses/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Tubes;
+package BaseClasses "Base models and functions for all tubes"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial tubbes, containing fundamental definitions for tubes.
+The content of this package is only of interest when adding new tubes to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/Tubes/BaseClasses/package.order b/SorpLib/Components/Tubes/BaseClasses/package.order
new file mode 100644
index 0000000..f7b4dc6
--- /dev/null
+++ b/SorpLib/Components/Tubes/BaseClasses/package.order
@@ -0,0 +1 @@
+PartialTube
diff --git a/SorpLib/Components/Tubes/LiquidTube.mo b/SorpLib/Components/Tubes/LiquidTube.mo
new file mode 100644
index 0000000..2824298
--- /dev/null
+++ b/SorpLib/Components/Tubes/LiquidTube.mo
@@ -0,0 +1,356 @@
+within SorpLib.Components.Tubes;
+model LiquidTube
+  "Tube model that is one 1D discretized in the flow direction"
+  extends BaseClasses.PartialTube(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in fp_a,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out fp_b,
+    final no_components=Medium.nX,
+    final type_energyBalance=
+    SorpLib.Choices.BalanceEquations.TransientFixedInitial,
+    redeclare Basics.Volumes.FluidVolumes.LiquidVolume fluidVolumes(
+      redeclare each final package Medium = Medium,
+      redeclare each final Basics.Volumes.Records.VolumeGeometry geometry(
+        dx=geometry.l/geometry.no_fluidVolumes,
+        dy=geometry.d_hydInner,
+        dz=geometry.d_hydInner,
+        A_xy=-1,
+        A_xz=geometry.A_heatTransferInner/geometry.no_fluidVolumes,
+        A_yz=geometry.A_hydCrossInner,
+        V=geometry.V_inner/geometry.no_fluidVolumes*geometry.no_hydraulicParallelTubes)),
+    redeclare Basics.Volumes.SolidVolumes.SolidVolume wallVolumes(
+      redeclare each final WallMaterial solidMedium,
+      redeclare each final Basics.Volumes.Records.VolumeGeometry geometry(
+        dx=geometry.l/geometry.no_wallVolumes,
+        dy=geometry.t_wall/2,
+        dz=Modelica.Constants.pi*(geometry.d_hydInner + geometry.d_hydOuter)/2,
+        A_xy=geometry.t_wall*geometry.l/geometry.no_wallVolumes,
+        A_xz=Modelica.Constants.pi*(geometry.d_hydInner + geometry.d_hydOuter)/2
+            *geometry.l/geometry.no_wallVolumes,
+        A_yz=geometry.A_hydCrossWall/geometry.no_wallVolumes,
+        V=geometry.V_wall/geometry.no_wallVolumes*geometry.no_hydraulicParallelTubes),
+      final T_initial=T_wallInitial,
+      final p = p_wall,
+      each independentStateVariables=SorpLib.Choices.IndependentVariablesVolume.pTX),
+    redeclare Fittings.Resistors.LiquidTubeResistance pressureDrop(
+      redeclare each final model PressureLossModel = PressureDrop,
+      redeclare each final package Medium = Medium,
+      redeclare each final SorpLib.Components.Fittings.Records.GeometryTube geometry(
+        l=geometry.l/(geometry.no_fluidVolumes-1),
+        d_hyd_a=geometry.d_hydInner,
+        d_hyd_b=geometry.d_hydInner,
+        roughness=geometry.roughness,
+        no_hydraulicParallelFlows=geometry.no_hydraulicParallelTubes)),
+    thermalConduction_wall1(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=wallVolumes[1:no_wallVolumes-1].solidProperties.p,
+        T=wallVolumes[1:no_wallVolumes-1].solidProperties.T,
+        rho={1/wallVolumes[i].solidProperties.v for i in 1:no_wallVolumes-1},
+        cp=wallVolumes[1:no_wallVolumes-1].solidProperties.c,
+        eta=0,
+        lambda=wallVolumes[1:no_wallVolumes-1].solidProperties.lambda)),
+    thermalConduction_wall2(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=wallVolumes[2:no_wallVolumes].solidProperties.p,
+        T=wallVolumes[2:no_wallVolumes].solidProperties.T,
+        rho={1/wallVolumes[i].solidProperties.v for i in 2:no_wallVolumes},
+        cp=wallVolumes[2:no_wallVolumes].solidProperties.c,
+        eta=0,
+        lambda=wallVolumes[2:no_wallVolumes].solidProperties.lambda)),
+    thermalConduction_wallToHeatPort(final fluidProperties=
+      SorpLib.Components.HeatTransfer.Records.FluidProperties(
+        p=wallVolumes[:].solidProperties.p,
+        T=wallVolumes[:].solidProperties.T,
+        rho={1/wallVolumes[i].solidProperties.v for i in 1:no_wallVolumes},
+        cp=wallVolumes[:].solidProperties.c,
+        eta=0,
+        lambda=wallVolumes[:].solidProperties.lambda)));
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  replaceable model WallMaterial =
+      SorpLib.Media.Solids.MetalsAndMetalAlloys.Copper
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Solid wall medium"
+    annotation (Dialog(tab="General", group="Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of state records
+  //
+  Medium.ThermodynamicState state_a = Medium.setState_phX(
+    p = fp_a.p,
+    h = if avoid_events then noEvent(actualStream(fp_a.h_outflow)) else
+      actualStream(fp_a.h_outflow),
+    X = if avoid_events then noEvent(actualStream(fp_a.Xi_outflow)) else
+      actualStream(fp_a.Xi_outflow))
+    "Record describing current state properties at port a";
+  Medium.ThermodynamicState state_b = Medium.setState_phX(
+    p = fp_b.p,
+    h = if avoid_events then noEvent(actualStream(fp_b.h_outflow)) else
+      actualStream(fp_b.h_outflow),
+    X = if avoid_events then noEvent(actualStream(fp_b.Xi_outflow)) else
+      actualStream(fp_b.Xi_outflow))
+    "Record describing current state properties at port b";
+
+equation
+  //
+  // Calculate difference enthalpy stream
+  //
+  DH_flow = m_flow_a * Medium.specificEnthalpy(state=state_a) +
+    m_flow_a * Medium.specificEnthalpy(state=state_b)
+    "Difference enthalpy flow rate between port a and port b";
+
+  //
+  // Calculate fluid properties
+  //
+  if no_fluidVolumes == no_wallVolumes then
+    //
+    // Identical discretization number
+    //
+    propertiesWall.p = wallVolumes.solidProperties.p
+      "Pressures used to calcualte conductive heat transfer at fluid side";
+    propertiesWall.T = wallVolumes.solidProperties.T
+      "Temperatures used to calcualte conductive heat transfer at fluid side";
+    propertiesWall.rho = 1 ./ wallVolumes.solidProperties.v
+      "Densities used to calcualte conductive heat transfer at fluid side";
+    propertiesWall.cp = wallVolumes.solidProperties.c
+      "Specific heat capacities used to calcualte conductive heat transfer at 
+      fluid side";
+    propertiesWall.eta = zeros(no_wallVolumes)
+      "Dynamic viscosities used to calcualte conductive heat transfer at 
+      fluid side";
+    propertiesWall.lambda = wallVolumes.solidProperties.lambda
+      "Thermal conductivities used to calcualte conductive heat transfer at 
+      fluid side";
+
+  elseif no_fluidVolumes > no_wallVolumes then
+    //
+    // More fluid volumes than wall volumes
+    //
+    propertiesWall.p = wallVolumes.solidProperties.p
+      "Pressures used to calcualte conductive heat transfer at fluid side";
+    propertiesWall.T = wallVolumes.solidProperties.T
+      "Temperatures used to calcualte conductive heat transfer at fluid side";
+    propertiesWall.rho = 1 ./ wallVolumes.solidProperties.v
+      "Densities used to calcualte conductive heat transfer at fluid side";
+    propertiesWall.cp = wallVolumes.solidProperties.c
+      "Specific heat capacities used to calcualte conductive heat transfer at 
+      fluid side";
+    propertiesWall.eta = zeros(no_wallVolumes)
+      "Dynamic viscosities used to calcualte conductive heat transfer at 
+      fluid side";
+    propertiesWall.lambda = wallVolumes.solidProperties.lambda
+      "Thermal conductivities used to calcualte conductive heat transfer at 
+      fluid side";
+
+  else
+    //
+    // More wall volumes than fluid volumes
+    //
+    if fluidPropertyPosition == 1 then
+      for i in 1:no_fluidVolumes loop
+        propertiesWall[i].p =
+          wallVolumes[1+(i-1)*factorDiscretization].solidProperties.p
+          "Pressures used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].T =
+          wallVolumes[1+(i-1)*factorDiscretization].solidProperties.T
+          "Temperatures used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].rho =
+          1 ./ wallVolumes[1+(i-1)*factorDiscretization].solidProperties.v
+          "Densities used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].cp =
+          wallVolumes[1+(i-1)*factorDiscretization].solidProperties.c
+          "Specific heat capacities used to calcualte conductive heat transfer at 
+          fluid side";
+        propertiesWall[i].eta = 0
+          "Dynamic viscosities used to calcualte conductive heat transfer at 
+          fluid side";
+        propertiesWall[i].lambda =
+          wallVolumes[1+(i-1)*factorDiscretization].solidProperties.lambda
+          "Thermal conductivities used to calcualte conductive heat transfer at 
+          fluid side";
+      end for;
+
+    elseif fluidPropertyPosition == 2 then
+      for i in 1:no_fluidVolumes loop
+        propertiesWall[i].p =
+          wallVolumes[i*factorDiscretization].solidProperties.p
+          "Pressures used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].T =
+          wallVolumes[i*factorDiscretization].solidProperties.T
+          "Temperatures used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].rho =
+          1 ./ wallVolumes[i*factorDiscretization].solidProperties.v
+          "Densities used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].cp =
+          wallVolumes[i*factorDiscretization].solidProperties.c
+          "Specific heat capacities used to calcualte conductive heat transfer at 
+          fluid side";
+        propertiesWall[i].eta = 0
+          "Dynamic viscosities used to calcualte conductive heat transfer at 
+          fluid side";
+        propertiesWall[i].lambda =
+          wallVolumes[i*factorDiscretization].solidProperties.lambda
+          "Thermal conductivities used to calcualte conductive heat transfer at 
+          fluid side";
+      end for;
+
+    else
+      for i in 1:no_fluidVolumes loop
+        propertiesWall[i].p = 1/factorDiscretization *
+          sum(wallVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].solidProperties.p)
+          "Pressures used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].T = 1/factorDiscretization *
+          sum(wallVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].solidProperties.T)
+          "Temperatures used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].rho = 1/factorDiscretization *
+          sum(1 ./ wallVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].solidProperties.v)
+          "Densities used to calcualte conductive heat transfer at fluid side";
+        propertiesWall[i].cp = 1/factorDiscretization *
+          sum(wallVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].solidProperties.c)
+          "Specific heat capacities used to calcualte conductive heat transfer at 
+          fluid side";
+        propertiesWall[i].eta = 0
+          "Dynamic viscosities used to calcualte conductive heat transfer at 
+          fluid side";
+        propertiesWall[i].lambda = 1/factorDiscretization *
+          sum(wallVolumes[1+(i-1)*factorDiscretization:
+          i*factorDiscretization].solidProperties.lambda)
+          "Thermal conductivities used to calcualte conductive heat transfer at 
+          fluid side";
+      end for;
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  January 29, 2024, by Mirko Engelpracht:<br/>
+  Major adaptations due to restructering of the library and documentation.
+  </li>
+  <li>
+  January 14, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The tube model is 1D-discretized in axial direction via an upwing discretization
+scheme. It models the liquid flow through a pipe or a bunch of parallel pipes,
+considering the friction-based pressure drop and heat transfer between the fluid
+and wall. By design, the tube uses circular cross-sectional areas, but non-circular
+cross-sectional areas can be used via appropriate hydraulic geometry parameter.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The tube model has a steady-state/transient mass balance for the liquid, and
+a transient energy balance for the liquid and wall. For a detailed documentation,
+see
+<a href=\"Modelica://SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume\">SorpLib.Basics.Volumes.FluidVolumes.LiquidVolume</a>
+and
+<a href=\"Modelica://SorpLib.Basics.Volumes.SolidVolumes.SolidVolume\">SorpLib.Basics.Volumes.SolidVolumes.SolidVolume</a>.
+<br/<br/>
+The fluid volumes are coupled to each other via a hydraulic resistor, which
+allows to consider different pressure drop correlations. For a detailed documentation,
+see
+<a href=\"Modelica://SorpLib.Components.Fittings.Resistors.LiquidTubeResistance\">SorpLib.Components.Fittings.Resistors.LiquidTubeResistance</a>.
+<br/<br/>
+The fluid and wall volumes are coupled via a heat transfer model, describing the
+convective heat transfer fluid at the tube side. For a detailed documentation, see
+<a href=\"Modelica://SorpLib.Components.HeatTransfer.TubeInsideHeatTransfer\">SorpLib.Components.HeatTransfer.TubeInsideHeatTransfer</a>.
+<br/<br/>
+Moreover,
+<a href=\"Modelica://SorpLib.Components.HeatTransfer.ConductionHeatTransfer\">conductive heat transfer</a>
+can be considered within the wall.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>  
+  Constant volumes within the control volumes
+  </li>
+  <li>
+  Homogenous properties within the control volumes
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The tube model is typically used to model tubes within heat exchangers, such as
+evaporators, condensers, or adsorbers.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>useConductionPerpendicularFlowDirection</i>:
+  Defines if conductive heat transfer perpendicular to the flow direction
+  is considered within the wall.
+  </li>
+  <li>
+  <i>useConductionFlowDirection</i>:
+  Defines if conductive heat transfer in the flow direction is considered 
+  within the wall.
+  </li>
+  <li>
+  <i>calcFluidTransportProperties</i>:
+  Defines if fluid and transport properties are required for transport
+  phenomena.
+  </li>
+  <br/>
+  <li>
+  <i>type_overallMassBalance</i>:
+  Defines the type of the overall mass balance.
+  </li>
+  <li>
+  <i>type_independentMassBalances</i>:
+  Defines the type of the independent mass balances.
+  </li>
+  <li>
+  <i>type_energyBalance</i>:
+  Defines the type of the energy balance.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+This model has three dynamic state when using default options:
+</p>
+<ul>
+  <li>
+  Fluid pressure <i>p<sub>liq</sub></i>, fluid temperature <i>T<sub>liq</sub></i>, and wall temperature <i>T<sub>wall</sub></i>
+  </li>
+</ul>
+<p>
+Note that this model does not have the pressure <i>p</i> as dynamic state if the
+fluid medium is a single state model.
+</p>
+</html>"));
+end LiquidTube;
diff --git a/SorpLib/Components/Tubes/Records/GeometryTube.mo b/SorpLib/Components/Tubes/Records/GeometryTube.mo
new file mode 100644
index 0000000..b9bf461
--- /dev/null
+++ b/SorpLib/Components/Tubes/Records/GeometryTube.mo
@@ -0,0 +1,127 @@
+within SorpLib.Components.Tubes.Records;
+record GeometryTube
+  "This record contains the geometry of tubes"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of parameters regarding the disretization
+  //
+  parameter Integer no_fluidVolumes(min=1) = 1
+    "Number of fluid volumes"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+  parameter Integer no_wallVolumes(min=1) = 1
+    "Number of wall volumes"
+    annotation (Dialog(tab="General", group="Discretization", enable=false));
+
+  //
+  // Definition of parameters regarding the general geometry
+  //
+  parameter Integer no_hydraulicParallelTubes(min=1) = 1
+    "Number of hydraulically parallel tubes"
+    annotation (Dialog(tab="General", group="Geometry"));
+
+  parameter Modelica.Units.SI.Length l = 1
+    "Length of the tube"
+    annotation (Dialog(tab="General", group="Geometry"));
+
+  parameter Modelica.Units.SI.Length roughness = 7.5e-7
+    "Absolute roughness of the tube"
+    annotation (Dialog(tab="General", group="Geometry"));
+
+  //
+  // Definition of parameters regarding diameters
+  //
+  parameter Modelica.Units.SI.Diameter d_inner = 0.01
+    "Inner diameter"
+    annotation (Dialog(tab="General", group="Geometry - Diameters"));
+  parameter Modelica.Units.SI.Diameter d_outer = 0.012
+    "Outer diameter"
+    annotation (Dialog(tab="General", group="Geometry - Diameters"));
+
+  parameter Modelica.Units.SI.Diameter d_hydInner = d_inner
+    "Hydraulic inner diameter"
+    annotation (Dialog(tab="General", group="Geometry - Diameters"));
+  parameter Modelica.Units.SI.Diameter d_hydOuter = d_outer
+    "Hydraulic outer diameter"
+    annotation (Dialog(tab="General", group="Geometry - Diameters"));
+
+  parameter Modelica.Units.SI.Thickness t_wall = (d_outer - d_inner) / 2
+    "Wall thickness"
+    annotation (Dialog(tab="General", group="Geometry - Diameters"));
+
+  //
+  // Definition of parameters regarding areas
+  //
+  parameter Modelica.Units.SI.Area A_crossInner = Modelica.Constants.pi/4 * d_inner^2
+    "Inner cross-sectional area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+  parameter Modelica.Units.SI.Area A_crossOuter = Modelica.Constants.pi/4 * d_outer^2
+    "Outer cross-sectional area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+  parameter Modelica.Units.SI.Area A_crossWall = A_crossOuter - A_crossInner
+    "Wall cross-sectional area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+
+  parameter Modelica.Units.SI.Area A_hydCrossInner = A_crossInner
+    "Hydraulic inner cross-sectional area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossOuter = A_crossOuter
+    "Hydraulic outer cross-sectional area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+  parameter Modelica.Units.SI.Area A_hydCrossWall = A_hydCrossOuter - A_hydCrossInner
+    "Hydraulic wall cross-sectional area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+
+  parameter Modelica.Units.SI.Area A_heatTransferInner=
+    Modelica.Constants.pi * d_inner * l
+    "Total inner heat transfer area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+  parameter Modelica.Units.SI.Area A_heatTransferOuter=
+    Modelica.Constants.pi * d_outer * l
+    "Total outer heat transfer area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+
+  parameter Real f_finAreaRatioInner(min=0, max=1) = 0
+    "Ratio of total inner fin area to total inner heat transfer area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+  parameter Real f_finAreaRatioOuter(min=0, max=1) = 0
+    "Ratio of total outer fin area to total outer heat transfer area"
+    annotation (Dialog(tab="General", group="Geometry - Areas"));
+
+  //
+  // Definition of parameters regarding volumes
+  //
+  parameter Modelica.Units.SI.Volume V_inner = A_crossInner * l
+    "Total inner volume"
+    annotation (Dialog(tab="General", group="Geometry - Volumes"));
+  parameter Modelica.Units.SI.Volume V_outer = A_crossOuter * l
+    "Total outer volume"
+    annotation (Dialog(tab="General", group="Geometry - Volumes"));
+  parameter Modelica.Units.SI.Volume V_wall = V_outer - V_inner
+    "Total wall volume"
+    annotation (Dialog(tab="General", group="Geometry - Volumes"));
+
+  parameter Real f_finVolumeRatioInner(min=0, max=1) = 0
+    "Ratio of total inner fin volume to total wall volume"
+    annotation (Dialog(tab="General", group="Geometry - Volumes"));
+  parameter Real f_finVolumeRatioOuter(min=0, max=1) = 0
+    "Ratio of total outer fin volume to total wall volume"
+    annotation (Dialog(tab="General", group="Geometry - Volumes"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains geometric parameters required by models calculating the heat
+transfer coefficients at the inside or outside of tubes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 29, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GeometryTube;
diff --git a/SorpLib/Components/Tubes/Records/package.mo b/SorpLib/Components/Tubes/Records/package.mo
new file mode 100644
index 0000000..552ba5e
--- /dev/null
+++ b/SorpLib/Components/Tubes/Records/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Tubes;
+package Records "Package containing records"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records. These records are used to cluster 
+variables and tidy up the model output.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Components/Tubes/Records/package.order b/SorpLib/Components/Tubes/Records/package.order
new file mode 100644
index 0000000..617b36e
--- /dev/null
+++ b/SorpLib/Components/Tubes/Records/package.order
@@ -0,0 +1 @@
+GeometryTube
diff --git a/SorpLib/Components/Tubes/Tester/Test_LiquidTube.mo b/SorpLib/Components/Tubes/Tester/Test_LiquidTube.mo
new file mode 100644
index 0000000..37b0a52
--- /dev/null
+++ b/SorpLib/Components/Tubes/Tester/Test_LiquidTube.mo
@@ -0,0 +1,152 @@
+within SorpLib.Components.Tubes.Tester;
+model Test_LiquidTube "Tester for the liquid tube"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_a(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_mFlowInput=false,
+    use_VFlowInput=true,
+    V_flow_fixed=-10/60/1000,
+    T_fixed=288.15,
+    redeclare final package Medium = Medium)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+  SorpLib.Basics.Sources.Fluids.LiquidSource fs_b(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    use_pInput=true,
+    T_fixed=358.15,
+    redeclare final package Medium = Medium)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  SorpLib.Basics.Sources.Thermal.HeatSource hs(
+    boundaryType=SorpLib.Choices.BoundaryThermal.Temperature,
+    use_TInput=true)
+    "Heat source for walls" annotation (Placement(
+        transformation(
+        extent={{10,-10},{-10,10}},
+        rotation=90,
+        origin={0,40})));
+
+  //
+  // Definition of models
+  //
+  SorpLib.Components.Tubes.LiquidTube tube(
+    redeclare Records.GeometryTube geometry(l=10),
+    fluidPropertyPosition=3,
+    redeclare model FluidThermalConvectionTubeInside =
+      HeatTransfer.HeatTransferCoefficientCorrelations.TubeInside.ConstantAlphaA
+        (
+       constantAlphaA=100),
+    redeclare model PressureDrop =
+      SorpLib.Components.Fittings.PressureLossCorrelations.TubeInside.Konakov (
+      showTotalPressures=true,
+      showVelocities=true,
+      showDarcyFrictionNumber=true,
+      showIndividualPressureLosses=true),
+    redeclare final package Medium = Medium,
+    redeclare model WallMaterial = Media.Solids.MetalsAndMetalAlloys.Copper (
+      calcCaloricProperties=false,
+      approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Constant,
+      approach_lambda=SorpLib.Choices.ThermalConductivitySolid.Constant))
+    "Tube model"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+
+  SorpLib.Components.HeatTransfer.GenericHeatTransfer heatTransfer_boundaryToWall(
+    n_a=tube.no_wallVolumes,
+    n_b=1,
+    redeclare model HeatTransferCoefficient =
+        HeatTransfer.HeatTransferCoefficientCorrelations.Generic.ConstantAlphaA
+        (constantAlphaA=100)) "Heat transfer from heat source to wall"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={0,20})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Sine input_V_flow(
+    amplitude=15/1000/60,
+    f=1/500,
+    offset=-10/1000/60) "Input signal for volume flow rate"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Modelica.Blocks.Sources.Ramp input_p(
+    height=1e5,
+    duration=2500,
+    offset=2e5) "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+  Modelica.Blocks.Sources.Sine input_TWall(
+    amplitude=25,
+    f=1/250,
+    offset=273.15 + 50) "Input signal for wall temperature boundary"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,60})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a.port, tube.fp_a) annotation (Line(
+      points={{-60,0},{-10,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(tube.fp_b, fs_b.port) annotation (Line(
+      points={{10,0},{60,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(hs.port, heatTransfer_boundaryToWall.hp_b[1]) annotation (Line(
+      points={{0,40},{0,28}},
+      color={238,46,47},
+      thickness=1));
+  connect(heatTransfer_boundaryToWall.hp_a, tube.hp_wall) annotation (Line(
+      points={{0,12},{0,4}},
+      color={238,46,47},
+      thickness=1));
+
+  connect(input_V_flow.y, fs_a.V_flow_input) annotation (Line(points={{-79,0},{-70,
+          0},{-70,2},{-61.2,2}}, color={0,0,127}));
+  connect(input_p.y, fs_b.p_input)
+    annotation (Line(points={{79,0},{70,0},{70,5},{61.2,5}}, color={0,0,127}));
+  connect(input_TWall.y, hs.T_input) annotation (Line(points={{-2.22045e-15,49},
+          {0,49},{0,44},{-5.2,44},{-5.2,41}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the liquid tube.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  January 29, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_LiquidTube;
diff --git a/SorpLib/Components/Tubes/Tester/package.mo b/SorpLib/Components/Tubes/Tester/package.mo
new file mode 100644
index 0000000..4575950
--- /dev/null
+++ b/SorpLib/Components/Tubes/Tester/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Tubes;
+package Tester "Models to test and varify tube models"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented tubes. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Tubes/Tester/package.order b/SorpLib/Components/Tubes/Tester/package.order
new file mode 100644
index 0000000..3cc9ee3
--- /dev/null
+++ b/SorpLib/Components/Tubes/Tester/package.order
@@ -0,0 +1 @@
+Test_LiquidTube
diff --git a/SorpLib/Components/Tubes/package.mo b/SorpLib/Components/Tubes/package.mo
new file mode 100644
index 0000000..1c88b85
--- /dev/null
+++ b/SorpLib/Components/Tubes/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components;
+package Tubes "Tubes containing fluids"
+  extends SorpLib.Icons.TubesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains tubes. Ready-to-use models are based on the Modelica 
+Standard library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tubes;
diff --git a/SorpLib/Components/Tubes/package.order b/SorpLib/Components/Tubes/package.order
new file mode 100644
index 0000000..386b785
--- /dev/null
+++ b/SorpLib/Components/Tubes/package.order
@@ -0,0 +1,4 @@
+BaseClasses
+Records
+LiquidTube
+Tester
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialCompressibleThreeWayValve.mo b/SorpLib/Components/Valves/BaseClasses/PartialCompressibleThreeWayValve.mo
new file mode 100644
index 0000000..96630a8
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialCompressibleThreeWayValve.mo
@@ -0,0 +1,143 @@
+within SorpLib.Components.Valves.BaseClasses;
+model PartialCompressibleThreeWayValve
+  "Base model for all three-way valves for compressible fluids"
+  extends SorpLib.Components.Valves.BaseClasses.PartialThreeWayValve;
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Density rho_a
+    "Instreaming density at port a";
+  Modelica.Media.Common.IsentropicExponent gamma_a
+    "Instreaming isentropic exponent at port a";
+
+  Real radicand_ab
+    "Radicand if flowing from port a to b";
+  Real radicand_ac
+    "Radicand if flowing from port a to c";
+
+  Real weightingFactor_ab
+    "Weighting factor used to distinguish between flow regimes if flowing from
+    port a to b";
+  Real weightingFactor_ac
+    "Weighting factor used to distinguish between flow regimes if flowing from
+    port b to c";
+
+equation
+  //
+  // Calculate radicands
+  //
+  if avoid_events then
+    weightingFactor_ab =
+      SorpLib.Numerics.smoothTransition_noEvent(
+        x=(port_b.p / port_a.p),
+        transitionPoint=(2 / (gamma_a + 1)) ^ (gamma_a / (gamma_a - 1)),
+        transitionLength=1e-4,
+        noDiff=2)
+      "Weighting factor used to distinguish between flow regimes if flowing from
+      port a to b";
+    weightingFactor_ac =
+      SorpLib.Numerics.smoothTransition_noEvent(
+        x=(port_c.p / port_a.p),
+        transitionPoint=(2 / (gamma_a + 1)) ^ (gamma_a / (gamma_a - 1)),
+        transitionLength=1e-4,
+        noDiff=2)
+      "Weighting factor used to distinguish between flow regimes if flowing from
+      port a to c";
+
+  else
+    weightingFactor_ab =
+      SorpLib.Numerics.smoothTransition(
+        x=(port_b.p / port_a.p),
+        transitionPoint=(2 / (gamma_a + 1)) ^ (gamma_a / (gamma_a - 1)),
+        transitionLength=1e-4,
+        noDiff=2)
+      "Weighting factor used to distinguish between flow regimes if flowing from
+      port a to b";
+    weightingFactor_ac =
+      SorpLib.Numerics.smoothTransition(
+        x=(port_c.p / port_a.p),
+        transitionPoint=(2 / (gamma_a + 1)) ^ (gamma_a / (gamma_a - 1)),
+        transitionLength=1e-4,
+        noDiff=2)
+      "Weighting factor used to distinguish between flow regimes if flowing from
+      port a to c";
+
+  end if;
+
+  radicand_ab = (2 * rho_a * port_a.p) *
+    (weightingFactor_ab * (2 ^ (2 / (gamma_a - 1)) * gamma_a /
+    (gamma_a + 1) ^ ((gamma_a + 1) / (gamma_a - 1))) +
+    (1-weightingFactor_ab) * (gamma_a / (gamma_a - 1) *
+    ((port_b.p / port_a.p) ^ (2 / gamma_a) -
+    (port_b.p / port_a.p) ^ ((gamma_a + 1) / gamma_a))))
+    "Radicand if flowing from port a to b";
+  radicand_ac = (2 * rho_a * port_a.p) *
+    (weightingFactor_ac * (2 ^ (2 / (gamma_a - 1)) * gamma_a /
+    (gamma_a + 1) ^ ((gamma_a + 1) / (gamma_a - 1))) +
+    (1-weightingFactor_ac) * (gamma_a / (gamma_a - 1) *
+    ((port_c.p / port_a.p) ^ (2 / gamma_a) -
+    (port_c.p / port_a.p) ^ ((gamma_a + 1) / gamma_a))))
+    "Radicand if flowing from port a to c";
+
+  //
+  // Calculate the mass flow rates
+  //
+  port_b.m_flow = -A_eff_b * (if avoid_events then
+    SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+    y=dp_ab,
+    delta_x=sqrt(dpRegularization),
+    f_positive=radicand_ab,
+    f_negative=0) else
+    SorpLib.Numerics.regSquareWFactors_inv(
+    y=dp_ab,
+    delta_x=sqrt(dpRegularization),
+    f_positive=radicand_ab,
+    f_negative=0))
+    "Mass flow rate at port b: Design flow direction from port a to b and no
+    other flow direction is allowed";
+  port_c.m_flow = -A_eff_c * (if avoid_events then
+    SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+    y=dp_ac,
+    delta_x=sqrt(dpRegularization),
+    f_positive=radicand_ac,
+    f_negative=0) else
+    SorpLib.Numerics.regSquareWFactors_inv(
+    y=dp_ac,
+    delta_x=sqrt(dpRegularization),
+    f_positive=radicand_ac,
+    f_negative=0))
+    "Mass flow rate at port c: Design flow direction from port a to c and no
+    other flow direction is allowed";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all three-way valves for compressible 
+fluids. It defines fundamental parameters and variables required by all three-way
+valves for compressible fluids.
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the fluid 
+ports and to add a medium model. The following variables must be specified in the 
+model that inherit properties:
+</p>
+<ul>
+  <li>
+  <i>rho_a</i>: Instreaming density at port a.
+  </li>
+  <li>
+  <i>gamma_a</i>: Instreaming isentropic exponent at port a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialCompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialCompressibleValve.mo b/SorpLib/Components/Valves/BaseClasses/PartialCompressibleValve.mo
new file mode 100644
index 0000000..7391fdf
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialCompressibleValve.mo
@@ -0,0 +1,177 @@
+within SorpLib.Components.Valves.BaseClasses;
+partial model PartialCompressibleValve
+  "Base model for all valves for compressible fluids"
+  extends SorpLib.Components.Valves.BaseClasses.PartialOrificeValve(
+    final strictCheckValve=true,
+    final accountHydraulicHead=false,
+    final p_hydraulicHead=1000*9.81*0.25);
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Density rho_a
+    "Instreaming density at port a";
+  Modelica.Units.SI.Density rho_b
+    "Instreaming density at port b";
+
+  Modelica.Media.Common.IsentropicExponent gamma_a
+    "Instreaming isentropic exponent at port a";
+  Modelica.Media.Common.IsentropicExponent gamma_b
+    "Instreaming isentropic exponent at port b";
+
+  Real radicand_a
+    "Radicand if flowing from port a to b";
+  Real radicand_b
+    "Radicand if flowing from port b to a";
+
+  Real weightingFactor_a
+    "Weighting factor used to distinguish between flow regimes if flowing from
+    port a to b";
+  Real weightingFactor_b
+    "Weighting factor used to distinguish between flow regimes if flowing from
+    port b to a";
+
+equation
+  //
+  // Calculate radicands
+  //
+  if avoid_events then
+    weightingFactor_a =
+      SorpLib.Numerics.smoothTransition_noEvent(
+        x=(port_b.p / port_a.p),
+        transitionPoint=(2 / (gamma_a + 1)) ^ (gamma_a / (gamma_a - 1)),
+        transitionLength=1e-4,
+        noDiff=2)
+      "Weighting factor used to distinguish between flow regimes if flowing from
+      port a to b";
+    weightingFactor_b =
+      SorpLib.Numerics.smoothTransition_noEvent(
+        x=(port_a.p / port_b.p),
+        transitionPoint=(2 / (gamma_b + 1)) ^ (gamma_b / (gamma_b - 1)),
+        transitionLength=1e-4,
+        noDiff=2)
+      "Weighting factor used to distinguish between flow regimes if flowing from
+      port a to b";
+
+  else
+    weightingFactor_a =
+      SorpLib.Numerics.smoothTransition(
+        x=(port_b.p / port_a.p),
+        transitionPoint=(2 / (gamma_a + 1)) ^ (gamma_a / (gamma_a - 1)),
+        transitionLength=1e-4,
+        noDiff=2)
+      "Weighting factor used to distinguish between flow regimes if flowing from
+      port a to b";
+    weightingFactor_b =
+      SorpLib.Numerics.smoothTransition(
+        x=(port_a.p / port_b.p),
+        transitionPoint=(2 / (gamma_b + 1)) ^ (gamma_b / (gamma_b - 1)),
+        transitionLength=1e-4,
+        noDiff=2)
+      "Weighting factor used to distinguish between flow regimes if flowing from
+      port a to b";
+
+  end if;
+
+  radicand_a = (2 * rho_a * port_a.p) *
+    (weightingFactor_a * (2 ^ (2 / (gamma_a - 1)) * gamma_a /
+    (gamma_a + 1) ^ ((gamma_a + 1) / (gamma_a - 1))) +
+    (1-weightingFactor_a) * (gamma_a / (gamma_a - 1) *
+    ((port_b.p / port_a.p) ^ (2 / gamma_a) -
+    (port_b.p / port_a.p) ^ ((gamma_a + 1) / gamma_a))))
+    "Radicand if flowing from port a to b";
+  radicand_b = (2 * rho_b * port_b.p) *
+    (weightingFactor_b * (2 ^ (2 / (gamma_b - 1)) * gamma_b /
+    (gamma_b + 1) ^ ((gamma_b + 1) / (gamma_b - 1))) +
+    (1-weightingFactor_b) * (gamma_b / (gamma_b - 1) *
+    ((port_a.p / port_b.p) ^ (2 / gamma_b) -
+    (port_a.p / port_b.p) ^ ((gamma_b + 1) / gamma_b))))
+    "Radicand if flowing from port b to a";
+
+  //
+  // Calculate the mass flow rate
+  //
+  if checkValve and strictCheckValve then
+    port_a.m_flow = A_eff * (if avoid_events then
+      SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=radicand_a,
+      f_negative=0) else
+      SorpLib.Numerics.regSquareWFactors_inv(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=radicand_a,
+      f_negative=0))
+      "Mass flow rate at port a: Design flow direction from port a to b and no
+      other flow direction is allowed";
+
+  elseif checkValve and not strictCheckValve then
+    port_a.m_flow = A_eff * (if avoid_events then
+      SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=radicand_a,
+      f_negative=0) else
+      SorpLib.Numerics.regSquareWFactors_inv(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=radicand_a,
+      f_negative=0))
+      "Mass flow rate at port a: Design flow direction from port a to b and a
+      minimal flow from port b to a is allowed";
+
+  else
+    port_a.m_flow = A_eff * (if avoid_events then
+      SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=radicand_a,
+      f_negative=radicand_b) else
+      SorpLib.Numerics.regSquareWFactors_inv(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=radicand_a,
+      f_negative=radicand_b))
+      "Mass flow rate at port a: Design flow direction from port a to b but
+      both flow directions are allowed";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all valves for compressible fluids. It 
+defines fundamental parameters and variables required by all valves for compressible
+fluids.
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the fluid 
+ports and to add a medium model. The following variables must be specified in the 
+model that inherit properties:
+</p>
+<ul>
+  <li>
+  <i>rho_a</i>: Instreaming density at port a.
+  </li>
+  <li>
+  <i>rho_b</i>: Instreaming density at port b.
+  </li>
+  <li>
+  <i>gamma_a</i>: Instreaming isentropic exponent at port a.
+  </li>
+  <li>
+  <i>gamma_b</i>: Instreaming isentropic exponent at port b.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialCompressibleValve;
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialCondensateRefluxValve.mo b/SorpLib/Components/Valves/BaseClasses/PartialCondensateRefluxValve.mo
new file mode 100644
index 0000000..dc46378
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialCondensateRefluxValve.mo
@@ -0,0 +1,207 @@
+within SorpLib.Components.Valves.BaseClasses;
+partial model PartialCondensateRefluxValve
+  "Base model for all condensate reflux valves"
+
+  //
+  // Definition setup parameters
+  //
+  parameter Real setPoint = 0.25
+    "Set point of process variable that is controlled (e.g., relative filling
+    level of a phase separator volume) at port a (i.e., mass flows from port a to
+    b)"
+    annotation (Dialog(tab="General", group="Valve Setup"));
+
+  //
+  // Definition of parameters regarding the valve characteristic
+  //
+  parameter Integer controlType(min=1, max=3) = 2
+    "Control type: Constant, linear, or quadratic"
+    annotation (Dialog(tab="Valve Characteristic", group="Type"),
+                choices(
+                  choice=1 "Constant",
+                  choice=2 "Linear",
+                  choice=3 "Quadratic"));
+
+  parameter Modelica.Units.SI.MassFlowRate m_flow_constant = 10/60
+    "Constant mass flow rate used if controlType = 'Constant'"
+    annotation (Dialog(tab="Valve Characteristic", group="Constant Controler",
+                enable=controlType==1));
+  parameter Real kp_linear(final unit="kg/s") = 0.15
+    "Linear valve coefficient if controlType = 'Linear'"
+    annotation (Dialog(tab="Valve Characteristic", group="Linear Controler",
+                enable=controlType==2));
+  parameter Real kp_quadratic(final unit="kg/s") = 0.15
+    "Quadratic valve coefficient if controlType = 'Quadratic'"
+    annotation (Dialog(tab="Valve Characteristic", group="Quadratic Controler",
+                enable=controlType==3));
+
+  extends SorpLib.Components.Valves.BaseClasses.PartialValve(
+    final controllableOpening=false,
+    final fixedOpening=1,
+    final useTimeConstant=false,
+    final tau=1,
+    final leackage=false,
+    final leackageOpening=0,
+    final accountHydraulicHead=false,
+    final p_hydraulicHead = 1000 * 9.81 * 0.25,
+    final opening_initial=0);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Real setPointRegularization = 1e-2
+    "Regularization around set point required for smooth transition to zero mass 
+    flow rate if valve is a check valve or controlType = 'Constant'"
+    annotation (Dialog(tab="Advanced", group="Numerics",
+                enable=checkValve or controlType==1),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer noDiff(min=1,max=3) = 3
+    "Specification how often smoothTransition-function can be differentiated 
+    (i.e., 1, 2 or 3) if valve is a check valve"
+    annotation (Dialog(tab="Advanced", group="Numerics",
+                enable=checkValve),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of inputs
+  //
+  Modelica.Blocks.Interfaces.RealInput processVariable
+    "Process variable that is controlled to reach a set point"
+    annotation (Placement(transformation(extent={{-36,32},{-16,52}}),
+                iconTransformation(extent={{-36,32},{-16,52}})));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real weightingFactor = if checkValve then (if avoid_events then
+    SorpLib.Numerics.smoothTransition_noEvent(
+      x=processVariable,
+      transitionPoint=setPoint,
+      transitionLength=setPointRegularization,
+      noDiff=noDiff) else
+    SorpLib.Numerics.smoothTransition(
+      x=processVariable,
+      transitionPoint=setPoint,
+      transitionLength=setPointRegularization,
+      noDiff=noDiff)) else 0
+    "Weighting factor used for smooth transition to zero mass flow rate if valve
+    is a check valve: 1 at 'setPoint-setPointRegularization/2' and 0 at 
+    'setPoint+setPointRegularization/2";
+
+equation
+  //
+  // Calculate flow characteristic depending on the control type
+  //
+  if controlType == 1 then
+    if checkValve and strictCheckValve then
+      port_a.m_flow = (1 - (if avoid_events then
+        SorpLib.Numerics.smoothTransition_noEvent(
+          x=processVariable,
+          transitionPoint=setPoint+setPointRegularization/2,
+          transitionLength=setPointRegularization,
+          noDiff=noDiff) else
+        SorpLib.Numerics.smoothTransition(
+          x=processVariable,
+          transitionPoint=setPoint+setPointRegularization/2,
+          transitionLength=setPointRegularization,
+          noDiff=noDiff))) * m_flow_constant
+        "Mass flow rate at port a: Design flow direction from port a to b and no
+        other flow direction is allowed";
+
+    elseif checkValve and not strictCheckValve then
+      port_a.m_flow = (1-weightingFactor) * m_flow_constant
+        "Mass flow rate at port a: Design flow direction from port a to b and a
+        minimal flow from port b to a is allowed";
+
+    else
+      port_a.m_flow = if avoid_events then
+        SorpLib.Numerics.regStep_noEvent(
+          x=processVariable-setPoint,
+          y1=m_flow_constant,
+          y2=-m_flow_constant,
+          x_small=setPointRegularization) else
+        SorpLib.Numerics.regStep(
+          x=processVariable-setPoint,
+          y1=m_flow_constant,
+          y2=-m_flow_constant,
+          x_small=setPointRegularization)
+        "Mass flow rate at port a: Design flow direction from port a to b but
+        both flow directions are allowed";
+
+    end if;
+
+  elseif controlType == 2 then
+    if checkValve and strictCheckValve then
+      port_a.m_flow = smooth(0, max(processVariable - setPoint, 0)) * kp_linear
+        "Mass flow rate at port a: Design flow direction from port a to b and no
+        other flow direction is allowed";
+
+    elseif checkValve and not strictCheckValve then
+      port_a.m_flow = (1-weightingFactor) * (processVariable - setPoint) * kp_linear
+        "Mass flow rate at port a: Design flow direction from port a to b and a
+        minimal flow from port b to a is allowed";
+
+    else
+      port_a.m_flow = (processVariable - setPoint) * kp_linear
+        "Mass flow rate at port a: Design flow direction from port a to b but
+        both flow directions are allowed";
+
+    end if;
+
+  else
+    if checkValve and strictCheckValve then
+      port_a.m_flow = smooth(0, max(sign(processVariable - setPoint) *
+        (processVariable - setPoint)^2, 0)) * kp_quadratic
+        "Mass flow rate at port a: Design flow direction from port a to b and no
+        other flow direction is allowed";
+
+    elseif checkValve and not strictCheckValve then
+      port_a.m_flow = (1-weightingFactor) * sign(processVariable - setPoint) *
+        (processVariable - setPoint)^2 * kp_quadratic
+        "Mass flow rate at port a: Design flow direction from port a to b and a
+        minimal flow from port b to a is allowed";
+
+    else
+      port_a.m_flow = sign(processVariable - setPoint) *
+        (processVariable - setPoint)^2 * kp_quadratic
+        "Mass flow rate at port a: Design flow direction from port a to b but
+        both flow directions are allowed";
+
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all condensate reflux valves. It defines fundamental 
+parameters and variables required by all condensate reflux valves. These valves act as control 
+valves: I.e., a process variable (e.g., the relative filling level in a phase separator volume)
+is regulated to its setpoint via the mass flow through the valve. Three characteristics are 
+available for the control behavior: A constant mass flow, a mass flow that is linear to the 
+deviation from the setpoint, and a mass flow that is quadratic to the deviation from the setpoint.
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the fluid ports and to
+add a medium model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  Major revisions (new functionalities, documentation).
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  Smaller revisions after restructuring of the library.
+  </li>
+  <li>
+  December 11, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end PartialCondensateRefluxValve;
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialIncompressibleThreeWayValve.mo b/SorpLib/Components/Valves/BaseClasses/PartialIncompressibleThreeWayValve.mo
new file mode 100644
index 0000000..c5b0b1d
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialIncompressibleThreeWayValve.mo
@@ -0,0 +1,70 @@
+within SorpLib.Components.Valves.BaseClasses;
+model PartialIncompressibleThreeWayValve
+  "Base model for all three-way valves for incompressible fluids"
+  extends SorpLib.Components.Valves.BaseClasses.PartialThreeWayValve;
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Density rho_a
+    "Instreaming density at port a";
+
+equation
+  //
+  // Calculate the mass flow rates
+  //
+  port_b.m_flow = -A_eff_b * (if avoid_events then
+    SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+    y=dp_ab,
+    delta_x=sqrt(dpRegularization),
+    f_positive=2*rho_a,
+    f_negative=0) else
+    SorpLib.Numerics.regSquareWFactors_inv(
+    y=dp_ab,
+    delta_x=sqrt(dpRegularization),
+    f_positive=2*rho_a,
+    f_negative=0))
+    "Mass flow rate at port b: Design flow direction from port a to b and no
+    other flow direction is allowed";
+  port_c.m_flow = -A_eff_c * (if avoid_events then
+    SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+    y=dp_ac,
+    delta_x=sqrt(dpRegularization),
+    f_positive=2*rho_a,
+    f_negative=0) else
+    SorpLib.Numerics.regSquareWFactors_inv(
+    y=dp_ac,
+    delta_x=sqrt(dpRegularization),
+    f_positive=2*rho_a,
+    f_negative=0))
+    "Mass flow rate at port c: Design flow direction from port a to c and no
+    other flow direction is allowed";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all three-way valves for incompresible 
+fluids. It defines fundamental parameters and variables required by all three-way
+valves for incompresible fluids.
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the fluid 
+ports and to add a medium model. The following variables must be specified in the 
+model that inherit properties:
+</p>
+<ul>
+  <li>
+  <i>rho_a</i>: Instreaming density at port a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialIncompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialIncompressibleValve.mo b/SorpLib/Components/Valves/BaseClasses/PartialIncompressibleValve.mo
new file mode 100644
index 0000000..b1b57ae
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialIncompressibleValve.mo
@@ -0,0 +1,96 @@
+within SorpLib.Components.Valves.BaseClasses;
+partial model PartialIncompressibleValve
+  "Base model for all valves for incompressible fluids"
+  extends SorpLib.Components.Valves.BaseClasses.PartialOrificeValve(
+    final strictCheckValve=true);
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Density rho_a
+    "Instreaming density at port a";
+  Modelica.Units.SI.Density rho_b
+    "Instreaming density at port b";
+
+equation
+  //
+  // Calculate the mass flow rate
+  //
+  if checkValve and strictCheckValve then
+    port_a.m_flow = A_eff * (if avoid_events then
+      SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=2*rho_a,
+      f_negative=0) else
+      SorpLib.Numerics.regSquareWFactors_inv(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=2*rho_a,
+      f_negative=0))
+      "Mass flow rate at port a: Design flow direction from port a to b and no
+      other flow direction is allowed";
+
+  elseif checkValve and not strictCheckValve then
+    port_a.m_flow = A_eff * (if avoid_events then
+      SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=2*rho_a,
+      f_negative=0) else
+      SorpLib.Numerics.regSquareWFactors_inv(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=2*rho_a,
+      f_negative=0))
+      "Mass flow rate at port a: Design flow direction from port a to b and a
+      minimal flow from port b to a is allowed";
+
+  else
+    port_a.m_flow = A_eff * (if avoid_events then
+      SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=2*rho_a,
+      f_negative=2*rho_b) else
+      SorpLib.Numerics.regSquareWFactors_inv(
+      y=dp_,
+      delta_x=sqrt(dpRegularization),
+      f_positive=2*rho_a,
+      f_negative=2*rho_b))
+      "Mass flow rate at port a: Design flow direction from port a to b but
+      both flow directions are allowed";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all valves for incompresible fluids. It 
+defines fundamental parameters and variables required by all valves for incompresible
+fluids.
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the fluid 
+ports and to add a medium model. The following variables must be specified in the 
+model that inherit properties:
+</p>
+<ul>
+  <li>
+  <i>rho_a</i>: Instreaming density at port a.
+  </li>
+  <li>
+  <i>rho_b</i>: Instreaming density at port b.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialIncompressibleValve;
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialOrificeValve.mo b/SorpLib/Components/Valves/BaseClasses/PartialOrificeValve.mo
new file mode 100644
index 0000000..0fb63e6
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialOrificeValve.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Valves.BaseClasses;
+partial model PartialOrificeValve
+  "Base model for all orifice valves"
+
+  //
+  // Definition of parameters regarding the valve characteristic
+  //
+  parameter Boolean useKvsValue = true
+    " = true, if Kvs-value is used to determine mass flow rate; otherwise, A_eff
+    is used to determine mass flow rate"
+    annotation (Dialog(tab="Valve Characteristic", group="Type"),
+                Evaluate=true);
+  parameter Integer valveCharacteristic = 1
+    "Valve characteristic used to calculate the flow coefficient or effective area
+    depending on the actual opening: Linear, quadratic, or equal percentage"
+    annotation (Dialog(tab="Valve Characteristic", group="Type"),
+                choices(
+                  choice=1 "Linear",
+                  choice=2 "Quadratic",
+                  choice=3 "Equal percentage"));
+
+  parameter Real opening_A_eff_min = 1e-2
+    "Minimal valve opening (i.e., position) that corresponds to minimal effective 
+    flow area"
+    annotation (Dialog(tab="Valve Characteristic", group="Effective Flow Area",
+                enable=not useKvsValue and valveCharacteristic==3));
+  parameter Modelica.Units.SI.Area A_eff_min = 0.1e-6
+    "Minimal effective flow area if valve is almost closed"
+    annotation (Dialog(tab="Valve Characteristic", group="Effective Flow Area",
+                enable=not useKvsValue and valveCharacteristic==3));
+  parameter Modelica.Units.SI.Area A_eff_max = 0.3e-6
+    "Maximal effective flow area if valve is completly open"
+    annotation (Dialog(tab="Valve Characteristic", group="Effective Flow Area",
+                enable=not useKvsValue));
+
+  parameter Modelica.Units.SI.PressureDifference dp_ref = 1e5
+    "Reference pressure difference that corresponds to the Kvs-value"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+  parameter Modelica.Units.SI.Density rho_ref = 1e3
+    "Reference density that corresponds to the Kvs-value"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+  parameter Real opening_Kv_min = 1e-2
+    "Minimal valve opening (i.e., position) that corresponds to minimal flow
+    coefficient"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue and valveCharacteristic==3));
+  parameter Real Kv_min(unit="m3/h") = 0.5
+    "Minimal flow coefficient if valve is almost closed"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue and valveCharacteristic==3));
+  parameter Real Kvs(unit="m3/h") = 1.5
+    "Maximal flow coefficient if valve is completly open"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+
+  extends SorpLib.Components.Valves.BaseClasses.PartialValve(
+    controllableOpening=true);
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Modelica.Units.SI.PressureDifference dpRegularization = 10
+    "Regularization around zero pressure drop for continous flow reversal or
+    check valve implementation"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Area A_eff
+    "Effective flow area used to calculate the mass flow rate: This area considers 
+    the actual opening and the calculation approach (i.e., Kvs-value or effective 
+    flow area";
+
+equation
+  //
+  // Calculate the effective flow area
+  //
+  if useKvsValue then
+    if valveCharacteristic == 1 then
+      A_eff =
+        SorpLib.Components.Valves.ValveCharacteristics.linearCharacteristic(
+        opening=opening_internal,
+        fc_max=Kvs) * sqrt(rho_ref / (2 * dp_ref)) / 3600
+        "Effective flow area used to calculate the mass flow rate";
+
+    elseif valveCharacteristic == 2 then
+      A_eff =
+        SorpLib.Components.Valves.ValveCharacteristics.quadraticCharacteristic(
+        opening=opening_internal,
+        fc_max=Kvs) * sqrt(rho_ref / (2 * dp_ref)) / 3600
+        "Effective flow area used to calculate the mass flow rate";
+
+    else
+      A_eff =
+        SorpLib.Components.Valves.ValveCharacteristics.equalPercentageCharacteristic(
+        opening=opening_internal,
+        fc_max=Kvs,
+        fc_min=Kv_min,
+        opening_min=opening_Kv_min) * sqrt(rho_ref / (2 * dp_ref)) / 3600
+        "Effective flow area used to calculate the mass flow rate";
+
+    end if;
+
+  else
+    if valveCharacteristic == 1 then
+      A_eff =
+        SorpLib.Components.Valves.ValveCharacteristics.linearCharacteristic(
+        opening=opening_internal,
+        fc_max=A_eff_max)
+        "Effective flow area used to calculate the mass flow rate";
+
+    elseif valveCharacteristic == 2 then
+      A_eff =
+        SorpLib.Components.Valves.ValveCharacteristics.quadraticCharacteristic(
+        opening=opening_internal,
+        fc_max=A_eff_max)
+        "Effective flow area used to calculate the mass flow rate";
+
+    else
+      A_eff =
+        SorpLib.Components.Valves.ValveCharacteristics.equalPercentageCharacteristic(
+        opening=opening_internal,
+        fc_max=A_eff_max,
+        fc_min=A_eff_min,
+        opening_min=opening_A_eff_min)
+        "Effective flow area used to calculate the mass flow rate";
+
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all orifice valves. It defines fundamental parameters 
+and variables required by all orifice valves.
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the fluid ports and to
+add a medium model. The following variables must be specified in the model that inherit 
+properties:
+</p>
+<ul>
+  <li>
+  The flow variable <i>port_a.m_flow</i> that defines the mass flow rate at port a. The
+  mass flow rate depends on the pressure difference <i>dp_</i> between the two ports. Further,
+  the mass flow rate depends on the valve type (i.e., (strict) check valve or normal valve).
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialOrificeValve;
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialThreeWayValve.mo b/SorpLib/Components/Valves/BaseClasses/PartialThreeWayValve.mo
new file mode 100644
index 0000000..04b8f7c
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialThreeWayValve.mo
@@ -0,0 +1,440 @@
+within SorpLib.Components.Valves.BaseClasses;
+partial model PartialThreeWayValve
+  "Base model for all three-way valves"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of setup parameters
+  //
+  parameter Boolean controllablePosition = false
+    " = true, if valve position is contrallable via an input signal"
+    annotation (Dialog(tab="General", group="Valve Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Real fixedPosition(min=0, max=1) = 0
+    "Fixed valve position if the valve is not controllable: If 0, mass flows from
+    port a to b; if 1, mass flows from port a to c"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=not controllablePosition));
+
+  parameter Boolean useTimeConstant = false
+    " = true, if time constant is used to delay valve position"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=controllablePosition),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Modelica.Units.SI.Time tau = 1
+    "Time constant for valve position"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=controllablePosition and useTimeConstant));
+
+  parameter Boolean leackage = false
+    " = true, if valve has a leackage mass flow rate (i.e., cannot be fully 
+    switched to position 0 or 1) to avoid singularities"
+    annotation (Dialog(tab="General", group="Valve Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Real leackagePosition(min=0, max=1) = 1e-3
+    "Leackage valve position to avoid singularities"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=leackage));
+
+  //
+  // Definition of parameters regarding the valve characteristic
+  //
+  parameter Boolean useKvsValue = true
+    " = true, if Kvs-value is used to determine mass flow rate; otherwise, A_eff
+    is used to determine mass flow rate"
+    annotation (Dialog(tab="Valve Characteristic", group="Type"),
+                Evaluate=true);
+
+  parameter Modelica.Units.SI.Area A_eff_max_b = 0.3e-6
+    "Maximal effective flow area at port b if valve is completly open"
+    annotation (Dialog(tab="Valve Characteristic", group="Effective Flow Area",
+                enable=not useKvsValue));
+  parameter Modelica.Units.SI.Area A_eff_max_c = A_eff_max_b
+    "Maximal effective flow area at port c if valve is completly open"
+    annotation (Dialog(tab="Valve Characteristic", group="Effective Flow Area",
+                enable=not useKvsValue));
+
+  parameter Modelica.Units.SI.PressureDifference dp_ref_b = 1e5
+    "Reference pressure difference that corresponds to the Kvs-value at port b"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+  parameter Modelica.Units.SI.PressureDifference dp_ref_c = dp_ref_b
+    "Reference pressure difference that corresponds to the Kvs-value at port c"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+  parameter Modelica.Units.SI.Density rho_ref_b = 1e3
+    "Reference density that corresponds to the Kvs-value at port b"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+  parameter Modelica.Units.SI.Density rho_ref_c = rho_ref_b
+    "Reference density that corresponds to the Kvs-value at port c"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+  parameter Real Kvs_b(unit="m3/h") = 1.5
+    "Maximal flow coefficient at port b if valve is completly open"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+  parameter Real Kvs_c(unit="m3/h") = Kvs_b
+    "Maximal flow coefficient at port c if valve is completly open"
+    annotation (Dialog(tab="Valve Characteristic", group="Flow coefficient",
+                enable=useKvsValue));
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Real position_initial = 1
+    "Initial value of valve position if valve position is delayed"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=controllablePosition and useTimeConstant));
+
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+  parameter Modelica.Units.SI.PressureDifference dpRegularization = 10
+    "Regularization around zero pressure drop for check valve implementation"
+    annotation (Dialog(tab="Advanced", group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of inputs
+  //
+  Modelica.Blocks.Interfaces.RealInput position(min=0, max=1) if
+    controllablePosition
+    "Valve position input signal"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,70}), iconTransformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,70})));
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-10,-88},{10,-68}}),
+                iconTransformation(extent={{-10,-88},{10,-68}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{-90,-10},{-70,10}}),
+                iconTransformation(extent={{-90,-10},{-70,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_c
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid port c"
+    annotation (Placement(transformation(extent={{70,-10},{90,10}}),
+                iconTransformation(extent={{70,-10},{90,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.PressureDifference dp_ab
+    "Pressure difference between port a and b";
+  Modelica.Units.SI.PressureDifference dp_ac
+    "Pressure difference between port a and c";
+
+  Modelica.Units.SI.Area A_eff_b
+    "Effective flow area used to calculate the mass flow rate at port b: This area 
+    considers the actual position and the calculation approach (i.e., Kvs-value 
+    or effective flow area";
+  Modelica.Units.SI.Area A_eff_c
+    "Effective flow area used to calculate the mass flow rate at port c: This area 
+    considers the actual position and the calculation approach (i.e., Kvs-value 
+    or effective flow area";
+
+  //
+  // Definition of blocks
+  //
+  Modelica.Blocks.Continuous.CriticalDamping filter(
+    n=2,
+    f=5 / (2 * Modelica.Constants.pi * tau),
+    normalized=true,
+    initType=Modelica.Blocks.Types.Init.InitialOutput,
+    y_start=position_initial) if controllablePosition and useTimeConstant
+    "Critical damping filter to filter position signal"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=270,
+                origin={0,40})),
+                HideResult=true);
+
+  SorpLib.Components.Valves.Utilities.Limiter limiter(
+    lowerLimit=if leackage then leackagePosition else 0,
+    upperLimit=if leackage then 1-leackagePosition else 1) if
+    controllablePosition
+    "Limits the input signal"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=270,
+                origin={0,10})),
+                HideResult=true);
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput position_internal(min=0, max=1)
+    "Needed for connecting to conditional components";
+
+equation
+  //
+  // Assertations
+  //
+  if not controllablePosition then
+    assert(fixedPosition >= 0 and fixedPosition <= 1,
+          "Fixed position (" + String(fixedPosition) + ") must between 0 and 1!",
+          level = AssertionLevel.error);
+  end if;
+
+  //
+  // Momentum balance
+  //
+  dp_ab = port_a.p - port_b.p
+    "Pressure difference between port a and b";
+  dp_ac = port_a.p - port_c.p
+    "Pressure difference between port a and c";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + port_b.m_flow + port_c.m_flow
+    "Steady-state mass balance";
+
+  port_a.Xi_outflow = SorpLib.Components.Valves.Utilities.mixStreamVariables(
+    m_flow_1=port_b.m_flow,
+    m_flow_2=port_c.m_flow,
+    streamVariable_1=inStream(port_b.Xi_outflow),
+    streamVariable_2=inStream(port_c.Xi_outflow))
+    "Mixed stream variables accounting for flow directions of the three-way
+    valve";
+  port_b.Xi_outflow = SorpLib.Components.Valves.Utilities.mixStreamVariables(
+    m_flow_1=port_a.m_flow,
+    m_flow_2=port_c.m_flow,
+    streamVariable_1=inStream(port_a.Xi_outflow),
+    streamVariable_2=inStream(port_c.Xi_outflow))
+    "Mixed stream variables accounting for flow directions of the three-way
+    valve";
+  port_c.Xi_outflow = SorpLib.Components.Valves.Utilities.mixStreamVariables(
+    m_flow_1=port_a.m_flow,
+    m_flow_2=port_b.m_flow,
+    streamVariable_1=inStream(port_a.Xi_outflow),
+    streamVariable_2=inStream(port_b.Xi_outflow))
+    "Mixed stream variables accounting for flow directions of the three-way
+    valve";
+
+  //
+  // Energy balance
+  //
+  port_a.h_outflow = SorpLib.Components.Valves.Utilities.mixStreamVariables(
+    m_flow_1=port_b.m_flow,
+    m_flow_2=port_c.m_flow,
+    streamVariable_1=inStream(port_b.h_outflow),
+    streamVariable_2=inStream(port_c.h_outflow))
+    "Mixed stream variables accounting for flow directions of the three-way
+    valve";
+  port_b.h_outflow = SorpLib.Components.Valves.Utilities.mixStreamVariables(
+    m_flow_1=port_a.m_flow,
+    m_flow_2=port_c.m_flow,
+    streamVariable_1=inStream(port_a.h_outflow),
+    streamVariable_2=inStream(port_c.h_outflow))
+    "Mixed stream variables accounting for flow directions of the three-way
+    valve";
+  port_c.h_outflow = SorpLib.Components.Valves.Utilities.mixStreamVariables(
+    m_flow_1=port_a.m_flow,
+    m_flow_2=port_b.m_flow,
+    streamVariable_1=inStream(port_a.h_outflow),
+    streamVariable_2=inStream(port_b.h_outflow))
+    "Mixed stream variables accounting for flow directions of the three-way
+    valve";
+
+  //
+  // Calculate actual opening
+  //
+  if not controllablePosition then
+    position_internal = if leackage then
+      min(max(fixedPosition,leackagePosition),1-leackagePosition) else
+      fixedPosition
+      "Needed for connecting to conditional components";
+  else
+    if useTimeConstant then
+      connect(position, filter.u)
+        annotation (Line(points={{0,70},{0,52}}, color={0,0,127}));
+      connect(filter.y, limiter.u)
+        annotation (Line(points={{0,29},{0,22}}, color={0,0,127}));
+
+    else
+      connect(position, limiter.u)
+        annotation (Line(points={{0,70},{0,22}}, color={0,0,127}));
+
+    end if;
+
+    connect(position_internal, limiter.y)
+      "Needed for connecting to conditional components";
+
+  end if;
+
+  //
+  // Calculate the effective flow area
+  //
+  if useKvsValue then
+    A_eff_b = Kvs_b * sqrt(rho_ref_b / (2 * dp_ref_b)) / 3600 *
+      (1 - position_internal)
+      "Effective flow area used to calculate the mass flow rate at port b";
+    A_eff_c = Kvs_c * sqrt(rho_ref_c / (2 * dp_ref_c)) / 3600 *
+      position_internal
+      "Effective flow area used to calculate the mass flow rate at port c";
+
+  else
+    A_eff_b = A_eff_max_b * (1 - position_internal)
+      "Effective flow area used to calculate the mass flow rate at port b";
+    A_eff_c = A_eff_max_c * position_internal
+      "Effective flow area used to calculate the mass flow rate at port c";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all three-way valves. It defines fundamental 
+parameters and variables required by all valves. 
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the fluid 
+ports. Furthermore, inherting models may have to add a medium model. The following 
+variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  The flow variable <i>port_b.m_flow</i> that defines the mass flow rate at port b
+  in dependance of the pressure drop between port a and b <i>dp_ab</i>.
+  </li>
+  <li>
+  The flow variable <i>port_c.m_flow</i> that defines the mass flow rate at port c
+  in dependance of the pressure drop between port a and c <i>dp_ac</i>.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"), Icon(coordinateSystem(extent={{-100,-100},{100,100}}),
+                graphics={    Line(
+          points={{0,40},{0,0}},
+          color={0,0,0},
+          thickness=1),
+        Polygon(
+          points={{-80,62},{-80,62}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-80,50},{-80,-50},{0,0},{-80,50}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-40,50},{-40,-50},{40,0},{-40,50}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          origin={40,0},
+          rotation=180),
+        Ellipse(
+          extent={{-16,60},{16,28}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Text(
+          extent={{-10,54},{10,34}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString="M",
+          textStyle={TextStyle.Bold}),
+        Polygon(
+          points={{-40,50},{-40,-50},{40,0},{-40,50}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          origin={0,-40},
+          rotation=90),
+        Line(
+          points={{-40,0},{-40,-40}},
+          color={0,0,0},
+          arrow={Arrow.None,Arrow.Filled},
+          origin={20,40},
+          rotation=90),
+        Line(
+          points={{10,0},{-10,0}},
+          color={238,46,47},
+          thickness=1,
+          arrow={Arrow.None,Arrow.Filled},
+          origin={0,-50},
+          rotation=90),
+        Text(
+          extent={{-10,12},{10,-12}},
+          lineColor={238,46,47},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="x",
+          origin={0,-46},
+          rotation=180),
+        Line(
+          points={{-40,-80},{-40,-40}},
+          color={0,0,0},
+          arrow={Arrow.None,Arrow.Filled},
+          origin={-100,40},
+          rotation=90)}),
+    Diagram(coordinateSystem(extent={{-100,-100},{100,100}})));
+end PartialThreeWayValve;
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialValve.mo b/SorpLib/Components/Valves/BaseClasses/PartialValve.mo
new file mode 100644
index 0000000..65eb738
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialValve.mo
@@ -0,0 +1,357 @@
+within SorpLib.Components.Valves.BaseClasses;
+partial model PartialValve
+  "Base model for all valves"
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  parameter Integer no_components = 1
+    "Number of components"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of setup parameters
+  //
+  parameter Boolean controllableOpening = false
+    " = true, if valve opening (i.e., position) is contrallable via an input 
+    signal"
+    annotation (Dialog(tab="General", group="Valve Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Real fixedOpening(min=0, max=1) = 0
+    "Fixed valve opening (i.e., position) if the valve is not controllable"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=not controllableOpening));
+
+  parameter Boolean useTimeConstant = false
+    " = true, if time constant is used to delay valve opening (i.e., position)"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=controllableOpening),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Modelica.Units.SI.Time tau = 1
+    "Time constant for valve opening (i.e., position)"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=controllableOpening and useTimeConstant));
+
+  parameter Boolean leackage = false
+    " = true, if valve has a leackage mass flow rate (i.e., minimal opening) to 
+    avoid singularities"
+    annotation (Dialog(tab="General", group="Valve Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Real leackageOpening(min=0, max=1) = 1e-3
+    "Leackage valve opening (i.e., minimal valve position) to avoid singularities"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=leackage));
+
+  parameter Boolean checkValve = false
+    " = true, if valve is a check valve (i.e., mass flow direction from port a 
+    to port b)"
+    annotation (Dialog(tab="General", group="Valve Setup"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+  parameter Boolean strictCheckValve = false
+    " = true, if check valve is strict: Mass can only flow from port a to b; 
+    otherwise, a smoothTransition-function is used that allows minimal mass flow 
+    from port b around the transition point of the check valve (e.g., pressure 
+    difference) but increases numerical stability"
+    annotation (Dialog(tab="General", group="Valve Setup",
+                enable=checkValve),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+
+  //
+  // Definition of parameters regarding the valve characteristic
+  //
+  parameter Boolean accountHydraulicHead = false
+    " = true, if additional hydraulic head shall be considered to calculate the
+    driving potential (i.e., pressure difference) for the mass flow rate"
+    annotation (Dialog(tab="Valve Characteristic", group="Driving Potential"),
+                choices(checkBox=true),
+                HideResult=true,
+                Evaluate=true);
+
+  parameter Modelica.Units.SI.Pressure p_hydraulicHead = 1000 * 9.81 * 0.25
+    "Additional hydraulic head (i.e., rho * g * h) used to increase the pressure 
+    at port a (i.e., positive if port a is located higher than port b)"
+    annotation (Dialog(tab="Valve Characteristic", group="Driving Potential",
+                enable=accountHydraulicHead));
+
+  //
+  // Definition or initialisation parameters
+  //
+  parameter Real opening_initial = 1
+    "Initial value of valve opening (i.e., position) if valve opening is delayed"
+    annotation (Dialog(tab="Initialisation", group="Initial Values",
+                enable=controllableOpening and useTimeConstant));
+
+  parameter Modelica.Units.SI.MassFlowRate m_flow_start = 1e-4
+    "Start value for mass flow rate"
+    annotation (Dialog(tab="Initialisation", group="Start Values"));
+
+  //
+  // Definition of advanced parameters
+  //
+  parameter Boolean avoid_events = false
+    "= true, if events are avoid by using noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "Numerics"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult = true);
+
+  //
+  // Definition of inputs
+  //
+  Modelica.Blocks.Interfaces.RealInput opening(min=0, max=1) if
+    controllableOpening
+    "Valve opening (i.e., position) input signal"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,70}), iconTransformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,70})));
+
+  //
+  // Definition of ports
+  //
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_a
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=m_flow_start))
+    "Fluid port a"
+    annotation (Placement(transformation(extent={{-90,-10},{-70,10}}),
+                iconTransformation(extent={{-90,-10},{-70,10}})),
+                choicesAllMatching=true);
+
+  replaceable SorpLib.Basics.Interfaces.BaseClasses.PartialFluidPort port_b
+    constrainedby Basics.Interfaces.BaseClasses.PartialFluidPort(
+      final no_components=no_components,
+      m_flow(start=-m_flow_start))
+    "Fluid port b"
+    annotation (Placement(transformation(extent={{70,-10},{90,10}}),
+                iconTransformation(extent={{70,-10},{90,10}})),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.PressureDifference dp
+    "Pressure difference between ports";
+  Modelica.Units.SI.PressureDifference dp_wHydraulicHead
+    "Pressure difference between ports when accounting the hydraulic";
+
+  //
+  // Definition of blocks
+  //
+  Modelica.Blocks.Continuous.CriticalDamping filter(
+    n=2,
+    f=5 / (2 * Modelica.Constants.pi * tau),
+    normalized=true,
+    initType=Modelica.Blocks.Types.Init.InitialOutput,
+    y_start=opening_initial) if controllableOpening and useTimeConstant
+    "Critical damping filter to filter opening signal"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=270,
+                origin={0,40})),
+                HideResult=true);
+
+  SorpLib.Components.Valves.Utilities.Limiter limiter(
+    lowerLimit=if leackage then leackageOpening else 0,
+    upperLimit=1) if controllableOpening
+    "Limits the input signal"
+    annotation (Placement(transformation(
+                extent={{-10,-10},{10,10}},
+                rotation=270,
+                origin={0,10})),
+                HideResult=true);
+
+  //
+  // Definition of protected connectors
+  //
+protected
+  Modelica.Blocks.Interfaces.RealInput opening_internal(min=0, max=1)
+    "Needed for connecting to conditional components";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.PressureDifference dp_
+    "Pressure difference used as driving potential to calculate mass flow rate";
+
+equation
+  //
+  // Assertations
+  //
+  if not controllableOpening then
+    assert(fixedOpening >= 0 and fixedOpening <= 1,
+          "Fixed opening (" + String(fixedOpening) + ") must between 0 and 1!",
+          level = AssertionLevel.error);
+  end if;
+
+  if leackage then
+    assert(leackageOpening >= 0 and leackageOpening <= 1,
+          "Leackage opening (" + String(leackageOpening) + ") must between 0 " +
+          "and 1!",
+          level = AssertionLevel.error);
+  end if;
+
+  //
+  // Momentum balance
+  //
+  dp = port_a.p - port_b.p
+    "Pressure difference between ports";
+  dp_wHydraulicHead = (port_a.p + p_hydraulicHead) - port_b.p
+    "Pressure difference between ports when accounting the hydraulic";
+
+  dp_ = if accountHydraulicHead then dp_wHydraulicHead else dp
+    "Pressure difference used as driving potential to calculate mass flow rate";
+
+  //
+  // Mass balance
+  //
+  0 = port_a.m_flow + port_b.m_flow
+    "Steady-state mass balance";
+
+  port_a.Xi_outflow = inStream(port_b.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+  port_b.Xi_outflow = inStream(port_a.Xi_outflow)
+    "Stream variable: Trivial equation since no change of mass fractions";
+
+  //
+  // Energy balance
+  //
+  port_a.h_outflow = inStream(port_b.h_outflow)
+    "Stream variable: Trivial equation since no change of energy";
+  port_b.h_outflow = inStream(port_a.h_outflow)
+    "Stream variable: Trivial equation since no change of energy";
+
+  //
+  // Calculate actual opening
+  //
+  if not controllableOpening then
+    opening_internal = if leackage then max(fixedOpening, leackageOpening) else
+      fixedOpening
+      "Needed for connecting to conditional components";
+  else
+    if useTimeConstant then
+      connect(opening, filter.u)
+        annotation (Line(points={{0,70},{0,52}}, color={0,0,127}));
+      connect(filter.y, limiter.u)
+        annotation (Line(points={{0,29},{0,22}}, color={0,0,127}));
+
+    else
+      connect(opening, limiter.u)
+        annotation (Line(points={{0,70},{0,22}}, color={0,0,127}));
+
+    end if;
+
+    connect(opening_internal, limiter.y)
+      "Needed for connecting to conditional components";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model of all valves. It defines fundamental parameters
+and variables required by all valves. 
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the fluid ports.
+Furthermore, inherting models may have to add further inputs and a medium model. The following 
+variables must be specified in the model that inherit properties:
+</p>
+<ul>
+  <li>
+  The flow variable <i>port_a.m_flow</i> that defines the mass flow rate at port a. The
+  mass flow rate often depends on the pressure difference <i>dp</i> between the two ports
+  but alternative calculation approaches can also be implemented.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  Major revisions (new functionalities, documentation).
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  Smaller revisions after restructuring of the library.
+  </li>
+  <li>
+  December 11, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"), Icon(coordinateSystem(extent={{-100,-100},{100,100}}),
+                graphics={    Line(
+          points={{0,40},{0,0}},
+          color={0,0,0},
+          thickness=1),
+        Polygon(
+          points={{-80,62},{-80,62}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-80,50},{-80,-50},{0,0},{-80,50}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-40,50},{-40,-50},{40,0},{-40,50}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          origin={40,0},
+          rotation=180),
+        Ellipse(
+          extent={{-16,60},{16,28}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Text(
+          extent={{-10,54},{10,34}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textString="M",
+          textStyle={TextStyle.Bold}),
+        Line(
+          points={{-40,-40},{40,-40}},
+          color={0,0,0},
+          arrow={Arrow.None,Arrow.Filled}),
+        Line(
+          points={{8,-20},{-12,-20}},
+          color={238,46,47},
+          thickness=1,
+          arrow={Arrow.None,Arrow.Filled},
+          visible=checkValve),
+        Text(
+          extent={{-10,-6},{10,-30}},
+          lineColor={238,46,47},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          textStyle={TextStyle.Bold},
+          textString="x",
+          visible=checkValve)}),
+    Diagram(coordinateSystem(extent={{-100,-100},{100,100}})));
+end PartialValve;
diff --git a/SorpLib/Components/Valves/BaseClasses/PartialValveCharacteristic.mo b/SorpLib/Components/Valves/BaseClasses/PartialValveCharacteristic.mo
new file mode 100644
index 0000000..57133af
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/PartialValveCharacteristic.mo
@@ -0,0 +1,44 @@
+within SorpLib.Components.Valves.BaseClasses;
+partial function PartialValveCharacteristic
+  "Base function for all valve characteristics"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real opening(min=0, max=1)
+    "Valve opening (i.e., position)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real fc_max = 1.6
+    "Maximal flow coefficient if valve is completly open"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real fc
+    "Flow coefficient"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the base function for all valve characteristics. It
+definies common inputs and outputs. This partial functions is based on the function
+<a href=\"Modelica://Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.baseFun\">Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.baseFun</a>.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add 
+further inputs and the calculation approach for the valve characteristic 
+(i.e., <i>fc(opening)</i>).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end PartialValveCharacteristic;
diff --git a/SorpLib/Components/Valves/BaseClasses/package.mo b/SorpLib/Components/Valves/BaseClasses/package.mo
new file mode 100644
index 0000000..9949264
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Components.Valves;
+package BaseClasses "Base models and functions for all valves"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial valve models and valve characteristic functions,
+containing fundamental definitions for valves and their charecteristics. The 
+content of this package is only of interest when adding new valves to the library. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Components/Valves/BaseClasses/package.order b/SorpLib/Components/Valves/BaseClasses/package.order
new file mode 100644
index 0000000..7be8b8c
--- /dev/null
+++ b/SorpLib/Components/Valves/BaseClasses/package.order
@@ -0,0 +1,9 @@
+PartialValve
+PartialCondensateRefluxValve
+PartialOrificeValve
+PartialIncompressibleValve
+PartialCompressibleValve
+PartialThreeWayValve
+PartialIncompressibleThreeWayValve
+PartialCompressibleThreeWayValve
+PartialValveCharacteristic
diff --git a/SorpLib/Components/Valves/GasValves/CompressibleThreeWayValve.mo b/SorpLib/Components/Valves/GasValves/CompressibleThreeWayValve.mo
new file mode 100644
index 0000000..9ce7b8b
--- /dev/null
+++ b/SorpLib/Components/Valves/GasValves/CompressibleThreeWayValve.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Valves.GasValves;
+model CompressibleThreeWayValve
+  "Three-way valve for compressible fluids"
+  extends
+    SorpLib.Components.Valves.BaseClasses.PartialCompressibleThreeWayValve(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variabbles
+  //
+protected
+  Medium.ThermodynamicState state_a_in
+    "Thermodynamic state record with instreaming properties at port a";
+
+equation
+  //
+  // Calculate fluid properties
+  //
+  state_a_in = Medium.setState_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Thermodynamic state record with instreaming properties at port a";
+
+  rho_a = Medium.density(state=state_a_in)
+    "Instreaming density at port a";
+  gamma_a = Medium.isentropicExponent( state=state_a_in)
+    "Instreaming isentropic exponent at port a";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This three-way valve can be applied for compressible fluids, such as air. 
+The valve splits a mass flow entering port a into two mass flows leaving port b 
+and c. For thus purpose, the valve position defines the division of the instreaming 
+mass flow at port a: I.e., for <i>position = 0</i>, the mass flows to port b; 
+for <i>position = 1</i>, the mass flows to port c. The position can be set by an 
+input signal.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mass flow rates <i>port_b.m_flow</i> and <i>port_c.m_flow</i> are calculated 
+in dependance of the instreaming pressure <i>p</i>, instreaming density <i>&rho;</i>, 
+and discharge function <i>&Psi;<sub>i</sub></i>, following the equation of Bernoulli 
+for compressible fluids (i.e., equation of Saint-Venant & Wantzel):
+</p>
+<pre>
+    port_b.m_flow = -A<sub>eff,b</sub> * <strong>sqrt</strong>(2 * &rho; * p) * &Psi;<sub>a</sub>;
+</pre>
+<pre>
+    port_c.m_flow = -A<sub>eff,c</sub> * <strong>sqrt</strong>(2 * &rho; * p) * &Psi;<sub>c</sub>;
+</pre>
+<p>
+The effective areas <i>A<sub>eff,i</sub></i> depends on the actual valve position
+and are calculated via a linear valve characteristic. For this purpose, the maximal 
+effective areas <i>A<sub>eff,max,i</sub></i> are required. The maximal effective 
+areas <i>A<sub>eff,max,i</sub></i> are present if the valve is fully opened and 
+can directly be specified. Alternatively, they can be calculated using the maximal 
+flow coefficients <i>Kvs<sub>i</sub></i>, reference densities <i>&rho;<sub>ref,i</sub></i>, 
+and reference pressure drops <i>&Delta;p<sub>ref,i</sub></i>:
+</p>
+<pre>
+    <i>A<sub>eff,max,i</sub></i> = Kvs<sub>i</sub> * <strong>sqrt</strong>(&rho;<sub>ref,i</sub> / (2 * &Delta;p<sub>ref,i</sub>));
+</pre>
+<p>
+The discharge functions <i>&Psi;<sub>i</sub></i> depend on the pressure ratios between the 
+outstreaming and instreaming pressures <i>p<sub>out,i</sub>/p<sub>in</sub></i> as long as 
+the velocity is below the speed of sound. Once the speed of sound is reached, the discharge 
+functions do not change anymore:
+</p>
+<pre>
+    &Psi;<sub>i</sub> = <strong>if</strong> p<sub>out,i</sub>/p<sub>in</sub> &gt; (2 / (&gamma; + 1)) ^ (&gamma; / (&gamma; - 1)) <strong>then</strong> 
+         <strong>sqrt</strong>(&gamma; / (&gamma; - 1) * ((p<sub>out,i</sub>/p<sub>in</sub>) ^ (2 / &gamma;) - (p<sub>out,i</sub>/p<sub>in</sub>) ^ ((&gamma; + 1) / &gamma;))) <strong>else</strong>
+         <strong>sqrt</strong>(2 ^ (2 / (&gamma; - 1)) * &gamma; / (&gamma; + 1) ^ ((&gamma; + 1) / (&gamma; - 1)));
+</pre>
+<p>
+Not that the valve is a check valve, thus mass can only flow from port a to port b and c.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Compressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  Isentropic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks of open sorption systems to
+split a mass flow rate.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>controllablePosition</i>:
+  Defines if the valve position can be set via an input signal.
+  </li>
+  <li>
+  <i>useTimeConstant</i>:
+  Defines if the valve position input signal is delayed by a time constant.
+  </li>
+  <li>
+  <i>leackage</i>:
+  Defines if the valve has a small leackage flow.
+  </li>
+  <br/>
+  <li>
+  <i>useKvsValue</i>:
+  Defines if the mass flow rates at port b and c are calculated using the 
+  Kvs-approach or A_eff-approach.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The model has two dynamic states if the input signal describing the valve position
+is delayed by a time constant. Otherwise, the model has no dynamic states.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/GasValves/CompressibleValve.mo b/SorpLib/Components/Valves/GasValves/CompressibleValve.mo
new file mode 100644
index 0000000..736f334
--- /dev/null
+++ b/SorpLib/Components/Valves/GasValves/CompressibleValve.mo
@@ -0,0 +1,179 @@
+within SorpLib.Components.Valves.GasValves;
+model CompressibleValve "Valve for compressible fluids"
+  extends SorpLib.Components.Valves.BaseClasses.PartialCompressibleValve(
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.GasPort_out port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the ideal gas, ideal gas mixture, or ideal gas-vapor mixture"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variabbles
+  //
+protected
+  Medium.ThermodynamicState state_a_in
+    "Thermodynamic state record with instreaming properties at port a";
+  Medium.ThermodynamicState state_b_in
+    "Thermodynamic state record with instreaming properties at port b";
+
+equation
+  //
+  // Calculate fluid properties
+  //
+  state_a_in = Medium.setState_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Thermodynamic state record with instreaming properties at port a";
+  state_b_in = Medium.setState_phX(
+    p=port_b.p,
+    h=inStream(port_b.h_outflow),
+    X=cat(1,inStream(port_b.Xi_outflow),{1-sum(inStream(port_b.Xi_outflow))}))
+    "Thermodynamic state record with instreaming properties at port b";
+
+  rho_a = Medium.density(state=state_a_in)
+    "Instreaming density at port a";
+  rho_b = Medium.density(state=state_b_in)
+    "Instreaming density at port b";
+
+  gamma_a = Medium.isentropicExponent( state=state_a_in)
+    "Instreaming isentropic exponent at port a";
+  gamma_b = Medium.isentropicExponent( state=state_b_in)
+    "Instreaming isentropic exponent at port b";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This valve can be applied for compressible fluids, such as air. The valve opening 
+(i.e., position) can be set via an input signal. The valve can be used as a simple 
+on/off valve (i.e., opening = 0/1) or as a control valve by setting the valve opening 
+betwenn 0 and 1.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mass flow rate <i>port_a.m_flow</i> is calculated in dependance of the instreaming
+pressure  <i>p</i>, instreaming density <i>&rho;</i>, and discharge function <i>&Psi;</i>,
+following the equation of Bernoulli for compressible fluids (i.e., equation of Saint-Venant 
+& Wantzel):
+</p>
+<pre>
+    port_a.m_flow = A<sub>eff</sub> * <strong>sqrt</strong>(2 * &rho; * p) * &Psi;;
+</pre>
+<p>
+The effective area <i>A<sub>eff</sub></i> depends on the actual valve opening (i.e., 
+position) and is calculated via the selected 
+<a href=\"Modelica://SorpLib.Components.Valves.ValveCharacteristics\">valve characteristic</a>).
+For this purpose, the maximal effective area <i>A<sub>eff,max</sub></i> is required.
+The maximal effective area <i>A<sub>eff,max</sub></i> is present if the valve is fully
+opened and can directly be specified. Alternatively, it can be calculated using the maximal 
+flow coefficient <i>Kvs</i>, reference density <i>&rho;<sub>ref</sub></i>, and reference 
+pressure drop <i>&Delta;p<sub>ref</sub></i>:
+</p>
+<pre>
+    <i>A<sub>eff,max</sub></i> = Kvs * <strong>sqrt</strong>(&rho;<sub>ref</sub> / (2 * &Delta;p<sub>ref</sub>));
+</pre>
+<p>
+The discharge function <i>&Psi;</i> depends on the pressure ratio between the outstreaming and
+instreaming pressure <i>p<sub>out</sub>/p<sub>in</sub></i> as long as the velocity is below the
+speed of sound. Once the speed of sound is reached, the discharge function does not change anymore:
+</p>
+<pre>
+    &Psi; = <strong>if</strong> p<sub>out</sub>/p<sub>in</sub> &gt; (2 / (&gamma; + 1)) ^ (&gamma; / (&gamma; - 1)) <strong>then</strong> 
+         <strong>sqrt</strong>(&gamma; / (&gamma; - 1) * ((p<sub>out</sub>/p<sub>in</sub>) ^ (2 / &gamma;) - (p<sub>out</sub>/p<sub>in</sub>) ^ ((&gamma; + 1) / &gamma;))) <strong>else</strong>
+         <strong>sqrt</strong>(2 ^ (2 / (&gamma; - 1)) * &gamma; / (&gamma; + 1) ^ ((&gamma; + 1) / (&gamma; - 1)));
+</pre>
+<p>
+To account for the flow direction, the root expression is calculated using the anti-symmetric 
+root approximation
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+Furthermore, the valve can be a check valve (see options). If the valve is a check valve, mass 
+can only flow from port a to port b.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Compressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  Isentropic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks of open sorption systems.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>controllableOpening</i>:
+  Defines if the valve opening can be set via an input signal.
+  </li>
+  <li>
+  <i>useTimeConstant</i>:
+  Defines if the valve opening input signal is delayed by a time constant.
+  </li>
+  <li>
+  <i>leackage</i>:
+  Defines if the valve has a small leackage flow.
+  </li>
+  <li>
+  <i>checkValve</i>:
+  Defines if the valve is a strict check valve, thus only allowing a mass flow from 
+  port a to port b.
+  </li>
+  <br/>
+  <li>
+  <i>useKvsValue</i>:
+  Defines if the mass flow rate is calculated using the Kvs-approach or A_eff-approach.
+  </li>
+  <li>
+  <i>valveCharacteristic</i>:
+  Defines the valve characteristic (see 
+  <a href=\"Modelica://SorpLib.Components.Valves.ValveCharacteristics\">SorpLib.Components.Valves.ValveCharacteristics</a>).
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The model has two dynamic states if the input signal describing the valve opening is
+delayed by a time constant. Otherwise, the model has no dynamic states.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CompressibleValve;
diff --git a/SorpLib/Components/Valves/GasValves/Tester/Test_CompressibleThreeWayValve.mo b/SorpLib/Components/Valves/GasValves/Tester/Test_CompressibleThreeWayValve.mo
new file mode 100644
index 0000000..8019765
--- /dev/null
+++ b/SorpLib/Components/Valves/GasValves/Tester/Test_CompressibleThreeWayValve.mo
@@ -0,0 +1,178 @@
+within SorpLib.Components.Valves.GasValves.Tester;
+model Test_CompressibleThreeWayValve
+  "Tester for the three-way valve for compressible fluids"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource[3] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="bar") = 100000,
+    each T_fixed=373.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource[3] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,40},{50,60}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource[3] fs_c(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-40},{50,-60}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.GasValves.CompressibleThreeWayValve threeWayValve(
+      controllablePosition=true)
+    "Three-way valve: Controllable, no time constant, no leackage"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,40})));
+
+  SorpLib.Components.Valves.GasValves.CompressibleThreeWayValve threeWayValve_delay(
+    controllablePosition=true,
+    useTimeConstant=true,
+    tau=10,
+    position_initial=0)
+    "Three-way valve: Controllable, time constant, no leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,0})));
+
+  SorpLib.Components.Valves.GasValves.CompressibleThreeWayValve threeWayValve_delay_leackage(
+    controllablePosition=true,
+    useTimeConstant=true,
+    leackage=true,
+    position_initial=0)
+    "Three-way valve: Controllable, time constant, leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,-40})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=1,
+    rising=150,
+    width=50,
+    falling=0,
+    period=250,
+    offset=0)
+    "Input signal for relative filling level"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={10,90})));
+
+  Modelica.Blocks.Sources.Sine input_p_b(
+    amplitude=-0.4e5,
+    f=1/100,
+    offset=1e5)  "Input signal for pressure at port b"
+    annotation (Placement(transformation(extent={{100,40},{80,60}})));
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=25,
+    f=1/100,
+    offset=273.15 + 150)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+  Modelica.Blocks.Sources.Sine input_p_c(
+    amplitude=-0.4e5,
+    f=1/100,
+    offset=1e5)  "Input signal for pressure at port c"
+    annotation (Placement(transformation(extent={{100,-60},{80,-40}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, threeWayValve.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,40},{-7.8,40}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[2].port, threeWayValve_delay.port_a) annotation (Line(
+      points={{-60,0},{-7.8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[3].port, threeWayValve_delay_leackage.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,-40},{-7.8,-40}},
+      color={244,125,35},
+      thickness=1));
+  connect(threeWayValve.port_b, fs_b[1].port) annotation (Line(
+      points={{0,48},{0,50},{60,50}},
+      color={244,125,35},
+      thickness=1));
+  connect(threeWayValve_delay.port_b, fs_b[2].port) annotation (Line(
+      points={{0,8},{0,10},{20,10},{20,50},{60,50}},
+      color={244,125,35},
+      thickness=1));
+  connect(threeWayValve_delay_leackage.port_b, fs_b[3].port) annotation (Line(
+      points={{0,-32},{0,-30},{20,-30},{20,50},{60,50}},
+      color={244,125,35},
+      thickness=1));
+  connect(threeWayValve.port_c, fs_c[1].port) annotation (Line(
+      points={{0,32},{0,30},{40,30},{40,-50},{60,-50}},
+      color={244,125,35},
+      thickness=1));
+  connect(threeWayValve_delay.port_c, fs_c[2].port) annotation (Line(
+      points={{0,-8},{0,-10},{40,-10},{40,-50},{60,-50}},
+      color={244,125,35},
+      thickness=1));
+  connect(threeWayValve_delay_leackage.port_c, fs_c[3].port) annotation (Line(
+      points={{0,-48},{0,-50},{60,-50}},
+      color={244,125,35},
+      thickness=1));
+
+  for ind in 1:3 loop
+    connect(input_T.y, fs_b[ind].T_input) annotation (Line(points={{79,0},{70,0},
+            {70,48},{61.2,48}},
+                          color={0,0,127}));
+    connect(input_T.y, fs_c[ind].T_input) annotation (Line(points={{79,0},{70,0},{70,
+            -48},{61.2,-48}}, color={0,0,127}));
+
+    connect(input_p_b.y, fs_b[ind].p_input) annotation (Line(points={{79,50},{70,
+            50},{70,55},{61.2,55}}, color={0,0,127}));
+    connect(input_p_c.y, fs_c[ind].p_input) annotation (Line(points={{79,-50},{70,-50},
+            {70,-55},{61.2,-55}}, color={0,0,127}));
+  end for;
+
+  connect(input_lRel.y, threeWayValve.position)
+    annotation (Line(points={{10,79},{10,40},{7,40}}, color={0,0,127}));
+  connect(input_lRel.y, threeWayValve_delay.position)
+    annotation (Line(points={{10,79},{10,0},{7,0}}, color={0,0,127}));
+  connect(input_lRel.y, threeWayValve_delay_leackage.position)
+    annotation (Line(points={{10,79},{10,-40},{7,-40}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the compressible three-way valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_CompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/GasValves/Tester/Test_CompressibleValve.mo b/SorpLib/Components/Valves/GasValves/Tester/Test_CompressibleValve.mo
new file mode 100644
index 0000000..8e287c9
--- /dev/null
+++ b/SorpLib/Components/Valves/GasValves/Tester/Test_CompressibleValve.mo
@@ -0,0 +1,286 @@
+within SorpLib.Components.Valves.GasValves.Tester;
+model Test_CompressibleValve
+  "Tester for the valve for compressible fluids"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource[9] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="bar") = 100000,
+    each T_fixed=373.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.GasVaporMixtureSource[9] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=1) "Compressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,80},{10,100}})));
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=2) "Compressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,60},{10,80}})));
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=3) "Compressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,40},{10,60}})));
+
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_delay_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=1,
+    opening_initial=0) "Compressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_delay_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=2,
+    opening_initial=0) "Compressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_delay_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=3,
+    opening_initial=0) "Compressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_delay_leackage_check_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=1,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=1,
+    opening_initial=0) "Compressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,-60},{10,-40}})));
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_delay_leackage_check_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=1,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=2,
+    opening_initial=0) "Compressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,-80},{10,-60}})));
+  SorpLib.Components.Valves.GasValves.CompressibleValve valve_controllable_delay_leackage_check_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=true,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=3,
+    opening_initial=0) "Compressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,-100},{10,-80}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=1,
+    rising=150,
+    width=50,
+    falling=0,
+    period=250,
+    offset=0)
+    "Input signal for relative filling level"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+  Modelica.Blocks.Sources.Sine input_p(
+    amplitude=-0.4e5,
+    f=1/100,
+    offset=1e5)
+    "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,10},{80,30}})));
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=25,
+    f=1/100,
+    offset=273.15 + 150)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,-30},{80,-10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, valve_controllable_Kvs_cType1.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,90},{-8,90}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[2].port, valve_controllable_Kvs_cType2.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,70},{-8,70}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[3].port, valve_controllable_Kvs_cType3.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,50},{-8,50}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[4].port, valve_controllable_delay_Kvs_cType1.port_a) annotation (
+      Line(
+      points={{-60,0},{-20,0},{-20,20},{-8,20}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[5].port, valve_controllable_delay_Kvs_cType2.port_a) annotation (
+      Line(
+      points={{-60,0},{-8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[6].port, valve_controllable_delay_Kvs_cType3.port_a) annotation (
+      Line(
+      points={{-60,0},{-20,0},{-20,-20},{-8,-20}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[7].port, valve_controllable_delay_leackage_check_Kvs_cType1.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-50},{-8,-50}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[8].port, valve_controllable_delay_leackage_check_Kvs_cType2.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-70},{-8,-70}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_a[9].port, valve_controllable_delay_leackage_check_Kvs_cType3.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-90},{-8,-90}},
+      color={244,125,35},
+      thickness=1));
+
+  connect(fs_b[1].port, valve_controllable_Kvs_cType1.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,90},{8,90}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b[2].port, valve_controllable_Kvs_cType2.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,70},{8,70}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b[3].port, valve_controllable_Kvs_cType3.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,50},{8,50}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b[4].port, valve_controllable_delay_Kvs_cType1.port_b) annotation (
+      Line(
+      points={{60,0},{20,0},{20,20},{8,20}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b[5].port, valve_controllable_delay_Kvs_cType2.port_b) annotation (
+      Line(
+      points={{60,0},{8,0}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b[6].port, valve_controllable_delay_Kvs_cType3.port_b) annotation (
+      Line(
+      points={{60,0},{20,0},{20,-20},{8,-20}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b[7].port, valve_controllable_delay_leackage_check_Kvs_cType1.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-50},{8,-50}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b[8].port, valve_controllable_delay_leackage_check_Kvs_cType2.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-70},{8,-70}},
+      color={244,125,35},
+      thickness=1));
+  connect(fs_b[9].port, valve_controllable_delay_leackage_check_Kvs_cType3.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-90},{8,-90}},
+      color={244,125,35},
+      thickness=1));
+
+  for ind in 1:9 loop
+    connect(input_T.y, fs_b[ind].T_input) annotation (Line(points={{79,-20},{70,
+            -20},{70,-2},{61.2,-2}},
+                          color={0,0,127}));
+    connect(input_p.y, fs_b[ind].p_input)
+      annotation (Line(points={{79,20},{70,20},{70,5},{61.2,5}},
+                                                               color={0,0,127}));
+  end for;
+
+  connect(input_lRel.y, valve_controllable_Kvs_cType1.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,97},{0,97}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_Kvs_cType2.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,77},{0,77}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_Kvs_cType3.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,57},{0,57}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType1.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,27},{0,27}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType2.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,7},{0,7}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType3.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-13},{0,-13}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType1.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-43},{0,-43}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType2.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-63},{0,-63}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType3.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-83},{0,-83}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the compressible valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_CompressibleValve;
diff --git a/SorpLib/Components/Valves/GasValves/Tester/package.mo b/SorpLib/Components/Valves/GasValves/Tester/package.mo
new file mode 100644
index 0000000..b1f0bdf
--- /dev/null
+++ b/SorpLib/Components/Valves/GasValves/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Valves.GasValves;
+package Tester "Models to test and varify models for gas valves"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented gas, gas mixture,
+and gas-vapor mixture valves. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Valves/GasValves/Tester/package.order b/SorpLib/Components/Valves/GasValves/Tester/package.order
new file mode 100644
index 0000000..042bf5b
--- /dev/null
+++ b/SorpLib/Components/Valves/GasValves/Tester/package.order
@@ -0,0 +1,2 @@
+Test_CompressibleValve
+Test_CompressibleThreeWayValve
diff --git a/SorpLib/Components/Valves/GasValves/package.mo b/SorpLib/Components/Valves/GasValves/package.mo
new file mode 100644
index 0000000..b708497
--- /dev/null
+++ b/SorpLib/Components/Valves/GasValves/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Valves;
+package GasValves "Gas, gas mixture, and gas-vapor mixture valves"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains gas, gas mixture, and gas-vapor mixture valves based on 
+the open-source Modelica Standard Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end GasValves;
diff --git a/SorpLib/Components/Valves/GasValves/package.order b/SorpLib/Components/Valves/GasValves/package.order
new file mode 100644
index 0000000..d872a20
--- /dev/null
+++ b/SorpLib/Components/Valves/GasValves/package.order
@@ -0,0 +1,3 @@
+CompressibleValve
+CompressibleThreeWayValve
+Tester
diff --git a/SorpLib/Components/Valves/LiquidValves/IncompressibleThreeWayValve.mo b/SorpLib/Components/Valves/LiquidValves/IncompressibleThreeWayValve.mo
new file mode 100644
index 0000000..078d7e9
--- /dev/null
+++ b/SorpLib/Components/Valves/LiquidValves/IncompressibleThreeWayValve.mo
@@ -0,0 +1,138 @@
+within SorpLib.Components.Valves.LiquidValves;
+model IncompressibleThreeWayValve
+  "Three-way valve for incompressible fluids"
+  extends
+    SorpLib.Components.Valves.BaseClasses.PartialIncompressibleThreeWayValve(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculate fluid properties
+  //
+  rho_a = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Instreaming density at port a";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This three-way valve can be applied for incompressible fluids, such as liquid water. 
+The valve splits a mass flow entering port a into two mass flows leaving port b 
+and c. For thus purpose, the valve position defines the division of the instreaming 
+mass flow at port a: I.e., for <i>position = 0</i>, the mass flows to port b; 
+for <i>position = 1</i>, the mass flows to port c. The position can be set by an 
+input signal.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mass flow rates <i>port_b.m_flow</i> and <i>port_c.m_flow</i> are calculated 
+in dependance of the pressure drops <i>&Delta;p<sub>ab</sub> = port_a.p - port_b.p</i>, 
+and <i>&Delta;p<sub>ac</sub> = port_a.p - port_c.p</i>, following the equation of 
+Bernoulli for incompressible fluids:
+</p>
+<pre>
+    port_b.m_flow = -A<sub>eff,b</sub> * <strong>sqrt</strong>(2 * &rho; * &Delta;p<sub>ab</sub>) *(1 - position);
+</pre>
+<pre>
+    port_c.m_flow = -A<sub>eff,c</sub> * <strong>sqrt</strong>(2 * &rho; * &Delta;p<sub>ac</sub>) * position;
+</pre>
+<p>
+The effective areas <i>A<sub>eff,i</sub></i> depends on the actual valve position
+and are calculated via a linear valve characteristic. For this purpose, the maximal 
+effective areas <i>A<sub>eff,max,i</sub></i> are required. The maximal effective 
+areas <i>A<sub>eff,max,i</sub></i> are present if the valve is fully opened and 
+can directly be specified. Alternatively, they can be calculated using the maximal 
+flow coefficients <i>Kvs<sub>i</sub></i>, reference densities <i>&rho;<sub>ref,i</sub></i>, 
+and reference pressure drops <i>&Delta;p<sub>ref,i</sub></i>:
+</p>
+<pre>
+    <i>A<sub>eff,max,i</sub></i> = Kvs<sub>i</sub> * <strong>sqrt</strong>(&rho;<sub>ref,i</sub> / (2 * &Delta;p<sub>ref,i</sub>));
+</pre>
+<p>
+The density <i>&rho;</i> corresponds to the inlet density of the actual flow 
+direction. Note that the valve is a strict check valve, thus mass can only flow 
+from port a to port b and c.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Incompressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks of closed sorption systems to
+split a mass flow rate.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>controllablePosition</i>:
+  Defines if the valve position can be set via an input signal.
+  </li>
+  <li>
+  <i>useTimeConstant</i>:
+  Defines if the valve position input signal is delayed by a time constant.
+  </li>
+  <li>
+  <i>leackage</i>:
+  Defines if the valve has a small leackage flow.
+  </li>
+  <br/>
+  <li>
+  <i>useKvsValue</i>:
+  Defines if the mass flow rates at port b and c are calculated using the 
+  Kvs-approach or A_eff-approach.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The model has two dynamic states if the input signal describing the valve position
+is delayed by a time constant. Otherwise, the model has no dynamic states.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IncompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/LiquidValves/IncompressibleValve.mo b/SorpLib/Components/Valves/LiquidValves/IncompressibleValve.mo
new file mode 100644
index 0000000..2d9391b
--- /dev/null
+++ b/SorpLib/Components/Valves/LiquidValves/IncompressibleValve.mo
@@ -0,0 +1,151 @@
+within SorpLib.Components.Valves.LiquidValves;
+model IncompressibleValve "Valve for incompressible fluids"
+  extends SorpLib.Components.Valves.BaseClasses.PartialIncompressibleValve(
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.LiquidPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_R1pT
+    constrainedby Modelica.Media.Interfaces.PartialMedium
+    "Medium model of the (ideal) liquid"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculate fluid properties
+  //
+  rho_a = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Instreaming density at port a";
+  rho_b = Medium.density_phX(
+    p=port_b.p,
+    h=inStream(port_b.h_outflow),
+    X=cat(1,inStream(port_b.Xi_outflow),{1-sum(inStream(port_b.Xi_outflow))}))
+    "Instreaming density at port b";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This valve can be applied for incompressible fluids, such as liquid water. The valve
+opening (i.e., position) can be set via an input signal. The valve can be used as a
+simple on/off valve (i.e., opening = 0/1) or as a control valve by setting the valve
+opening betwenn 0 and 1.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mass flow rate <i>port_a.m_flow</i> is calculated in dependance of the pressure 
+drop <i>&Delta;p = (port_a.p + &Delta;p<sub>hydraulic head</sub>) - port_b.p</i>, 
+which can be increased by accounting a hydaulic head (see options), following the 
+equation of Bernoulli for incompressible fluids:
+</p>
+<pre>
+    port_a.m_flow = A<sub>eff</sub> * <strong>sqrt</strong>(2 * &rho; * &Delta;p);
+</pre>
+<p>
+The effective area <i>A<sub>eff</sub></i> depends on the actual valve opening (i.e., 
+position) and is calculated via the selected 
+<a href=\"Modelica://SorpLib.Components.Valves.ValveCharacteristics\">valve characteristic</a>).
+For this purpose, the maximal effective area <i>A<sub>eff,max</sub></i> is required.
+The maximal effective area <i>A<sub>eff,max</sub></i> is present if the valve is fully
+opened and can directly be specified. Alternatively, it can be calculated using the maximal 
+flow coefficient <i>Kvs</i>, reference density <i>&rho;<sub>ref</sub></i>, and reference 
+pressure drop <i>&Delta;p<sub>ref</sub></i>:
+</p>
+<pre>
+    <i>A<sub>eff,max</sub></i> = Kvs * <strong>sqrt</strong>(&rho;<sub>ref</sub> / (2 * &Delta;p<sub>ref</sub>));
+</pre>
+<p>
+The density <i>&rho;</i> corresponds to the inlet density of the actual flow direction.
+To account for the flow direction, the root expression is calculated using the anti-symmetric 
+root approximation
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+Furthermore, the valve can be a check valve (see options). If the valve is a check valve, mass 
+can only flow from port a to port b.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Incompressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks of closed sorption systems.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>controllableOpening</i>:
+  Defines if the valve opening can be set via an input signal.
+  </li>
+  <li>
+  <i>useTimeConstant</i>:
+  Defines if the valve opening input signal is delayed by a time constant.
+  </li>
+  <li>
+  <i>leackage</i>:
+  Defines if the valve has a small leackage flow.
+  </li>
+  <li>
+  <i>checkValve</i>:
+  Defines if the valve is a strict check valve, thus only allowing a mass flow from 
+  port a to port b.
+  </li>
+  <br/>
+  <li>
+  <i>useKvsValue</i>:
+  Defines if the mass flow rate is calculated using the Kvs-approach or A_eff-approach.
+  </li>
+  <li>
+  <i>valveCharacteristic</i>:
+  Defines the valve characteristic (see 
+  <a href=\"Modelica://SorpLib.Components.Valves.ValveCharacteristics\">SorpLib.Components.Valves.ValveCharacteristics</a>).
+  </li>
+  <li>
+  <i>accountHydraulicHead</i>:
+  Defines if a hydraulic head is used to increase the pressure at port a.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The model has two dynamic states if the input signal describing the valve opening is
+delayed by a time constant. Otherwise, the model has no dynamic states.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IncompressibleValve;
diff --git a/SorpLib/Components/Valves/LiquidValves/Tester/Test_IncompressibleThreeWayValve.mo b/SorpLib/Components/Valves/LiquidValves/Tester/Test_IncompressibleThreeWayValve.mo
new file mode 100644
index 0000000..8bc4185
--- /dev/null
+++ b/SorpLib/Components/Valves/LiquidValves/Tester/Test_IncompressibleThreeWayValve.mo
@@ -0,0 +1,178 @@
+within SorpLib.Components.Valves.LiquidValves.Tester;
+model Test_IncompressibleThreeWayValve
+  "Tester for the three-way valve for incompressible fluids"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource[3] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="bar") = 1000000,
+    each T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource[3] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,40},{50,60}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource[3] fs_c(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-40},{50,-60}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.LiquidValves.IncompressibleThreeWayValve threeWayValve(
+      controllablePosition=true)
+    "Three-way valve: Controllable, no time constant, no leackage"
+    annotation (Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,40})));
+
+  SorpLib.Components.Valves.LiquidValves.IncompressibleThreeWayValve threeWayValve_delay(
+    controllablePosition=true,
+    useTimeConstant=true,
+    tau=10,
+    position_initial=0)
+    "Three-way valve: Controllable, time constant, no leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,0})));
+
+  SorpLib.Components.Valves.LiquidValves.IncompressibleThreeWayValve threeWayValve_delay_leackage(
+    controllablePosition=true,
+    useTimeConstant=true,
+    leackage=true,
+    position_initial=0)
+    "Three-way valve: Controllable, time constant, leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,-40})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=1,
+    rising=150,
+    width=50,
+    falling=0,
+    period=250,
+    offset=0)
+    "Input signal for relative filling level"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={10,90})));
+
+  Modelica.Blocks.Sources.Sine input_p_b(
+    amplitude=-1e5,
+    f=1/100,
+    offset=10e5) "Input signal for pressure at port b"
+    annotation (Placement(transformation(extent={{100,40},{80,60}})));
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=25,
+    f=1/100,
+    offset=273.15 + 50)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+  Modelica.Blocks.Sources.Sine input_p_c(
+    amplitude=-1e5,
+    f=1/100,
+    offset=10e5) "Input signal for pressure at port c"
+    annotation (Placement(transformation(extent={{100,-60},{80,-40}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, threeWayValve.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,40},{-7.8,40}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[2].port, threeWayValve_delay.port_a) annotation (Line(
+      points={{-60,0},{-7.8,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[3].port, threeWayValve_delay_leackage.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,-40},{-7.8,-40}},
+      color={28,108,200},
+      thickness=1));
+  connect(threeWayValve.port_b, fs_b[1].port) annotation (Line(
+      points={{0,48},{0,50},{60,50}},
+      color={28,108,200},
+      thickness=1));
+  connect(threeWayValve_delay.port_b, fs_b[2].port) annotation (Line(
+      points={{0,8},{0,10},{20,10},{20,50},{60,50}},
+      color={28,108,200},
+      thickness=1));
+  connect(threeWayValve_delay_leackage.port_b, fs_b[3].port) annotation (Line(
+      points={{0,-32},{0,-30},{20,-30},{20,50},{60,50}},
+      color={28,108,200},
+      thickness=1));
+  connect(threeWayValve.port_c, fs_c[1].port) annotation (Line(
+      points={{0,32},{0,30},{40,30},{40,-50},{60,-50}},
+      color={28,108,200},
+      thickness=1));
+  connect(threeWayValve_delay.port_c, fs_c[2].port) annotation (Line(
+      points={{0,-8},{0,-10},{40,-10},{40,-50},{60,-50}},
+      color={28,108,200},
+      thickness=1));
+  connect(threeWayValve_delay_leackage.port_c, fs_c[3].port) annotation (Line(
+      points={{0,-48},{0,-50},{60,-50}},
+      color={28,108,200},
+      thickness=1));
+
+  for ind in 1:3 loop
+    connect(input_T.y, fs_b[ind].T_input) annotation (Line(points={{79,0},{70,0},
+            {70,48},{61.2,48}},
+                          color={0,0,127}));
+    connect(input_T.y, fs_c[ind].T_input) annotation (Line(points={{79,0},{70,0},{70,
+            -48},{61.2,-48}}, color={0,0,127}));
+
+    connect(input_p_b.y, fs_b[ind].p_input) annotation (Line(points={{79,50},{70,
+            50},{70,55},{61.2,55}}, color={0,0,127}));
+    connect(input_p_c.y, fs_c[ind].p_input) annotation (Line(points={{79,-50},{70,-50},
+            {70,-55},{61.2,-55}}, color={0,0,127}));
+  end for;
+
+  connect(input_lRel.y, threeWayValve.position)
+    annotation (Line(points={{10,79},{10,40},{7,40}}, color={0,0,127}));
+  connect(input_lRel.y, threeWayValve_delay.position)
+    annotation (Line(points={{10,79},{10,0},{7,0}}, color={0,0,127}));
+  connect(input_lRel.y, threeWayValve_delay_leackage.position)
+    annotation (Line(points={{10,79},{10,-40},{7,-40}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the incompressible three-way valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_IncompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/LiquidValves/Tester/Test_IncompressibleValve.mo b/SorpLib/Components/Valves/LiquidValves/Tester/Test_IncompressibleValve.mo
new file mode 100644
index 0000000..aae46f2
--- /dev/null
+++ b/SorpLib/Components/Valves/LiquidValves/Tester/Test_IncompressibleValve.mo
@@ -0,0 +1,280 @@
+within SorpLib.Components.Valves.LiquidValves.Tester;
+model Test_IncompressibleValve
+  "Tester for the valve for incompressible fluids"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.LiquidSource[9] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="bar") = 1000000,
+    each T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.LiquidSource[9] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=1) "Incompressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,80},{10,100}})));
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=2) "Incompressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,60},{10,80}})));
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=3) "Incompressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,40},{10,60}})));
+
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_delay_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=1,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_delay_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=2,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_delay_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=3,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_delay_leackage_check_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=1,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=1,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,-60},{10,-40}})));
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_delay_leackage_check_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=1,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=2,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,-80},{10,-60}})));
+  SorpLib.Components.Valves.LiquidValves.IncompressibleValve valve_controllable_delay_leackage_check_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=true,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=3,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,-100},{10,-80}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=1,
+    rising=150,
+    width=50,
+    falling=0,
+    period=250,
+    offset=0)
+    "Input signal for relative filling level"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=25,
+    f=1/100,
+    offset=273.15 + 50)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,-30},{80,-10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, valve_controllable_Kvs_cType1.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,90},{-8,90}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[2].port, valve_controllable_Kvs_cType2.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,70},{-8,70}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[3].port, valve_controllable_Kvs_cType3.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,50},{-8,50}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[4].port, valve_controllable_delay_Kvs_cType1.port_a) annotation (
+      Line(
+      points={{-60,0},{-20,0},{-20,20},{-8,20}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[5].port, valve_controllable_delay_Kvs_cType2.port_a) annotation (
+      Line(
+      points={{-60,0},{-8,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[6].port, valve_controllable_delay_Kvs_cType3.port_a) annotation (
+      Line(
+      points={{-60,0},{-20,0},{-20,-20},{-8,-20}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[7].port, valve_controllable_delay_leackage_check_Kvs_cType1.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-50},{-8,-50}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[8].port, valve_controllable_delay_leackage_check_Kvs_cType2.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-70},{-8,-70}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_a[9].port, valve_controllable_delay_leackage_check_Kvs_cType3.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-90},{-8,-90}},
+      color={28,108,200},
+      thickness=1));
+
+  connect(fs_b[1].port, valve_controllable_Kvs_cType1.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,90},{8,90}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b[2].port, valve_controllable_Kvs_cType2.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,70},{8,70}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b[3].port, valve_controllable_Kvs_cType3.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,50},{8,50}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b[4].port, valve_controllable_delay_Kvs_cType1.port_b) annotation (
+      Line(
+      points={{60,0},{20,0},{20,20},{8,20}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b[5].port, valve_controllable_delay_Kvs_cType2.port_b) annotation (
+      Line(
+      points={{60,0},{8,0}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b[6].port, valve_controllable_delay_Kvs_cType3.port_b) annotation (
+      Line(
+      points={{60,0},{20,0},{20,-20},{8,-20}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b[7].port, valve_controllable_delay_leackage_check_Kvs_cType1.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-50},{8,-50}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b[8].port, valve_controllable_delay_leackage_check_Kvs_cType2.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-70},{8,-70}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_b[9].port, valve_controllable_delay_leackage_check_Kvs_cType3.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-90},{8,-90}},
+      color={28,108,200},
+      thickness=1));
+
+  for ind in 1:9 loop
+    connect(input_T.y, fs_b[ind].T_input) annotation (Line(points={{79,-20},{70,
+            -20},{70,-2},{61.2,-2}},
+                          color={0,0,127}));
+    connect(input_p.y, fs_b[ind].p_input)
+      annotation (Line(points={{79,20},{70,20},{70,5},{61.2,5}},
+                                                               color={0,0,127}));
+  end for;
+
+  connect(input_lRel.y, valve_controllable_Kvs_cType1.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,97},{0,97}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_Kvs_cType2.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,77},{0,77}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_Kvs_cType3.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,57},{0,57}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType1.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,27},{0,27}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType2.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,7},{0,7}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType3.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-13},{0,-13}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType1.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-43},{0,-43}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType2.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-63},{0,-63}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType3.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-83},{0,-83}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the incompressible valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_IncompressibleValve;
diff --git a/SorpLib/Components/Valves/LiquidValves/Tester/package.mo b/SorpLib/Components/Valves/LiquidValves/Tester/package.mo
new file mode 100644
index 0000000..c71ffaa
--- /dev/null
+++ b/SorpLib/Components/Valves/LiquidValves/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components.Valves.LiquidValves;
+package Tester "Models to test and varify models for liquid valves"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented liquid valves. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Valves/LiquidValves/Tester/package.order b/SorpLib/Components/Valves/LiquidValves/Tester/package.order
new file mode 100644
index 0000000..dc575e2
--- /dev/null
+++ b/SorpLib/Components/Valves/LiquidValves/Tester/package.order
@@ -0,0 +1,2 @@
+Test_IncompressibleValve
+Test_IncompressibleThreeWayValve
diff --git a/SorpLib/Components/Valves/LiquidValves/package.mo b/SorpLib/Components/Valves/LiquidValves/package.mo
new file mode 100644
index 0000000..b231388
--- /dev/null
+++ b/SorpLib/Components/Valves/LiquidValves/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Valves;
+package LiquidValves "Liquid valves"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains liquid valves based on the open-source Modelica Standard
+Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end LiquidValves;
diff --git a/SorpLib/Components/Valves/LiquidValves/package.order b/SorpLib/Components/Valves/LiquidValves/package.order
new file mode 100644
index 0000000..163bd3d
--- /dev/null
+++ b/SorpLib/Components/Valves/LiquidValves/package.order
@@ -0,0 +1,3 @@
+IncompressibleValve
+IncompressibleThreeWayValve
+Tester
diff --git a/SorpLib/Components/Valves/Utilities/Limiter.mo b/SorpLib/Components/Valves/Utilities/Limiter.mo
new file mode 100644
index 0000000..90fc751
--- /dev/null
+++ b/SorpLib/Components/Valves/Utilities/Limiter.mo
@@ -0,0 +1,61 @@
+within SorpLib.Components.Valves.Utilities;
+block Limiter
+  "Limiter that limits a signal to an upper and a lower bound"
+  extends Modelica.Blocks.Interfaces.SISO;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real lowerLimit = 0
+    "Lower limit"
+    annotation (Dialog(tab="General", group="Limits"));
+  parameter Real upperLimit = 1
+    "Upper limit"
+    annotation (Dialog(tab="General", group="Limits"));
+
+equation
+  //
+  // Assertations
+  //
+  assert(upperLimit >= lowerLimit,
+        "Limits must be consistent, but upper limit (" + String(upperLimit) +
+        ") is greater than lower limit (" + String(upperLimit) + ")!",
+        level = AssertionLevel.error);
+
+  //
+  // Limit signal
+  //
+  y = smooth(0, max(min(u, upperLimit), lowerLimit))
+    "Limited input signal";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This blocks limit the input signal <i>u</i> to the lower limit <i>lowerLimit</i>
+and upper limit <i>upperLimit</i>. This block is a simplified version of
+<a href=\"Modelica://Modelica.Blocks.Nonlinear.Limiter\">Modelica.Blocks.Nonlinear.Limiter</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+    Polygon(
+      points={{0,90},{-8,68},{8,68},{0,90}},
+      lineColor={192,192,192},
+      fillColor={192,192,192},
+      fillPattern=FillPattern.Solid),
+    Line(points={{0,-90},{0,68}}, color={192,192,192}),
+    Line(points={{-90,0},{68,0}}, color={192,192,192}),
+    Polygon(
+      points={{90,0},{68,-8},{68,8},{90,0}},
+      lineColor={192,192,192},
+      fillColor={192,192,192},
+      fillPattern=FillPattern.Solid),
+    Line(points={{-80,-70},{-50,-70},{50,70},{80,70}})}));
+end Limiter;
diff --git a/SorpLib/Components/Valves/Utilities/mixStreamVariables.mo b/SorpLib/Components/Valves/Utilities/mixStreamVariables.mo
new file mode 100644
index 0000000..4556f37
--- /dev/null
+++ b/SorpLib/Components/Valves/Utilities/mixStreamVariables.mo
@@ -0,0 +1,61 @@
+within SorpLib.Components.Valves.Utilities;
+function mixStreamVariables
+  "Function mixing two stream variables of three-way valves"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MassFlowRate m_flow_1
+    "Flow variable of first stream variable"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MassFlowRate m_flow_2
+    "Flow variable of second stream variable"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real streamVariable_1
+    "First stream variable"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real streamVariable_2
+    "Second stream variable"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real mixedStreamVariable
+    "Mixed stream variable"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+
+
+algorithm
+  mixedStreamVariable := (streamVariable_1 * (max(m_flow_1,0) +
+    max(-m_flow_2,0) + 0.5*Modelica.Constants.eps) + streamVariable_2 *
+    (max(m_flow_2,0) + max(-m_flow_1,0) +0.5*Modelica.Constants.eps)) /
+    (abs(m_flow_1) + abs(m_flow_2) + Modelica.Constants.eps)
+    "Mixed stream variable";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function mixes two stream variables as required by three-way valves. The
+function is based on the Modelica Standard library (MSL)
+(<a href=\"Modelica://Modelica.Fluid.Fittings.MultiPort\">Modelica.Fluid.Fittings.MultiPort</a>)
+and TIL library
+(<a href=\"Modelica://TIL.Internals.joiningTwoStreams\">TIL.Internals.joiningTwoStreams</a>).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end mixStreamVariables;
diff --git a/SorpLib/Components/Valves/Utilities/package.mo b/SorpLib/Components/Valves/Utilities/package.mo
new file mode 100644
index 0000000..630a1ae
--- /dev/null
+++ b/SorpLib/Components/Valves/Utilities/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components.Valves;
+package Utilities "Utility models and functions for all valves"
+  extends Modelica.Icons.UtilitiesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains utility models and functions used to create valve models. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Utilities;
diff --git a/SorpLib/Components/Valves/Utilities/package.order b/SorpLib/Components/Valves/Utilities/package.order
new file mode 100644
index 0000000..632068b
--- /dev/null
+++ b/SorpLib/Components/Valves/Utilities/package.order
@@ -0,0 +1,2 @@
+Limiter
+mixStreamVariables
diff --git a/SorpLib/Components/Valves/VLEValves/CompressibleThreeWayValve.mo b/SorpLib/Components/Valves/VLEValves/CompressibleThreeWayValve.mo
new file mode 100644
index 0000000..007e6df
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/CompressibleThreeWayValve.mo
@@ -0,0 +1,163 @@
+within SorpLib.Components.Valves.VLEValves;
+model CompressibleThreeWayValve
+  "Three-way valve for compressible fluids"
+  extends
+    SorpLib.Components.Valves.BaseClasses.PartialCompressibleThreeWayValve(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variabbles
+  //
+protected
+  Medium.ThermodynamicState state_a_in
+    "Thermodynamic state record with instreaming properties at port a";
+
+equation
+  //
+  // Calculate fluid properties
+  //
+  state_a_in = Medium.setState_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Thermodynamic state record with instreaming properties at port a";
+
+  rho_a = Medium.density(state=state_a_in)
+    "Instreaming density at port a";
+  gamma_a = Medium.isentropicExponent( state=state_a_in)
+    "Instreaming isentropic exponent at port a";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This three-way valve can be applied for compressible fluids, such as air. 
+The valve splits a mass flow entering port a into two mass flows leaving port b 
+and c. For thus purpose, the valve position defines the division of the instreaming 
+mass flow at port a: I.e., for <i>position = 0</i>, the mass flows to port b; 
+for <i>position = 1</i>, the mass flows to port c. The position can be set by an 
+input signal.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mass flow rates <i>port_b.m_flow</i> and <i>port_c.m_flow</i> are calculated 
+in dependance of the instreaming pressure <i>p</i>, instreaming density <i>&rho;</i>, 
+and discharge function <i>&Psi;<sub>i</sub></i>, following the equation of Bernoulli 
+for compressible fluids (i.e., equation of Saint-Venant & Wantzel):
+</p>
+<pre>
+    port_b.m_flow = -A<sub>eff,b</sub> * <strong>sqrt</strong>(2 * &rho; * p) * &Psi;<sub>a</sub>;
+</pre>
+<pre>
+    port_c.m_flow = -A<sub>eff,c</sub> * <strong>sqrt</strong>(2 * &rho; * p) * &Psi;<sub>c</sub>;
+</pre>
+<p>
+The effective areas <i>A<sub>eff,i</sub></i> depends on the actual valve position
+and are calculated via a linear valve characteristic. For this purpose, the maximal 
+effective areas <i>A<sub>eff,max,i</sub></i> are required. The maximal effective 
+areas <i>A<sub>eff,max,i</sub></i> are present if the valve is fully opened and 
+can directly be specified. Alternatively, they can be calculated using the maximal 
+flow coefficients <i>Kvs<sub>i</sub></i>, reference densities <i>&rho;<sub>ref,i</sub></i>, 
+and reference pressure drops <i>&Delta;p<sub>ref,i</sub></i>:
+</p>
+<pre>
+    <i>A<sub>eff,max,i</sub></i> = Kvs<sub>i</sub> * <strong>sqrt</strong>(&rho;<sub>ref,i</sub> / (2 * &Delta;p<sub>ref,i</sub>));
+</pre>
+<p>
+The discharge functions <i>&Psi;<sub>i</sub></i> depend on the pressure ratios between the 
+outstreaming and instreaming pressures <i>p<sub>out,i</sub>/p<sub>in</sub></i> as long as 
+the velocity is below the speed of sound. Once the speed of sound is reached, the discharge 
+functions do not change anymore:
+</p>
+<pre>
+    &Psi;<sub>i</sub> = <strong>if</strong> p<sub>out,i</sub>/p<sub>in</sub> &gt; (2 / (&gamma; + 1)) ^ (&gamma; / (&gamma; - 1)) <strong>then</strong> 
+         <strong>sqrt</strong>(&gamma; / (&gamma; - 1) * ((p<sub>out,i</sub>/p<sub>in</sub>) ^ (2 / &gamma;) - (p<sub>out,i</sub>/p<sub>in</sub>) ^ ((&gamma; + 1) / &gamma;))) <strong>else</strong>
+         <strong>sqrt</strong>(2 ^ (2 / (&gamma; - 1)) * &gamma; / (&gamma; + 1) ^ ((&gamma; + 1) / (&gamma; - 1)));
+</pre>
+<p>
+Not that the valve is a check valve, thus mass can only flow from port a to port b and c.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Compressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  Isentropic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks of open sorption systems to
+split a mass flow rate.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>controllablePosition</i>:
+  Defines if the valve position can be set via an input signal.
+  </li>
+  <li>
+  <i>useTimeConstant</i>:
+  Defines if the valve position input signal is delayed by a time constant.
+  </li>
+  <li>
+  <i>leackage</i>:
+  Defines if the valve has a small leackage flow.
+  </li>
+  <br/>
+  <li>
+  <i>useKvsValue</i>:
+  Defines if the mass flow rates at port b and c are calculated using the 
+  Kvs-approach or A_eff-approach.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The model has two dynamic states if the input signal describing the valve position
+is delayed by a time constant. Otherwise, the model has no dynamic states.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/VLEValves/CompressibleValve.mo b/SorpLib/Components/Valves/VLEValves/CompressibleValve.mo
new file mode 100644
index 0000000..bc126ad
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/CompressibleValve.mo
@@ -0,0 +1,179 @@
+within SorpLib.Components.Valves.VLEValves;
+model CompressibleValve "Valve for compressible fluids"
+  extends SorpLib.Components.Valves.BaseClasses.PartialCompressibleValve(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Definition of variabbles
+  //
+protected
+  Medium.ThermodynamicState state_a_in
+    "Thermodynamic state record with instreaming properties at port a";
+  Medium.ThermodynamicState state_b_in
+    "Thermodynamic state record with instreaming properties at port b";
+
+equation
+  //
+  // Calculate fluid properties
+  //
+  state_a_in = Medium.setState_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Thermodynamic state record with instreaming properties at port a";
+  state_b_in = Medium.setState_phX(
+    p=port_b.p,
+    h=inStream(port_b.h_outflow),
+    X=cat(1,inStream(port_b.Xi_outflow),{1-sum(inStream(port_b.Xi_outflow))}))
+    "Thermodynamic state record with instreaming properties at port b";
+
+  rho_a = Medium.density(state=state_a_in)
+    "Instreaming density at port a";
+  rho_b = Medium.density(state=state_b_in)
+    "Instreaming density at port b";
+
+  gamma_a = Medium.isentropicExponent( state=state_a_in)
+    "Instreaming isentropic exponent at port a";
+  gamma_b = Medium.isentropicExponent( state=state_b_in)
+    "Instreaming isentropic exponent at port b";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This valve can be applied for compressible fluids, such as air. The valve opening 
+(i.e., position) can be set via an input signal. The valve can be used as a simple 
+on/off valve (i.e., opening = 0/1) or as a control valve by setting the valve opening 
+betwenn 0 and 1.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mass flow rate <i>port_a.m_flow</i> is calculated in dependance of the instreaming
+pressure  <i>p</i>, instreaming density <i>&rho;</i>, and discharge function <i>&Psi;</i>,
+following the equation of Bernoulli for compressible fluids (i.e., equation of Saint-Venant 
+& Wantzel):
+</p>
+<pre>
+    port_a.m_flow = A<sub>eff</sub> * <strong>sqrt</strong>(2 * &rho; * p) * &Psi;;
+</pre>
+<p>
+The effective area <i>A<sub>eff</sub></i> depends on the actual valve opening (i.e., 
+position) and is calculated via the selected 
+<a href=\"Modelica://SorpLib.Components.Valves.ValveCharacteristics\">valve characteristic</a>).
+For this purpose, the maximal effective area <i>A<sub>eff,max</sub></i> is required.
+The maximal effective area <i>A<sub>eff,max</sub></i> is present if the valve is fully
+opened and can directly be specified. Alternatively, it can be calculated using the maximal 
+flow coefficient <i>Kvs</i>, reference density <i>&rho;<sub>ref</sub></i>, and reference 
+pressure drop <i>&Delta;p<sub>ref</sub></i>:
+</p>
+<pre>
+    <i>A<sub>eff,max</sub></i> = Kvs * <strong>sqrt</strong>(&rho;<sub>ref</sub> / (2 * &Delta;p<sub>ref</sub>));
+</pre>
+<p>
+The discharge function <i>&Psi;</i> depends on the pressure ratio between the outstreaming and
+instreaming pressure <i>p<sub>out</sub>/p<sub>in</sub></i> as long as the velocity is below the
+speed of sound. Once the speed of sound is reached, the discharge function does not change anymore:
+</p>
+<pre>
+    &Psi; = <strong>if</strong> p<sub>out</sub>/p<sub>in</sub> &gt; (2 / (&gamma; + 1)) ^ (&gamma; / (&gamma; - 1)) <strong>then</strong> 
+         <strong>sqrt</strong>(&gamma; / (&gamma; - 1) * ((p<sub>out</sub>/p<sub>in</sub>) ^ (2 / &gamma;) - (p<sub>out</sub>/p<sub>in</sub>) ^ ((&gamma; + 1) / &gamma;))) <strong>else</strong>
+         <strong>sqrt</strong>(2 ^ (2 / (&gamma; - 1)) * &gamma; / (&gamma; + 1) ^ ((&gamma; + 1) / (&gamma; - 1)));
+</pre>
+<p>
+To account for the flow direction, the root expression is calculated using the anti-symmetric 
+root approximation
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+Furthermore, the valve can be a check valve (see options). If the valve is a check valve, mass 
+can only flow from port a to port b.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Compressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  Isentropic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks of open sorption systems.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>controllableOpening</i>:
+  Defines if the valve opening can be set via an input signal.
+  </li>
+  <li>
+  <i>useTimeConstant</i>:
+  Defines if the valve opening input signal is delayed by a time constant.
+  </li>
+  <li>
+  <i>leackage</i>:
+  Defines if the valve has a small leackage flow.
+  </li>
+  <li>
+  <i>checkValve</i>:
+  Defines if the valve is a strict check valve, thus only allowing a mass flow from 
+  port a to port b.
+  </li>
+  <br/>
+  <li>
+  <i>useKvsValue</i>:
+  Defines if the mass flow rate is calculated using the Kvs-approach or A_eff-approach.
+  </li>
+  <li>
+  <i>valveCharacteristic</i>:
+  Defines the valve characteristic (see 
+  <a href=\"Modelica://SorpLib.Components.Valves.ValveCharacteristics\">SorpLib.Components.Valves.ValveCharacteristics</a>).
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The model has two dynamic states if the input signal describing the valve opening is
+delayed by a time constant. Otherwise, the model has no dynamic states.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CompressibleValve;
diff --git a/SorpLib/Components/Valves/VLEValves/CondensateRefluxValve.mo b/SorpLib/Components/Valves/VLEValves/CondensateRefluxValve.mo
new file mode 100644
index 0000000..94cbfe5
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/CondensateRefluxValve.mo
@@ -0,0 +1,122 @@
+within SorpLib.Components.Valves.VLEValves;
+model CondensateRefluxValve
+  "Condensate reflux valve"
+  extends SorpLib.Components.Valves.BaseClasses.PartialCondensateRefluxValve(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The control valve acts as a simple P-like controler to regulate a process variable 
+(e.g., the relative filling level in a phase separator volume) to its setpoint via 
+the mass flow through the valve.
+</p>
+
+<h4>Main equations</h4>
+<p>
+Three characteristics are available for the control behavior: A constant mass flow, 
+a mass flow that is linear to the deviation from the setpoint, and a mass flow that 
+is quadratic to the deviation from the setpoint:
+</p>
+<pre>
+    'Constant': port_a.m_flow = <strong>if</strong> (processVariable - setPoint) &gt; 0 <strong>then</strong> m_flow_constant <strong>else</strong> -m_flow_constant;
+</pre>
+<pre>
+    'Linear': port_a.m_flow = (processVariable - setPoint) * kp<sub>linear</sub>;
+</pre>
+<pre>
+    'Quadratic': port_a.m_flow = (processVariable - setPoint)<sup>2</sup> * kp<sub>quadratic</sub>;
+</pre>
+
+<p>
+If the valve is a check valve (see options), mass can only flow from port a to port 
+b. To achiev this, the valve can act a 'normal' check valve or a 'strict' check 
+valve. A 'normal' check valve regulates the mass flow rate to zero if the process
+variables reaches its setpoint via the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>.
+Thus, minimal mass flows from port b to port a are possible, which can increase 
+the numerical stability of the model. These mass flows are not necessarily possible 
+in reality, but they are usually so small that the error is negligible. In contract, 
+a 'strict' check valve strictly regulates the mass flow rate to zero if the process
+variables reaches its setpoint, and now flow reversal is possible.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Incompressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No change in kinetic and potential energy between inlet and outlet
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in closed sorption systems (e.g., adsorption chillers) 
+to return the condensate from the condenser into the evaporator.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>checkValve</i>:
+  Defines if the valve is a check valve, thus only allowing a mass flow from port
+  a to port b except for a minor mass flow rate from port b to port a to increase
+  numerical stability.
+  </li>
+  <li>
+  <i>strictCheckValve</i>:
+  Defines if the valve is a strict check valve, thus only allowing a mass flow 
+  from port a to port b.
+  </li>
+  <br/>
+  <li>
+  <i>controlType</i>:
+  Defines the control type for determining the mass flow rate at port a (see main
+  equations).
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  Major revisions (new functionalities, documentation).
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CondensateRefluxValve;
diff --git a/SorpLib/Components/Valves/VLEValves/IncompressibleThreeWayValve.mo b/SorpLib/Components/Valves/VLEValves/IncompressibleThreeWayValve.mo
new file mode 100644
index 0000000..ebb9772
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/IncompressibleThreeWayValve.mo
@@ -0,0 +1,139 @@
+within SorpLib.Components.Valves.VLEValves;
+model IncompressibleThreeWayValve
+  "Three-way valve for incompressible fluids"
+  extends
+    SorpLib.Components.Valves.BaseClasses.PartialIncompressibleThreeWayValve(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_c,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculate fluid properties
+  //
+  rho_a = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Instreaming density at port a";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This three-way valve can be applied for incompressible fluids, such as liquid water. 
+The valve splits a mass flow entering port a into two mass flows leaving port b 
+and c. For thus purpose, the valve position defines the division of the instreaming 
+mass flow at port a: I.e., for <i>position = 0</i>, the mass flows to port b; 
+for <i>position = 1</i>, the mass flows to port c. The position can be set by an 
+input signal.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mass flow rates <i>port_b.m_flow</i> and <i>port_c.m_flow</i> are calculated 
+in dependance of the pressure drops <i>&Delta;p<sub>ab</sub> = port_a.p - port_b.p</i>, 
+and <i>&Delta;p<sub>ac</sub> = port_a.p - port_c.p</i>, following the equation of 
+Bernoulli for incompressible fluids:
+</p>
+<pre>
+    port_b.m_flow = -A<sub>eff,b</sub> * <strong>sqrt</strong>(2 * &rho; * &Delta;p<sub>ab</sub>) *(1 - position);
+</pre>
+<pre>
+    port_c.m_flow = -A<sub>eff,c</sub> * <strong>sqrt</strong>(2 * &rho; * &Delta;p<sub>ac</sub>) * position;
+</pre>
+<p>
+The effective areas <i>A<sub>eff,i</sub></i> depends on the actual valve position
+and are calculated via a linear valve characteristic. For this purpose, the maximal 
+effective areas <i>A<sub>eff,max,i</sub></i> are required. The maximal effective 
+areas <i>A<sub>eff,max,i</sub></i> are present if the valve is fully opened and 
+can directly be specified. Alternatively, they can be calculated using the maximal 
+flow coefficients <i>Kvs<sub>i</sub></i>, reference densities <i>&rho;<sub>ref,i</sub></i>, 
+and reference pressure drops <i>&Delta;p<sub>ref,i</sub></i>:
+</p>
+<pre>
+    <i>A<sub>eff,max,i</sub></i> = Kvs<sub>i</sub> * <strong>sqrt</strong>(&rho;<sub>ref,i</sub> / (2 * &Delta;p<sub>ref,i</sub>));
+</pre>
+<p>
+The density <i>&rho;</i> corresponds to the inlet density of the actual flow 
+direction. Note that the valve is a strict check valve, thus mass can only flow 
+from port a to port b and c.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Incompressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks of closed sorption systems to
+split a mass flow rate.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>controllablePosition</i>:
+  Defines if the valve position can be set via an input signal.
+  </li>
+  <li>
+  <i>useTimeConstant</i>:
+  Defines if the valve position input signal is delayed by a time constant.
+  </li>
+  <li>
+  <i>leackage</i>:
+  Defines if the valve has a small leackage flow.
+  </li>
+  <br/>
+  <li>
+  <i>useKvsValue</i>:
+  Defines if the mass flow rates at port b and c are calculated using the 
+  Kvs-approach or A_eff-approach.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The model has two dynamic states if the input signal describing the valve position
+is delayed by a time constant. Otherwise, the model has no dynamic states.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IncompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/VLEValves/IncompressibleValve.mo b/SorpLib/Components/Valves/VLEValves/IncompressibleValve.mo
new file mode 100644
index 0000000..187ff8a
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/IncompressibleValve.mo
@@ -0,0 +1,152 @@
+within SorpLib.Components.Valves.VLEValves;
+model IncompressibleValve "Valve for incompressible fluids"
+  extends SorpLib.Components.Valves.BaseClasses.PartialIncompressibleValve(
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_out port_b,
+    redeclare final Basics.Interfaces.FluidPorts.VLEPort_in port_a,
+    final no_components=Medium.nX);
+
+  //
+  // Definition of parameters regarding the medium
+  //
+  replaceable package Medium =
+    Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium model of the real fluid (i.e., with two-phase regime)"
+    annotation (Dialog(tab="General", group="Medium"),
+                Evaluate=true,
+                HideResult=true,
+                choicesAllMatching=true);
+
+equation
+  //
+  // Calculate fluid properties
+  //
+  rho_a = Medium.density_phX(
+    p=port_a.p,
+    h=inStream(port_a.h_outflow),
+    X=cat(1,inStream(port_a.Xi_outflow),{1-sum(inStream(port_a.Xi_outflow))}))
+    "Instreaming density at port a";
+  rho_b = Medium.density_phX(
+    p=port_b.p,
+    h=inStream(port_b.h_outflow),
+    X=cat(1,inStream(port_b.Xi_outflow),{1-sum(inStream(port_b.Xi_outflow))}))
+    "Instreaming density at port b";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This valve can be applied for incompressible fluids, such as liquid water. The valve
+opening (i.e., position) can be set via an input signal. The valve can be used as a
+simple on/off valve (i.e., opening = 0/1) or as a control valve by setting the valve
+opening betwenn 0 and 1.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mass flow rate <i>port_a.m_flow</i> is calculated in dependance of the pressure 
+drop <i>&Delta;p = (port_a.p + &Delta;p<sub>hydraulic head</sub>) - port_b.p</i>, 
+which can be increased by accounting a hydaulic head (see options), following the 
+equation of Bernoulli for incompressible fluids:
+</p>
+<pre>
+    port_a.m_flow = A<sub>eff</sub> * <strong>sqrt</strong>(2 * &rho; * &Delta;p);
+</pre>
+<p>
+The effective area <i>A<sub>eff</sub></i> depends on the actual valve opening (i.e., 
+position) and is calculated via the selected 
+<a href=\"Modelica://SorpLib.Components.Valves.ValveCharacteristics\">valve characteristic</a>).
+For this purpose, the maximal effective area <i>A<sub>eff,max</sub></i> is required.
+The maximal effective area <i>A<sub>eff,max</sub></i> is present if the valve is fully
+opened and can directly be specified. Alternatively, it can be calculated using the maximal 
+flow coefficient <i>Kvs</i>, reference density <i>&rho;<sub>ref</sub></i>, and reference 
+pressure drop <i>&Delta;p<sub>ref</sub></i>:
+</p>
+<pre>
+    <i>A<sub>eff,max</sub></i> = Kvs * <strong>sqrt</strong>(&rho;<sub>ref</sub> / (2 * &Delta;p<sub>ref</sub>));
+</pre>
+<p>
+The density <i>&rho;</i> corresponds to the inlet density of the actual flow direction.
+To account for the flow direction, the root expression is calculated using the anti-symmetric 
+root approximation
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+Furthermore, the valve can be a check valve (see options). If the valve is a check valve, mass 
+can only flow from port a to port b.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Incompressible fluid
+  </li>
+  <li>
+  Adiabatic process
+  </li>
+  <li>
+  Isenthalpic process
+  </li>
+  <li>
+  No storage of mass or energy
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The valve is typically used in hydraulic networks of closed sorption systems.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  <i>controllableOpening</i>:
+  Defines if the valve opening can be set via an input signal.
+  </li>
+  <li>
+  <i>useTimeConstant</i>:
+  Defines if the valve opening input signal is delayed by a time constant.
+  </li>
+  <li>
+  <i>leackage</i>:
+  Defines if the valve has a small leackage flow.
+  </li>
+  <li>
+  <i>checkValve</i>:
+  Defines if the valve is a strict check valve, thus only allowing a mass flow from 
+  port a to port b.
+  </li>
+  <br/>
+  <li>
+  <i>useKvsValue</i>:
+  Defines if the mass flow rate is calculated using the Kvs-approach or A_eff-approach.
+  </li>
+  <li>
+  <i>valveCharacteristic</i>:
+  Defines the valve characteristic (see 
+  <a href=\"Modelica://SorpLib.Components.Valves.ValveCharacteristics\">SorpLib.Components.Valves.ValveCharacteristics</a>).
+  </li>
+  <li>
+  <i>accountHydraulicHead</i>:
+  Defines if a hydraulic head is used to increase the pressure at port a.
+  </li>
+  <br/>
+  <li>
+  <i>avoid_events</i>:
+  Defines if events shall be avoided via the noEvent()-operator.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+The model has two dynamic states if the input signal describing the valve opening is
+delayed by a time constant. Otherwise, the model has no dynamic states.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IncompressibleValve;
diff --git a/SorpLib/Components/Valves/VLEValves/Tester/Test_CompressibleThreeWayValve.mo b/SorpLib/Components/Valves/VLEValves/Tester/Test_CompressibleThreeWayValve.mo
new file mode 100644
index 0000000..b9d7ea0
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/Tester/Test_CompressibleThreeWayValve.mo
@@ -0,0 +1,180 @@
+within SorpLib.Components.Valves.VLEValves.Tester;
+model Test_CompressibleThreeWayValve
+  "Tester for the three-way valve for compressible fluids"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource[3] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="bar") = 50000,
+    each T_fixed=373.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource[3] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,40},{50,60}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource[3] fs_c(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-40},{50,-60}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.VLEValves.CompressibleThreeWayValve threeWayValve(
+    controllablePosition=true)
+    "Three-way valve: Controllable, no time constant, no leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,40})));
+
+  SorpLib.Components.Valves.VLEValves.CompressibleThreeWayValve threeWayValve_delay(
+    controllablePosition=true,
+    useTimeConstant=true,
+    tau=10,
+    position_initial=0)
+    "Three-way valve: Controllable, time constant, no leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,0})));
+
+  SorpLib.Components.Valves.VLEValves.CompressibleThreeWayValve threeWayValve_delay_leackage(
+    controllablePosition=true,
+    useTimeConstant=true,
+    leackage=true,
+    position_initial=0)
+    "Three-way valve: Controllable, time constant, leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,-40})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=1,
+    rising=150,
+    width=50,
+    falling=0,
+    period=250,
+    offset=0)
+    "Input signal for relative filling level"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={10,90})));
+
+  Modelica.Blocks.Sources.Sine input_p_b(
+    amplitude=-0.4e5,
+    f=1/100,
+    offset=0.5e5)
+                 "Input signal for pressure at port b"
+    annotation (Placement(transformation(extent={{100,40},{80,60}})));
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=25,
+    f=1/100,
+    offset=273.15 + 150)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+  Modelica.Blocks.Sources.Sine input_p_c(
+    amplitude=-0.4e5,
+    f=1/100,
+    offset=0.5e5)
+                 "Input signal for pressure at port c"
+    annotation (Placement(transformation(extent={{100,-60},{80,-40}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, threeWayValve.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,40},{-7.8,40}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[2].port, threeWayValve_delay.port_a) annotation (Line(
+      points={{-60,0},{-7.8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[3].port, threeWayValve_delay_leackage.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,-40},{-7.8,-40}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve.port_b, fs_b[1].port) annotation (Line(
+      points={{0,48},{0,50},{60,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve_delay.port_b, fs_b[2].port) annotation (Line(
+      points={{0,8},{0,10},{20,10},{20,50},{60,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve_delay_leackage.port_b, fs_b[3].port) annotation (Line(
+      points={{0,-32},{0,-30},{20,-30},{20,50},{60,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve.port_c, fs_c[1].port) annotation (Line(
+      points={{0,32},{0,30},{40,30},{40,-50},{60,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve_delay.port_c, fs_c[2].port) annotation (Line(
+      points={{0,-8},{0,-10},{40,-10},{40,-50},{60,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve_delay_leackage.port_c, fs_c[3].port) annotation (Line(
+      points={{0,-48},{0,-50},{60,-50}},
+      color={0,140,72},
+      thickness=1));
+
+  for ind in 1:3 loop
+    connect(input_T.y, fs_b[ind].T_input) annotation (Line(points={{79,0},{70,0},
+            {70,48},{61.2,48}},
+                          color={0,0,127}));
+    connect(input_T.y, fs_c[ind].T_input) annotation (Line(points={{79,0},{70,0},{70,
+            -48},{61.2,-48}}, color={0,0,127}));
+
+    connect(input_p_b.y, fs_b[ind].p_input) annotation (Line(points={{79,50},{70,
+            50},{70,55},{61.2,55}}, color={0,0,127}));
+    connect(input_p_c.y, fs_c[ind].p_input) annotation (Line(points={{79,-50},{70,-50},
+            {70,-55},{61.2,-55}}, color={0,0,127}));
+  end for;
+
+  connect(input_lRel.y, threeWayValve.position)
+    annotation (Line(points={{10,79},{10,40},{7,40}}, color={0,0,127}));
+  connect(input_lRel.y, threeWayValve_delay.position)
+    annotation (Line(points={{10,79},{10,0},{7,0}}, color={0,0,127}));
+  connect(input_lRel.y, threeWayValve_delay_leackage.position)
+    annotation (Line(points={{10,79},{10,-40},{7,-40}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the compressible three-way valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_CompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/VLEValves/Tester/Test_CompressibleValve.mo b/SorpLib/Components/Valves/VLEValves/Tester/Test_CompressibleValve.mo
new file mode 100644
index 0000000..53d5648
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/Tester/Test_CompressibleValve.mo
@@ -0,0 +1,286 @@
+within SorpLib.Components.Valves.VLEValves.Tester;
+model Test_CompressibleValve
+  "Tester for the valve for compressible fluids"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource[9] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="bar") = 50000,
+    each T_fixed=373.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource[9] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=1) "Compressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,80},{10,100}})));
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=2) "Compressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,60},{10,80}})));
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=3) "Compressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,40},{10,60}})));
+
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_delay_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=1,
+    opening_initial=0) "Compressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_delay_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=2,
+    opening_initial=0) "Compressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_delay_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=3,
+    opening_initial=0) "Compressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_delay_leackage_check_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=1,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=1,
+    opening_initial=0) "Compressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,-60},{10,-40}})));
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_delay_leackage_check_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=1,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=2,
+    opening_initial=0) "Compressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,-80},{10,-60}})));
+  SorpLib.Components.Valves.VLEValves.CompressibleValve valve_controllable_delay_leackage_check_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=true,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=3,
+    opening_initial=0) "Compressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,-100},{10,-80}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=1,
+    rising=150,
+    width=50,
+    falling=0,
+    period=250,
+    offset=0)
+    "Input signal for relative filling level"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+  Modelica.Blocks.Sources.Sine input_p(
+    amplitude=-0.4e5,
+    f=1/100,
+    offset=0.5e5)
+    "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,10},{80,30}})));
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=25,
+    f=1/100,
+    offset=273.15 + 150)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,-30},{80,-10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, valve_controllable_Kvs_cType1.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,90},{-8,90}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[2].port, valve_controllable_Kvs_cType2.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,70},{-8,70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[3].port, valve_controllable_Kvs_cType3.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,50},{-8,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[4].port, valve_controllable_delay_Kvs_cType1.port_a) annotation (
+      Line(
+      points={{-60,0},{-20,0},{-20,20},{-8,20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[5].port, valve_controllable_delay_Kvs_cType2.port_a) annotation (
+      Line(
+      points={{-60,0},{-8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[6].port, valve_controllable_delay_Kvs_cType3.port_a) annotation (
+      Line(
+      points={{-60,0},{-20,0},{-20,-20},{-8,-20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[7].port, valve_controllable_delay_leackage_check_Kvs_cType1.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-50},{-8,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[8].port, valve_controllable_delay_leackage_check_Kvs_cType2.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-70},{-8,-70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[9].port, valve_controllable_delay_leackage_check_Kvs_cType3.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-90},{-8,-90}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(fs_b[1].port, valve_controllable_Kvs_cType1.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,90},{8,90}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[2].port, valve_controllable_Kvs_cType2.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,70},{8,70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[3].port, valve_controllable_Kvs_cType3.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,50},{8,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[4].port, valve_controllable_delay_Kvs_cType1.port_b) annotation (
+      Line(
+      points={{60,0},{20,0},{20,20},{8,20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[5].port, valve_controllable_delay_Kvs_cType2.port_b) annotation (
+      Line(
+      points={{60,0},{8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[6].port, valve_controllable_delay_Kvs_cType3.port_b) annotation (
+      Line(
+      points={{60,0},{20,0},{20,-20},{8,-20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[7].port, valve_controllable_delay_leackage_check_Kvs_cType1.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-50},{8,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[8].port, valve_controllable_delay_leackage_check_Kvs_cType2.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-70},{8,-70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[9].port, valve_controllable_delay_leackage_check_Kvs_cType3.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-90},{8,-90}},
+      color={0,140,72},
+      thickness=1));
+
+  for ind in 1:9 loop
+    connect(input_T.y, fs_b[ind].T_input) annotation (Line(points={{79,-20},{70,
+            -20},{70,-2},{61.2,-2}},
+                          color={0,0,127}));
+    connect(input_p.y, fs_b[ind].p_input)
+      annotation (Line(points={{79,20},{70,20},{70,5},{61.2,5}},
+                                                               color={0,0,127}));
+  end for;
+
+  connect(input_lRel.y, valve_controllable_Kvs_cType1.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,97},{0,97}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_Kvs_cType2.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,77},{0,77}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_Kvs_cType3.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,57},{0,57}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType1.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,27},{0,27}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType2.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,7},{0,7}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType3.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-13},{0,-13}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType1.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-43},{0,-43}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType2.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-63},{0,-63}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType3.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-83},{0,-83}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the compressible valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_CompressibleValve;
diff --git a/SorpLib/Components/Valves/VLEValves/Tester/Test_CondensateRefluxValve.mo b/SorpLib/Components/Valves/VLEValves/Tester/Test_CondensateRefluxValve.mo
new file mode 100644
index 0000000..8e268ab
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/Tester/Test_CondensateRefluxValve.mo
@@ -0,0 +1,215 @@
+within SorpLib.Components.Valves.VLEValves.Tester;
+model Test_CondensateRefluxValve
+  "Tester for the condensate reflux valve"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource[9] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="kPa") = 1000*(4.246*1.1),
+    each T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource[9] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="kPa") = 1000*(1.7051*1.1),
+    each T_fixed=288.15)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType1(
+    controlType=1) "Condensate reflux valve: No check valve, control type 1"
+    annotation (Placement(transformation(extent={{-10,80},{10,100}})));
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType2(
+    controlType=2) "Condensate reflux valve: No check valve, control type 2"
+    annotation (Placement(transformation(extent={{-10,60},{10,80}})));
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType3(
+    controlType=3) "Condensate reflux valve: No check valve, control type 3"
+    annotation (Placement(transformation(extent={{-10,40},{10,60}})));
+
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType1_checkValve(
+      controlType=1,
+      checkValve=true) "Condensate reflux valve: Ceck valve, control type 1"
+    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType2_checkValve(
+      controlType=2,
+      checkValve=true) "Condensate reflux valve: Check valve, control type 2"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType3_checkValve(
+      controlType=3,
+      checkValve=true) "Condensate reflux valve: Check valve, control type 3"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType1_strictCheckValve(
+      controlType=1,
+      checkValve=true,
+      strictCheckValve=true)
+    "Condensate reflux valve: Ceck valve, control type 1"
+    annotation (Placement(transformation(extent={{-10,-60},{10,-40}})));
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType2_strictCheckValve(
+      controlType=2,
+      checkValve=true,
+      strictCheckValve=true)
+    "Condensate reflux valve: Check valve, control type 2"
+    annotation (Placement(transformation(extent={{-10,-80},{10,-60}})));
+  SorpLib.Components.Valves.VLEValves.CondensateRefluxValve refluxValve_cType3_strictCheckValve(
+      controlType=3,
+      checkValve=true,
+      strictCheckValve=true)
+    "Condensate reflux valve: Check valve, control type 3"
+    annotation (Placement(transformation(extent={{-10,-100},{10,-80}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=-0.6,
+    rising=200,
+    width=50,
+    falling=200,
+    period=500,
+    offset=0.75)
+    "Input signal for relative filling leveö"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, refluxValve_cType1.port_a) annotation (Line(
+      points={{-60,0},{-32,0},{-32,90},{-8,90}},
+      color={0,140,72},
+      thickness=1));
+  connect(refluxValve_cType3.port_a, fs_a[2].port) annotation (Line(
+      points={{-8,50},{-32,50},{-32,0},{-60,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(refluxValve_cType2.port_a, fs_a[3].port) annotation (Line(
+      points={{-8,70},{-32,70},{-32,0},{-60,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(refluxValve_cType1_checkValve.port_a, fs_a[4].port) annotation (Line(
+      points={{-8,20},{-32,20},{-32,0},{-60,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(refluxValve_cType2_checkValve.port_a, fs_a[5].port) annotation (Line(
+      points={{-8,0},{-60,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(refluxValve_cType3_checkValve.port_a, fs_a[6].port) annotation (Line(
+      points={{-8,-20},{-32,-20},{-32,0},{-60,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(refluxValve_cType1_strictCheckValve.port_a, fs_a[7].port) annotation (
+      Line(
+      points={{-8,-50},{-32,-50},{-32,0},{-60,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(refluxValve_cType2_strictCheckValve.port_a, fs_a[8].port) annotation (
+      Line(
+      points={{-8,-70},{-32,-70},{-32,0},{-60,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(refluxValve_cType3_strictCheckValve.port_a, fs_a[9].port) annotation (
+      Line(
+      points={{-8,-90},{-32,-90},{-32,0},{-60,0}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(fs_b[1].port, refluxValve_cType1.port_b) annotation (Line(
+      points={{60,0},{30,0},{30,90},{8,90}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[2].port, refluxValve_cType2.port_b) annotation (Line(
+      points={{60,0},{30,0},{30,70},{8,70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[3].port, refluxValve_cType3.port_b) annotation (Line(
+      points={{60,0},{30,0},{30,50},{8,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[4].port, refluxValve_cType1_checkValve.port_b) annotation (Line(
+      points={{60,0},{30,0},{30,20},{8,20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[5].port, refluxValve_cType2_checkValve.port_b) annotation (Line(
+      points={{60,0},{8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[6].port, refluxValve_cType3_checkValve.port_b) annotation (Line(
+      points={{60,0},{30,0},{30,-20},{8,-20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[7].port, refluxValve_cType1_strictCheckValve.port_b) annotation (
+      Line(
+      points={{60,0},{30,0},{30,-50},{8,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[8].port, refluxValve_cType2_strictCheckValve.port_b) annotation (
+      Line(
+      points={{60,0},{30,0},{30,-70},{8,-70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[9].port, refluxValve_cType3_strictCheckValve.port_b) annotation (
+      Line(
+      points={{60,0},{30,0},{30,-90},{8,-90}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(input_lRel.y, refluxValve_cType1.processVariable) annotation (Line(
+        points={{-79,0},{-70,0},{-70,94.2},{-2.6,94.2}}, color={0,0,127}));
+  connect(input_lRel.y, refluxValve_cType2.processVariable) annotation (Line(
+        points={{-79,0},{-70,0},{-70,74.2},{-2.6,74.2}}, color={0,0,127}));
+  connect(input_lRel.y, refluxValve_cType3.processVariable) annotation (Line(
+        points={{-79,0},{-70,0},{-70,54.2},{-2.6,54.2}}, color={0,0,127}));
+  connect(input_lRel.y, refluxValve_cType1_checkValve.processVariable)
+    annotation (Line(points={{-79,0},{-70,0},{-70,24.2},{-2.6,24.2}}, color={0,0,
+          127}));
+  connect(input_lRel.y, refluxValve_cType2_checkValve.processVariable)
+    annotation (Line(points={{-79,0},{-70,0},{-70,16},{-40,16},{-40,4.2},{-2.6,4.2}},
+        color={0,0,127}));
+  connect(input_lRel.y, refluxValve_cType3_checkValve.processVariable)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-15.8},{-2.6,-15.8}}, color={0,
+          0,127}));
+  connect(input_lRel.y, refluxValve_cType1_strictCheckValve.processVariable)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-45.8},{-2.6,-45.8}}, color={0,
+          0,127}));
+  connect(input_lRel.y, refluxValve_cType2_strictCheckValve.processVariable)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-65.8},{-2.6,-65.8}}, color={0,
+          0,127}));
+  connect(input_lRel.y, refluxValve_cType3_strictCheckValve.processVariable)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-85.8},{-2.6,-85.8}}, color={0,
+          0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the condensate reflux valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  Minor revisions (documentation, test new functionalities).
+  </li>
+  <li>
+  January 20, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_CondensateRefluxValve;
diff --git a/SorpLib/Components/Valves/VLEValves/Tester/Test_IncompressibleThreeWayValve.mo b/SorpLib/Components/Valves/VLEValves/Tester/Test_IncompressibleThreeWayValve.mo
new file mode 100644
index 0000000..dc6553b
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/Tester/Test_IncompressibleThreeWayValve.mo
@@ -0,0 +1,178 @@
+within SorpLib.Components.Valves.VLEValves.Tester;
+model Test_IncompressibleThreeWayValve
+  "Tester for the three-way valve for incompressible fluids"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource[3] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="bar") = 1000000,
+    each T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource[3] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,40},{50,60}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource[3] fs_c(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source c"
+    annotation (Placement(transformation(extent={{70,-40},{50,-60}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.VLEValves.IncompressibleThreeWayValve threeWayValve(
+    controllablePosition=true)
+    "Three-way valve: Controllable, no time constant, no leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,40})));
+
+  SorpLib.Components.Valves.VLEValves.IncompressibleThreeWayValve threeWayValve_delay(
+    controllablePosition=true,
+    useTimeConstant=true,
+    tau=10,
+    position_initial=0)
+    "Three-way valve: Controllable, time constant, no leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,0})));
+
+  SorpLib.Components.Valves.VLEValves.IncompressibleThreeWayValve threeWayValve_delay_leackage(
+    controllablePosition=true,
+    useTimeConstant=true,
+    leackage=true,
+    position_initial=0)
+    "Three-way valve: Controllable, time constant, leackage" annotation (
+      Placement(transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={0,-40})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=1,
+    rising=150,
+    width=50,
+    falling=0,
+    period=250,
+    offset=0)
+    "Input signal for relative filling level"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}},
+        rotation=270,
+        origin={10,90})));
+
+  Modelica.Blocks.Sources.Sine input_p_b(
+    amplitude=-1e5,
+    f=1/100,
+    offset=10e5) "Input signal for pressure at port b"
+    annotation (Placement(transformation(extent={{100,40},{80,60}})));
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=25,
+    f=1/100,
+    offset=273.15 + 50)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,-10},{80,10}})));
+  Modelica.Blocks.Sources.Sine input_p_c(
+    amplitude=-1e5,
+    f=1/100,
+    offset=10e5) "Input signal for pressure at port c"
+    annotation (Placement(transformation(extent={{100,-60},{80,-40}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, threeWayValve.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,40},{-7.8,40}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[2].port, threeWayValve_delay.port_a) annotation (Line(
+      points={{-60,0},{-7.8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[3].port, threeWayValve_delay_leackage.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,-40},{-7.8,-40}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve.port_b, fs_b[1].port) annotation (Line(
+      points={{0,48},{0,50},{60,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve_delay.port_b, fs_b[2].port) annotation (Line(
+      points={{0,8},{0,10},{20,10},{20,50},{60,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve_delay_leackage.port_b, fs_b[3].port) annotation (Line(
+      points={{0,-32},{0,-30},{20,-30},{20,50},{60,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve.port_c, fs_c[1].port) annotation (Line(
+      points={{0,32},{0,30},{40,30},{40,-50},{60,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve_delay.port_c, fs_c[2].port) annotation (Line(
+      points={{0,-8},{0,-10},{40,-10},{40,-50},{60,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(threeWayValve_delay_leackage.port_c, fs_c[3].port) annotation (Line(
+      points={{0,-48},{0,-50},{60,-50}},
+      color={0,140,72},
+      thickness=1));
+
+  for ind in 1:3 loop
+    connect(input_T.y, fs_b[ind].T_input) annotation (Line(points={{79,0},{70,0},
+            {70,48},{61.2,48}},
+                          color={0,0,127}));
+    connect(input_T.y, fs_c[ind].T_input) annotation (Line(points={{79,0},{70,0},{70,
+            -48},{61.2,-48}}, color={0,0,127}));
+
+    connect(input_p_b.y, fs_b[ind].p_input) annotation (Line(points={{79,50},{70,
+            50},{70,55},{61.2,55}}, color={0,0,127}));
+    connect(input_p_c.y, fs_c[ind].p_input) annotation (Line(points={{79,-50},{70,-50},
+            {70,-55},{61.2,-55}}, color={0,0,127}));
+  end for;
+
+  connect(input_lRel.y, threeWayValve.position)
+    annotation (Line(points={{10,79},{10,40},{7,40}}, color={0,0,127}));
+  connect(input_lRel.y, threeWayValve_delay.position)
+    annotation (Line(points={{10,79},{10,0},{7,0}}, color={0,0,127}));
+  connect(input_lRel.y, threeWayValve_delay_leackage.position)
+    annotation (Line(points={{10,79},{10,-40},{7,-40}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the incompressible three-way valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_IncompressibleThreeWayValve;
diff --git a/SorpLib/Components/Valves/VLEValves/Tester/Test_IncompressibleValve.mo b/SorpLib/Components/Valves/VLEValves/Tester/Test_IncompressibleValve.mo
new file mode 100644
index 0000000..4bfd0ff
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/Tester/Test_IncompressibleValve.mo
@@ -0,0 +1,286 @@
+within SorpLib.Components.Valves.VLEValves.Tester;
+model Test_IncompressibleValve
+  "Tester for the valve for incompressible fluids"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of boundary models
+  //
+  SorpLib.Basics.Sources.Fluids.VLESource[9] fs_a(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each p_fixed(displayUnit="bar") = 1000000,
+    each T_fixed=303.15)
+    "Fluid source a"
+    annotation (Placement(transformation(extent={{-70,-10},{-50,10}})));
+
+  SorpLib.Basics.Sources.Fluids.VLESource[9] fs_b(
+    each boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    each boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    each use_pInput=true,
+    each use_TInput=true)
+    "Fluid source b"
+    annotation (Placement(transformation(extent={{70,-10},{50,10}})));
+
+  //
+  // Definition of valves
+  //
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=1) "Incompressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,80},{10,100}})));
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=2) "Incompressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,60},{10,80}})));
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=false,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=3) "Incompressible valve: Controllable, no time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,40},{10,60}})));
+
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_delay_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=1,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,10},{10,30}})));
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_delay_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=2,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_delay_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=10,
+    leackage=false,
+    checkValve=false,
+    useKvsValue=true,
+    valveCharacteristic=3,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, no leackage, no check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,-30},{10,-10}})));
+
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_delay_leackage_check_Kvs_cType1(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=1,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=1,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 1"
+    annotation (Placement(transformation(extent={{-10,-60},{10,-40}})));
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_delay_leackage_check_Kvs_cType2(
+    controllableOpening=true,
+    useTimeConstant=true,
+    tau=1,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=2,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 2"
+    annotation (Placement(transformation(extent={{-10,-80},{10,-60}})));
+  SorpLib.Components.Valves.VLEValves.IncompressibleValve valve_controllable_delay_leackage_check_Kvs_cType3(
+    controllableOpening=true,
+    useTimeConstant=true,
+    leackage=true,
+    checkValve=true,
+    useKvsValue=true,
+    valveCharacteristic=3,
+    opening_initial=0) "Incompressible valve: Controllable, time constant, leackage, check valve, 
+    Kvs-approach, and characterisitc 3"
+    annotation (Placement(transformation(extent={{-10,-100},{10,-80}})));
+
+  //
+  // Definition of input signals
+  //
+protected
+  Modelica.Blocks.Sources.Trapezoid input_lRel(
+    amplitude=1,
+    rising=150,
+    width=50,
+    falling=0,
+    period=250,
+    offset=0)
+    "Input signal for relative filling level"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+
+  Modelica.Blocks.Sources.Sine input_p(
+    amplitude=-1e5,
+    f=1/100,
+    offset=10e5)
+    "Input signal for pressure"
+    annotation (Placement(transformation(extent={{100,10},{80,30}})));
+  Modelica.Blocks.Sources.Sine input_T(
+    amplitude=25,
+    f=1/100,
+    offset=273.15 + 50)
+    "Input signal for temperature"
+    annotation (Placement(transformation(extent={{100,-30},{80,-10}})));
+
+equation
+  //
+  // Connections
+  //
+  connect(fs_a[1].port, valve_controllable_Kvs_cType1.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,90},{-8,90}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[2].port, valve_controllable_Kvs_cType2.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,70},{-8,70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[3].port, valve_controllable_Kvs_cType3.port_a) annotation (Line(
+      points={{-60,0},{-20,0},{-20,50},{-8,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[4].port, valve_controllable_delay_Kvs_cType1.port_a) annotation (
+      Line(
+      points={{-60,0},{-20,0},{-20,20},{-8,20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[5].port, valve_controllable_delay_Kvs_cType2.port_a) annotation (
+      Line(
+      points={{-60,0},{-8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[6].port, valve_controllable_delay_Kvs_cType3.port_a) annotation (
+      Line(
+      points={{-60,0},{-20,0},{-20,-20},{-8,-20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[7].port, valve_controllable_delay_leackage_check_Kvs_cType1.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-50},{-8,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[8].port, valve_controllable_delay_leackage_check_Kvs_cType2.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-70},{-8,-70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_a[9].port, valve_controllable_delay_leackage_check_Kvs_cType3.port_a)
+    annotation (Line(
+      points={{-60,0},{-20,0},{-20,-90},{-8,-90}},
+      color={0,140,72},
+      thickness=1));
+
+  connect(fs_b[1].port, valve_controllable_Kvs_cType1.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,90},{8,90}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[2].port, valve_controllable_Kvs_cType2.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,70},{8,70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[3].port, valve_controllable_Kvs_cType3.port_b) annotation (Line(
+      points={{60,0},{20,0},{20,50},{8,50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[4].port, valve_controllable_delay_Kvs_cType1.port_b) annotation (
+      Line(
+      points={{60,0},{20,0},{20,20},{8,20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[5].port, valve_controllable_delay_Kvs_cType2.port_b) annotation (
+      Line(
+      points={{60,0},{8,0}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[6].port, valve_controllable_delay_Kvs_cType3.port_b) annotation (
+      Line(
+      points={{60,0},{20,0},{20,-20},{8,-20}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[7].port, valve_controllable_delay_leackage_check_Kvs_cType1.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-50},{8,-50}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[8].port, valve_controllable_delay_leackage_check_Kvs_cType2.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-70},{8,-70}},
+      color={0,140,72},
+      thickness=1));
+  connect(fs_b[9].port, valve_controllable_delay_leackage_check_Kvs_cType3.port_b)
+    annotation (Line(
+      points={{60,0},{20,0},{20,-90},{8,-90}},
+      color={0,140,72},
+      thickness=1));
+
+  for ind in 1:9 loop
+    connect(input_T.y, fs_b[ind].T_input) annotation (Line(points={{79,-20},{70,
+            -20},{70,-2},{61.2,-2}},
+                          color={0,0,127}));
+    connect(input_p.y, fs_b[ind].p_input)
+      annotation (Line(points={{79,20},{70,20},{70,5},{61.2,5}},
+                                                               color={0,0,127}));
+  end for;
+
+  connect(input_lRel.y, valve_controllable_Kvs_cType1.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,97},{0,97}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_Kvs_cType2.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,77},{0,77}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_Kvs_cType3.opening) annotation (Line(
+        points={{-79,0},{-70,0},{-70,57},{0,57}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType1.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,27},{0,27}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType2.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,7},{0,7}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_Kvs_cType3.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-13},{0,-13}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType1.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-43},{0,-43}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType2.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-63},{0,-63}}, color={0,0,127}));
+  connect(input_lRel.y, valve_controllable_delay_leackage_check_Kvs_cType3.opening)
+    annotation (Line(points={{-79,0},{-70,0},{-70,-83},{0,-83}}, color={0,0,127}));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the incompressible valve.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_IncompressibleValve;
diff --git a/SorpLib/Components/Valves/VLEValves/Tester/package.mo b/SorpLib/Components/Valves/VLEValves/Tester/package.mo
new file mode 100644
index 0000000..f17a000
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/Tester/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components.Valves.VLEValves;
+package Tester "Models to test and varify models for VLE valves"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented VLE valves. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Valves/VLEValves/Tester/package.order b/SorpLib/Components/Valves/VLEValves/Tester/package.order
new file mode 100644
index 0000000..bee4d72
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/Tester/package.order
@@ -0,0 +1,5 @@
+Test_CondensateRefluxValve
+Test_IncompressibleValve
+Test_IncompressibleThreeWayValve
+Test_CompressibleValve
+Test_CompressibleThreeWayValve
diff --git a/SorpLib/Components/Valves/VLEValves/package.mo b/SorpLib/Components/Valves/VLEValves/package.mo
new file mode 100644
index 0000000..825d593
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Valves;
+package VLEValves "VLE valves"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains VLE valves based on the open-source Modelica Standard
+Library (MSL).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end VLEValves;
diff --git a/SorpLib/Components/Valves/VLEValves/package.order b/SorpLib/Components/Valves/VLEValves/package.order
new file mode 100644
index 0000000..25c6f5e
--- /dev/null
+++ b/SorpLib/Components/Valves/VLEValves/package.order
@@ -0,0 +1,6 @@
+CondensateRefluxValve
+IncompressibleValve
+IncompressibleThreeWayValve
+CompressibleValve
+CompressibleThreeWayValve
+Tester
diff --git a/SorpLib/Components/Valves/VLE_Valves/Partial/PartialValve.mo b/SorpLib/Components/Valves/VLE_Valves/Partial/PartialValve.mo
deleted file mode 100644
index 3caa614..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/Partial/PartialValve.mo
+++ /dev/null
@@ -1,69 +0,0 @@
-within SorpLib.Components.Valves.VLE_Valves.Partial;
-partial model PartialValve
-
-  /*********************** SIM ***********************************/
-
-  parameter TILMedia.VLEFluidTypes.BaseVLEFluid vleFluidType=sim.vleFluidType1
-    "VLE fluid type" annotation (Dialog(tab="SIM", group="SIM"), choices(
-      choice=sim.vleFluidType1 "VLE fluid 1 as defined in SIM",
-      choice=sim.vleFluidType2 "VLE fluid 2 as defined in SIM",
-      choice=sim.vleFluidType3 "VLE fluid 3 as defined in SIM"));
-protected
-  outer TIL.SystemInformationManager sim "System information manager";
-
-  /********************** Connecotrs *****************************/
-
-public
-  TIL.Connectors.VLEFluidPort portA(final vleFluidType=vleFluidType) "portA"
-    annotation (Placement(transformation(extent={{-90,-10},{-70,10}}, rotation=
-            0)));
-  TIL.Connectors.VLEFluidPort portB(final vleFluidType=vleFluidType) "portB"
-    annotation (Placement(transformation(extent={{70,-10},{90,10}}, rotation=0)));
-
-equation
-  portA.xi_outflow = inStream(portB.xi_outflow);
-  portB.xi_outflow = inStream(portA.xi_outflow);
-
-  portA.h_outflow = inStream(portB.h_outflow);
-  portB.h_outflow = inStream(portA.h_outflow);
-
-  portA.h_limit = -1e6;
-  // no limiter
-  portB.h_limit = -1e6;
-
-  portB.m_flow + portA.m_flow = 0 "mass balance";
-
-  annotation (Icon(coordinateSystem(extent={{-100,-60},{100,60}}), graphics={
-          Bitmap(extent={{-82,-48},{80,82}}, fileName=
-          "modelica://SorpLib/Resources/Images/MassTransfer.png")}),
-      Diagram(coordinateSystem(extent={{-100,-60},{100,60}}), graphics),
-    Documentation(info="<html>
-  <p>
-    The VLE valves are used to connect two VLE volumes and determine the mass flow between the volumes. 
-    The valve is modeled isenthalpic with no volume. 
-    The partial model includes the main equations, used for VLE valves models including:
-    <ul>
-      <li>2 vle ports</li>
-      <li>Mass balance</li>
-      <li>Energy balance</li>
-    </ul>
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    The VLE valve is modelled as isenthalpic valves with no storage volume. 
-    Thus, the mass balance reads:
-    <p align=\"center\"><i><code>m&#775;</code></i><sub>in</sub> = <i><code>m&#775;</code></i><sub>out</sub> </p>
-    The energy balance boils down to equal specific enthalpies:
-    <p align=\"center\"><i>h</i><sub>in</sub> = <i>h</i><sub>out</sub> </p>
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>December 11, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>
-"));
-end PartialValve;
diff --git a/SorpLib/Components/Valves/VLE_Valves/Partial/package.mo b/SorpLib/Components/Valves/VLE_Valves/Partial/package.mo
deleted file mode 100644
index 810b43e..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/Partial/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Components.Valves.VLE_Valves;
-package Partial
-extends SorpLib.Internals.ClassTypes.PartialPackage;
-
-end Partial;
diff --git a/SorpLib/Components/Valves/VLE_Valves/Partial/package.order b/SorpLib/Components/Valves/VLE_Valves/Partial/package.order
deleted file mode 100644
index 32ff566..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/Partial/package.order
+++ /dev/null
@@ -1 +0,0 @@
-PartialValve
diff --git a/SorpLib/Components/Valves/VLE_Valves/Testers/TestValveConstantFillingLevel.mo b/SorpLib/Components/Valves/VLE_Valves/Testers/TestValveConstantFillingLevel.mo
deleted file mode 100644
index ffd01ad..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/Testers/TestValveConstantFillingLevel.mo
+++ /dev/null
@@ -1,140 +0,0 @@
-within SorpLib.Components.Valves.VLE_Valves.Testers;
-model TestValveConstantFillingLevel
-  import SorpLib;
-
-  inner TIL.SystemInformationManager sim(redeclare
-      TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType1)
-    annotation (Placement(transformation(extent={{80,80},{100,100}})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundaryEvp(
-    streamVariablesInputType="T",
-    boundaryType="m_flow",
-    use_pressureInput=false,
-    use_massFlowRateInput=true,
-    TFixed=333.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=270,
-        origin={10,-42})));
-  SorpLib.Components.Valves.VLE_Valves.ValveConstantFillingLevel
-    valve_returnflow(
-    vleFluidType=sim.vleFluidType1,
-    kp=0.1,
-    ls=0.1,
-    l=vlePhaseSeparatorCond.l_relative) annotation (Placement(transformation(
-        extent={{-10,-6},{10,6}},
-        rotation=90,
-        origin={-22,8})));
-  TIL.VLEFluidComponents.Boundaries.Boundary vleBoundaryCond(
-    boundaryType="m_flow",
-    use_pressureInput=false,
-    use_massFlowRateInput=true,
-    streamVariablesInputType="h",
-    hFixed=2.5e6,
-    TFixed=333.15) annotation (Placement(transformation(
-        extent={{-4,-10},{4,10}},
-        rotation=90,
-        origin={10,52})));
-  Modelica.Blocks.Sources.Pulse pulseEvp(
-    period=1000,
-    amplitude=-0.001,
-    offset=0.001) annotation (Placement(transformation(
-        extent={{-3,-3},{3,3}},
-        rotation=270,
-        origin={12,-30})));
-  Modelica.Blocks.Sources.Pulse pulseEvp1(
-    period=1000,
-    amplitude=-0.001,
-    offset=0) annotation (Placement(transformation(
-        extent={{-3,-3},{3,3}},
-        rotation=90,
-        origin={8,38})));
-  SorpLib.Components.Cells.VLEPhaseSeparator.VLEPhaseSeparator vlePhaseSeparatorEvp(
-    vleFluidType=sim.vleFluidType1,
-    volume(displayUnit="l") = 0.005,
-    area=0.03,
-    includeDefaultSummary=true,
-    n=1,
-    k=1,
-    dInitial=300,
-    TInitial=298.15) annotation (Placement(transformation(
-        extent={{5,8},{-5,-8}},
-        rotation=180,
-        origin={10,-58})));
-  SorpLib.Components.Cells.VLEPhaseSeparator.VLEPhaseSeparator vlePhaseSeparatorCond(
-    vleFluidType=sim.vleFluidType1,
-    area=0.03,
-    includeDefaultSummary=true,
-    n=1,
-    k=1,
-    volume(displayUnit="l") = 0.002,
-    dInitial=200,
-    TInitial=298.15) annotation (Placement(transformation(
-        extent={{-5,8},{5,-8}},
-        rotation=0,
-        origin={10,68})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary1(
-    use_heatFlowRateInput=false,
-    boundaryType="T",
-    TFixed=288.15)
-    annotation (Placement(transformation(extent={{52,-64},{44,-52}})));
-  SorpLib.Components.HeatTransfer.HeatTransfer heatTransfer(redeclare model
-      HeatTransfer =
-        SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=1000))
-    annotation (Placement(transformation(extent={{24,-62},{40,-54}})));
-  SorpLib.Components.HeatTransfer.HeatTransfer heatTransfer1(redeclare model
-      HeatTransfer =
-        SorpLib.Components.HeatTransfer.HeatTransferPhenomena.ConstantAlphaA (
-          constantAlphaA=1000))
-    annotation (Placement(transformation(extent={{24,64},{40,72}})));
-  TIL.OtherComponents.Thermal.HeatBoundary heatBoundary2(
-    use_heatFlowRateInput=false,
-    boundaryType="T",
-    TFixed=308.15)
-    annotation (Placement(transformation(extent={{52,62},{44,74}})));
-equation
-  connect(vleBoundaryEvp.m_flow_in, pulseEvp.y)
-    annotation (Line(points={{12,-38},{12,-33.3}}, color={0,0,127}));
-  connect(vleBoundaryCond.m_flow_in, pulseEvp1.y)
-    annotation (Line(points={{8,48},{8,41.3}}, color={0,0,127}));
-  connect(vleBoundaryEvp.port, vlePhaseSeparatorEvp.vleVapourPort[1])
-    annotation (Line(
-      points={{10,-42},{10,-50}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vlePhaseSeparatorEvp.vleLiquidPort[1], valve_returnflow.portA)
-    annotation (Line(
-      points={{10,-66},{10,-66},{10,-78},{-22,-78},{-22,0}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vlePhaseSeparatorCond.vleVapourPort[1], vleBoundaryCond.port)
-    annotation (Line(
-      points={{10,60},{10,60},{10,52}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vlePhaseSeparatorCond.vleLiquidPort[1], valve_returnflow.portB)
-    annotation (Line(
-      points={{10,76},{10,86},{-22,86},{-22,16}},
-      color={153,204,0},
-      thickness=0.5));
-  connect(vlePhaseSeparatorEvp.heatPort, heatTransfer.heatPortA) annotation (
-      Line(
-      points={{15,-58},{19.5,-58},{24,-58}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer.heatPortB[1], heatBoundary1.heatPort) annotation (Line(
-      points={{40,-58},{44,-58},{48,-58}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(vlePhaseSeparatorCond.heatPort, heatTransfer1.heatPortA) annotation (
-      Line(
-      points={{15,68},{18,68},{24,68}},
-      color={204,0,0},
-      thickness=0.5));
-  connect(heatTransfer1.heatPortB[1], heatBoundary2.heatPort) annotation (Line(
-      points={{40,68},{48,68}},
-      color={204,0,0},
-      thickness=0.5));
-  annotation (
-    experiment(StopTime=5000),
-    __Dymola_experimentSetupOutput);
-end TestValveConstantFillingLevel;
diff --git a/SorpLib/Components/Valves/VLE_Valves/Testers/package.mo b/SorpLib/Components/Valves/VLE_Valves/Testers/package.mo
deleted file mode 100644
index 03d89ee..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/Testers/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Components.Valves.VLE_Valves;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-end Testers;
diff --git a/SorpLib/Components/Valves/VLE_Valves/Testers/package.order b/SorpLib/Components/Valves/VLE_Valves/Testers/package.order
deleted file mode 100644
index 97ff343..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/Testers/package.order
+++ /dev/null
@@ -1 +0,0 @@
-TestValveConstantFillingLevel
diff --git a/SorpLib/Components/Valves/VLE_Valves/ValveConstantFillingLevel.mo b/SorpLib/Components/Valves/VLE_Valves/ValveConstantFillingLevel.mo
deleted file mode 100644
index f22abe1..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/ValveConstantFillingLevel.mo
+++ /dev/null
@@ -1,39 +0,0 @@
-within SorpLib.Components.Valves.VLE_Valves;
-model ValveConstantFillingLevel
-  "This valve contains a constant filling level in one component"
-  extends Partial.PartialValve;
-
-  parameter Real kp(final unit="kg/s") = 0.1 "Linear Valve coefficient";
-
-  parameter Real ls=0.25 "Desired relative water level";
-
-  input Real l "relative water level";
-
-equation
-  portA.m_flow = (ls - l)*kp;
-
-  annotation (Documentation(info="<html>
-  <p>
-    The VLE valve with constant filling level model extends the <a href=\"modelica://SorpLib.Components.Valves.VLE_Valves.Partial.PartialValve\">SorpLib.Components.Valves.VLE_Valves.Partial.PartialValve</a>.<br>
-    The VLE valve with constant filling level model determines the mass flow, so that the filling level in one VLE volume model is constant.<br>
-  </p>
-  <h4>Main equations</h4>
-  <p>
-    The mass flow <code>m&#775;</code> is proportional to the difference between current filling level <i>l</i> and set point filling level <i>l</i><sub>set</sub>:
-    <p align=\"center\"><i><code>m&#775;</code></i><sub>in</sub> = <i>k</i> ( <i>l</i> - <i>l</i><sub>set</sub> ).</p>
-    with a linear mass transfer coefficient <i>k</i>.
-  </p>
-  <h4>Typical use and important parameters</h4>
-  <p>
-    The VLE valve with constant filling level is mainly used to connect the evaporator and the condenser in an adsorption chiller model.
-  </p>
-  <h4>Author Information</h4>
-  <p>
-    <ul>
-      <li>November 30, 2017, by Uwe Bau:<br>
-          Tidy up implementation and enhance documentation for publication of library.<br>
-      </li>
-    </ul>
-  </p>
-</html>"));
-end ValveConstantFillingLevel;
diff --git a/SorpLib/Components/Valves/VLE_Valves/package.mo b/SorpLib/Components/Valves/VLE_Valves/package.mo
deleted file mode 100644
index 9225c83..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/package.mo
+++ /dev/null
@@ -1,13 +0,0 @@
-within SorpLib.Components.Valves;
-package VLE_Valves
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-
-
-
-
-
-
-
-end VLE_Valves;
diff --git a/SorpLib/Components/Valves/VLE_Valves/package.order b/SorpLib/Components/Valves/VLE_Valves/package.order
deleted file mode 100644
index dcb4766..0000000
--- a/SorpLib/Components/Valves/VLE_Valves/package.order
+++ /dev/null
@@ -1,3 +0,0 @@
-ValveConstantFillingLevel
-Partial
-Testers
diff --git a/SorpLib/Components/Valves/ValveCharacteristics/Tester/Test_AllValveCharacteristics.mo b/SorpLib/Components/Valves/ValveCharacteristics/Tester/Test_AllValveCharacteristics.mo
new file mode 100644
index 0000000..d7fba02
--- /dev/null
+++ b/SorpLib/Components/Valves/ValveCharacteristics/Tester/Test_AllValveCharacteristics.mo
@@ -0,0 +1,70 @@
+within SorpLib.Components.Valves.ValveCharacteristics.Tester;
+model Test_AllValveCharacteristics
+  "Tester for all valve characteristics"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of paramters
+  //
+  parameter Real fc_min = 0.5
+    "Minimal flow coefficient if valve is almost closed (just for equal percentage
+    valve characteristic)"
+    annotation (Dialog(tab="General", group="Test Setup"));
+  parameter Real fc_max = 1.56
+    "Maximal flow coefficient"
+    annotation (Dialog(tab="General", group="Test Setup"));
+  parameter Real opening_min = 1e-2
+    "Minimal valve opening (i.e., position) at which the minimal flow coefficient
+    is reached (just for equal percentage valve characteristic)"
+    annotation (Dialog(tab="General", group="Test Setup"));
+
+  //
+  // Definition of variables
+  //
+  Real opening(start=0, fixed=true)
+    "Actual opening";
+
+  Real fc_linear=
+    SorpLib.Components.Valves.ValveCharacteristics.linearCharacteristic(
+      opening=opening,
+      fc_max=fc_max)
+    "Linear valve characteristic";
+  Real fc_quadratic=
+    SorpLib.Components.Valves.ValveCharacteristics.quadraticCharacteristic(
+      opening=opening,
+      fc_max=fc_max)
+    "Quadratic valve characteristic";
+  Real fc_equalPercentage=
+    SorpLib.Components.Valves.ValveCharacteristics.equalPercentageCharacteristic(
+      opening=opening,
+      fc_max=fc_max,
+      fc_min=fc_min,
+      opening_min=opening_min)
+    "Equal percentage valve characteristic";
+
+equation
+  //
+  // Calculate test setup
+  //
+  der(opening) = 1/2500
+    "Actual opening";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=2500), Documentation(info="<html>
+<p>
+This model checks the valve characteristics.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 2500 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_AllValveCharacteristics;
diff --git a/SorpLib/Components/Valves/ValveCharacteristics/Tester/package.mo b/SorpLib/Components/Valves/ValveCharacteristics/Tester/package.mo
new file mode 100644
index 0000000..2e74bfb
--- /dev/null
+++ b/SorpLib/Components/Valves/ValveCharacteristics/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Components.Valves.ValveCharacteristics;
+package Tester "Models to test and varify valve characteristic functions"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented valve
+characteristics. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Components/Valves/ValveCharacteristics/Tester/package.order b/SorpLib/Components/Valves/ValveCharacteristics/Tester/package.order
new file mode 100644
index 0000000..29fbe4c
--- /dev/null
+++ b/SorpLib/Components/Valves/ValveCharacteristics/Tester/package.order
@@ -0,0 +1 @@
+Test_AllValveCharacteristics
diff --git a/SorpLib/Components/Valves/ValveCharacteristics/equalPercentageCharacteristic.mo b/SorpLib/Components/Valves/ValveCharacteristics/equalPercentageCharacteristic.mo
new file mode 100644
index 0000000..b058635
--- /dev/null
+++ b/SorpLib/Components/Valves/ValveCharacteristics/equalPercentageCharacteristic.mo
@@ -0,0 +1,65 @@
+within SorpLib.Components.Valves.ValveCharacteristics;
+function equalPercentageCharacteristic
+  "Equal percentage valve characteristic"
+  extends BaseClasses.PartialValveCharacteristic;
+
+  //
+  // Definition of inputs
+  //
+  input Real fc_min = 0.5
+    "Minimal flow coefficient if valve is almost closed"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real opening_min = 1e-2
+    "Minimal opening used for linear regularization"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real weightingFactor=
+    SorpLib.Numerics.smoothTransition(
+      x=opening,
+      transitionPoint=opening_min,
+      transitionLength=2*opening_min,
+      noDiff=3)
+    "Weighting factor used for linear regularization";
+
+algorithm
+  fc := weightingFactor * (opening / opening_min) *
+    exp(fc_max / fc_min)^(opening_min - 1) * fc_max +
+    (1-weightingFactor) * exp(fc_max / fc_min)^(opening - 1) * fc_max
+    "Actual flow coefficient quadratically depends on the maximal flow coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The equal percentage valve characteristic calculates the flow coefficient such
+that the relative change of the flow coefficient is linearly proportional to
+the change of the opening:
+</p>
+<pre>
+    fc = <strong>exp</strong>(fc_max / fc_min)<sup>(opening - 1)</sup> * fc_max;
+</pre>
+<p>
+If the opening is below a minimal opening <i>opening_min</i>, the flow coefficient
+is calculated linearly proportional to the flow coefficient of the minimal opening:
+</p>
+<pre>
+    fc = (opening / opening_min) * <strong>exp</strong>(fc_max / fc_min)<sup>(opening_min - 1)</sup> * fc_max;
+</pre>
+<p>
+This function is based on the function
+<a href=\"Modelica://Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.equalPercentage\">Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.equalPercentage</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end equalPercentageCharacteristic;
diff --git a/SorpLib/Components/Valves/ValveCharacteristics/linearCharacteristic.mo b/SorpLib/Components/Valves/ValveCharacteristics/linearCharacteristic.mo
new file mode 100644
index 0000000..dc71dfd
--- /dev/null
+++ b/SorpLib/Components/Valves/ValveCharacteristics/linearCharacteristic.mo
@@ -0,0 +1,31 @@
+within SorpLib.Components.Valves.ValveCharacteristics;
+function linearCharacteristic "Linear valve characteristic"
+  extends BaseClasses.PartialValveCharacteristic;
+
+algorithm
+  fc := opening * fc_max
+    "Actual flow coefficient linearly depends on the maximal flow coefficient";
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The linear valve characteristic calculates the flow coefficient linearly 
+proportional to the maximum flow coefficient <i>fc_max</i>:
+</p>
+<pre>
+    fc = opening * fc_max;
+</pre>
+<p>
+This function is based on the function
+<a href=\"Modelica://Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.linear\">Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.linear</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end linearCharacteristic;
diff --git a/SorpLib/Components/Valves/ValveCharacteristics/package.mo b/SorpLib/Components/Valves/ValveCharacteristics/package.mo
new file mode 100644
index 0000000..f5b9c2d
--- /dev/null
+++ b/SorpLib/Components/Valves/ValveCharacteristics/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Components.Valves;
+package ValveCharacteristics "Package containing functions describing valve characteristics"
+  extends Modelica.Icons.FunctionsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains different functions describing valve characteristics. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ValveCharacteristics;
diff --git a/SorpLib/Components/Valves/ValveCharacteristics/package.order b/SorpLib/Components/Valves/ValveCharacteristics/package.order
new file mode 100644
index 0000000..11e6a7e
--- /dev/null
+++ b/SorpLib/Components/Valves/ValveCharacteristics/package.order
@@ -0,0 +1,4 @@
+linearCharacteristic
+quadraticCharacteristic
+equalPercentageCharacteristic
+Tester
diff --git a/SorpLib/Components/Valves/ValveCharacteristics/quadraticCharacteristic.mo b/SorpLib/Components/Valves/ValveCharacteristics/quadraticCharacteristic.mo
new file mode 100644
index 0000000..d76cf7b
--- /dev/null
+++ b/SorpLib/Components/Valves/ValveCharacteristics/quadraticCharacteristic.mo
@@ -0,0 +1,31 @@
+within SorpLib.Components.Valves.ValveCharacteristics;
+function quadraticCharacteristic "Quadratic valve characteristic"
+  extends BaseClasses.PartialValveCharacteristic;
+
+algorithm
+  fc := opening^2 * fc_max
+    "Actual flow coefficient quadratically depends on the maximal flow coefficient";
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+The linear valve characteristic calculates the flow coefficient quadratically 
+proportional to the maximum flow coefficient <i>fc_max</i>:
+</p>
+<pre>
+    fc = opening<sup>2</sup> * fc_max;
+</pre>
+<p>
+This function is based on the function
+<a href=\"Modelica://Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.quadratic\">Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.quadratic</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation
+  </li>
+</ul>
+</html>"));
+end quadraticCharacteristic;
diff --git a/SorpLib/Components/Valves/package.mo b/SorpLib/Components/Valves/package.mo
index 50df288..286d1ba 100644
--- a/SorpLib/Components/Valves/package.mo
+++ b/SorpLib/Components/Valves/package.mo
@@ -1,9 +1,21 @@
 within SorpLib.Components;
-package Valves "Valve models"
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
+package Valves "Valves to regulate and control fluid flows"
+  extends SorpLib.Icons.ValvesPackage;
 
-
-
-
-annotation (classOrder={"*","Testers"});
+  annotation (Documentation(info="<html>
+<p>
+This package includes various valves for (ideal) liquids, ideal gases, ideal gas 
+mixtures, ideal gas-vapor mixtures, and real substances (i.e., with a two-phase 
+region). The valve types include simple orfice valves for incompressible or 
+compressible fluids, three-way valves for incompressible or compressible fluids, 
+and P-like control valves.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
 end Valves;
diff --git a/SorpLib/Components/Valves/package.order b/SorpLib/Components/Valves/package.order
index 7f62b5a..caa3a32 100644
--- a/SorpLib/Components/Valves/package.order
+++ b/SorpLib/Components/Valves/package.order
@@ -1 +1,6 @@
-VLE_Valves
+BaseClasses
+LiquidValves
+GasValves
+VLEValves
+ValveCharacteristics
+Utilities
diff --git a/SorpLib/Components/package.mo b/SorpLib/Components/package.mo
index 280f0c2..154ad1a 100644
--- a/SorpLib/Components/package.mo
+++ b/SorpLib/Components/package.mo
@@ -1,29 +1,18 @@
 within SorpLib;
-package Components "Component models for adsorption energy systems"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-annotation (Icon(graphics={Ellipse(
-        extent={{-100,100},{102,-100}},
-        fillColor={170,213,255},
-        fillPattern=FillPattern.Solid,
-        pattern=LinePattern.None,
-        lineColor={0,0,0})}));
+package Components "Library containing components used to build sorption modules and sorption systems"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models of components typically used within sorption
+systems.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
 end Components;
diff --git a/SorpLib/Components/package.order b/SorpLib/Components/package.order
index bfe1f71..57da183 100644
--- a/SorpLib/Components/package.order
+++ b/SorpLib/Components/package.order
@@ -1,8 +1,10 @@
-Cells
+AdsorberColumns
+Fans
+Fittings
+HeatExchanger
 HeatTransfer
 MassTransfer
-ClosedAdsorber
-EvpCond
-OpenAdsorber
-HeatExchanger
+Pumps
+Sensors
+Tubes
 Valves
diff --git a/SorpLib/Examples/TwoBedAdsorptionChiller.mo b/SorpLib/Examples/TwoBedAdsorptionChiller.mo
new file mode 100644
index 0000000..52b130f
--- /dev/null
+++ b/SorpLib/Examples/TwoBedAdsorptionChiller.mo
@@ -0,0 +1,218 @@
+within SorpLib.Examples;
+model TwoBedAdsorptionChiller
+  "Example of a two-bed adsorption chiller"
+  extends Modelica.Icons.Example;
+  Components.HeatExchanger.CondensersEvaporators.SimpleCondenser condenser(
+    no_fluidVolumes=5,
+    nPortsVapor=2,
+    nPortsLiquid=1) "Condenser"
+    annotation (Placement(transformation(extent={{-10,50},{10,30}})));
+  Components.HeatExchanger.CondensersEvaporators.SimpleEvaporator evaporator(
+    no_fluidVolumes=5,
+    nPortsVapor=2,
+    nPortsLiquid=1) "Evaporator model"
+    annotation (Placement(transformation(extent={{-10,-60},{10,-40}})));
+  Components.HeatExchanger.Adsorbers.SimpleAdsorberDX adsorber1(no_fluidVolumes=
+       5, no_sorbentVolumes=1,
+    redeclare model WorkingPair =
+        SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Dubinin,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve,
+        approachSpecificVolume=SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve,
+        limitLowerPressureAdsorptive=true)) "First adsorber bed" annotation (Placement(
+        transformation(
+        extent={{-10,-10},{10,10}},
+        rotation=90,
+        origin={30,0})));
+
+  Components.HeatExchanger.Adsorbers.SimpleAdsorberDX adsorber2(
+    no_fluidVolumes=5,
+    no_sorbentVolumes=1,
+    redeclare model WorkingPair =
+        SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (
+        stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT,
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Dubinin,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve,
+        approachSpecificVolume=SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve,
+        limitLowerPressureAdsorptive=true)) "Second adsorber bed" annotation (
+      Placement(transformation(
+        extent={{-10,10},{10,-10}},
+        rotation=90,
+        origin={-30,0})));
+
+  Components.Valves.VLEValves.CondensateRefluxValve condensateRefluxValve
+    annotation (Placement(transformation(
+        extent={{-10,10},{10,-10}},
+        rotation=270,
+        origin={-70,0})));
+  Modelica.Blocks.Sources.RealExpression fillingLevelInput(y=condenser.phaseSeparatorVolume.l_liq_rel)
+    "Relativ filling level of the condenser"
+    annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
+  Basics.Sources.Fluids.LiquidSource fs_evapA(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed=-10/60/1000,
+    T_fixed=288.15,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Evaporator inlet"
+    annotation (Placement(transformation(extent={{-30,-60},{-10,-40}})));
+
+  Basics.Sources.Fluids.LiquidSource fs_evapB(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed=-10/60/1000,
+    T_fixed=288.15,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Evaporator outlet"
+    annotation (Placement(transformation(extent={{10,-60},{30,-40}})));
+
+  Basics.Sources.Fluids.LiquidSource fs_condA(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed=-10/60/1000,
+    T_fixed=298.15,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Condenser inlet"
+    annotation (Placement(transformation(extent={{-30,30},{-10,50}})));
+
+  Basics.Sources.Fluids.LiquidSource fs_condB(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed=-10/60/1000,
+    T_fixed=288.15,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Condenser outlet"
+    annotation (Placement(transformation(extent={{10,30},{30,50}})));
+
+  Basics.Sources.Fluids.LiquidSource fs_adsA1(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed=-10/60/1000,
+    use_TInput=true,
+    T_fixed=298.15,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Adsorber inlet"
+    annotation (Placement(transformation(extent={{-50,-22},{-30,-2}})));
+
+  Basics.Sources.Fluids.LiquidSource fs_adsA2(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.VolumeFlowRate,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    V_flow_fixed=-10/60/1000,
+    use_TInput=true,
+    T_fixed=298.15,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Adsorber inlet"
+    annotation (Placement(transformation(extent={{50,-22},{30,-2}})));
+
+  Basics.Sources.Fluids.LiquidSource fs_adsB1(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=1000000,
+    V_flow_fixed=-10/60/1000,
+    use_TInput=false,
+    T_fixed=298.15,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Adsorber outlet"
+    annotation (Placement(transformation(extent={{-50,2},{-30,22}})));
+
+  Basics.Sources.Fluids.LiquidSource fs_adsB2(
+    boundaryTypePotentialFlow=SorpLib.Choices.BoundaryFluidPotentialFlow.Pressure,
+    boundaryTypeStreamEnthalpy=SorpLib.Choices.BoundaryFluidStreamEnthalpy.Temperature,
+    p_fixed=1000000,
+    V_flow_fixed=-10/60/1000,
+    use_TInput=false,
+    T_fixed=298.15,
+    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater)
+    "Adsorber outlet"
+    annotation (Placement(transformation(extent={{30,2},{50,22}})));
+
+  Modelica.Blocks.Sources.Trapezoid inlet_TAds1(
+    amplitude=60,
+    rising=25,
+    width=490,
+    falling=25,
+    period=1000,
+    offset=273.15 + 25) "Adsorber inlet temperature"
+    annotation (Placement(transformation(extent={{-60,-20},{-48,-8}})));
+  Modelica.Blocks.Sources.Trapezoid inlet_TAds2(
+    amplitude=-60,
+    rising=25,
+    width=490,
+    falling=25,
+    period=1000,
+    offset=273.15 + 85) "Adsorber inlet temperature"
+    annotation (Placement(transformation(extent={{60,-20},{48,-8}})));
+equation
+  connect(evaporator.vaporPort[1], adsorber1.evaporatorPort) annotation (Line(
+      points={{0,-46.3},{0,-20},{26,-20},{26,-10}},
+      color={0,140,72},
+      thickness=1));
+  connect(adsorber2.evaporatorPort, evaporator.vaporPort[2]) annotation (Line(
+      points={{-26,-10},{-26,-20},{0,-20},{0,-45.3}},
+      color={0,140,72},
+      thickness=1));
+  connect(condenser.vaporPort[1], adsorber2.condenserPort) annotation (Line(
+      points={{0,36.3},{0,20},{-26,20},{-26,10}},
+      color={0,140,72},
+      thickness=1));
+  connect(condenser.vaporPort[2], adsorber1.condenserPort) annotation (Line(
+      points={{0,35.3},{0,20},{26,20},{26,10}},
+      color={0,140,72},
+      thickness=1));
+  connect(condensateRefluxValve.port_b, evaporator.liquidPort[1]) annotation (
+      Line(
+      points={{-70,-8},{-70,-60},{0,-60},{0,-53.8}},
+      color={0,140,72},
+      thickness=1));
+  connect(condenser.liquidPort[1], condensateRefluxValve.port_a) annotation (
+      Line(
+      points={{0,43.8},{0,50},{-70,50},{-70,8}},
+      color={0,140,72},
+      thickness=1));
+  connect(fillingLevelInput.y, condensateRefluxValve.processVariable)
+    annotation (Line(points={{-79,0},{-78,0},{-78,2.6},{-74.2,2.6}}, color={0,0,
+          127}));
+  connect(fs_evapA.port, evaporator.port_a) annotation (Line(
+      points={{-20,-50},{-10,-50}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_evapB.port, evaporator.port_b) annotation (Line(
+      points={{20,-50},{10,-50}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_condA.port, condenser.port_a) annotation (Line(
+      points={{-20,40},{-10,40}},
+      color={28,108,200},
+      thickness=1));
+  connect(condenser.port_b, fs_condB.port) annotation (Line(
+      points={{10,40},{20,40}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_adsA1.port, adsorber2.port_a) annotation (Line(
+      points={{-40,-12},{-30,-12},{-30,-10}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_adsB1.port, adsorber2.port_b) annotation (Line(
+      points={{-40,12},{-30,12},{-30,10}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_adsB2.port, adsorber1.port_b) annotation (Line(
+      points={{40,12},{30,12},{30,10}},
+      color={28,108,200},
+      thickness=1));
+  connect(fs_adsA2.port, adsorber1.port_a) annotation (Line(
+      points={{40,-12},{30,-12},{30,-10}},
+      color={28,108,200},
+      thickness=1));
+  connect(inlet_TAds1.y, fs_adsA1.T_input)
+    annotation (Line(points={{-47.4,-14},{-41.2,-14}}, color={0,0,127}));
+  connect(inlet_TAds2.y, fs_adsA2.T_input)
+    annotation (Line(points={{47.4,-14},{41.2,-14}}, color={0,0,127}));
+  annotation (experiment(
+      StopTime=5000,
+      __Dymola_NumberOfIntervals=5000,
+      __Dymola_Algorithm="Dassl"));
+end TwoBedAdsorptionChiller;
diff --git a/SorpLib/Examples/package.mo b/SorpLib/Examples/package.mo
new file mode 100644
index 0000000..5d75544
--- /dev/null
+++ b/SorpLib/Examples/package.mo
@@ -0,0 +1,17 @@
+within SorpLib;
+package Examples "Library containing example models"
+extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This packge contains example models of sorptions systems.
+</p>
+</html>"));
+end Examples;
diff --git a/SorpLib/Examples/package.order b/SorpLib/Examples/package.order
new file mode 100644
index 0000000..01c58f5
--- /dev/null
+++ b/SorpLib/Examples/package.order
@@ -0,0 +1 @@
+TwoBedAdsorptionChiller
diff --git a/SorpLib/Icons/AdsorberColumnsPackage/package.mo b/SorpLib/Icons/AdsorberColumnsPackage/package.mo
new file mode 100644
index 0000000..fdb36a3
--- /dev/null
+++ b/SorpLib/Icons/AdsorberColumnsPackage/package.mo
@@ -0,0 +1,1305 @@
+within SorpLib.Icons;
+partial package AdsorberColumnsPackage "Icon for packages containing adsorber column models"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing adsorber column models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Ellipse(
+          extent={{-30,-60},{-36,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,-52},{-32,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{-40,62},{0,-62}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Ellipse(
+          extent={{-22,-60},{-28,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,-60},{-20,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-6,-60},{-12,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,-52},{-16,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,-52},{-24,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-30,-44},{-36,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,-36},{-32,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-22,-44},{-28,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,-44},{-20,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-6,-44},{-12,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,-36},{-16,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,-36},{-24,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-30,-28},{-36,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,-20},{-32,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-22,-28},{-28,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,-28},{-20,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-6,-28},{-12,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,-20},{-16,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,-20},{-24,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-30,-12},{-36,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,-4},{-32,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-22,-12},{-28,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,-12},{-20,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-6,-12},{-12,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,-4},{-16,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,-4},{-24,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-30,4},{-36,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,12},{-32,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-22,4},{-28,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,4},{-20,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-6,4},{-12,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,12},{-16,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,12},{-24,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-30,20},{-36,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,28},{-32,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-22,20},{-28,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,20},{-20,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-6,20},{-12,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,28},{-16,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,28},{-24,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-30,36},{-36,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,44},{-32,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-22,36},{-28,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,36},{-20,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-6,36},{-12,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,44},{-16,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-18,44},{-24,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-30,52},{-36,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-22,52},{-28,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,52},{-20,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-6,52},{-12,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-60},{4,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{14,-52},{8,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{0,62},{40,-62}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Ellipse(
+          extent={{18,-60},{12,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{26,-60},{20,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,-60},{28,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,-52},{24,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,-52},{16,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-44},{4,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{14,-36},{8,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{18,-44},{12,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{26,-44},{20,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,-44},{28,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,-36},{24,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,-36},{16,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-28},{4,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{14,-20},{8,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{18,-28},{12,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{26,-28},{20,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,-28},{28,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,-20},{24,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,-20},{16,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-12},{4,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{14,-4},{8,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{18,-12},{12,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{26,-12},{20,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,-12},{28,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,-4},{24,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,-4},{16,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,4},{4,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{14,12},{8,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{18,4},{12,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{26,4},{20,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,4},{28,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,12},{24,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,12},{16,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,20},{4,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{14,28},{8,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{18,20},{12,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{26,20},{20,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,20},{28,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,28},{24,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,28},{16,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,36},{4,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{14,44},{8,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{18,36},{12,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{26,36},{20,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,36},{28,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{30,44},{24,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,44},{16,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,52},{4,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{18,52},{12,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{26,52},{20,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,52},{28,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{50,-60},{44,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{54,-52},{48,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{40,62},{80,-62}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Ellipse(
+          extent={{58,-60},{52,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{66,-60},{60,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,-60},{68,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-52},{64,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,-52},{56,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{50,-44},{44,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{54,-36},{48,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,-44},{52,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{66,-44},{60,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,-44},{68,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-36},{64,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,-36},{56,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{50,-28},{44,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{54,-20},{48,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,-28},{52,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{66,-28},{60,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,-28},{68,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-20},{64,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,-20},{56,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{50,-12},{44,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{54,-4},{48,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,-12},{52,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{66,-12},{60,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,-12},{68,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-4},{64,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,-4},{56,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{50,4},{44,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{54,12},{48,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,4},{52,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{66,4},{60,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,4},{68,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,12},{64,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,12},{56,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{50,20},{44,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{54,28},{48,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,20},{52,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{66,20},{60,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,20},{68,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,28},{64,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,28},{56,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{50,36},{44,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{54,44},{48,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,36},{52,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{66,36},{60,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,36},{68,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,44},{64,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,44},{56,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{50,52},{44,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,52},{52,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{66,52},{60,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,52},{68,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,-60},{-76,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,-52},{-72,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{-80,62},{-40,-62}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Ellipse(
+          extent={{-62,-60},{-68,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,-60},{-60,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-46,-60},{-52,-54}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,-52},{-56,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,-52},{-64,-46}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,-44},{-76,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,-36},{-72,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,-44},{-68,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,-44},{-60,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-46,-44},{-52,-38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,-36},{-56,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,-36},{-64,-30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,-28},{-76,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,-20},{-72,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,-28},{-68,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,-28},{-60,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-46,-28},{-52,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,-20},{-56,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,-20},{-64,-14}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,-12},{-76,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,-4},{-72,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,-12},{-68,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,-12},{-60,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-46,-12},{-52,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,-4},{-56,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,-4},{-64,2}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,4},{-76,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,12},{-72,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,4},{-68,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,4},{-60,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-46,4},{-52,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,12},{-56,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,12},{-64,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,20},{-76,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,28},{-72,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,20},{-68,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,20},{-60,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-46,20},{-52,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,28},{-56,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,28},{-64,34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,36},{-76,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,44},{-72,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,36},{-68,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,36},{-60,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-46,36},{-52,42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,44},{-56,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,44},{-64,50}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,52},{-76,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,52},{-68,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-54,52},{-60,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-46,52},{-52,58}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid)}));
+end AdsorberColumnsPackage;
diff --git a/SorpLib/Icons/AdsorberColumnsPackage/package.order b/SorpLib/Icons/AdsorberColumnsPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/AdsorbersPackage/package.mo b/SorpLib/Icons/AdsorbersPackage/package.mo
new file mode 100644
index 0000000..8d07b88
--- /dev/null
+++ b/SorpLib/Icons/AdsorbersPackage/package.mo
@@ -0,0 +1,632 @@
+within SorpLib.Icons;
+partial package AdsorbersPackage "Icon for packages containing adsorber models"
+  extends Modelica.Icons.Package;
+
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Rectangle(
+          extent={{-92,60},{94,-60}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Line(
+          points={{94,40},{-86,40},{74,0},{-86,-40},{94,-40}},
+          color={0,0,0},
+          thickness=1),
+        Ellipse(
+          extent={{-80,42},{-86,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-20,42},{-26,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-32,42},{-38,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,42},{-50,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-56,42},{-62,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-68,42},{-74,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,42},{46,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,42},{34,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,42},{22,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,42},{10,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,42},{-2,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,42},{-14,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{64,42},{58,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,42},{70,48}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,-48},{70,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{64,-48},{58,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{52,-48},{46,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,-48},{34,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,-48},{22,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,-48},{10,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,-48},{-2,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-8,-48},{-14,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-20,-48},{-26,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-32,-48},{-38,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,-48},{-50,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-56,-48},{-62,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-68,-48},{-74,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-80,-48},{-86,-42}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{82,-38},{76,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,-38},{64,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,-38},{52,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,-38},{40,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,-38},{28,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,-38},{16,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,-38},{4,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-2,-38},{-8,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,-38},{-20,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,-38},{-32,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-38,-38},{-44,-32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,-40},{-56,-34}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,34},{-56,40}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-38,32},{-44,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-26,32},{-32,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,32},{-20,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-2,32},{-8,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{10,32},{4,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{22,32},{16,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,32},{28,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,32},{40,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{58,32},{52,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,32},{64,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{82,32},{76,38}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-72,30},{-78,36}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,26},{-64,32}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-42,22},{-48,28}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-24,18},{-30,24}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,14},{-16,20}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{6,10},{0,16}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{24,6},{18,12}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{38,2},{32,8}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{54,-2},{48,4}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,24},{-20,30}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{0,20},{-6,26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,16},{10,22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{32,12},{26,18}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,8},{40,14}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,4},{56,10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-72,-36},{-78,-30}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,-32},{-64,-26}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-42,-28},{-48,-22}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-24,-24},{-30,-18}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-10,-20},{-16,-14}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{6,-16},{0,-10}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{24,-12},{18,-6}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{38,-8},{32,-2}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{62,-10},{56,-4}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,-14},{40,-8}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{32,-18},{26,-12}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{18,-22},{12,-16}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{0,-26},{-6,-20}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,-30},{-20,-24}},
+          lineColor={244,125,35},
+          lineThickness=1,
+          fillColor={244,125,35},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-50,24},{-56,30}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-60,34},{-66,40}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-82,34},{-88,40}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-14,42},{-20,48}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-20,26},{-26,32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-2,12},{-8,18}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{24,14},{18,20}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{46,0},{40,6}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,32},{22,38}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{70,42},{64,48}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{76,32},{70,38}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{14,-14},{8,-8}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-34,-26},{-40,-20}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,-40},{-64,-34}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-84,-42},{-90,-36}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-38,-48},{-44,-42}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{4,-38},{-2,-32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{34,-48},{28,-42}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{64,-38},{58,-32}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{40,-16},{34,-10}},
+          lineColor={0,140,72},
+          lineThickness=1,
+          fillColor={0,140,72},
+          fillPattern=FillPattern.Solid)}),
+        Documentation(info="<html>
+<p>
+This icon indicates a package containing adsorber models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end AdsorbersPackage;
diff --git a/SorpLib/Icons/AdsorbersPackage/package.order b/SorpLib/Icons/AdsorbersPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/CondensersEvaporatorsPackage/package.mo b/SorpLib/Icons/CondensersEvaporatorsPackage/package.mo
new file mode 100644
index 0000000..5a943af
--- /dev/null
+++ b/SorpLib/Icons/CondensersEvaporatorsPackage/package.mo
@@ -0,0 +1,126 @@
+within SorpLib.Icons;
+partial package CondensersEvaporatorsPackage "Icon for packages containing condensers and evaporators"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing recooler models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-40},
+            {100,40}}),                                         graphics={
+        Text(
+          extent={{-60,30},{-40,10}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.None,
+          fontSize=20,
+          textString="1"),
+        Text(
+          extent={{40,30},{60,10}},
+          lineColor={0,0,0},
+          lineThickness=1,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.None,
+          fontSize=20,
+          textString="n"),
+        Line(
+          points={{0,40},{0,22},{-2,14},{2,0},{-2,-14},{2,-24},{0,-40}},
+          color={0,0,0},
+          smooth=Smooth.Bezier),
+        Rectangle(
+          extent={{-100,-2},{100,-40}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-100,-10},{-80,8},{-54,-2},{-36,0},{-6,6},{14,-2},{42,4},{74,
+              4},{94,-6},{-100,-10}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          smooth=Smooth.Bezier,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Rectangle(
+          extent={{-100,40},{100,-40}},
+          lineColor={0,0,0},
+          lineThickness=1),
+        Polygon(
+          points={{-20,4},{-20,4},{-32,18},{-8,18},{-20,4}},
+          lineColor={0,0,0},
+          lineThickness=0.5),
+        Ellipse(
+          extent={{-66,38},{-78,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-28,38},{-40,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-12,38},{-24,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{16,22},{4,10}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{28,38},{16,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{36,22},{24,10}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-58,24},{-70,12}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{74,38},{62,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{48,38},{36,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{86,24},{74,12}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-84,34},{-96,22}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid)}));
+end CondensersEvaporatorsPackage;
diff --git a/SorpLib/Icons/CondensersEvaporatorsPackage/package.order b/SorpLib/Icons/CondensersEvaporatorsPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/ControllerPackage/package.mo b/SorpLib/Icons/ControllerPackage/package.mo
new file mode 100644
index 0000000..adda22c
--- /dev/null
+++ b/SorpLib/Icons/ControllerPackage/package.mo
@@ -0,0 +1,33 @@
+within SorpLib.Icons;
+partial package ControllerPackage "Icon for packages containing controller models of sorption modules"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing controller models of sorption modules.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Ellipse(extent={{-80,-80},{80,80}}),
+        Line(points={{80,0},{60,0}}),
+        Line(points={{69.282,40},{51.962,30}}),
+        Line(points={{40,69.282},{30,51.962}}),
+        Line(points={{0,80},{0,60}}),
+        Line(points={{-40,69.282},{-30,51.962}}),
+        Line(points={{-69.282,40},{-51.962,30}}),
+        Line(points={{-80,0},{-60,0}}),
+        Line(points={{-69.282,-40},{-51.962,-30}}),
+        Line(points={{-40,-69.282},{-30,-51.962}}),
+        Line(points={{0,-80},{0,-60}}),
+        Line(points={{40,-69.282},{30,-51.962}}),
+        Line(points={{69.282,-40},{51.962,-30}}),
+        Line(points={{80,0},{60,0}}),
+        Line(points={{0,0},{-50,50}}),
+        Line(points={{0,0},{40,0}})}));
+end ControllerPackage;
diff --git a/SorpLib/Icons/ControllerPackage/package.order b/SorpLib/Icons/ControllerPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/FansPackage/package.mo b/SorpLib/Icons/FansPackage/package.mo
new file mode 100644
index 0000000..a055b0f
--- /dev/null
+++ b/SorpLib/Icons/FansPackage/package.mo
@@ -0,0 +1,60 @@
+within SorpLib.Icons;
+partial package FansPackage "Icon for packages containing fan models"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing pump models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+          Rectangle(
+            extent={{-90,44},{90,-48}},
+            fillColor={244,125,35},
+            fillPattern=FillPattern.HorizontalCylinder,
+        lineColor={0,0,0}),
+          Polygon(
+            points={{-48,-48},{-72,-88},{72,-88},{48,-48},{-48,-48}},
+            lineColor={0,0,0},
+            pattern=LinePattern.None,
+            fillPattern=FillPattern.VerticalCylinder,
+        fillColor={0,0,0}),
+          Ellipse(
+            extent={{-80,78},{80,-82}},
+            fillPattern=FillPattern.Sphere,
+            fillColor={244,125,35},
+        lineColor={0,0,0}),
+          Polygon(
+            points={{46,20},{46,-20},{86,0},{46,20}},
+            pattern=LinePattern.None,
+            fillPattern=FillPattern.HorizontalCylinder,
+            fillColor={255,255,255}),
+      Polygon(
+        points={{-100,100},{-100,100}},
+        lineColor={0,0,0},
+        pattern=LinePattern.None,
+        fillPattern=FillPattern.Sphere,
+        fillColor={0,0,0}),
+      Polygon(
+        points={{54,40},{42,52},{-48,-40},{-38,-50},{54,40}},
+        lineColor={0,0,0},
+        pattern=LinePattern.None,
+        fillPattern=FillPattern.Sphere,
+        fillColor={255,255,255},
+        smooth=Smooth.Bezier,
+        lineThickness=0.5),
+      Polygon(
+        points={{42,-52},{52,-40},{-38,50},{-48,40},{42,-52}},
+        lineColor={0,0,0},
+        pattern=LinePattern.None,
+        fillPattern=FillPattern.Sphere,
+        fillColor={255,255,255},
+        smooth=Smooth.Bezier,
+        lineThickness=0.5)}));
+end FansPackage;
diff --git a/SorpLib/Icons/FansPackage/package.order b/SorpLib/Icons/FansPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/FittingsPackage/package.mo b/SorpLib/Icons/FittingsPackage/package.mo
new file mode 100644
index 0000000..9abce09
--- /dev/null
+++ b/SorpLib/Icons/FittingsPackage/package.mo
@@ -0,0 +1,36 @@
+within SorpLib.Icons;
+partial package FittingsPackage "Icon for packages containing fitting models"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing fitting models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+      Rectangle(
+        extent={{-80,50},{80,-50}},
+        lineColor={28,108,200},
+        fillColor={28,108,200},
+        fillPattern=FillPattern.HorizontalCylinder),
+          Line(
+            points={{-60,-30},{-60,30},{60,-30},{60,30}},
+            thickness=0.5,
+        color={255,255,255}),
+      Line(
+        points={{-60,70},{40,70}},
+        color={0,0,0},
+        thickness=0.5),
+      Polygon(
+        points={{60,70},{40,80},{40,60},{60,70}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillPattern=FillPattern.HorizontalCylinder,
+        fillColor={0,0,0})}));
+end FittingsPackage;
diff --git a/SorpLib/Icons/FittingsPackage/package.order b/SorpLib/Icons/FittingsPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/HeatExchangersPackage/package.mo b/SorpLib/Icons/HeatExchangersPackage/package.mo
new file mode 100644
index 0000000..85c43ae
--- /dev/null
+++ b/SorpLib/Icons/HeatExchangersPackage/package.mo
@@ -0,0 +1,95 @@
+within SorpLib.Icons;
+partial package HeatExchangersPackage "Icon for packages containing heat exchanger models"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing heat exchanger models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Rectangle(
+          extent={{-100,-24},{100,-28}},
+          fillColor={95,95,95},
+          fillPattern=FillPattern.Forward),
+        Rectangle(
+          extent={{-100,32},{100,28}},
+          fillColor={95,95,95},
+          fillPattern=FillPattern.Forward),
+        Rectangle(
+          extent={{-100,62},{100,32}},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={0,63,125}),
+        Rectangle(
+          extent={{-100,-28},{100,-58}},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={0,63,125}),
+        Rectangle(
+          extent={{-100,28},{100,-24}},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={0,128,255}),
+        Line(
+          points={{30,-83},{-60,-83}},
+          color={0,128,255}),
+        Polygon(
+          points={{20,-68},{60,-83},{20,-98},{20,-68}},
+          lineColor={0,128,255},
+          fillColor={0,128,255},
+          fillPattern=FillPattern.Solid),
+        Line(
+          points={{30,79},{-60,79}},
+          color={0,128,255}),
+        Polygon(
+          points={{-50,94},{-90,79},{-50,64},{-50,94}},
+          lineColor={0,128,255},
+          fillColor={0,128,255},
+          fillPattern=FillPattern.Solid),
+      Line(
+        points={{-36,40},{-56,32},{-62,18},{-50,10},{-36,0},{-38,-12}},
+        color={238,46,47},
+        smooth=Smooth.Bezier,
+        arrow={Arrow.Filled,Arrow.Filled},
+        thickness=1),
+      Line(
+        points={{-16,40},{-36,32},{-42,18},{-30,10},{-16,0},{-18,-12}},
+        color={238,46,47},
+        smooth=Smooth.Bezier,
+        arrow={Arrow.Filled,Arrow.Filled},
+        thickness=1),
+      Line(
+        points={{-54,40},{-74,32},{-80,18},{-68,10},{-54,0},{-56,-12}},
+        color={238,46,47},
+        smooth=Smooth.Bezier,
+        arrow={Arrow.Filled,Arrow.Filled},
+        thickness=1),
+      Line(
+        points={{13,26},{-7,18},{-13,4},{-1,-4},{13,-14},{11,-26}},
+        color={238,46,47},
+        smooth=Smooth.Bezier,
+        arrow={Arrow.Filled,Arrow.Filled},
+        thickness=1,
+        origin={67,-16},
+        rotation=180),
+      Line(
+        points={{13,26},{-7,18},{-13,4},{-1,-4},{13,-14},{11,-26}},
+        color={238,46,47},
+        smooth=Smooth.Bezier,
+        arrow={Arrow.Filled,Arrow.Filled},
+        thickness=1,
+        origin={47,-16},
+        rotation=180),
+      Line(
+        points={{13,26},{-7,18},{-13,4},{-1,-4},{13,-14},{11,-26}},
+        color={238,46,47},
+        smooth=Smooth.Bezier,
+        arrow={Arrow.Filled,Arrow.Filled},
+        thickness=1,
+        origin={29,-16},
+        rotation=180)}));
+end HeatExchangersPackage;
diff --git a/SorpLib/Icons/HeatExchangersPackage/package.order b/SorpLib/Icons/HeatExchangersPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/HeatTransfersPackage/package.mo b/SorpLib/Icons/HeatTransfersPackage/package.mo
new file mode 100644
index 0000000..79d57da
--- /dev/null
+++ b/SorpLib/Icons/HeatTransfersPackage/package.mo
@@ -0,0 +1,62 @@
+within SorpLib.Icons;
+partial package HeatTransfersPackage "Icon for packages containing heat transfer models"
+  extends Modelica.Icons.Package;
+
+  annotation (Icon(graphics={
+      Polygon(
+        origin={15.758,27.517},
+        lineColor = {128,128,128},
+        fillColor = {192,192,192},
+        fillPattern = FillPattern.Solid,
+        points = {{-54,-6},{-61,-7},{-75,-15},{-79,-24},{-80,-34},{-78,-42},{-73,-49},{-64,-51},{-57,-51},{-47,-50},{-41,-43},{-38,-35},{-40,-27},{-40,-20},{-42,-13},{-47,-7},{-54,-5},{-54,-6}}),
+    Polygon(
+        origin={15.758,27.517},
+        fillColor = {160,160,164},
+        fillPattern = FillPattern.Solid,
+        points = {{-75,-15},{-79,-25},{-80,-34},{-78,-42},{-72,-49},{-64,-51},{-57,-51},{-47,-50},{-57,-47},{-65,-45},{-71,-40},{-74,-33},{-76,-23},{-75,-15},{-75,-15}}),
+      Polygon(
+        origin={15.758,27.517},
+        lineColor = {160,160,164},
+        fillColor = {192,192,192},
+        fillPattern = FillPattern.Solid,
+        points = {{39,-6},{32,-7},{18,-15},{14,-24},{13,-34},{15,-42},{20,-49},{29,-51},{36,-51},{46,-50},{52,-43},{55,-35},{53,-27},{53,-20},{51,-13},{46,-7},{39,-5},{39,-6}}),
+      Polygon(
+        origin={15.758,27.517},
+        fillColor = {160,160,164},
+        fillPattern = FillPattern.Solid,
+        points = {{18,-15},{14,-25},{13,-34},{15,-42},{21,-49},{29,-51},{36,-51},{46,-50},{36,-47},{28,-45},{22,-40},{19,-33},{17,-23},{18,-15},{18,-15}}),
+      Polygon(
+        origin={15.758,27.517},
+        lineColor = {191,0,0},
+        fillColor = {191,0,0},
+        fillPattern = FillPattern.Solid,
+        points = {{-9,-23},{-9,-10},{18,-17},{-9,-23}}),
+      Line(
+        origin={15.758,27.517},
+        points = {{-41,-17},{-9,-17}},
+        color = {191,0,0},
+        thickness = 0.5),
+      Line(
+        origin={15.758,27.517},
+        points = {{-17,-40},{15,-40}},
+        color = {191,0,0},
+        thickness = 0.5),
+      Polygon(
+        origin={15.758,27.517},
+        lineColor = {191,0,0},
+        fillColor = {191,0,0},
+        fillPattern = FillPattern.Solid,
+        points = {{-17,-46},{-17,-34},{-40,-40},{-17,-46}})}), Documentation(
+        info="<html>
+<p>
+This icon indicates a package containing heat transfer models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end HeatTransfersPackage;
diff --git a/SorpLib/Icons/HeatTransfersPackage/package.order b/SorpLib/Icons/HeatTransfersPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/MassTransfersPackage/package.mo b/SorpLib/Icons/MassTransfersPackage/package.mo
new file mode 100644
index 0000000..59d1f81
--- /dev/null
+++ b/SorpLib/Icons/MassTransfersPackage/package.mo
@@ -0,0 +1,202 @@
+within SorpLib.Icons;
+partial package MassTransfersPackage "Icon for packages containing mass transfer models"
+  extends Modelica.Icons.Package;
+
+  annotation (Icon(graphics={
+        Ellipse(
+          extent={{84,60},{-36,-60}},
+          lineColor={0,0,0},
+          fillColor={175,175,175},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-8,54},{-4,46},{-4,38},{-2,32},{2,26},{10,16},{24,14},{56,14},
+              {54,8},{44,8},{22,10},{20,6},{28,2},{44,0},{50,-4},{52,-10},{50,-20},
+              {46,-26},{42,-34},{32,-38},{22,-40},{16,-40},{6,-36},{8,-32},{14,-36},
+              {22,-36},{30,-34},{36,-28},{42,-22},{44,-14},{42,-8},{36,-6},{30,-4},
+              {26,-2},{20,0},{16,4},{18,-2},{24,-8},{30,-16},{24,-16},{20,-8},{14,
+              -2},{12,2},{14,8},{10,12},{4,16},{0,18},{0,14},{-2,10},{0,8},{0,2},
+              {0,0},{0,-2},{2,-4},{4,-6},{8,-12},{0,-6},{0,-10},{0,-12},{0,-20},
+              {-6,-26},{-4,-10},{-2,-4},{-6,-2},{-20,0},{-26,4},{-24,6},{-12,2},
+              {-4,0},{-4,6},{-6,10},{-10,12},{-18,20},{-24,30},{-18,26},{-6,14},
+              {-4,20},{-6,26},{-10,32},{-6,40},{-8,54}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid,
+          smooth=Smooth.Bezier),
+        Text(
+          extent={{-36,78},{-16,58}},
+          lineColor={0,0,0},
+          fillColor={255,255,255},
+          fillPattern=FillPattern.None,
+          textString="D",
+          textStyle={TextStyle.Italic}),
+        Line(
+          points={{-20,64},{-14,60},{-8,52}},
+          color={0,140,72},
+          smooth=Smooth.Bezier,
+          arrow={Arrow.None,Arrow.Filled},
+          thickness=0.5),
+        Line(
+          points={{-6,50},{-6,42},{-2,28},{8,16},{18,8},{24,0},{38,-4},{48,-12},
+              {44,-24},{32,-36},{16,-38},{8,-34}},
+          color={0,140,72},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.None,Arrow.Filled}),
+        Ellipse(
+          extent={{-8,52},{-6,50}},
+          lineColor={0,140,72},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{8,-32},{10,-34}},
+          lineColor={0,140,72},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-64,50},{-56,58}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-56,38},{-48,46}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,30},{-62,38}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-56,18},{-48,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-68,10},{-60,18}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-56,0},{-48,8}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-80,18},{-72,26}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-80,42},{-72,50}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-52,60},{-44,68}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-76,62},{-68,70}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-62,72},{-54,80}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-78,-2},{-70,6}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-66,-8},{-58,0}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-52,-20},{-44,-12}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-70,-24},{-62,-16}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-84,-16},{-76,-8}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-82,-36},{-74,-28}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-60,-36},{-52,-28}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-44,-42},{-36,-34}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-72,-52},{-64,-44}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-56,-54},{-48,-46}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{-82,-66},{-74,-58}},
+          lineColor={28,108,200},
+          lineThickness=0.5,
+          fillColor={28,108,200},
+          fillPattern=FillPattern.Solid)}),
+          Documentation(info="<html>
+<p>
+This icon indicates a package containing mass transfer models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end MassTransfersPackage;
diff --git a/SorpLib/Icons/MassTransfersPackage/package.order b/SorpLib/Icons/MassTransfersPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/MediaPackage/package.mo b/SorpLib/Icons/MediaPackage/package.mo
new file mode 100644
index 0000000..31c420f
--- /dev/null
+++ b/SorpLib/Icons/MediaPackage/package.mo
@@ -0,0 +1,46 @@
+within SorpLib.Icons;
+partial package MediaPackage "Icon for packages containing fluid property models"
+  extends Modelica.Icons.Package;
+
+  annotation (Icon(graphics={
+        Line(
+          points={{-30,30},{-34,98},{-34,98}},
+          color={175,175,175}),
+        Line(
+          points={{-50,-18},{-64,94},{-64,94}},
+          color={175,175,175}),
+        Line(
+          points={{-66,-70},{-84,-6},{-84,-6}},
+          color={175,175,175}),
+        Line(
+          points={{-30,30},{78,30}},
+          color={175,175,175}),
+        Line(
+          points={{-50,-18},{66,-18}},
+          color={175,175,175}),
+        Line(
+          points={{-66,-70},{48,-70}},
+          color={175,175,175}),
+        Line(
+          points={{-66,-70},{-52,-20},{-22,50},{14,76},{58,76},{83,55},{72,2},{58,
+              -40},{48,-70}},
+          color={64,64,64},
+          smooth=Smooth.Bezier),
+        Line(
+          points={{66,-18},{80,-70}},
+          color={175,175,175}),
+        Line(
+          points={{78,30},{96,-48}},
+          color={175,175,175})}), Documentation(info="<html>
+<p>
+This icon indicates a package containing fluid property models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end MediaPackage;
diff --git a/SorpLib/Icons/MediaPackage/package.order b/SorpLib/Icons/MediaPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/PumpsPackage/package.mo b/SorpLib/Icons/PumpsPackage/package.mo
new file mode 100644
index 0000000..87e08ef
--- /dev/null
+++ b/SorpLib/Icons/PumpsPackage/package.mo
@@ -0,0 +1,35 @@
+within SorpLib.Icons;
+partial package PumpsPackage "Icon for packages containing pump models"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing pump models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+          Rectangle(
+            extent={{-90,44},{90,-48}},
+            fillColor={0,127,255},
+            fillPattern=FillPattern.HorizontalCylinder),
+          Polygon(
+            points={{-48,-48},{-72,-88},{72,-88},{48,-48},{-48,-48}},
+            lineColor={0,0,255},
+            pattern=LinePattern.None,
+            fillPattern=FillPattern.VerticalCylinder),
+          Ellipse(
+            extent={{-80,78},{80,-82}},
+            fillPattern=FillPattern.Sphere,
+            fillColor={0,100,199}),
+          Polygon(
+            points={{-32,24},{-32,-36},{46,-8},{-32,24}},
+            pattern=LinePattern.None,
+            fillPattern=FillPattern.HorizontalCylinder,
+            fillColor={255,255,255})}));
+end PumpsPackage;
diff --git a/SorpLib/Icons/PumpsPackage/package.order b/SorpLib/Icons/PumpsPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/RecoolersPackage/package.mo b/SorpLib/Icons/RecoolersPackage/package.mo
new file mode 100644
index 0000000..121d59b
--- /dev/null
+++ b/SorpLib/Icons/RecoolersPackage/package.mo
@@ -0,0 +1,152 @@
+within SorpLib.Icons;
+partial package RecoolersPackage "Icon for packages containing recoolers"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing recooler models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(coordinateSystem(preserveAspectRatio=false), graphics={
+        Polygon(
+          points={{-100,40},{-100,-40},{-60,-60},{60,-60},{100,-40},{100,40},{60,
+              60},{-60,60},{-100,40}},
+          lineColor={0,0,0},
+          lineThickness=0.5,
+          fillColor={255,255,255},
+          fillPattern=FillPattern.Solid),
+        Line(
+          points={{-100,0},{-80,60},{-60,-60},{-40,60},{-20,-60},{0,60},{20,-60},
+              {40,60},{60,-60},{80,60},{98,0}},
+          color={28,108,200},
+          thickness=1,
+          smooth=Smooth.Bezier),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-60,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-40,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-20,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={0,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={20,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={40,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={244,125,35},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={60,-46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-60,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-40,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={-20,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={0,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={20,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={40,46},
+          rotation=180),
+        Line(
+          points={{0,-10},{0,10}},
+          color={238,46,47},
+          thickness=0.5,
+          smooth=Smooth.Bezier,
+          arrow={Arrow.Filled,Arrow.None},
+          origin={60,46},
+          rotation=180),
+        Ellipse(
+          extent={{-60,64},{0,58}},
+          lineColor={0,0,0},
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid),
+        Ellipse(
+          extent={{0,64},{60,58}},
+          lineColor={0,0,0},
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid)}));
+end RecoolersPackage;
diff --git a/SorpLib/Icons/RecoolersPackage/package.order b/SorpLib/Icons/RecoolersPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/SorpLibPackage/package.mo b/SorpLib/Icons/SorpLibPackage/package.mo
new file mode 100644
index 0000000..17da812
--- /dev/null
+++ b/SorpLib/Icons/SorpLibPackage/package.mo
@@ -0,0 +1,89 @@
+within SorpLib.Icons;
+partial package SorpLibPackage "Icon for the SorpLib Modelica library"
+  extends Modelica.Icons.Package;
+
+annotation (Documentation(info="<html>
+<p>
+This icon is the base icon for the Modelica library SorpLib.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+      Rectangle(
+        extent={{-92,32},{28,-88}},
+        lineColor={0,0,0},
+        lineThickness=0.5),
+      Rectangle(
+        extent={{-32,92},{88,-28}},
+        lineColor={0,0,0},
+        lineThickness=0.5),
+      Line(
+        points={{-32,92},{-50,74},{-92,32}},
+        color={0,0,0},
+        thickness=0.5),
+      Line(
+        points={{-32,-28},{-50,-46},{-92,-88}},
+        color={0,0,0},
+        thickness=0.5),
+      Line(
+        points={{88,-28},{70,-46},{28,-88}},
+        color={0,0,0},
+        thickness=0.5),
+      Line(
+        points={{88,92},{70,74},{28,32}},
+        color={0,0,0},
+        thickness=0.5),
+      Ellipse(
+        extent={{-94,-90},{-88,-84}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{24,-90},{30,-84}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{84,-30},{90,-24}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{-34,-30},{-28,-24}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{-34,88},{-28,94}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{-94,28},{-88,34}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{24,28},{30,34}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid),
+      Ellipse(
+        extent={{84,88},{90,94}},
+        lineColor={0,0,0},
+        lineThickness=0.5,
+        fillColor={0,0,0},
+        fillPattern=FillPattern.Solid)}));
+end SorpLibPackage;
diff --git a/SorpLib/Icons/SorpLibPackage/package.order b/SorpLib/Icons/SorpLibPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/TubesPackage/package.mo b/SorpLib/Icons/TubesPackage/package.mo
new file mode 100644
index 0000000..ec88338
--- /dev/null
+++ b/SorpLib/Icons/TubesPackage/package.mo
@@ -0,0 +1,44 @@
+within SorpLib.Icons;
+partial package TubesPackage "Icon for packages containing tube models"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing heat exchanger models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Rectangle(
+          extent={{-100,-24},{100,-28}},
+          fillColor={95,95,95},
+          fillPattern=FillPattern.Forward),
+        Rectangle(
+          extent={{-100,32},{100,28}},
+          fillColor={95,95,95},
+          fillPattern=FillPattern.Forward),
+        Rectangle(
+          extent={{-100,28},{100,-24}},
+          fillPattern=FillPattern.HorizontalCylinder,
+          fillColor={0,128,255}),
+        Line(
+          points={{48,-58},{-52,-58}},
+          color={0,0,0}),
+        Polygon(
+          points={{20,-44},{60,-59},{20,-74},{20,-44}},
+          lineColor={0,0,0},
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid),
+        Polygon(
+          points={{-20,15},{20,0},{-20,-15},{-20,15}},
+          lineColor={0,0,0},
+          fillColor={0,0,0},
+          fillPattern=FillPattern.Solid,
+        origin={-40,-59},
+        rotation=180)}));
+end TubesPackage;
diff --git a/SorpLib/Icons/TubesPackage/package.order b/SorpLib/Icons/TubesPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/ValvesPackage/package.mo b/SorpLib/Icons/ValvesPackage/package.mo
new file mode 100644
index 0000000..2fa52d3
--- /dev/null
+++ b/SorpLib/Icons/ValvesPackage/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Icons;
+partial package ValvesPackage "Icon for packages containing valve models"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing valve models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Rectangle(
+          extent={{-20,60},{20,52}},
+          fillPattern=FillPattern.Solid),
+        Line(points={{0,52},{0,0}}),
+        Polygon(points={{-80,50},{80,-50},{80,50},{0,0},{-80,-50},{-80,50}})}));
+end ValvesPackage;
diff --git a/SorpLib/Icons/ValvesPackage/package.order b/SorpLib/Icons/ValvesPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/VolumesPackage/package.mo b/SorpLib/Icons/VolumesPackage/package.mo
new file mode 100644
index 0000000..faedbe3
--- /dev/null
+++ b/SorpLib/Icons/VolumesPackage/package.mo
@@ -0,0 +1,50 @@
+within SorpLib.Icons;
+partial package VolumesPackage "Icon for packages containing finite volume models"
+  extends Modelica.Icons.Package;
+
+  annotation (Documentation(info="<html>
+<p>
+This icon indicates a package containing volume models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"), Icon(graphics={
+        Rectangle(extent={{-90,30},{30,-90}}, lineColor={0,0,0}),
+        Line(points={{-90,30},{-30,90}}, color={0,0,0}),
+        Line(
+          points={{-30,-30},{-90,-90}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(points={{90,-30},{30,-90}}, color={0,0,0}),
+        Line(points={{90,90},{30,30}}, color={0,0,0}),
+        Line(points={{-30,90},{90,90},{90,-30}}, color={0,0,0}),
+        Line(
+          points={{90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-30,90},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dash),
+        Line(
+          points={{-60,-60},{60,-60},{60,60},{-60,60},{-60,-60}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{30,-30},{-30,-90},{-30,30},{30,90},{30,30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{-30,30},{-90,-30},{-30,-30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot),
+        Line(
+          points={{30,-30},{90,30},{30,30}},
+          color={0,0,0},
+          pattern=LinePattern.Dot)}));
+end VolumesPackage;
diff --git a/SorpLib/Icons/VolumesPackage/package.order b/SorpLib/Icons/VolumesPackage/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Icons/package.mo b/SorpLib/Icons/package.mo
new file mode 100644
index 0000000..c8bfe40
--- /dev/null
+++ b/SorpLib/Icons/package.mo
@@ -0,0 +1,19 @@
+within SorpLib;
+package Icons "Library of icons"
+  extends Modelica.Icons.IconsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains definitions of graphical icons used within the Modelica 
+library SorpLib. The icons should be used via inheritance, using the keyword 
+\"extends\" in the desired classes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Icons;
diff --git a/SorpLib/Icons/package.order b/SorpLib/Icons/package.order
new file mode 100644
index 0000000..e481d69
--- /dev/null
+++ b/SorpLib/Icons/package.order
@@ -0,0 +1,16 @@
+AdsorbersPackage
+AdsorberColumnsPackage
+CondensersEvaporatorsPackage
+ControllerPackage
+FansPackage
+FittingsPackage
+HeatExchangersPackage
+HeatTransfersPackage
+MassTransfersPackage
+MediaPackage
+PumpsPackage
+RecoolersPackage
+TubesPackage
+SorpLibPackage
+ValvesPackage
+VolumesPackage
diff --git a/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/Schmidt.mo b/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/Schmidt.mo
deleted file mode 100644
index 9acbc65..0000000
--- a/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/Schmidt.mo
+++ /dev/null
@@ -1,53 +0,0 @@
-within SorpLib.Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube;
-model Schmidt "Schmidt-Korrelation"
-  extends
-    TIL.LiquidComponents.Tubes.TransportPhenomena.HeatTransfer.PartialHeatTransfer(
-      final computeTransportProperties=true, final useAlphaAState=true);
-
-  Real Re "Reynolds-Number";
-  Real Nu "Nusselt-Number";
-
-  Modelica.SIunits.CoefficientOfHeatTransfer alpha "Heat transfer coefficient";
-
-  Real zeta "Resistance coefficient";
-
-  parameter Modelica.SIunits.Diameter coilDiameter=0.05 "Diameter of tube coil";
-
-equation
-
-  Re = noEvent(abs(mdotHydraulic))/cellGeometry.hydraulicCrossSectionalArea*tubeGeometry.hydraulicDiameter/properties.transp.eta;
-  zeta = 0.3164/Re^0.25+0.03*(tubeGeometry.hydraulicDiameter/coilDiameter)^0.5;
-
-  Nu = (zeta/8*Re*properties.transp.Pr)/(1 + 12.7*sqrt(zeta/8)*(properties.transp.Pr^(2/3) - 1));
-  alpha = Nu*properties.transp.lambda/tubeGeometry.hydraulicDiameter;
-
-  alphaA = alpha*cellGeometry.heatTransferArea;
-  annotation (Documentation(info="<html>
-<p>
-  This transfer model calculates heat transfer coefficients according to the Schmidt-Correlation (1967) for tube coils. 
-  The original form of the equation is slightly simplified by neglecting the viscosity factor.
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i>Q</i><sub>in</sub> = <i><code>&alpha;</code> A</i> (<i>T</i><sub>in</sub> - <i>T</i><sub>out</sub>) </p>
-  <p>where <i><code>&alpha;</code></i> is the heat tranfer coefficient and <i>A</i> is the heat transfer area. <i><code>&alpha;</code></i> is derived from a correlation between between the dimensionless quantities Nusselt number <i>Nu</i>, Reynolds number <i>Re</i> and Prandtl number <i>Pr</i>: </p>
-  <p align=\"center\"> <i>Nu</i> = (<i><code>&zeta;</code></i>/8 <i>Re</i> <i>Pr</i>) / (1 + 12.7 <code>&radic;</code>(<i><code>&zeta;</code></i>/8) (<i>Pr</i><sup>2/3</sup> - 1)) </p>
-  with
-  <p align=\"center\"> <i><code>&zeta;</code></i> = 0.3164/<i>Re</i><sup>0.25</sup> + 0.03 (<i>d</i><sub>i</sub>/<i>D</i><sub>coil</sub>)<sup>0.5</sup> </p>
-  <p>where <i>d</i><sub>i</sub> is the hydraulic diameter and <i>D</i><sub>coil</sub> is the diameter of the tube coil. </p>
-</p>
-<h4>References</h4>
-<ul>
-  <li>Schmidt E. F. Wärmeübergang und Druckverlust in Rohrschlangen. Chemie Ingenieur Technik, 1967.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 06, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end Schmidt;
diff --git a/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/SiederTate.mo b/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/SiederTate.mo
deleted file mode 100644
index 56d0ee9..0000000
--- a/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/SiederTate.mo
+++ /dev/null
@@ -1,47 +0,0 @@
-within SorpLib.Internals.AdditionalTransferPhenomena.HeatTransfer_insideTube;
-model SiederTate "SiederTate-Korrelation"
-  extends
-    TIL.LiquidComponents.Tubes.TransportPhenomena.HeatTransfer.PartialHeatTransfer(
-      final computeTransportProperties=true, final useAlphaAState=true);
-
-  Real Re "Reynolds-Number";
-  Real Nu "Nusselt-Number";
-
-  Modelica.SIunits.CoefficientOfHeatTransfer alpha "Heat tranfer coefficient";
-
-  parameter Real SiederTateConstant=0.027 "Sider-Tate-Constant";
-
-equation
-  Re = noEvent(abs(mdotHydraulic))/cellGeometry.hydraulicCrossSectionalArea*tubeGeometry.hydraulicDiameter/properties.transp.eta;
-
-  Nu = SiederTateConstant*Re^0.8*properties.transp.Pr^(1/3);
-  alpha = Nu*properties.transp.lambda/tubeGeometry.hydraulicDiameter;
-
-  alphaA = alpha*cellGeometry.heatTransferArea;
-  annotation (Documentation(info="<html>
-<p>
-  This transfer model calculates heat transfer coefficients according to the Sieder-Tate-Correlation (1936) for turbulend liquid flows in tubes.
-  The original form of the equation is slightly simplified by neglecting the viscosity factor.
-</p>
-<h4>Main equations</h4>
-<p>
-  <p align=\"center\"> <i>Q</i><sub>in</sub> = <i><code>&alpha;</code> A</i> (<i>T</i><sub>in</sub> - <i>T</i><sub>out</sub>) </p>
-  <p>where <i><code>&alpha;</code></i> is the heat tranfer coefficient and <i>A</i> is the heat transfer area. <i><code>&alpha;</code></i> is derived from a correlation between between the dimensionless quantities Nusselt number <i>Nu</i>, Reynolds number <i>Re</i> and Prandtl number <i>Pr</i>: </p>
-  <p align=\"center\"> <i>Nu</i> = <i>C</i><sub>ST</sub> <i>Re</i><sup>0.8</sup> <i>Pr</i><sup>1/3</sup> </p>
-  <p>where <i>C</i><sub>ST</sub> is the Sieder-Tate-Constant. </p>
-</p>
-<h4>References</h4>
-<ul>
-  <li>Sieder E. N. and Tate G. E. Heat Transfer and Pressure Drop of Liquids in Tubes. Industrial and Engineering Chemistry, 1936.</li>
-</ul>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      December 06, 2017, by Andrej Gibelhaus:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end SiederTate;
diff --git a/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/package.mo b/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/package.mo
deleted file mode 100644
index edd9923..0000000
--- a/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/package.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Internals.AdditionalTransferPhenomena;
-package HeatTransfer_insideTube
-  extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-annotation (Documentation(info="<html>
-<p>
-  This package contains additional heat transfer phenomena, which can be used in the tube model of the TIL library.
-</p>
-</html>"));
-end HeatTransfer_insideTube;
diff --git a/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/package.order b/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/package.order
deleted file mode 100644
index 27969dd..0000000
--- a/SorpLib/Internals/AdditionalTransferPhenomena/HeatTransfer_insideTube/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-SiederTate
-Schmidt
diff --git a/SorpLib/Internals/AdditionalTransferPhenomena/package.mo b/SorpLib/Internals/AdditionalTransferPhenomena/package.mo
deleted file mode 100644
index 8565cdc..0000000
--- a/SorpLib/Internals/AdditionalTransferPhenomena/package.mo
+++ /dev/null
@@ -1,5 +0,0 @@
-within SorpLib.Internals;
-package AdditionalTransferPhenomena
-  extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-end AdditionalTransferPhenomena;
diff --git a/SorpLib/Internals/AdditionalTransferPhenomena/package.order b/SorpLib/Internals/AdditionalTransferPhenomena/package.order
deleted file mode 100644
index 14d0e73..0000000
--- a/SorpLib/Internals/AdditionalTransferPhenomena/package.order
+++ /dev/null
@@ -1 +0,0 @@
-HeatTransfer_insideTube
diff --git a/SorpLib/Internals/ClassTypes/ApplicationPackage.mo b/SorpLib/Internals/ClassTypes/ApplicationPackage.mo
deleted file mode 100644
index 51e2a2a..0000000
--- a/SorpLib/Internals/ClassTypes/ApplicationPackage.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Internals.ClassTypes;
-partial class ApplicationPackage
-
-  annotation (Icon(graphics={Ellipse(
-          extent={{-100,100},{100,-100}},
-          pattern=LinePattern.None,
-          fillColor={213,0,0},
-          fillPattern=FillPattern.Solid,
-          lineColor={0,0,0})}));
-
-end ApplicationPackage;
diff --git a/SorpLib/Internals/ClassTypes/ComponentPackage.mo b/SorpLib/Internals/ClassTypes/ComponentPackage.mo
deleted file mode 100644
index 1481b14..0000000
--- a/SorpLib/Internals/ClassTypes/ComponentPackage.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Internals.ClassTypes;
-partial class ComponentPackage
-
-  annotation (Icon(graphics={Ellipse(
-          extent={{-100,100},{100,-100}},
-          fillColor={170,213,255},
-          fillPattern=FillPattern.Solid,
-          pattern=LinePattern.None,
-          lineColor={0,0,0})}), classOrder={"*","Internals","Testers"});
-
-end ComponentPackage;
diff --git a/SorpLib/Internals/ClassTypes/InternalPackage.mo b/SorpLib/Internals/ClassTypes/InternalPackage.mo
deleted file mode 100644
index 919c334..0000000
--- a/SorpLib/Internals/ClassTypes/InternalPackage.mo
+++ /dev/null
@@ -1,10 +0,0 @@
-within SorpLib.Internals.ClassTypes;
-partial class InternalPackage
-
-  annotation (Icon(graphics={Ellipse(
-          extent={{-100,100},{100,-100}},
-          pattern=LinePattern.None,
-          fillColor={215,215,215},
-          fillPattern=FillPattern.Solid,
-          lineColor={0,0,0})}));
-end InternalPackage;
diff --git a/SorpLib/Internals/ClassTypes/ModelPackage.mo b/SorpLib/Internals/ClassTypes/ModelPackage.mo
deleted file mode 100644
index 8d265c0..0000000
--- a/SorpLib/Internals/ClassTypes/ModelPackage.mo
+++ /dev/null
@@ -1,10 +0,0 @@
-within SorpLib.Internals.ClassTypes;
-partial class ModelPackage
-
-  annotation (Icon(graphics={Ellipse(
-          extent={{-100,100},{100,-100}},
-          pattern=LinePattern.None,
-          fillColor={240,221,5},
-          fillPattern=FillPattern.Solid,
-          lineColor={0,0,0})}));
-end ModelPackage;
diff --git a/SorpLib/Internals/ClassTypes/PartialPackage.mo b/SorpLib/Internals/ClassTypes/PartialPackage.mo
deleted file mode 100644
index 6d4411b..0000000
--- a/SorpLib/Internals/ClassTypes/PartialPackage.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Internals.ClassTypes;
-partial class PartialPackage
-
-  annotation (Icon(graphics={Ellipse(
-          extent={{-100,100},{100,-100}},
-          pattern=LinePattern.None,
-          fillColor={34,139,34},
-          fillPattern=FillPattern.Solid,
-          lineColor={0,0,0})}));
-
-end PartialPackage;
diff --git a/SorpLib/Internals/ClassTypes/Record.mo b/SorpLib/Internals/ClassTypes/Record.mo
deleted file mode 100644
index 4d5188e..0000000
--- a/SorpLib/Internals/ClassTypes/Record.mo
+++ /dev/null
@@ -1,13 +0,0 @@
-within SorpLib.Internals.ClassTypes;
-partial record Record "Partial Record"
-
-  annotation (Icon(graphics={Text(
-          extent={{-100,110},{100,70}},
-          lineColor={0,0,0},
-          textString="%name"),Bitmap(
-          extent={{-100,60},{100,-100}},
-          imageSource=
-            "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAIAAAAiOjnJAAAABnRSTlMA/wAAAACkwsAdAAAACXBIWXMAAAsTAAALEwEAmpwYAAACp0lEQVR42u3cMU4CQRSA4V2lVDsDYTmMpbUJcACtSTgJ6i2AS1ChHoAbQELCFSgsKCxNXJ7uW7+/32Qz8+VNsztlv1sVanyj8Wj2Okv0wpfXVze2rfltNpvt49P9x3uWFy5PE2u3367Xb/avmQ0fhunm1hcs+9fYqt4g3Zl4YdtytZgvppMpWDrfgTgeJrIFVpqeX2aJbIHFFljKYwsstsBSHltgsQWW8tgCiy2wlMcWWGyBpTy2wGILLOWxBRZbIXXqPLw6HG1kM20VRbGcL0+2isn0978NNLHMLbCUxxZYbIGlPLbAYgss5bEFFltgKY8tsNgCS3lsgcVWiC2w2AqxBRZbIbbAYivEFlhshdgCSyG2wFKILbAUYgsshdgCSyG2wFKILbAUYgsshdgCSyG2wFKILbAUYgsshdgCSyG2wFKILbAUYgsshdgCSyG2wFKILbAUYgsshdgCSyG2wFKIrY51yVLVG6R4z9M9zSaWQmyV/W5VFMVuv7UcOuNkNbEUElgCS2AJLAksgSWwJLAElsCSwBJYAksCS2AJLAksgaX/Vq2/dFaHoxVscXe3P+dhYslRKLAElgSWwBJYElgCS2BJYAksgSWBJbAElgSWwBJYElgCS2BJYAksgSWBJbAElgSWwBJYElgCS2BJYAksgSWBJbDU4mrd817nHnCZWBJYAktgSWAJLIElgSWwBJYElsASWBJYAktgSWAJLIElfVOtj9ZXh6MVbHF1/mkwseQoFFgCSwJLYAksCSyBJbAksASWwJLAElgCSwJLYAksCSyBJbAksASWwJLAElgCSwJLYAksCSyBJbAksASWwJLAElhqcbXuea9zD7hMLAksgSWwJLAElsCSwBJYAksCS2AJLAksgSWwJLD0R5X9bmUVZGIpR5/i9W1YEPGgigAAAABJRU5ErkJggg==",
-          fileName="modelica://TIL/Images/Record.png")}));
-
-end Record;
diff --git a/SorpLib/Internals/ClassTypes/RecordPackage.mo b/SorpLib/Internals/ClassTypes/RecordPackage.mo
deleted file mode 100644
index ddc5a36..0000000
--- a/SorpLib/Internals/ClassTypes/RecordPackage.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Internals.ClassTypes;
-partial class RecordPackage
-
-  annotation (Icon(graphics={Ellipse(
-          extent={{-100,100},{100,-100}},
-          fillColor={255,165,0},
-          fillPattern=FillPattern.Solid,
-          pattern=LinePattern.None,
-          lineColor={0,0,0})}), classOrder={"*","Internals","Testers"});
-
-end RecordPackage;
diff --git a/SorpLib/Internals/ClassTypes/package.mo b/SorpLib/Internals/ClassTypes/package.mo
deleted file mode 100644
index 81511be..0000000
--- a/SorpLib/Internals/ClassTypes/package.mo
+++ /dev/null
@@ -1,19 +0,0 @@
-within SorpLib.Internals;
-package ClassTypes "Icon definitions"
-
-
-
-
-
-
-
-
-
-
-annotation (Icon(graphics={Ellipse(
-        extent={{-100,100},{100,-100}},
-        pattern=LinePattern.None,
-        fillColor={215,215,215},
-        fillPattern=FillPattern.Solid,
-        lineColor={0,0,0})}));
-end ClassTypes;
diff --git a/SorpLib/Internals/ClassTypes/package.order b/SorpLib/Internals/ClassTypes/package.order
deleted file mode 100644
index 515302a..0000000
--- a/SorpLib/Internals/ClassTypes/package.order
+++ /dev/null
@@ -1,7 +0,0 @@
-ModelPackage
-ComponentPackage
-ApplicationPackage
-InternalPackage
-PartialPackage
-RecordPackage
-Record
diff --git a/SorpLib/Internals/SmoothTransition/SmoothSwitch.mo b/SorpLib/Internals/SmoothTransition/SmoothSwitch.mo
deleted file mode 100644
index 612a21d..0000000
--- a/SorpLib/Internals/SmoothTransition/SmoothSwitch.mo
+++ /dev/null
@@ -1,53 +0,0 @@
-within SorpLib.Internals.SmoothTransition;
-model SmoothSwitch
-
-  Modelica.Blocks.Interfaces.BooleanInput u(start=false, fixed=true)
-    annotation (Placement(transformation(extent={{-115,-15},{-85,15}})));
-  Modelica.Blocks.Interfaces.RealOutput y
-    annotation (Placement(transformation(extent={{87,-13},{113,13}})));
-
-  discrete Modelica.SIunits.Time start_time;
-  parameter Modelica.SIunits.Time interval=5
-    "duration of smooth transition period";
-
-protected
-  Boolean z(start=true, fixed=true);
-  Modelica.SIunits.Time time_act;
-  Modelica.SIunits.Time interval_act;
-
-initial equation
-  start_time = if u then 1000000 else -1000000;
-equation
-
-  time_act = if u then -time else time;
-  interval_act = if u then -interval/2 else interval/2;
-
-  z = not u;
-
-  when edge(u) or edge(z) then
-    start_time = -(pre(time_act) + pre(interval_act));
-  end when;
-
-  y = TIL.Utilities.Numerics.smoothTransition(
-    time_act,
-    start_time,
-    interval);
-
-  annotation (Diagram(graphics), Icon(graphics={Rectangle(
-          extent={{-100,-100},{100,100}},
-          lineColor={0,0,127},
-          fillColor={255,255,255},
-          fillPattern=FillPattern.Solid),Line(points={{-80,68},{-80,-80}},
-          color={192,192,192}),Polygon(
-          points={{-80,90},{-88,68},{-72,68},{-80,90}},
-          lineColor={192,192,192},
-          fillColor={192,192,192},
-          fillPattern=FillPattern.Solid),Line(points={{-90,-70},{82,-70}},
-          color={192,192,192}),Polygon(
-          points={{90,-70},{68,-62},{68,-78},{90,-70}},
-          lineColor={192,192,192},
-          fillColor={192,192,192},
-          fillPattern=FillPattern.Solid),Line(points={{-80,-70},{-50,-70},{-40,
-          -69.8838},{-30,-66.8763},{-20,-52.2781},{-10,-20.3259},{0,20.3259},{
-          10,52.2781},{20,66.8763},{30,69.8838},{40,70},{70,70}}, color={0,0,0})}));
-end SmoothSwitch;
diff --git a/SorpLib/Internals/SmoothTransition/Testers/package.mo b/SorpLib/Internals/SmoothTransition/Testers/package.mo
deleted file mode 100644
index 8ddab8e..0000000
--- a/SorpLib/Internals/SmoothTransition/Testers/package.mo
+++ /dev/null
@@ -1,21 +0,0 @@
-within SorpLib.Internals.SmoothTransition;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-  model SmoothTransitionTester
-
-    SmoothSwitch smoothSwitch
-      annotation (Placement(transformation(extent={{-2,2},{18,22}})));
-    Modelica.Blocks.Sources.BooleanPulse booleanPulse(period=50, startTime=50)
-      annotation (Placement(transformation(extent={{-40,2},{-20,22}})));
-  equation
-    connect(booleanPulse.y, smoothSwitch.u) annotation (Line(
-        points={{-19,12},{-2,12}},
-        color={255,0,255},
-        smooth=Smooth.None));
-    annotation (
-      Diagram(graphics),
-      experiment(StopTime=200, Interval=0.1),
-      __Dymola_experimentSetupOutput);
-  end SmoothTransitionTester;
-end Testers;
diff --git a/SorpLib/Internals/SmoothTransition/Testers/package.order b/SorpLib/Internals/SmoothTransition/Testers/package.order
deleted file mode 100644
index 9913f81..0000000
--- a/SorpLib/Internals/SmoothTransition/Testers/package.order
+++ /dev/null
@@ -1 +0,0 @@
-SmoothTransitionTester
diff --git a/SorpLib/Internals/SmoothTransition/package.mo b/SorpLib/Internals/SmoothTransition/package.mo
deleted file mode 100644
index 55c35bb..0000000
--- a/SorpLib/Internals/SmoothTransition/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Internals;
-package SmoothTransition
-extends SorpLib.Internals.ClassTypes.ComponentPackage;
-
-
-end SmoothTransition;
diff --git a/SorpLib/Internals/SmoothTransition/package.order b/SorpLib/Internals/SmoothTransition/package.order
deleted file mode 100644
index 378e45a..0000000
--- a/SorpLib/Internals/SmoothTransition/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-SmoothSwitch
-Testers
diff --git a/SorpLib/Internals/package.mo b/SorpLib/Internals/package.mo
deleted file mode 100644
index c0fd3f0..0000000
--- a/SorpLib/Internals/package.mo
+++ /dev/null
@@ -1,12 +0,0 @@
-within SorpLib;
-package Internals "Internal functions"
-
-
-
-annotation (Icon(graphics={Ellipse(
-        extent={{-100,100},{100,-100}},
-        pattern=LinePattern.None,
-        fillColor={215,215,215},
-        fillPattern=FillPattern.Solid,
-        lineColor={0,0,0})}));
-end Internals;
diff --git a/SorpLib/Internals/package.order b/SorpLib/Internals/package.order
deleted file mode 100644
index 442300f..0000000
--- a/SorpLib/Internals/package.order
+++ /dev/null
@@ -1,4 +0,0 @@
-ClassTypes
-SmoothTransition
-AdditionalTransferPhenomena
-systime
diff --git a/SorpLib/Internals/systime.mo b/SorpLib/Internals/systime.mo
deleted file mode 100644
index d191e76..0000000
--- a/SorpLib/Internals/systime.mo
+++ /dev/null
@@ -1,9 +0,0 @@
-within SorpLib.Internals;
-function systime "Returns current timestamp (of computer, not the simulation) "
-  output Real systime;
-
-external"C";
-  annotation (Include="#include <systime.c>");
-  // Don't forget to move systime.c to current working folder
-
-end systime;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/AQSOAZ02WaterGoldsworthy.mo b/SorpLib/Media/AdsorbentAdsorbate/AQSOAZ02WaterGoldsworthy.mo
deleted file mode 100644
index 6ea6411..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/AQSOAZ02WaterGoldsworthy.mo
+++ /dev/null
@@ -1,45 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate;
-model AQSOAZ02WaterGoldsworthy "AQSOA Z02 / Water, published by Goldsworthy (2014)"
-  extends SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin(
-      c_Sorbent=1000);
-
-  final parameter Real[4] c={3.466e-4,3.094e5,-9.765e4,
-    7.312e-7} "Coefficients for characteristic curve";
-
-equation
-  W = SorpLib.Media.Functions.CharCurve1Arctan(A,c);
-  h_bond = -A + T*water.VLEAdditional.beta_l*W/
-    SorpLib.Media.Functions.CharCurve1Arctan_dWdA(A,c);
-
-  assert(A>100e3, "The characteristic curve is not valid in this range of adsorption potential A");
-  assert(A<1500e3, "The characteristic curve is not valid in this range of adsorption potential A");
-
-  annotation (Documentation(info="<html>
-<p>
-  This model provides the equilibrium data for the working pair AQSOA Z02 / Water as measured by Goldsworthy (2014). <br>
-  The implementation is based on the Dubinin model, see <a href=\"modelica://SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin\">SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin</a>.<br>
-  The fit parameters were generated at the Chair of Technical Thermodynamics based on the reported measurement data by Goldsworthy (2014).
-</p>
-<h4>Main equations</h4>
-<p>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan\">SorpLib.Media.Functions.CharCurve1Arctan</a><br>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan_dWdA\">SorpLib.Media.Functions.CharCurve1Arctan_dWdA</a>
-</p>
-<h4>References</h4>
-<p>
-  <ul>
-    <li>Dubinin, M.M. Adsorption in micropores. J. Colloid Interface Sci., 1967, 23(4), 487-499.</li>
-    <li>Goldsworthy, M.J. Measurements of water vapour sorption isotherms for RD silica gel, AQSOA-Z01, AQSOA-Z02, AQSOA-Z05 and CECA zeolite 3A. Microporous and Mesoporous Materials, 2014, 196, 59-67.. </li>
-  </ul>
-</p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 17, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end AQSOAZ02WaterGoldsworthy;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Partial/PartialAdsorbentWater.mo b/SorpLib/Media/AdsorbentAdsorbate/Partial/PartialAdsorbentWater.mo
deleted file mode 100644
index 7b548bb..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Partial/PartialAdsorbentWater.mo
+++ /dev/null
@@ -1,57 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate.Partial;
-partial model PartialAdsorbentWater "Base model for Adsorbent / Water System"
-
-  Modelica.SIunits.Pressure p(start=5000) "Partial Water pressure";
-  input Real x(unit="kg/kg") "Water mass fraction";
-  input Modelica.SIunits.Temperature T "Temperature";
-
-  Modelica.SIunits.SpecificEnthalpy h_ads "Enthalpy of water in adsorbed phase";
-  Modelica.SIunits.SpecificInternalEnergy u_ads
-    "Internal energy of water in adsorbed phase";
-  Real dudT_x(unit="J/(kg.K)") "Partial derivative of u wrt T at constant x";
-
-  /********************** Parameters *********************************/
-
-  final Modelica.SIunits.SpecificHeatCapacity R_Water=Modelica.Constants.R/water.M
-    "Specific gas constant of water [J/kg K]";
-
-  parameter Modelica.SIunits.SpecificHeatCapacity c_Sorbent=1000
-    "Constant Heat Capacity of Sorbent [J/kg K]";
-
-  final parameter TILMedia.VLEFluidTypes.TILMedia_Water vleFluidType;
-
-  /********************** Object water *********************************/
-
-  TILMedia.VLEFluid_dT water(
-    final vleFluidType=vleFluidType,
-    T=T,
-    d=water.VLE.d_l,
-    computeVLEAdditionalProperties=true)
-    annotation (Placement(transformation(extent={{-10,-12},{10,8}})));
-
-equation
-  u_ads=h_ads-p/water.d;
-  dudT_x = c_Sorbent + x*water.VLEAdditional.cp_l;
-
-  annotation (Icon(graphics={Bitmap(extent={{-190,-168},{192,124}}, fileName=
-              "modelica://SorpLib/Resources/Images/AdsorbensAdsorbate.png")}),
-      Documentation(info="<html>
-<p>This partial model contains all necessary variables and the basic equations to describe equilibrium data </p>
-<p>The partial model needs to be extended by the specific functions for each working pair </p>
-<h4>Main equations</h4>
-<p align=\"center\"><i>u<sub>ads</sub> = h<sub>ads</sub> - p<sub>ad</sub> / <code>&rho;</code><sub>ad</sub> </i></p>
-<p>where <i>u</i><sub>ads</sub> is the specific internal energy of the adsorbate, <i>h</i><sub>ads</sub> is the specific enthalpy of the adsorbate of the adsorbate, <i>p</i><sub>ad</sub> is the
-pressure and <i><code>&rho;</code></i><sub>ad</sub> is the density of the adsorbate</p>
-<p align=\"center\"><i>dudT_x = c<sub>sor</sub> + x * c<sub>ad</sub> , </i></p>
-<p>where <i>dudT_x</i> is the specific heat capacity of adsorbent and adsorbate, <i>c</i><sub>sor</sub> is the specific heat capacity of the adsorbent, <i>x</i> is the loading and 
-<i>c</i><sub>ad</sub> is the specific heat capacity of the adsorbate (approximated by the specific heat capacity of liquid water).</p>
-<h4>References</h4>
-<ul>
-<li>N&uacute;&ntilde;ez, T. Charakterisierung und Bewertung von Adsorbentien f&uuml;r W&auml;rmetransformationsanwendungen. PhD Thesis. Freiburg, 2001. </li>
-</ul>
-<h4>Author Information</h4>
-<ul>
-<li>November 17, 2017, by Uwe Bau:<br>Tidy up implementation and enhance documentation for publication of library.<br></li>
-</ul>
-</html>"));
-end PartialAdsorbentWater;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Partial/PartialAdsorbentWaterDubinin.mo b/SorpLib/Media/AdsorbentAdsorbate/Partial/PartialAdsorbentWaterDubinin.mo
deleted file mode 100644
index e981cec..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Partial/PartialAdsorbentWaterDubinin.mo
+++ /dev/null
@@ -1,34 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate.Partial;
-partial model PartialAdsorbentWaterDubinin
-  "Base model for Adsorbent / Water System based on the model of Dubinin"
-  extends SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWater;
-
-  Modelica.SIunits.SpecificVolume W(start=5e-5) "Specific volume of adsorbate";
-  Modelica.SIunits.SpecificEnergy A(start=1e5) "Adsorption Potential";
-  Modelica.SIunits.SpecificEnthalpy h_bond "Bonding enthalpy";
-
-equation
-  W = x/water.VLE.d_l;
-  p = water.p*exp(-A/R_Water/T);
-  h_ads = water.VLE.h_l + h_bond;
-  annotation (Documentation(info="<html>
-<p>This partial model provides the basic equations to describe equilibrium data for the working pair according to the Dubinin (1967) model.</p><p>The partial model needs to be extended by the specific functions based on the characteristic curve: W = f(A) and h<sub>bond</sub>. </p>
-<h4>Main equations</h4>
-<p align=\"center\"><i>W = x / <code>&rho;</code><sub>ad</sub>(T) , </i></p>
-<p>where <i>W</i> is the specific volume of the adsorbate, <i>x</i> is the loading, <code><i>&rho;</i></code><sub>ad</sub> is the density of the adsorbate, and <i>T</i> is the temperature. </p>
-<p align=\"center\"><i>p = p<sub>s</sub>(T) exp(-A / (R T)) , </i></p>
-<p>where <i>A</i> is the adsorption potential, <i>p</i><sub>s</sub>(<i>T</i>) is the saturation pressure at temperature <i>T</i>, and <i>R</i> is the specific gas constant of water.</p>
-<p><br><i>h</i><sub>ads</sub> describes the specific enthalpy of the adsorbate given the specific enthalpy of water as reference state. </p>
-<p align=\"center\"><i>h<sub>ads</sub> = h<sub>l</sub> + h<sub>bond</sub> , </i></p>
-<p>where <i>h</i><sub>l</sub> is specific enthalpy of liquid water and <i>h</i><sub>bond</sub> is the specific bonding enthalpy. </p>
-<h4>References</h4>
-<ul>
-<li>Dubinin, M.M. Adsorption in micropores. J. Colloid Interface Sci., 1967, 23(4), 487-499. </li>
-<li>N&uacute;&ntilde;ez, T. Charakterisierung und Bewertung von Adsorbentien f&uuml;r W&auml;rmetransformationsanwendungen. PhD Thesis. Freiburg, 2001. </li>
-</ul>
-<h4>Author Information</h4>
-<ul>
-<li>November 17, 2017, by Uwe Bau:<br>Tidy up implementation and enhance documentation for publication of library.<br></li>
-</ul>
-</html>"));
-end PartialAdsorbentWaterDubinin;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Partial/package.mo b/SorpLib/Media/AdsorbentAdsorbate/Partial/package.mo
deleted file mode 100644
index 847d512..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Partial/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate;
-package Partial
-  extends SorpLib.Internals.ClassTypes.PartialPackage;
-
-
-end Partial;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Partial/package.order b/SorpLib/Media/AdsorbentAdsorbate/Partial/package.order
deleted file mode 100644
index ed8adc1..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Partial/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-PartialAdsorbentWater
-PartialAdsorbentWaterDubinin
diff --git a/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace123WaterSchawe.mo b/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace123WaterSchawe.mo
deleted file mode 100644
index defd18e..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace123WaterSchawe.mo
+++ /dev/null
@@ -1,44 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate;
-model SilgelGrace123WaterSchawe
-  "Silicagel Grace 123 / Water, published by Schawe (1999)"
-  extends SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin(
-      c_Sorbent=1000);
-
-  final parameter Real[4] c={5.072313e-4,1.305531e5,-8.492403e4,4.128962e-6} "Coefficients for characteristic curve";
-
-equation
-  W = SorpLib.Media.Functions.CharCurve1Arctan(A,c);
-  h_bond = -A + T*water.VLEAdditional.beta_l*W/
-    SorpLib.Media.Functions.CharCurve1Arctan_dWdA(A,c);
-
-  assert(A>17e3, "The characteristic curve is not valid in this range of adsorption potential A");
-  assert(A<1940e3, "The characteristic curve is not valid in this range of adsorption potential A");
-
-  annotation (Documentation(info="<html>
-<p>
-  This model provides the equilibrium data for the working pair Silica gel Grace 123 / Water as measured by Schawe (1999).<br>
-  The implementation is based on the Dubinin model, see <a href=\"modelica://SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin\">SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin</a>.
-</p>
-<h4>Main equations</h4>
-<p>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan\">SorpLib.Media.Functions.CharCurve1Arctan</a><br>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan_dWdA\">SorpLib.Media.Functions.CharCurve1Arctan_dWdA</a>
-</p>
-<h4>References</h4>
-<p>
-  <ul>
-    <li>Dubinin, M.M. Adsorption in micropores. J. Colloid Interface Sci., 1967, 23(4), 487-499.</li>
-    <li>Schawe, D. Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers. PhD Thesis. Stuttgart, 1999. </li>
-  </ul>
-</p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 17, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end SilgelGrace123WaterSchawe;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace125WaterNunez.mo b/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace125WaterNunez.mo
deleted file mode 100644
index 6832389..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace125WaterNunez.mo
+++ /dev/null
@@ -1,47 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate;
-model SilgelGrace125WaterNunez
-  "Silicagel Grace 125 / Water, published by Nunez (2001)"
-  extends SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin(
-      c_Sorbent=1000);
-
-  final parameter Real[3] cNom={5.66e-14,0,0.3545}
-    "Coefficients for nominator of characteristic curve";
-  final parameter Real[3] cDenom={4.13143e-8,0,1000}
-    "Coefficients for denominator of characteristic curve";
-
-equation
-  W = SorpLib.Media.Functions.CharCurve2Polynomial(A,cNom,cDenom);
-  h_bond = -A + T*water.VLEAdditional.beta_l*W/
-    SorpLib.Media.Functions.CharCurve2Polynomial_dWdA(A,cNom,cDenom);
-
-  assert(A>17e3, "The characteristic curve is not valid in this range of adsorption potential A");
-  assert(A<1940e3, "The characteristic curve is not valid in this range of adsorption potential A");
-
-  annotation (Documentation(info="<html>
-<p>
-  This model provides the equilibrium data for the working pair Silica gel Grace 125 / Water as measured by N&uacute;&ntilde;ez (2001). <br>
-  The implementation is based on the Dubinin model, see <a href=\"modelica://SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin\">SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin</a>.
-</p>
-<h4>Main equations</h4>
-<p>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan\">SorpLib.Media.Functions.CharCurve1Arctan</a><br>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan_dWdA\">SorpLib.Media.Functions.CharCurve1Arctan_dWdA</a>
-</p>
-<h4>References</h4>
-<p>
-  <ul>
-    <li>Dubinin, M.M. Adsorption in micropores. J. Colloid Interface Sci., 1967, 23(4), 487-499.</li>
-    <li>N&uacute;&ntilde;ez, T. Charakterisierung und Bewertung von Adsorbentien f&uuml;r W&auml;rmetransformationsanwendungen. PhD Thesis. Freiburg, 2001. </li>
-  </ul>
-</p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 17, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end SilgelGrace125WaterNunez;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace125WaterSchawe.mo b/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace125WaterSchawe.mo
deleted file mode 100644
index 0f4dcb8..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/SilgelGrace125WaterSchawe.mo
+++ /dev/null
@@ -1,45 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate;
-model SilgelGrace125WaterSchawe
-  "Silicagel Grace 125 / Water, published by Schawe (1999)"
-  extends SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin(
-      c_Sorbent=1000);
-
-  final parameter Real[4] c={4.527805e-4,1.229005e5,-8.847167e4,
-      6.034706e-7} "Coefficients for characteristic curve";
-
-equation
-  W = SorpLib.Media.Functions.CharCurve1Arctan(A,c);
-  h_bond = -A + T*water.VLEAdditional.beta_l*W/
-    SorpLib.Media.Functions.CharCurve1Arctan_dWdA(A,c);
-
-  assert(A>20e3, "The characteristic curve is not valid in this range of adsorption potential A");
-  assert(A<1570e3, "The characteristic curve is not valid in this range of adsorption potential A");
-
-  annotation (Documentation(info="<html>
-<p>
-  This model provides the equilibrium data for the working pair Silica gel Grace 125 / Water as measured by Schawe (1999).<br>
-  The implementation is based on the Dubinin model, see <a href=\"modelica://SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin\">SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin</a>.
-</p>
-<h4>Main equations</h4>
-<p>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan\">SorpLib.Media.Functions.CharCurve1Arctan</a><br>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve1Arctan_dWdA\">SorpLib.Media.Functions.CharCurve1Arctan_dWdA</a>
-</p>
-<h4>References</h4>
-<p>
-  <ul>
-    <li>Dubinin, M.M. Adsorption in micropores. J. Colloid Interface Sci., 1967, 23(4), 487-499.</li>
-    <li>Schawe, D. Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers. PhD Thesis. Stuttgart, 1999. </li>
-  </ul>
-</p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 17, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end SilgelGrace125WaterSchawe;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestAQSOAZ02WaterGoldsworthy.mo b/SorpLib/Media/AdsorbentAdsorbate/Testers/TestAQSOAZ02WaterGoldsworthy.mo
deleted file mode 100644
index 7d367e5..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestAQSOAZ02WaterGoldsworthy.mo
+++ /dev/null
@@ -1,15 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate.Testers;
-model TestAQSOAZ02WaterGoldsworthy
-
-  SorpLib.Media.AdsorbentAdsorbate.AQSOAZ02WaterGoldsworthy
-    aqsoaZ02(x=x, T=T)
-    annotation (Placement(transformation(extent={{-10,-8},{10,12}})));
-
-  Real x(start=0.06);
-  Modelica.SIunits.Temperature T(start=273.15 + 200);
-
-equation
-  x = 0.05 + 0.01*time;
-  T = (273.15 + 60);
-  annotation (experiment(StopTime=20), __Dymola_experimentSetupOutput);
-end TestAQSOAZ02WaterGoldsworthy;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace123WaterSchawe.mo b/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace123WaterSchawe.mo
deleted file mode 100644
index 5ce3980..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace123WaterSchawe.mo
+++ /dev/null
@@ -1,16 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate.Testers;
-model TestSilgelGrace123WaterSchawe
-
-  SorpLib.Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe
-    silgelGrace123Water_Schawe(x=x, T=T)
-    annotation (Placement(transformation(extent={{-10,-8},{10,12}})));
-
-  Real x;
-  Modelica.SIunits.Temperature T;
-
-equation
-   x = 0.05+time*0.0025;
-   T = 300;
-
-  annotation (experiment(StopTime=100));
-end TestSilgelGrace123WaterSchawe;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace125WaterNunez.mo b/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace125WaterNunez.mo
deleted file mode 100644
index ea8f37f..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace125WaterNunez.mo
+++ /dev/null
@@ -1,16 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate.Testers;
-model TestSilgelGrace125WaterNunez
-
-  SorpLib.Media.AdsorbentAdsorbate.SilgelGrace125WaterNunez
-    silgelGrace125WaterNunez(x=x, T=T)
-    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
-
-  Real x;
-  Modelica.SIunits.Temperature T;
-
-equation
-   x = 0.01+time*0.0025;
-   T = 300;
-
-  annotation (experiment(StopTime=100));
-end TestSilgelGrace125WaterNunez;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace125WaterSchawe.mo b/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace125WaterSchawe.mo
deleted file mode 100644
index 62f2cbe..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestSilgelGrace125WaterSchawe.mo
+++ /dev/null
@@ -1,16 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate.Testers;
-model TestSilgelGrace125WaterSchawe
-
-  SorpLib.Media.AdsorbentAdsorbate.SilgelGrace125WaterSchawe
-    silgelGrace125Water_Schawe(x=x, T=T)
-    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
-
-  Real x;
-  Modelica.SIunits.Temperature T;
-
-equation
-   x = 0.01+time*0.0025;
-   T = 300;
-
-  annotation (experiment(StopTime=100));
-end TestSilgelGrace125WaterSchawe;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestWorkingPairs_comp.mo b/SorpLib/Media/AdsorbentAdsorbate/Testers/TestWorkingPairs_comp.mo
deleted file mode 100644
index b8d3ae8..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestWorkingPairs_comp.mo
+++ /dev/null
@@ -1,32 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate.Testers;
-model TestWorkingPairs_comp "Test and compare multiple working pairs"
-
-  SorpLib.Media.AdsorbentAdsorbate.SilgelGrace123WaterSchawe
-    silgelGrace123Water_Schawe(x=x, T=T)
-    annotation (Placement(transformation(extent={{56,58},{76,78}})));
-
-  SorpLib.Media.AdsorbentAdsorbate.SilgelGrace125WaterSchawe
-    silgelGrace125Water_Schawe(x=x, T=T)
-    annotation (Placement(transformation(extent={{14,58},{34,78}})));
-
-  SorpLib.Media.AdsorbentAdsorbate.SilgelGrace125WaterNunez
-    silgelGrace125WaterNunez(x=x, T=T)
-    annotation (Placement(transformation(extent={{-30,58},{-10,78}})));
-
-  SorpLib.Media.AdsorbentAdsorbate.Zeolite13XWaterNunez
-    zeolite13X(x=x, T=T)
-    annotation (Placement(transformation(extent={{-74,58},{-54,78}})));
-
-  SorpLib.Media.AdsorbentAdsorbate.AQSOAZ02WaterGoldsworthy
-    aqsoaZ02(x=x, T=T)
-    annotation (Placement(transformation(extent={{-74,24},{-54,44}})));
-
-  Real x;
-  Modelica.SIunits.Temperature T;
-
-equation
-  x = 0.03 + time*0.0025;
-  T = 300;
-
-  annotation (experiment(StopTime=100));
-end TestWorkingPairs_comp;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestZeolite13XWaterNunez.mo b/SorpLib/Media/AdsorbentAdsorbate/Testers/TestZeolite13XWaterNunez.mo
deleted file mode 100644
index 7e83f09..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Testers/TestZeolite13XWaterNunez.mo
+++ /dev/null
@@ -1,14 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate.Testers;
-model TestZeolite13XWaterNunez
-
-  SorpLib.Media.AdsorbentAdsorbate.Zeolite13XWaterNunez
-    zeolite13X(x=x, T=T)
-    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
-
-  Real x(start=0.06);
-  Modelica.SIunits.Temperature T(start=273.15 + 200);
-
-equation
-  x = 0.05 + 0.01*time;
-  T = (273.15 + 257)-8.5*time;
-end TestZeolite13XWaterNunez;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Testers/package.mo b/SorpLib/Media/AdsorbentAdsorbate/Testers/package.mo
deleted file mode 100644
index f883279..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Testers/package.mo
+++ /dev/null
@@ -1,10 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-
-
-
-
-end Testers;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Testers/package.order b/SorpLib/Media/AdsorbentAdsorbate/Testers/package.order
deleted file mode 100644
index e9816c7..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Testers/package.order
+++ /dev/null
@@ -1,6 +0,0 @@
-TestSilgelGrace123WaterSchawe
-TestSilgelGrace125WaterSchawe
-TestSilgelGrace125WaterNunez
-TestZeolite13XWaterNunez
-TestAQSOAZ02WaterGoldsworthy
-TestWorkingPairs_comp
diff --git a/SorpLib/Media/AdsorbentAdsorbate/Zeolite13XWaterNunez.mo b/SorpLib/Media/AdsorbentAdsorbate/Zeolite13XWaterNunez.mo
deleted file mode 100644
index 3df7580..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/Zeolite13XWaterNunez.mo
+++ /dev/null
@@ -1,46 +0,0 @@
-within SorpLib.Media.AdsorbentAdsorbate;
-model Zeolite13XWaterNunez "Zeolite 13 X / Water, published by Nunez (2001)"
-  extends SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin(
-      c_Sorbent=1000);
-
-  final parameter Real[4] cNom={-9.39e-20,4.279e-13,-5.968e-7,0.2974}
-    "Coefficients for nominator of characteristic curve";
-  final parameter Real[4] cDenom={2.64e-16,5.361e-10,-1.4929e-3,1000}
-    "Coefficients for denominator of characteristic curve";
-
-equation
-  W = SorpLib.Media.Functions.CharCurve2Polynomial(A,cNom,cDenom);
-  h_bond = -A + T*water.VLEAdditional.beta_l*W/
-    SorpLib.Media.Functions.CharCurve2Polynomial_dWdA(A,cNom,cDenom);
-
-  assert(A>18e3, "The characteristic curve is not valid in this range of adsorption potential A");
-  assert(A<2000e3, "The characteristic curve is not valid in this range of adsorption potential A");
-
-  annotation (Documentation(info="<html>
-<p>
-  This model provides the equilibrium data for the working pair zeolite 13 X / Water as measured by N&uacute;&ntilde;ez (2001).<br>
-  The implementation is based on the Dubinin model, see <a href=\"modelica://SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin\">SorpLib.Media.AdsorbentAdsorbate.Partial.PartialAdsorbentWaterDubinin</a>.
-</p>
-<h4>Main equations</h4>
-<p>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve2Polynomial\">SorpLib.Media.Functions.CharCurve2Polynomial</a><br>
-  see <a href=\"modelica://SorpLib.Media.Functions.CharCurve2Polynomial_dWdA\">SorpLib.Media.Functions.CharCurve2Polynomial_dWdA</a>
-</p>
-<h4>References</h4>
-<p>
-  <ul>
-    <li>Dubinin, M.M. Adsorption in micropores. J. Colloid Interface Sci., 1967, 23(4), 487-499.</li>
-    <li>N&uacute;&ntilde;ez, T. Charakterisierung und Bewertung von Adsorbentien f&uuml;r W&auml;rmetransformationsanwendungen. PhD Thesis. Freiburg, 2001. </li>
-  </ul>
-</p>
-<h4>Author Information</h4>
-<p>
-  <ul>
-    <li>
-      November 17, 2017, by Uwe Bau:<br>
-      Tidy up implementation and enhance documentation for publication of library.<br>
-    </li>
-  </ul>
-</p>
-</html>"));
-end Zeolite13XWaterNunez;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/package.mo b/SorpLib/Media/AdsorbentAdsorbate/package.mo
deleted file mode 100644
index 6f3b9b8..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/package.mo
+++ /dev/null
@@ -1,11 +0,0 @@
-within SorpLib.Media;
-package AdsorbentAdsorbate
-extends SorpLib.Internals.ClassTypes.ModelPackage;
-
-
-
-
-
-
-
-end AdsorbentAdsorbate;
diff --git a/SorpLib/Media/AdsorbentAdsorbate/package.order b/SorpLib/Media/AdsorbentAdsorbate/package.order
deleted file mode 100644
index 86e5f6d..0000000
--- a/SorpLib/Media/AdsorbentAdsorbate/package.order
+++ /dev/null
@@ -1,7 +0,0 @@
-SilgelGrace123WaterSchawe
-SilgelGrace125WaterSchawe
-SilgelGrace125WaterNunez
-Zeolite13XWaterNunez
-AQSOAZ02WaterGoldsworthy
-Partial
-Testers
diff --git a/SorpLib/Media/Functions/CharCurve1Arctan.mo b/SorpLib/Media/Functions/CharCurve1Arctan.mo
deleted file mode 100644
index 33cac68..0000000
--- a/SorpLib/Media/Functions/CharCurve1Arctan.mo
+++ /dev/null
@@ -1,56 +0,0 @@
-within SorpLib.Media.Functions;
-function CharCurve1Arctan
-  input Modelica.SIunits.SpecificEnergy A "Adsorption Potential";
-  input Real c[4] "Coefficients for arctan function (see Info)";
-  output Modelica.SIunits.SpecificVolume W "Specific volume of adsorbate";
-
-algorithm
-  assert(A>0, "The adsorption potential A should be positive");
-
-  W := c[1]/Modelica.Constants.pi*(Modelica.Math.atan(
-    (A - c[2])/c[3]) + Modelica.Constants.pi/2) + c[4];
-
-  assert(W>0, "The specific volume W should be positive");
-
-  annotation (smoothOrder=2, inverse(A=CharCurve1Arctan_inverse(W,c)),
-    Documentation(info="<html>
-<p>
-This function describes characteristic curves based on an arctan function.
-</p>
-<h4>Main equations</h4>
-<p>
-The characteristic curve has the following basic equation:
-<p align=\"center\" style=\"font-style:italic;\">
-W = c<sub>1</sub> / <code>&#960;</code> [ arctan ((A-c<sub>2</sub>) / c<sub>3</sub>) + <code>&#960;</code> / 2 ] + c<sub>4</sub> + ,
-</p>
-<p>
-where <i>c<sub>1</sub></i>,<i>c<sub>2</sub></i>,<i>c<sub>3</sub></i>,<i>c<sub>4</sub></i> are the fit parameters of the chracteristic curve.
-</p>
-<h4>Assumptions and limitations</h4>
-<p>
-Both the adsorption potential A and the specific volume of the adsorbate should be non-negative
-</p>
-<h4>Typical use and important parameters</h4>
-<p>
-The function is used to describe empirical equilibrium data of working pairs following the Dubinin model.
-</p>
-<h4>References</h4>
-<p>
-This type of characteristic curve is used in the following publications:
-<ul>
-  <li>
-  Schawe, D. Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers. PhD Thesis. Stuttgart, 1999.
-  </li>
-</ul>
-</p>
-<h4>Author Information</h4>
-<p>
-<ul>
-  <li>
-  November 17, 2017, by Uwe Bau:<br/>
-  Tidy up implementation and enhance documentation for publication of library.<br>
-  </li>
-</ul>
-</p>
-</html>"));
-end CharCurve1Arctan;
diff --git a/SorpLib/Media/Functions/CharCurve1Arctan_dWdA.mo b/SorpLib/Media/Functions/CharCurve1Arctan_dWdA.mo
deleted file mode 100644
index 3771b1d..0000000
--- a/SorpLib/Media/Functions/CharCurve1Arctan_dWdA.mo
+++ /dev/null
@@ -1,34 +0,0 @@
-within SorpLib.Media.Functions;
-function CharCurve1Arctan_dWdA
-  input Modelica.SIunits.SpecificEnergy A "Adsorption Potential";
-  input Real c[4] "Coefficients for arctan function (see Info)";
-  output Real dWdA(unit="m3/J") "Derivative of specific volume of adsorbate W wrt to adsorption potential A";
-
-algorithm
-  assert(A>0, "The adsorption potential A should be positive");
-
-  dWdA := c[1]/(Modelica.Constants.pi*c[3]*(1 + (A
-     - c[2])^2/c[3]^2));
-
-  annotation (smoothOrder=2,
-    Documentation(info="<html>
-<p>This function describes the derivative of the characteristic curve with respect to the adsorption potential <i>A</i>: <i>dW/dA</i> </p>
-<h4>Main equations</h4>
-<p>The derivative with respect to the adsorption potential has the following basic equation: </p>
-<p align=\"center\"><i>dW/dA = c<sub>1</sub> / ( <code>&pi;</code> * c<sub>3</sub> ( 1 + (A-c<sub>2</sub>)<sup>2</sup> / c<sub>3</sub><sup>2</sup> )) </i></p>
-<p>where <i>c<sub>1</i></sub>,<i>c<sub>2</i></sub>,<i>c<sub>3</i></sub>,<i>c<sub>4</i></sub> are the fit parameters of the chracteristic curve. </p>
-<h4>Assumptions and limitations</h4>
-<p>Both the adsorption potential A and the specific volume of the adsorbate should be non-negative </p>
-<h4>Typical use and important parameters</h4>
-<p>The function is used to describe empirical equilibrium data of working pairs following the Dubinin model. </p>
-<h4>References</h4>
-<p>This type of characteristic curve is used in the following publications: </p>
-<ul>
-<li>Schawe, D. Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers. PhD Thesis. Stuttgart, 1999. </li>
-</ul>
-<h4>Author Information</h4>
-<ul>
-<li>November 17, 2017, by Uwe Bau:<br>Tidy up implementation and enhance documentation for publication of library.<br> </li>
-</ul>
-</html>"));
-end CharCurve1Arctan_dWdA;
diff --git a/SorpLib/Media/Functions/CharCurve1Arctan_inverse.mo b/SorpLib/Media/Functions/CharCurve1Arctan_inverse.mo
deleted file mode 100644
index 2882167..0000000
--- a/SorpLib/Media/Functions/CharCurve1Arctan_inverse.mo
+++ /dev/null
@@ -1,56 +0,0 @@
-within SorpLib.Media.Functions;
-function CharCurve1Arctan_inverse
-  input Modelica.SIunits.SpecificVolume W "Specific volume of adsorbate";
-  input Real c[4] "Coefficients for arctan function (see Info)";
-
-  output Modelica.SIunits.SpecificEnergy A "Adsorption Potential";
-
-algorithm
-  assert(W>0, "The specific volume W should be positive");
-
-  A := c[3]*Modelica.Math.tan((W-c[4])/c[1]*Modelica.Constants.pi-Modelica.Constants.pi/2)+c[2];
-
-  assert(A>0, "The adsorption potential A should be positive");
-
-  annotation (smoothOrder=2, inverse(W=CharCurve1Arctan(A,c)),
-    Documentation(info="<html>
-<p>
-This function implements the inverse function of the arctan characteristic curves.
-</p>
-<h4>Main equations</h4>
-<p>
-The characteristic curve has the following basic equation:
-<p align=\"center\" style=\"font-style:italic;\">
-A = c<sub>3</sub> tan (( W - c<sub>4</sub> ) * <code>&#960;</code> / c<sub>1</sub>  - <code>&#960;</code> / 2 ) + c<sub>2</sub> ,
-</p>
-<p>
-where <i>c<sub>1</sub></i>,<i>c<sub>2</sub></i>,<i>c<sub>3</sub></i>,<i>c<sub>4</sub></i> are the fit parameters of the chracteristic curve.
-</p>
-<h4>Assumptions and limitations</h4>
-<p>
-Both the adsorption potential A and the specific volume of the adsorbate should be non-negative
-</p>
-<h4>Typical use and important parameters</h4>
-<p>
-The function is used to describe empirical equilibrium data of working pairs following the Dubinin model.
-</p>
-<h4>References</h4>
-<p>
-This type of characteristic curve is used in the following publications:
-<ul>
-  <li>
-  Schawe, D. Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers. PhD Thesis. Stuttgart, 1999.
-  </li>
-</ul>
-</p>
-<h4>Author Information</h4>
-<p>
-<ul>
-  <li>
-  November 17, 2017, by Uwe Bau:<br/>
-  Tidy up implementation and enhance documentation for publication of library.<br>
-  </li>
-</ul>
-</p>
-</html>"));
-end CharCurve1Arctan_inverse;
diff --git a/SorpLib/Media/Functions/CharCurve2Polynomial.mo b/SorpLib/Media/Functions/CharCurve2Polynomial.mo
deleted file mode 100644
index 7227ce2..0000000
--- a/SorpLib/Media/Functions/CharCurve2Polynomial.mo
+++ /dev/null
@@ -1,53 +0,0 @@
-within SorpLib.Media.Functions;
-function CharCurve2Polynomial
-  input Modelica.SIunits.SpecificEnergy A "Adsorption Potential";
-  input Real c_u[:] "Coefficients for nominator (see Info)";
-  input Real c_v[:] "Coefficients for denominator (see Info)";
-  output Modelica.SIunits.SpecificVolume W "Specific volume of adsorbate";
-
-protected
-  Integer n_u = size(c_u,1);
-  Integer n_v = size(c_v,1);
-  Real u "Nominator";
-  Real v "Denominator";
-
-algorithm
-  assert(A>0, "The adsorption potential A should be positive");
-
-  u := c_u[1];
-  for i in 2:n_u loop
-    u := u*A + c_u[i];
-  end for;
-
-  v := c_v[1];
-  for i in 2:n_v loop
-    v := v*A + c_v[i];
-  end for;
-
-  W := u/v;
-
-  assert(W>0, "The specific volume W should be positive");
-
-  annotation (smoothOrder=2,
-    Documentation(info="<html>
-<p>This function describes characteristic curves based on polynomial functions. </p>
-<h4>Main equations</h4>
-<p>The characteristic curve has the following basic equation: </p> 
-<p align=\"center\"><i>W = <code>&sum;</code><sub>i=1</sub><sup>N</sup> c<sub>nom,i</sub> A<sup>N-i</sup> / 
-<code>&sum;</code><sub>j=1</sub><sup>N</sup> c<sub>denom,j</sub> A<sup>N-j</sup>, </i></p>
-<p>where <i>c<sub>nom,i</i></sub> and <i>c<sub>denom,i</i></sub> are the fit parameters of the chracteristic curve. </p>
-<h4>Assumptions and limitations</h4>
-<p>Both the adsorption potential A and the specific volume of the adsorbate should be non-negative </p>
-<h4>Typical use and important parameters</h4>
-<p>The function is used to describe empirical equilibrium data of working pairs following the Dubinin model. </p>
-<h4>References</h4>
-<p>This type of characteristic curve is used in the following publications: </p>
-<ul>
-<li>Núñez, T. Charakterisierung und Bewertung von Adsorbentien für Wärmetransformationsanwendungen. PhD Thesis. Freiburg, 2001. </li>
-</ul>
-<h4>Author Information</h4>
-<ul>
-<li>November 17, 2017, by Uwe Bau:<br>Tidy up implementation and enhance documentation for publication of library.<br></li>
-</ul>
-</html>"));
-end CharCurve2Polynomial;
diff --git a/SorpLib/Media/Functions/CharCurve2Polynomial_dWdA.mo b/SorpLib/Media/Functions/CharCurve2Polynomial_dWdA.mo
deleted file mode 100644
index 1ae933d..0000000
--- a/SorpLib/Media/Functions/CharCurve2Polynomial_dWdA.mo
+++ /dev/null
@@ -1,71 +0,0 @@
-within SorpLib.Media.Functions;
-function CharCurve2Polynomial_dWdA
-  input Modelica.SIunits.SpecificEnergy A "Adsorption Potential";
-  input Real c_u[:] "Coefficients for nominator (see Info)";
-  input Real c_v[:] "Coefficients for denominator (see Info)";
-  output Real dWdA(unit="m3/J")
-    "Derivative of specific volume of adsorbate W wrt to adsorption potential A";
-
-
-protected
-  Integer n_u=size(c_u, 1);
-  Integer n_v=size(c_v, 1);
-  Real u "Nominator";
-  Real v "Denominator";
-  Real u_der "Derivate of nominator wrt A";
-  Real v_der "Derivate of denominator wrt A";
-
-
-algorithm
-  assert(A > 0, "The adsorption potential A should be positive");
-
-  u := c_u[1];
-  for i in 2:n_u loop
-    u := u*A + c_u[i];
-  end for;
-
-  v := c_v[1];
-  for j in 2:n_v loop
-    v := v*A + c_v[j];
-  end for;
-
-
-  if n_u > 1 then
-    u_der := (n_u-1)*c_u[1];
-    for i in 2:n_u - 1 loop
-      u_der := u_der*A + (n_u-i)*c_u[i];
-    end for;
-  else
-    u_der := 0;
-  end if;
-
-  if n_v > 1 then
-    v_der := (n_v-1)*c_v[1];
-    for j in 2:n_v - 1 loop
-      v_der := v_der*A + (n_v-j)*c_v[j];
-    end for;
-  else
-    v_der := 0;
-  end if;
-
-  dWdA := ((u_der*v) - (u*v_der))/(v*v);
-
-  annotation (smoothOrder=2, Documentation(info="<html>
-<p>This function describes the derivative of the characteristic curve with respect to the adsorption potential A: dW/dA </p>
-<h4>Main equations</h4>
-<p>The derivative with respect to the adsorption potential for a rational polynomial function is determined by the quotient rule</p> 
-<h4>Assumptions and limitations</h4>
-<p>Both the adsorption potential A and the specific volume of the adsorbate should be non-negative </p>
-<h4>Typical use and important parameters</h4>
-<p>The function is used to describe empirical equilibrium data of working pairs following the Dubinin model. </p>
-<h4>References</h4>
-<p>This type of characteristic curve is used in the following publications: </p>
-<ul>
-<li>Núñez, T. Charakterisierung und Bewertung von Adsorbentien für Wärmetransformationsanwendungen. PhD Thesis. Freiburg, 2001. </li>
-</ul>
-<h4>Author Information</h4>
-<ul>
-<li>November 17, 2017, by Uwe Bau:<br>Tidy up implementation and enhance documentation for publication of library.<br></li>
-</ul>
-</html>"));
-end CharCurve2Polynomial_dWdA;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialMulti_h_ads.mo b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialMulti_h_ads.mo
new file mode 100644
index 0000000..9563530
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialMulti_h_ads.mo
@@ -0,0 +1,87 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses;
+partial function PartialMulti_h_ads
+  "Base function for functions calculating the sorption enthalpy for multi components"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass[:] M_i
+    "Molar masses of components"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerUptakeByPressure[size(M_i,1)] dx_adsorpt_dp
+    "Partial derivatives of the uptakes w.r.t. pressure at constant molar fractions
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByMolarFraction[size(M_i,1),size(M_i,1)-1] dx_adsorpt_dy_i
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    gas phase components at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByTemperature[size(M_i,1)] dx_adsorpt_dT
+    "Partial derivatives of the uptakes w.r.t. temperature at contant pressure and
+    molar fractions"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_threshold_min = 100*Modelica.Constants.eps
+    "Threshold for partial pressures of all components: If a partial pressure is
+    below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.MoleFraction y_i_threshold_min = 100*Modelica.Constants.eps
+    "Threshold for independent mole fractions of the adsorptive phase: If a independent
+    mole fraction is below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.MolarEnthalpy[size(M_i,1)] h_ads(each displayUnit="kJ/mol")
+    "Molar adsorption enthalpies of components"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the
+sorption enthalpies for multi components.
+<br/><br/>
+This partial function defines the molar masses of the components <i>M_i</i>, the
+pressure <i>p_adsorpt</i>, the independent mole fractions in the adsorptive phase
+<i>y_i</i>, the temperature <i>T_adsorpt</i>, the partial derivatives of the
+uptakes with respect to the pressure at constant molar fractions and temperature
+<i>dx_adsorpt_dp</i>, the partial derivatives of the uptakes with respect to the 
+independent mole fractions in the adsorptive phase at constant pressure and
+temperature <i>dx_adsorpt_dy_i</i>, and the partial derivatives of the uptakes with
+respect to the temperature at constant pressure and molar fractions <i>dx_adsorpt_dT</i> 
+as inputs. Optional inputs regarding numerics are the thresholds <i>p_threshold_min</i> 
+and <i>y_i_threshold_min</i>, describing the lower limits of the total pressure 
+and independent molar fractions of the adsorptive phase. The sorption enthalpies 
+<i>h_ads</i> are defined as outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMulti_h_ads;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_dh_ads_dT.mo b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_dh_ads_dT.mo
new file mode 100644
index 0000000..8bfae3e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_dh_ads_dT.mo
@@ -0,0 +1,48 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses;
+partial function PartialPure_dh_ads_dT
+  "Base function for functions calculating the partial derivative of the sorption enthalpy w.r.t. temperature at constant pressure for pure components"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.MolarHeatCapacity dh_ads_dT(displayUnit="kJ/(mol.K)")
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the
+partial derivative of the sorption enthalpy with respect to the temperature at
+consstant pressure for pure components.
+<br/><br/>
+This partial function defines the temperature <i>T_adsorpt</i> as input and the
+partial derivative of the sorption enthalpy fwith respect to the temperature at
+constant pressure <i>dh_ads_dT</i> as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_dh_ads_dT;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_dh_ads_dp.mo b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_dh_ads_dp.mo
new file mode 100644
index 0000000..664edce
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_dh_ads_dp.mo
@@ -0,0 +1,48 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses;
+partial function PartialPure_dh_ads_dp
+  "Base function for functions calculating the partial derivative of the sorption enthalpy w.r.t. pressure at constant temperature for pure components"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the
+partial derivative of the sorption enthalpy with respect to the pressure at
+consstant temperature for pure components.
+<br/><br/>
+This partial function defines the temperature <i>T_adsorpt</i> as input and the
+partial derivative of the sorption enthalpy fwith respect to the pressure at
+constant temperature <i>dh_ads_dp</i> as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_dh_ads_dp;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_h_ads.mo b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_h_ads.mo
new file mode 100644
index 0000000..b4e9f8b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialPure_h_ads.mo
@@ -0,0 +1,45 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses;
+partial function PartialPure_h_ads
+  "Base function for functions calculating the sorption enthalpy for pure components"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.MolarEnthalpy h_ads(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the
+sorption enthalpy for pure components.
+<br/><br/>
+This partial function defines the temperature <i>T_adsorpt</i> as input and the 
+sorption enthalpy <i>h_ads</i> as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_h_ads;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialTestMulti.mo b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialTestMulti.mo
new file mode 100644
index 0000000..930beed
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialTestMulti.mo
@@ -0,0 +1,126 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses;
+partial model PartialTestMulti
+  "Base model for testers of sorption enthalpy models describing multi-component adsorption"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Integer no_components = 2
+    "Number of components of the isotherm model"
+    annotation (Dialog(tab="Isotherm model", group="General"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_coefficients = 3
+    "Number of coefficients of the isotherm model (i.e., highest number among 
+    different components)"
+    annotation (Dialog(tab="Isotherm model", group="General"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MolarMass[no_components] M_i = {0.018, 0.044}
+    "Molar masses of the components"
+    annotation (Dialog(tab="Isotherm model", group="General"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.Pressure p_adsorpt_start = 1
+    "Start value of equilibrium pressure"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.MoleFraction[no_components-1] y_i_start={1e-2}
+    "Start values independent mole fractions"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_start = 278.15
+    "Start value of equilibrium temperature"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+
+  parameter Modelica.Units.SI.Pressure p_threshold_min = 1e-6
+    "Threshold for partial pressures of all components: If a partial pressure is
+    below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="Numerics", group="Limiter"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MoleFraction y_i_threshold_min = 1e-6
+    "Threshold for independent mole fractions of the adsorptive phase: If a independent
+    mole fraction is below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="Numerics", group="Limiter"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt(start=p_adsorpt_start, fixed=true)
+    "Pressure";
+  Modelica.Units.SI.MoleFraction[no_components-1] y_i(start=y_i_start, each fixed=true)
+    "Independent mole fractions";
+  Modelica.Units.SI.Temperature T_adsorpt(start=T_adsorpt_start, fixed=true)
+    "Temperature";
+
+  SorpLib.Units.Uptake[no_components] x_adsorpt
+    "Uptake";
+  SorpLib.Units.DerUptakeByPressure[no_components] dx_adsorpt_dp
+    "Partial derivative of uptakes w.r.t. pressure at constant mole fractions and
+    temperature";
+  SorpLib.Units.DerUptakeByMolarFraction[no_components,no_components-1] dx_adsorpt_dy_i
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    components of adsorptive phase at constant pressure and temperature";
+  SorpLib.Units.DerUptakeByTemperature[no_components] dx_adsorpt_dT
+    "Partial derivative of uptakes w.r.t. temperature at constant pressure and
+    mole fractions";
+
+  Modelica.Units.SI.MolarEnthalpy[no_components] h_ads(each displayUnit="kJ/mol")
+    "Molar adsorption enthalpy";
+
+protected
+  Real[no_coefficients,no_components] c
+    "Coefficients of isotherm model";
+  Real[no_coefficients,no_components] dc_dT
+    "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+equation
+  //
+  // Calculate sorptions enthalies
+  //
+  h_ads = SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents.h_ads_clausiusClapeyron(
+    M_i=M_i,
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dy_i=dx_adsorpt_dy_i,
+    dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar adsorption enthalpy";
+
+  //
+  // Annotations
+  //
+  annotation (
+    Icon(coordinateSystem(preserveAspectRatio=false)),
+    Diagram(coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the basic model for all testers of sorption enthalpies for
+multi components. This partial model defines all some relevant parameters and 
+variables that are required for most sorption enthalpy models.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the 
+coefficients of the isotherm model (i.e., <i>c</i>) and their partial derivatives 
+with respect to temperature (i.e., <i>dc_dT</i>). Additionally, equations for the
+following variables must be implemted: <i>p_adsorpt</i>, <i>y_i</i>, <i>T_adsorpt</i>, 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialTestMulti;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialTestPure.mo b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialTestPure.mo
new file mode 100644
index 0000000..0b6b7c5
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/PartialTestPure.mo
@@ -0,0 +1,304 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses;
+partial model PartialTestPure
+  "Base model for testers of sorption enthalpy models describing pure component adsorption"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_ph
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Medium"),
+                choicesAllMatching = true);
+
+  parameter Integer no_coefficients = 6
+    "Number of coefficients of selected isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Pressure p_adsorpt_start = 700
+    "Start value of equilibrium pressure"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_start = 278.15
+    "Start value of equilibrium temperature"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.MolarMass M_adsorptive = 0.018
+    "Molar mass of adsorptive"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used to calculated partial derivatives numerically"
+    annotation (Dialog(tab="General",group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculated partial derivatives numerically"
+    annotation (Dialog(tab="General",group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Units.Uptake dx = 1e-3
+    "Uptake difference used to calculated partial derivatives numerically"
+    annotation (Dialog(tab="General",group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt(start=p_adsorpt_start, fixed=true)
+    "Pressure";
+  Modelica.Units.SI.Temperature T_adsorpt(start=T_adsorpt_start, fixed=true)
+    "Temperature";
+  SorpLib.Units.Uptake x_adsorpt
+    "Uptake";
+
+  Medium.ThermodynamicState state_adsorptive_pT
+    "State properties of adsorptive at p_adsorpt and T_adsorpt";
+  Medium.ThermodynamicState state_bubble_T
+    "State properties of bubble point at T_adsorpt";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy";
+
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T_num
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at
+    constant temperature calculated numerically";
+
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p(displayUnit="kJ/(mol.K)")
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant pressure";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p_num(displayUnit="kJ/(mol.K)")
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature
+    calculated numerically at constant pressure";
+
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_x(displayUnit="kJ/(mol.K)")
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant uptake";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_x_num(displayUnit="kJ/(mol.K)")
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature
+    calculated numerically at constant uptake";
+
+  SorpLib.Units.DerMolarEnthalpyByUptake dh_ads_dx_T
+    "Partial derivative of molar adsorption enthalpy w.r.t. uptake at
+    constant temperature";
+  SorpLib.Units.DerMolarEnthalpyByUptake dh_ads_dx_T_num
+    "Partial derivative of molar adsorption enthalpy w.r.t. uptake at
+    constant temperature calculated numerically";
+
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_x
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at
+    constant uptake";
+  SorpLib.Units.DerMolarEnthalpyByUptake dh_ads_dx_p
+    "Partial derivative of molar adsorption enthalpy w.r.t. uptake at
+    constant pressure";
+
+protected
+  Real c[no_coefficients]
+    "Coefficients of the isotherm model";
+  Real c_pdT[no_coefficients]
+    "Coefficients of the isotherm model: T + dT";
+  Real c_mdT[no_coefficients]
+    "Coefficients of the isotherm model: T - dT";
+
+  Real dc_dT[no_coefficients]
+    "Partial derivative of coefficients of the isotherm model w.r.t. temperature";
+  Real dc_dT_pdT[no_coefficients]
+    "Partial derivative of coefficients of the isotherm model w.r.t. temperature:
+    T + dT";
+  Real dc_dT_mdT[no_coefficients]
+    "Partial derivative of coefficients of the isotherm model w.r.t. temperature:
+    T - dT";
+
+  Real ddc_dT_dT[no_coefficients]
+    "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature";
+
+  Medium.SaturationProperties sat_T
+    "Saturated state properties at T_adsorpt";
+  Medium.SaturationProperties sat_T_pdT
+    "Saturated state properties at T_adsorpt: T + dT";
+  Medium.SaturationProperties sat_T_mdT
+    "Saturated state properties at T_adsorpt: T - dT";
+
+  Medium.ThermodynamicState state_adsorptive_pT_pdp
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: p + dp";
+  Medium.ThermodynamicState state_adsorptive_pT_mdp
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: p - dp";
+  Medium.ThermodynamicState state_adsorptive_pT_pdT
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: T + dT";
+  Medium.ThermodynamicState state_adsorptive_pT_mdT
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: T - dT";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant prssure";
+
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads_pdp_T(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: p + dp";
+  Modelica.Units.SI.MolarEnthalpy h_ads_mdp_T(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: p - dp";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads_pdT_p(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: T + dT";
+  Modelica.Units.SI.MolarEnthalpy h_ads_mdT_p(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: T - dT";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads_pdT_x(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt, T+dT) and T_adsorpt: T + dT";
+  Modelica.Units.SI.MolarEnthalpy h_ads_mdT_x(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt, T-dT) and T_adsorpt: T - dT";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads_pdx_T(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt+dx) and T_adsorpt";
+  Modelica.Units.SI.MolarEnthalpy h_ads_mdx_T(displayUnit="kJ/mol")
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt-dx) and T_adsorpt";
+
+equation
+  //
+  // Calculation of state properties
+  //
+  sat_T = Medium.setSat_T(T=T_adsorpt)
+    "Saturated state properties at T_adsorpt";
+  sat_T_pdT = Medium.setSat_T(T=T_adsorpt+dT)
+    "Saturated state properties at T_adsorpt: T + dT";
+  sat_T_mdT = Medium.setSat_T(T=T_adsorpt-dT)
+    "Saturated state properties at T_adsorpt: T - dT";
+
+  state_adsorptive_pT = Medium.setState_pTX(
+    p=p_adsorpt,
+    T=T_adsorpt)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt";
+  state_adsorptive_pT_pdp = Medium.setState_pTX(
+    p=p_adsorpt+dp,
+    T=T_adsorpt)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: p + dp";
+  state_adsorptive_pT_mdp = Medium.setState_pTX(
+    p=p_adsorpt-dp,
+    T=T_adsorpt)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: p - dp";
+  state_adsorptive_pT_pdT = Medium.setState_pTX(
+    p=p_adsorpt,
+    T=T_adsorpt+dT)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: T + dT";
+  state_adsorptive_pT_mdT = Medium.setState_pTX(
+    p=p_adsorpt,
+    T=T_adsorpt-dT)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: T - dT";
+
+  state_bubble_T = Medium.setBubbleState(sat=sat_T)
+    "State properties of bubble point at T_adsorpt";
+
+  //
+  // Calculate properties
+  //
+  dh_ads_dT_x = dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant uptake";
+  dh_ads_dx_T = dh_ads_dp_T / dx_adsorpt_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. uptake at
+    constant temperature";
+
+  dh_ads_dp_x = dh_ads_dp_T - dh_ads_dT_p * dx_adsorpt_dp / dx_adsorpt_dT
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at
+    constant uptake";
+  dh_ads_dx_p = dh_ads_dT_p / dx_adsorpt_dT
+    "Partial derivative of molar adsorption enthalpy w.r.t. uptake at
+    constant pressure";
+
+  //
+  // Calculate nuermical derivatives
+  //
+  dh_ads_dp_T_num = (h_ads_pdp_T - h_ads_mdp_T) / (2*dp)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature calculated numerically";
+  dh_ads_dT_p_num = (h_ads_pdT_p - h_ads_mdT_p) / (2*dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure calculated numerically";
+  dh_ads_dT_x_num = (h_ads_pdT_x - h_ads_mdT_x) / (2*dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake calculated numerically";
+  dh_ads_dx_T_num = (h_ads_pdx_T - h_ads_mdx_T) / (2*dx)
+    "Partial derivative of molar adsorption enthalpy w.r.t. uptake at constant
+    temperature calculated numerically";
+
+  //
+  // Definition of assertions: Check numerical implementations
+  //
+  assert(abs(dh_ads_dp_T-dh_ads_dp_T_num) < 1e-6,
+    "Partial derivative of h_ads w.r.t. pressure at constant temperature is not " +
+    "valied: Deviation (|" +
+    String(abs(dh_ads_dp_T-dh_ads_dp_T_num)) +
+    "|) is greater than 1e-6 J/mol/Pa!",
+    level = AssertionLevel.warning);
+  assert(abs(dh_ads_dT_p-dh_ads_dT_p_num) < 1e-6,
+    "Partial derivative of h_ads w.r.t. temperature at constant pressure is not " +
+    "valied: Deviation (|" +
+    String(abs(dh_ads_dT_p-dh_ads_dT_p_num)) +
+    "|) is greater than 1e-6 J/mol/K!",
+    level = AssertionLevel.warning);
+  assert(abs(dh_ads_dT_x-dh_ads_dT_x_num) < 1e-6,
+    "Partial derivative of h_ads w.r.t. temperature at constant uptake is not " +
+    "valied: Deviation (|" +
+    String(abs(dh_ads_dT_x-dh_ads_dT_x_num)) +
+    "|) is greater than 1e-6 J/mol/K!",
+    level = AssertionLevel.warning);
+  assert(abs(dh_ads_dx_T-dh_ads_dx_T_num) < 1e-6,
+    "Partial derivative of h_ads w.r.t. uptake at constant temperature is not " +
+    "valied: Deviation (|" +
+    String(abs(dh_ads_dx_T-dh_ads_dx_T_num)) +
+    "|) is greater than 1e-6 J.kg/mol/kg!",
+    level = AssertionLevel.warning);
+
+  //
+  // Annotations
+  //
+  annotation (
+    Icon(coordinateSystem(preserveAspectRatio=false)),
+    Diagram(coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the basic model for all testers of sorption enthalpies for
+pure components. This partial model defines all some relevant parameters and 
+variables that are required for most sorption enthalpy models.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the 
+<i>medium</i> and test setup. Besides, the coefficients of the isotherm model 
+(i.e., <i>c</i>, <i>c_pdT</i>, and <i>c_mdT</i>) and their partial derivatives 
+with respect to temperature (i.e., <i>dc_dT</i>, <i>dc_dT_pdT</i>, <i>dc_dT_mdT</i>, 
+and <i>ddc_dT_dT</i>) have to be implemented. Additionally, equations for the
+following variables must be implemted: <i>p_adsorpt</i>, <i>T_adsorpt</i>, 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp</i>, <i>dx_adsorpt_dT</i>, <i>ddx_adsorpt_dp_dp</i>,
+<i>ddx_adsorpt_dT_dT</i>, <i>ddx_adsorpt_dp_dT</i>, <i>h_ads</i>, <i>dh_ads_dp_T</i>, 
+<i>dh_ads_dT_p</i>, <i>h_ads_pdp_T</i>, <i>h_ads_mdp_T</i>, <i>h_ads_pdT_p</i>, 
+<i>h_ads_mdT_p</i>, <i>h_ads_pdT_x</i>, <i>h_ads_mdT_x</i>, <i>h_ads_pdx_T</i>, 
+and <i>h_ads_mdx_T</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialTestPure;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/package.mo b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/package.mo
new file mode 100644
index 0000000..2ca6439
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions.SorptionEnthalpies;
+package BasesClasses "Base classes used to build new functions calculating sorption enthalpies"
+  extends Modelica.Icons.BasesPackage;
+
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This package contains partial basic functions and models. These partial functions
+and models contain fundamental definitions of functions calculating sorption enthalpies
+for pure and multi-component adsorption. The content of this package is only of 
+interest when adding new functions to the library.
+</p>
+</html>"));
+end BasesClasses;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/package.order b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/package.order
new file mode 100644
index 0000000..7349d12
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/BasesClasses/package.order
@@ -0,0 +1,6 @@
+PartialPure_h_ads
+PartialPure_dh_ads_dp
+PartialPure_dh_ads_dT
+PartialMulti_h_ads
+PartialTestPure
+PartialTestMulti
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/Test_h_ads_clausiusClapeyron_binary.mo b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/Test_h_ads_clausiusClapeyron_binary.mo
new file mode 100644
index 0000000..7adab13
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/Test_h_ads_clausiusClapeyron_binary.mo
@@ -0,0 +1,156 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents.Testers;
+model Test_h_ads_clausiusClapeyron_binary
+  "Tester for the functions 'h_ads_clausiusClapeyron' and 'h_ads_binary_clausiusClapeyron'"
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialTestMulti;
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.32, 0.22}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {1.075e-4, 1.075e-4}
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] Q(each unit="J/mol") = {28.752e3, 28.752e3}
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] n_ref(each unit="1") = {2.312, 2.812}
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] alpha(each unit="1") = {0.5559, 0.5559}
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.MolarEnthalpy[no_components] h_ads_binary(each displayUnit="kJ/mol")
+    "Molar adsorption enthalpy calculated via binary approach";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 100000/20
+    "Predecsriped slope of p_adsorpt to demonstrate the isotherm model";
+  der(y_i) = {0.98/20}
+    "Predecsriped slope of y_i to demonstrate the isotherm model";
+  der(T_adsorpt) = 90/20
+    "Predecsriped slope of T_adsorpt to demonstrate the isotherm model";
+
+  //
+  // Calculate coefficients of the isotherm model
+  //
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = -T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2 /
+      (1/n_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt))^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+  end for;
+
+  //
+  // Calculate properties
+  //
+  x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.x_pyT(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Uptakes";
+
+  dx_adsorpt_dp = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.dx_dp(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Partial derivative of uptakes w.r.t. pressure at constant mole fractions and
+    temperature";
+
+  dx_adsorpt_dy_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.dx_dy(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    components of adsorptive phase at constant pressure and temperature";
+
+  dx_adsorpt_dT = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.dx_dT(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT,
+    p_threshold_min=p_threshold_min)
+    "Partial derivative of uptakes w.r.t. temperature at constant pressure and
+    mole fractions";
+
+  h_ads_binary = SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents.h_ads_binary_clausiusClapeyron(
+    M_i=M_i,
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dy_i=dx_adsorpt_dy_i,
+    dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar adsorption enthalpy calculated via binary approach";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'h_ads_ClausiusClapeyron_binary.'
+<br/><br/>
+To see the function behavior, plot the variables <i>h_ads_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_h_ads_clausiusClapeyron_binary;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/Test_h_ads_clausiusClapeyron_ternary.mo b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/Test_h_ads_clausiusClapeyron_ternary.mo
new file mode 100644
index 0000000..8812d4b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/Test_h_ads_clausiusClapeyron_ternary.mo
@@ -0,0 +1,159 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents.Testers;
+model Test_h_ads_clausiusClapeyron_ternary
+  "Tester for the functions 'h_ads_clausiusClapeyron' and 'h_ads_ternary_clausiusClapeyron'"
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialTestMulti(
+    final no_components = 3,
+    final M_i={0.018,0.044,0.035},
+    final y_i_start={0.01,0.01});
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.32, 0.22, 0.11}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1, 0.2}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {1.075e-4, 1.075e-4, 1.075e-4}
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] Q(each unit="J/mol") = {28.752e3, 28.752e3, 28.752e3}
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] n_ref(each unit="1") = {2.312, 2.812, 2.812}
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Real[no_components] alpha(each unit="1") = {0.5559, 0.5559, 0.5559}
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="Isotherm model", group="Parameters"),
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.MolarEnthalpy[no_components] h_ads_ternary(each displayUnit="kJ/mol")
+    "Molar adsorption enthalpy calculated via ternary approach";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 100000/20
+    "Predecsriped slope of p_adsorpt to demonstrate the isotherm model";
+  der(y_i) = {0.97/20/3*2, 0.97/20/3*1}
+    "Predecsriped slope of y_i to demonstrate the isotherm model";
+  der(T_adsorpt) = 90/20
+    "Predecsriped slope of T_adsorpt to demonstrate the isotherm model";
+
+  //
+  // Calculate coefficients of the isotherm model
+  //
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = -T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2 /
+      (1/n_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt))^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+  end for;
+
+  //
+  // Calculate properties
+  //
+  x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.x_pyT(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Uptakes";
+
+  dx_adsorpt_dp = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.dx_dp(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Partial derivative of uptakes w.r.t. pressure at constant mole fractions and
+    temperature";
+
+  dx_adsorpt_dy_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.dx_dy(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    components of adsorptive phase at constant pressure and temperature";
+
+  dx_adsorpt_dT = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.dx_dT(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT,
+    p_threshold_min=p_threshold_min)
+    "Partial derivative of uptakes w.r.t. temperature at constant pressure and
+    mole fractions";
+
+  h_ads_ternary = SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents.h_ads_ternary_clausiusClapeyron(
+    M_i=M_i,
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dy_i=dx_adsorpt_dy_i,
+    dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar adsorption enthalpy calculated via ternary approach";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'h_ads_ClausiusClapeyron_ternary.'
+<br/><br/>
+To see the function behavior, plot the variables <i>h_ads_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_h_ads_clausiusClapeyron_ternary;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/package.mo b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/package.mo
new file mode 100644
index 0000000..63ef7a3
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents;
+package Testers "Models to test and varify functions for sorption enthalpies for multi components"
+  extends Modelica.Icons.ExamplesPackage;
+
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions and models of the
+'MultiComponents' package. The test models check the implementation of the functions 
+and models and enable verification of their behavior. In addition, the test models 
+demonstrate the functions' and models' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/package.order b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/package.order
new file mode 100644
index 0000000..65d0b1e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/Testers/package.order
@@ -0,0 +1,2 @@
+Test_h_ads_clausiusClapeyron_binary
+Test_h_ads_clausiusClapeyron_ternary
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_binary_clausiusClapeyron.mo b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_binary_clausiusClapeyron.mo
new file mode 100644
index 0000000..6b65aa0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_binary_clausiusClapeyron.mo
@@ -0,0 +1,151 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents;
+function h_ads_binary_clausiusClapeyron
+  "Molar adsorption enthalpies for a binary mixture according to Clausius Clapeyron"
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialMulti_h_ads;
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt_
+    "Limited total pressure";
+  Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i_
+    "Limited mole fractions of independent components in the vapor or gas phase";
+
+  Real[size(M_i,1)] numerator_i
+    "Numerators of all components";
+  Real numerator_summand_1
+    "Summand 1 of the numerator for each component";
+  Real numerator_summand_2
+    "Summand 2 of the numerator for each component";
+
+  Real denominator
+    "Denominator for each component";
+
+algorithm
+  //
+  // Define initial values
+  //
+  p_adsorpt_ := max(p_adsorpt, p_threshold_min)
+    "Limited total pressure";
+  for ind in 1:size(M_i,1)-1 loop
+    y_i_[ind] := max(y_i[ind], y_i_threshold_min)
+      "Limited mole fractions of independent components in the vapor or gas phase";
+  end for;
+
+  //
+  // Set up numerators
+  //
+  numerator_summand_1 :=(dx_adsorpt_dT[1]*dx_adsorpt_dy_i[2, 1] -
+    dx_adsorpt_dT[2]*dx_adsorpt_dy_i[1, 1])
+    "Summand 1 of the numerator for each component";
+  numerator_summand_2 :=(dx_adsorpt_dp[1]*dx_adsorpt_dT[2] -
+    dx_adsorpt_dp[2]*dx_adsorpt_dT[1])
+    "Summand 2 of the numerator for each component";
+
+  numerator_i[1] := 1 / (p_adsorpt_ * M_i[1] *  M_i[2]) * numerator_summand_1 +
+    1 / (y_i_[1] * M_i[1] *  M_i[2]) * numerator_summand_2
+    "Numerator of first component";
+  numerator_i[2] := 1 / (p_adsorpt_ * M_i[1] *  M_i[2]) * numerator_summand_1 -
+    1 / ((1 - y_i_[1]) * M_i[1] *  M_i[2]) * numerator_summand_2
+    "Numerator of second component";
+
+  //
+  // Set up denominator
+  //
+  denominator := -1 / (M_i[1] *  M_i[2]) *
+    (dx_adsorpt_dp[1] * dx_adsorpt_dy_i[2,1] -
+     dx_adsorpt_dp[2] * dx_adsorpt_dy_i[1,1])
+    "Denominator for each components";
+
+  //
+  // Calculate adsorption enthalpies
+  //
+  if p_adsorpt < p_threshold_min then
+    //
+    // Vacuum
+    //
+    h_ads := fill(100*Modelica.Constants.eps, size(M_i,1))
+      "Molar adsorption enthalpy";
+
+  else
+    //
+    // No vacuum
+    //
+    if y_i[1] > y_i_threshold_min then
+      h_ads[1] := Modelica.Constants.R * T_adsorpt^2 *
+        numerator_i[1] / denominator
+        "Molar adsorption enthalpy of first component";
+    else
+      h_ads[1] := 100*Modelica.Constants.eps
+        "Molar adsorption enthalpy of first component";
+    end if;
+
+    if 1-y_i[1] > y_i_threshold_min then
+      h_ads[2] := Modelica.Constants.R * T_adsorpt^2 *
+        numerator_i[2] / denominator
+        "Molar adsorption enthalpy of second component";
+    else
+      h_ads[2] := 100*Modelica.Constants.eps
+        "Molar adsorption enthalpy of second component";
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the molar adsorption enthalpies for binary mixtures according 
+to Clausius Clapeyron assumptions.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads,i</sub></i> of component <i>i</i>
+is defined as follows:
+</p>
+<pre>
+    &Delta;h<sub>ads,<i>i</i></sub> = R * T<sup>2</sup> * [&part;(<strong>ln</strong>(y<sub><i>i</i></sub> * p), x<sub>1</sub>, ..., x<sub>N</sub>) / &part;(p, T, y<sub>1</sub>, ..., y<sub>N-1</sub>)] / [&part;(T, x<sub>1</sub>, ..., x<sub>N</sub>) / &part;(p, T, y<sub>1</sub>, ..., y<sub>N-1</sub>)];
+</pre>
+<p>
+Herein, <i>R</i> is the ideal gas constant, <i>p</i> is the pressure, <i>T</i> is
+the temperature, <i>x<sub>i</sub></i> are the uptakes, and <i>y<sub>i</sub></i>
+are the independent mole fractions in the adsorptive phase.
+<br><br>
+The determinants in the numerator and denominator have already been solved.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The specific volume of the adsorpt phase can be neglected compared to the specific
+  volume of the adsorptive phase.
+  </li>
+  <li>
+  The adsorptive can be treated as an ideal gas mixture.
+  </li>
+  <li>
+  The adsorpt can be treated as an ideal solution.
+  </li>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Sircar, S. (1984). Excess Properties and Thermodynamics of Multicomponent Gas Adsorption. Journal of the Chemical Society, Faraday Transactions 1: Physical Chemistry in Condensed Phases, 81:1527-1540. DOI: https://doi.org/10.1039/F19858101527.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end h_ads_binary_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_clausiusClapeyron.mo b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_clausiusClapeyron.mo
new file mode 100644
index 0000000..569b6d4
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_clausiusClapeyron.mo
@@ -0,0 +1,220 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents;
+function h_ads_clausiusClapeyron
+  "Molar adsorption enthalpies according to Clausius Clapeyron"
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialMulti_h_ads;
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt_
+    "Limited total pressure";
+  Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i_
+    "Limited mole fractions of independent components in the vapor or gas phase";
+
+  //
+  // Dimension 1: Components
+  // Dimension 2: p_adsorpt or T_adsorpt | x_1 | ... | x_size(M_i,1)
+  // Dimension 3: p_adsorpt | T_adsorpt | y_1 | ... | y_size(M_i,1)-1
+  //
+  Real[size(M_i,1),size(M_i,1)+1,size(M_i,1)+1] numerator_i
+    "Numerators of all components";
+  Real[size(M_i,1),size(M_i,1)+1,size(M_i,1)+1] denominator_i
+    "Denominators of all components";
+
+algorithm
+  //
+  // Define initial values
+  //
+  p_adsorpt_ := max(p_adsorpt, p_threshold_min)
+    "Limited total pressure";
+  for ind in 1:size(M_i,1)-1 loop
+    y_i_[ind] := max(y_i[ind], y_i_threshold_min)
+      "Limited mole fractions of independent components in the vapor or gas phase";
+  end for;
+
+  numerator_i:= zeros(size(M_i,1),size(M_i,1)+1,size(M_i,1)+1)
+    "Numerators of all components";
+  denominator_i:= zeros(size(M_i,1),size(M_i,1)+1,size(M_i,1)+1)
+    "Denominators of all components";
+
+  //
+  // Set up numerators and denominators
+  //
+  for ind_comp in 1:size(M_i,1) loop
+    //
+    // First row of numerators and denominators
+    //
+    numerator_i[ind_comp,1,1] :=1/p_adsorpt_
+      "Partial derivatives of partial pressures w.r.t. pressure";
+    numerator_i[ind_comp,1,2] :=0
+      "Partial derivatives of partial pressures w.r.t. temperature";
+
+    denominator_i[ind_comp,1,1] :=0
+      "Partial derivatives of temperature w.r.t. pressure";
+    denominator_i[ind_comp,1,2] :=1
+      "Partial derivatives of temperature w.r.t. temperature";
+
+    for ind_indep_comp in 1:size(M_i,1)-1 loop
+      if ind_comp < size(M_i,1) then
+        numerator_i[ind_comp,1,2+ind_indep_comp] :=if ind_comp ==
+          ind_indep_comp then 1/y_i_[ind_indep_comp] else 0
+          "Partial derivatives of partial pressures w.r.t. independent mole
+          fractions of adsorptive phase";
+      else
+        numerator_i[ind_comp,1,2+ind_indep_comp] := -1 / (1 - sum(y_i_))
+          "Partial derivatives of partial pressures w.r.t. independent mole
+          fractions of adsorptive phase";
+      end if;
+
+      denominator_i[ind_comp,1,2+ind_indep_comp] :=0
+        "Partial derivatives of partial pressures w.r.t. independent mole
+        fractions of adsorptive phase";
+
+    end for;
+
+    //
+    // Second to last row of numerators and denominators
+    //
+    for ind_comp_inner in 1:size(M_i,1) loop
+      //
+      // Partial derivatives w.r.t. pressure
+      //
+      numerator_i[ind_comp,1+ind_comp_inner,1] :=
+        1 / M_i[ind_comp_inner] * dx_adsorpt_dp[ind_comp_inner]
+        "Partial derivatives of uptake w.r.t. pressure";
+      denominator_i[ind_comp,1+ind_comp_inner,1] :=
+        1 / M_i[ind_comp_inner] * dx_adsorpt_dp[ind_comp_inner]
+        "Partial derivatives of uptake w.r.t. pressure";
+
+      //
+      // Partial derivatives w.r.t. temperature
+      //
+      numerator_i[ind_comp,1+ind_comp_inner,2] :=
+        1 / M_i[ind_comp_inner] * dx_adsorpt_dT[ind_comp_inner]
+        "Partial derivatives of uptake w.r.t. pressure";
+      denominator_i[ind_comp,1+ind_comp_inner,2] :=
+        1 / M_i[ind_comp_inner] * dx_adsorpt_dT[ind_comp_inner]
+        "Partial derivatives of uptake w.r.t. pressure";
+
+      //
+      // Partial derivatives w.r.t. independent mole fractions of adsorptive phase
+      //
+      for ind_indep_comp in 1:size(M_i,1)-1 loop
+        numerator_i[ind_comp,1+ind_comp_inner,2+ind_indep_comp] :=
+          1 / M_i[ind_comp_inner] * dx_adsorpt_dy_i[ind_comp_inner,ind_indep_comp]
+          "Partial derivatives of uptake w.r.t. independent mole fractions";
+        denominator_i[ind_comp,1+ind_comp_inner,2+ind_indep_comp] :=
+          1 / M_i[ind_comp_inner] * dx_adsorpt_dy_i[ind_comp_inner,ind_indep_comp]
+          "Partial derivatives of uptake w.r.t. independent mole fractions";
+
+      end for;
+    end for;
+  end for;
+
+  //
+  // Calculate adsorption enthalpies
+  //
+  if p_adsorpt < p_threshold_min then
+    //
+    // Vacuum
+    //
+    h_ads := fill(100*Modelica.Constants.eps, size(M_i,1))
+      "Molar adsorption enthalpy";
+
+  else
+    //
+    // Independent components
+    //
+    for ind_comp in 1:size(M_i,1)-1 loop
+      if y_i[ind_comp] > y_i_threshold_min then
+        h_ads[ind_comp] := Modelica.Constants.R * T_adsorpt^2 *
+          Modelica.Math.Matrices.det(numerator_i[ind_comp,:,:]) /
+          Modelica.Math.Matrices.det(denominator_i[ind_comp,:,:])
+          "Molar adsorption enthalpy";
+
+      else
+        h_ads[ind_comp] := -100*Modelica.Constants.eps
+          "Molar adsorption enthalpy";
+
+      end if;
+    end for;
+
+    //
+    // Dependent components
+    //
+    if 1-sum(y_i) > y_i_threshold_min then
+      h_ads[size(M_i,1)] := Modelica.Constants.R * T_adsorpt^2 *
+        Modelica.Math.Matrices.det(numerator_i[size(M_i,1),:,:]) /
+        Modelica.Math.Matrices.det(denominator_i[size(M_i,1),:,:])
+        "Molar adsorption enthalpy";
+
+    else
+      h_ads[size(M_i,1)] := 100*Modelica.Constants.eps
+        "Molar adsorption enthalpy";
+
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the molar adsorption enthalpies for mixtures according to 
+Clausius Clapeyron assumptions.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads,i</sub></i> of component <i>i</i>
+is defined as follows:
+</p>
+<pre>
+    &Delta;h<sub>ads,<i>i</i></sub> = R * T<sup>2</sup> * [&part;(<strong>ln</strong>(y<sub><i>i</i></sub> * p), x<sub>1</sub>, ..., x<sub>N</sub>) / &part;(p, T, y<sub>1</sub>, ..., y<sub>N-1</sub>)] / [&part;(T, x<sub>1</sub>, ..., x<sub>N</sub>) / &part;(p, T, y<sub>1</sub>, ..., y<sub>N-1</sub>)];
+</pre>
+<p>
+Herein, <i>R</i> is the ideal gas constant, <i>p</i> is the pressure, <i>T</i> is
+the temperature, <i>x<sub>i</sub></i> are the uptakes, and <i>y<sub>i</sub></i>
+are the independent mole fractions in the adsorptive phase.
+<br><br>
+The determinants in the numerator and denominator are calculated using the Modelica
+function
+<a href=\"Modelica://Modelica.Math.Matrices.det\">Modelica.Math.Matrices.det</a>.
+Hence, it is more efficient to use other functions that not rely on the Modelica
+function but have the determinats already solved.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The specific volume of the adsorpt phase can be neglected compared to the specific
+  volume of the adsorptive phase.
+  </li>
+  <li>
+  The adsorptive can be treated as an ideal gas mixture.
+  </li>
+  <li>
+  The adsorpt can be treated as an ideal solution.
+  </li>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Sircar, S. (1984). Excess Properties and Thermodynamics of Multicomponent Gas Adsorption. Journal of the Chemical Society, Faraday Transactions 1: Physical Chemistry in Condensed Phases, 81:1527-1540. DOI: https://doi.org/10.1039/F19858101527.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end h_ads_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_ternary_clausiusClapeyron.mo b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_ternary_clausiusClapeyron.mo
new file mode 100644
index 0000000..7e6dd9e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/h_ads_ternary_clausiusClapeyron.mo
@@ -0,0 +1,191 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.MultiComponents;
+function h_ads_ternary_clausiusClapeyron
+  "Molar adsorption enthalpies for a ternary mixture according to Clausius Clapeyron"
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialMulti_h_ads;
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt_
+    "Limited total pressure";
+  Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i_
+    "Limited mole fractions of independent components in the vapor or gas phase";
+
+  Real[size(M_i,1)] numerator_i
+    "Numerators of all components";
+  Real numerator_summand_1
+    "Summand 1 of the numerator for each component";
+  Real numerator_summand_2
+    "Summand 2 of the numerator for each component";
+  Real numerator_summand_3
+    "Summand 3 of the numerator for each component";
+
+  Real denominator
+    "Denominator for each component";
+
+algorithm
+  //
+  // Define initial values
+  //
+  p_adsorpt_ := max(p_adsorpt, p_threshold_min)
+    "Limited total pressure";
+  for ind in 1:size(M_i,1)-1 loop
+    y_i_[ind] := max(y_i[ind], y_i_threshold_min)
+      "Limited mole fractions of independent components in the vapor or gas phase";
+  end for;
+
+  //
+  // Set up numerators
+  //
+  numerator_summand_1 := dx_adsorpt_dT[1] *
+    (dx_adsorpt_dy_i[2,1] * dx_adsorpt_dy_i[3,2] -
+     dx_adsorpt_dy_i[3,1] * dx_adsorpt_dy_i[2,2]) - dx_adsorpt_dy_i[1,1] *
+    (dx_adsorpt_dT[2] * dx_adsorpt_dy_i[3,2] -
+     dx_adsorpt_dT[3] * dx_adsorpt_dy_i[2,2]) + dx_adsorpt_dy_i[1,2] *
+    (dx_adsorpt_dT[2] * dx_adsorpt_dy_i[3,1] -
+     dx_adsorpt_dT[3] * dx_adsorpt_dy_i[2,1])
+    "Summand 1 of the numerator for each component";
+  numerator_summand_2 :=dx_adsorpt_dp[1] *
+    (dx_adsorpt_dT[2] * dx_adsorpt_dy_i[3,2] -
+     dx_adsorpt_dT[3] * dx_adsorpt_dy_i[2,2]) - dx_adsorpt_dT[1] *
+    (dx_adsorpt_dp[2] * dx_adsorpt_dy_i[3,2] -
+     dx_adsorpt_dp[3] * dx_adsorpt_dy_i[2,2]) + dx_adsorpt_dy_i[1,2] *
+    (dx_adsorpt_dp[2] * dx_adsorpt_dT[3] -
+     dx_adsorpt_dp[3] * dx_adsorpt_dT[2])
+    "Summand 2 of the numerator for each component";
+  numerator_summand_3 :=dx_adsorpt_dp[1] *
+    (dx_adsorpt_dT[2] * dx_adsorpt_dy_i[3,1] -
+     dx_adsorpt_dT[3] * dx_adsorpt_dy_i[2,1]) - dx_adsorpt_dT[1] *
+    (dx_adsorpt_dp[2] * dx_adsorpt_dy_i[3,1] -
+     dx_adsorpt_dp[3] * dx_adsorpt_dy_i[2,1]) + dx_adsorpt_dy_i[1,1] *
+    (dx_adsorpt_dp[2] * dx_adsorpt_dT[3] -
+     dx_adsorpt_dp[3] * dx_adsorpt_dT[2])
+    "Summand 3 of the numerator for each component";
+
+  numerator_i[1] :=
+    1 / (p_adsorpt_ * M_i[1] *  M_i[2] *  M_i[3]) * numerator_summand_1 +
+    1 / (y_i_[1] * M_i[1] *  M_i[2] *  M_i[3]) * numerator_summand_2
+    "Numerator of first component";
+  numerator_i[2] :=
+    1 / (p_adsorpt_ * M_i[1] *  M_i[2] *  M_i[3]) * numerator_summand_1 -
+    1 / (y_i_[2] * M_i[1] *  M_i[2] *  M_i[3]) * numerator_summand_3
+    "Numerator of second component";
+  numerator_i[3] :=
+    1 / (p_adsorpt_ * M_i[1] *  M_i[2] *  M_i[3]) * numerator_summand_1 +
+    1 / (-(1 - sum(y_i_)) * M_i[1] *  M_i[2] *  M_i[3]) * numerator_summand_2 -
+    1 / (-(1 - sum(y_i_)) * M_i[1] *  M_i[2] *  M_i[3]) * numerator_summand_3
+    "Numerator of third component";
+
+  //
+  // Set up denominator
+  //
+  denominator := -1 / (M_i[1] *  M_i[2] *  M_i[3]) * (dx_adsorpt_dp[1] *
+     (dx_adsorpt_dy_i[2,1] * dx_adsorpt_dy_i[3,2] -
+      dx_adsorpt_dy_i[3,1] * dx_adsorpt_dy_i[2,2]) - dx_adsorpt_dy_i[1,1] *
+     (dx_adsorpt_dp[2] * dx_adsorpt_dy_i[3,2] -
+      dx_adsorpt_dp[3] * dx_adsorpt_dy_i[2,2]) + dx_adsorpt_dy_i[1,2] *
+     (dx_adsorpt_dp[2] * dx_adsorpt_dy_i[3,1] -
+      dx_adsorpt_dp[3] * dx_adsorpt_dy_i[2,1]))
+    "Denominator for each components";
+
+  //
+  // Calculate adsorption enthalpies
+  //
+  if p_adsorpt < p_threshold_min then
+    //
+    // Vacuum
+    //
+    h_ads := fill(100*Modelica.Constants.eps, size(M_i,1))
+      "Molar adsorption enthalpy";
+
+  else
+    //
+    // No vacuum
+    //
+    if y_i[1] > y_i_threshold_min then
+      h_ads[1] := Modelica.Constants.R * T_adsorpt^2 *
+        numerator_i[1] / denominator
+        "Molar adsorption enthalpy of first component";
+    else
+      h_ads[1] := 100*Modelica.Constants.eps
+        "Molar adsorption enthalpy of first component";
+    end if;
+
+    if y_i[2] > y_i_threshold_min then
+      h_ads[2] := Modelica.Constants.R * T_adsorpt^2 *
+        numerator_i[2] / denominator
+        "Molar adsorption enthalpy of first component";
+    else
+      h_ads[2] := 100*Modelica.Constants.eps
+        "Molar adsorption enthalpy of second component";
+    end if;
+
+    if 1-y_i[1]-y_i[2] > y_i_threshold_min then
+      h_ads[3] := Modelica.Constants.R * T_adsorpt^2 *
+        numerator_i[3] / denominator
+        "Molar adsorption enthalpy of third component";
+    else
+      h_ads[3] := 100*Modelica.Constants.eps
+        "Molar adsorption enthalpy of third component";
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the molar adsorption enthalpies for ternary mixtures according 
+to Clausius Clapeyron assumptions.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads,i</sub></i> of component <i>i</i>
+is defined as follows:
+</p>
+<pre>
+    &Delta;h<sub>ads,<i>i</i></sub> = R * T<sup>2</sup> * [&part;(<strong>ln</strong>(y<sub><i>i</i></sub> * p), x<sub>1</sub>, ..., x<sub>N</sub>) / &part;(p, T, y<sub>1</sub>, ..., y<sub>N-1</sub>)] / [&part;(T, x<sub>1</sub>, ..., x<sub>N</sub>) / &part;(p, T, y<sub>1</sub>, ..., y<sub>N-1</sub>)];
+</pre>
+<p>
+Herein, <i>R</i> is the ideal gas constant, <i>p</i> is the pressure, <i>T</i> is
+the temperature, <i>x<sub>i</sub></i> are the uptakes, and <i>y<sub>i</sub></i>
+are the independent mole fractions in the adsorptive phase.
+<br><br>
+The determinants in the numerator and denominator have already been solved.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The specific volume of the adsorpt phase can be neglected compared to the specific
+  volume of the adsorptive phase.
+  </li>
+  <li>
+  The adsorptive can be treated as an ideal gas mixture.
+  </li>
+  <li>
+  The adsorpt can be treated as an ideal solution.
+  </li>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Sircar, S. (1984). Excess Properties and Thermodynamics of Multicomponent Gas Adsorption. Journal of the Chemical Society, Faraday Transactions 1: Physical Chemistry in Condensed Phases, 81:1527-1540. DOI: https://doi.org/10.1039/F19858101527.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end h_ads_ternary_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/package.mo b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/package.mo
new file mode 100644
index 0000000..856655e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/package.mo
@@ -0,0 +1,28 @@
+within SorpLib.Media.Functions.SorptionEnthalpies;
+package MultiComponents "Functions required to calculate sorption enthalpies for multi components"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models to calculate sorption enthalpies for pure component 
+adsorption.
+</p>
+
+<h4>Implemented functions for each sorption enthalpy model</h4>
+<p>
+The following functions are provided for each sorption enthalpy model:
+</p>
+<ul>
+  <li>
+  Sorption enthalpy.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end MultiComponents;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/package.order b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/package.order
new file mode 100644
index 0000000..41622bd
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/MultiComponents/package.order
@@ -0,0 +1,4 @@
+h_ads_clausiusClapeyron
+h_ads_binary_clausiusClapeyron
+h_ads_ternary_clausiusClapeyron
+Testers
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads.mo
new file mode 100644
index 0000000..976e199
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads.mo
@@ -0,0 +1,505 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.Testers;
+model Test_h_ads
+  "Tester for the function 'h_ads' and all corresponding functions"
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialTestPure(
+    final no_coefficients = 6,
+    final dp = 1e-2,
+    final dT = 1e-2,
+    final dx = 1e-4);
+
+  //
+  // Definition of variables
+  //
+protected
+  Medium.ThermodynamicState state_adsorptive_pT_pdT_x
+    "State properties of adsorptive at p_adsorpt(x_adsorpt,T_adsorpt+dT) and 
+    T_adsorpt + dT";
+  Medium.ThermodynamicState state_adsorptive_pT_mdT_x
+    "State properties of adsorptive at p_adsorpt(x_adsorpt,T_adsorpt-dT) and 
+    T_adsorpt - dT";
+  Medium.ThermodynamicState state_adsorptive_pT_pdx
+    "State properties of adsorptive at p_adsorpt(x_adsorpt+dx,T_adsorpt) and T_adsorpt";
+  Medium.ThermodynamicState state_adsorptive_pT_mdx
+    "State properties of adsorptive at p_adsorpt(x_adsorpt-dx,T_adsorpt) and T_adsorpt";
+
+  Medium.ThermodynamicState state_bubble_T_pdT
+    "State properties of bubble point at T_adsorpt: T + dT";
+  Medium.ThermodynamicState state_bubble_T_mdT
+    "State properties of bubble point at T_adsorpt: T - dT";
+
+  Modelica.Units.SI.Pressure p_adsorpt_pdT_x
+    "Pressure at x_adsorpt and T_adsorpt + dT";
+  Modelica.Units.SI.Pressure p_adsorpt_mdT_x
+    "Pressure at x_adsorpt and T_adsorpt - dT";
+
+  Modelica.Units.SI.Pressure p_adsorpt_pdx_T
+    "Pressure at T_adsorpt and x_adsorpt + xT";
+  Modelica.Units.SI.Pressure p_adsorpt_mdx_T
+    "Pressure at T_adsorpt and x_adsorpt - xT";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_pdT_p
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T + dT";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_mdT_p
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T - dT";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_pdp_T
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: p + dp";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_mdp_T
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: p - dp";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_pdT_x
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x_adsorpt
+    and T + dT";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_mdT_x
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x_adsorpt
+    and T - dT";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_pdx_T
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x + dx";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_mdx_T
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x - dx";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_pdT_p
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T + dT";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_mdT_p
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T - dT";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_pdp_T
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: p + dp";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_mdp_T
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: p - dp";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_pdT_x
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x_adsorpt
+    and T + dT";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_mdT_x
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x_adsorpt
+    and T - dT";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_pdx_T
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x + dx";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_mdx_T
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x - dx";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 0.75 * dc_dT[1]
+    "Predecsriped slope of p_adsorpt";
+  der(T_adsorpt) = 90/20
+    "Predecsriped slope of T_adsorpt";
+
+  //
+  // Calculate coefficients of the isotherm model
+  //
+  c[1] = state_bubble_T.p;
+  c[2] = state_bubble_T.d;
+  c[3] = 5.072313e-1 / 1000;
+  c[4] = 1.305531e2 * 1000 * 0.018;
+  c[5] = -8.492403e1 * 1000 * 0.018;
+  c[6] = 4.128962e-3 / 1000;
+
+  c_pdT[1] = sat_T_pdT.psat;
+  c_pdT[2] = Medium.bubbleDensity(sat=sat_T_pdT);
+  c_pdT[3] = 5.072313e-1 / 1000;
+  c_pdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_pdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_pdT[6] = 4.128962e-3 / 1000;
+
+  c_mdT[1] = sat_T_mdT.psat;
+  c_mdT[2] = Medium.bubbleDensity(sat=sat_T_mdT);
+  c_mdT[3] = 5.072313e-1 / 1000;
+  c_mdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_mdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_mdT[6] = 4.128962e-3 / 1000;
+
+  //
+  // Calculate partial derivatives of coefficients of the isotherm model w.r.t.
+  // temperature
+  //
+  dc_dT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T);
+  dc_dT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T) * dc_dT[1];
+  dc_dT[3] = 0;
+  dc_dT[4] = 0;
+  dc_dT[5] = 0;
+  dc_dT[6] = 0;
+
+  dc_dT_pdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_pdT);
+  dc_dT_pdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_pdT) * dc_dT_pdT[1];
+  dc_dT_pdT[3] = 0;
+  dc_dT_pdT[4] = 0;
+  dc_dT_pdT[5] = 0;
+  dc_dT_pdT[6] = 0;
+
+  dc_dT_mdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_mdT);
+  dc_dT_mdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_mdT) * dc_dT_mdT[1];
+  dc_dT_mdT[3] = 0;
+  dc_dT_mdT[4] = 0;
+  dc_dT_mdT[5] = 0;
+  dc_dT_mdT[6] = 0;
+
+  //
+  // Calculate second-order partial derivatives of coefficients of the isotherm
+  // model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (dc_dT_pdT[1] - dc_dT_mdT[1]) / (2*dT);
+  ddc_dT_dT[2] = (dc_dT_pdT[2] - dc_dT_mdT[2]) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Calculation of state properties
+  //
+  state_adsorptive_pT_pdT_x = Medium.setState_pTX(
+    p=p_adsorpt_pdT_x,
+    T=T_adsorpt+dT)
+    "State properties of adsorptive at p_adsorpt(x_adsorpt,T_adsorpt+dT) and 
+    T_adsorpt + dT";
+  state_adsorptive_pT_mdT_x = Medium.setState_pTX(
+    p=p_adsorpt_mdT_x,
+    T=T_adsorpt-dT)
+    "State properties of adsorptive at p_adsorpt(x_adsorpt,T_adsorpt-dT) and 
+    T_adsorpt - dT";
+
+  state_adsorptive_pT_pdx = Medium.setState_pTX(
+    p=p_adsorpt_pdx_T,
+    T=T_adsorpt)
+    "State properties of adsorptive at p_adsorpt(x_adsorpt+dx,T_adsorpt) and T_adsorpt";
+  state_adsorptive_pT_mdx = Medium.setState_pTX(
+    p=p_adsorpt_mdx_T,
+    T=T_adsorpt)
+    "State properties of adsorptive at p_adsorpt(x_adsorpt-dx,T_adsorpt) and T_adsorpt";
+
+  state_bubble_T_pdT = Medium.setBubbleState(sat=sat_T_pdT)
+    "State properties of bubble point at T_adsorpt: T + dT";
+  state_bubble_T_mdT = Medium.setBubbleState(sat=sat_T_mdT)
+    "State properties of bubble point at T_adsorpt: T - dT";
+
+  //
+  // Calculate properties
+  //
+  x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake";
+
+  dx_adsorpt_dp = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dT_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT,
+    ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  h_ads = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar adsorption enthalpy";
+
+  dh_ads_dp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dv_adsorptive_dp=(1/state_adsorptive_pT_pdp.d - 1/state_adsorptive_pT_mdp.d) /
+      (2*dp),
+    dv_adsorpt_dp=0,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+    ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at
+    constant temperature";
+  dh_ads_dT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dv_adsorptive_dT=(1/state_adsorptive_pT_pdT.d - 1/state_adsorptive_pT_mdT.d) /
+      (2*dT),
+    dv_adsorpt_dT=-1/state_bubble_T.d^2 * dc_dT[2],
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT,
+    ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant pressure";
+
+  //
+  // Calculate pressures for numerical derivatives
+  //
+  p_adsorpt_pdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt and T_adsorpt + dT";
+  p_adsorpt_mdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt and T_adsorpt - dT";
+
+  p_adsorpt_pdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt+dx,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at T_adsorpt and x_adsorpt + dx";
+  p_adsorpt_mdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt-dx,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at T_adsorpt and x_adsorpt - dx";
+
+  //
+  // Calculate partial derivatives of uptake w.r.t. pressure at constant temperature
+  // for numerical derivatives
+  //
+  dx_adsorpt_dp_pdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt+dp,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: p + dp";
+  dx_adsorpt_dp_mdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt-dp,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: p - dp";
+
+  dx_adsorpt_dp_pdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T + dT";
+  dx_adsorpt_dp_mdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T - dT";
+
+  dx_adsorpt_dp_pdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt_pdT_x,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x_adsorpt 
+    and T + dT";
+  dx_adsorpt_dp_mdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt_mdT_x,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x_adsorpt 
+    and T - dT";
+
+  dx_adsorpt_dp_pdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt_pdx_T,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T_adsorpt 
+    and x + dx";
+  dx_adsorpt_dp_mdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt_mdx_T,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T_adsorpt 
+    and x - dx";
+
+  //
+  // Calculate partial derivatives of uptake w.r.t. temperature at constant pressure
+  // for numerical derivatives
+  //
+  dx_adsorpt_dT_pdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt+dp,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: p + dp";
+  dx_adsorpt_dT_mdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt-dp,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: p - dp";
+
+  dx_adsorpt_dT_pdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT,
+    dc_dT_adsorpt=dc_dT_pdT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T + dT";
+  dx_adsorpt_dT_mdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT,
+    dc_dT_adsorpt=dc_dT_mdT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T - dT";
+
+  dx_adsorpt_dT_pdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt_pdT_x,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT,
+    dc_dT_adsorpt=dc_dT_pdT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x_adsorpt
+    and T + dT";
+  dx_adsorpt_dT_mdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt_mdT_x,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT,
+    dc_dT_adsorpt=dc_dT_mdT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x_adsorpt
+    and T - dT";
+
+  dx_adsorpt_dT_pdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt_pdx_T,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T_adsorpt
+    and x + dx";
+  dx_adsorpt_dT_mdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt_mdx_T,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T_adsorpt
+    and x - dx";
+
+  //
+  // Calculate molar adsorption potentials for numerical derivatives
+  //
+  h_ads_pdp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT_pdp.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dx_adsorpt_dp=dx_adsorpt_dp_pdp_T,
+    dx_adsorpt_dT=dx_adsorpt_dT_pdp_T)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: p + dp";
+  h_ads_mdp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT_mdp.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dx_adsorpt_dp=dx_adsorpt_dp_mdp_T,
+    dx_adsorpt_dT=dx_adsorpt_dT_mdp_T)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: p - dp";
+
+  h_ads_pdT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt+dT,
+    v_adsorptive=1/state_adsorptive_pT_pdT.d,
+    v_adsorpt=1/state_bubble_T_pdT.d,
+    dx_adsorpt_dp=dx_adsorpt_dp_pdT_p,
+    dx_adsorpt_dT=dx_adsorpt_dT_pdT_p)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: T + dT";
+  h_ads_mdT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt-dT,
+    v_adsorptive=1/state_adsorptive_pT_mdT.d,
+    v_adsorpt=1/state_bubble_T_mdT.d,
+    dx_adsorpt_dp=dx_adsorpt_dp_mdT_p,
+    dx_adsorpt_dT=dx_adsorpt_dT_mdT_p)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: T - dT";
+
+  h_ads_pdT_x = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt+dT,
+    v_adsorptive=1/state_adsorptive_pT_pdT_x.d,
+    v_adsorpt=1/state_bubble_T_pdT.d,
+    dx_adsorpt_dp=dx_adsorpt_dp_pdT_x,
+    dx_adsorpt_dT=dx_adsorpt_dT_pdT_x)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt, T+dT) and T_adsorpt: T + dT";
+  h_ads_mdT_x = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt-dT,
+    v_adsorptive=1/state_adsorptive_pT_mdT_x.d,
+    v_adsorpt=1/state_bubble_T_mdT.d,
+    dx_adsorpt_dp=dx_adsorpt_dp_mdT_x,
+    dx_adsorpt_dT=dx_adsorpt_dT_mdT_x)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt, T-dT) and T_adsorpt: T - dT";
+
+  h_ads_pdx_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT_pdx.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dx_adsorpt_dp=dx_adsorpt_dp_pdx_T,
+    dx_adsorpt_dT=dx_adsorpt_dT_pdx_T)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt+dx) and T_adsorpt";
+  h_ads_mdx_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT_mdx.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dx_adsorpt_dp=dx_adsorpt_dp_mdx_T,
+    dx_adsorpt_dT=dx_adsorpt_dT_mdx_T)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt-dx) and T_adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'h_ads' function and its 
+partial derivative with resprect to temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>h_ads_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_h_ads;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads_Dubinin.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads_Dubinin.mo
new file mode 100644
index 0000000..77fa98a
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads_Dubinin.mo
@@ -0,0 +1,674 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.Testers;
+model Test_h_ads_Dubinin
+  "Tester for the function 'h_ads_Dubinin' and all corresponding functions"
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialTestPure(
+    final no_coefficients = 6);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+
+  Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+    "Isobaric expansion coefficient of the adsorpt phase";
+
+  SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential";
+
+protected
+  Medium.ThermodynamicState state_bubble_T_pdT
+    "State properties of bubble point at T_adsorpt: T + dT";
+  Medium.ThermodynamicState state_bubble_T_mdT
+    "State properties of bubble point at T_adsorpt: T - dT";
+
+  SorpLib.Units.Uptake x_adsorpt_pdp_T
+    "Uptake: T_adsorpt and p + dp";
+  SorpLib.Units.Uptake x_adsorpt_mdp_T
+    "Uptake: T_adsorpt and p - dp";
+  SorpLib.Units.Uptake x_adsorpt_pdT_p
+    "Uptake: p_adsorpt and T + dT";
+  SorpLib.Units.Uptake x_adsorpt_mdT_p
+    "Uptake: p_adsorpt and T - dT";
+
+  Modelica.Units.SI.Pressure p_adsorpt_pdT_x
+    "Pressure at x_adsorpt and T_adsorpt + dT";
+  Modelica.Units.SI.Pressure p_adsorpt_mdT_x
+    "Pressure at x_adsorpt and T_adsorpt - dT";
+  Modelica.Units.SI.Pressure p_adsorpt_pdx_T
+    "Pressure at T_adsorpt and x_adsorpt + xT";
+  Modelica.Units.SI.Pressure p_adsorpt_mdx_T
+    "Pressure at T_adsorpt and x_adsorpt - xT";
+
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid_pdp
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): p + dp";
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid_mdp
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): p - dp";
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid_pdT
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): T + dT";
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid_mdT
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): T - dT";
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid_pdT_x
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): x_adsorpt and T + dT";
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid_mdT_x
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): x_adsorpt and T - dT";
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid_pdx_T
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): x_adsorpt + dx and T";
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid_mdx_T
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): x_adsorpt - dx and T";
+
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+  SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_adsorpt_dT
+    "Partial derivative of isobaric expansion coefficient of the adsorpt phase
+    w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.MolarAdsorptionPotential A_pdp_T
+    "Molar adsorption potential: T_adsorpt p + dp";
+  SorpLib.Units.MolarAdsorptionPotential A_mdp_T
+    "Molar adsorption potential: T_adsorpt and p - dp";
+  SorpLib.Units.MolarAdsorptionPotential A_pdT_p
+    "Molar adsorption potential: p_adsorpt and T + dT";
+  SorpLib.Units.MolarAdsorptionPotential A_mdT_p
+    "Molar adsorption potential: p_adsorpt and T - dT";
+  SorpLib.Units.MolarAdsorptionPotential A_pdT_x
+    "Molar adsorption potential: x_adsorpt and T + dT";
+  SorpLib.Units.MolarAdsorptionPotential A_mdT_x
+    "Molar adsorption potential: x_adsorpt and T - dT";
+  SorpLib.Units.MolarAdsorptionPotential A_pdx_T
+    "Molar adsorption potential: T_adsorpt and x + dx";
+  SorpLib.Units.MolarAdsorptionPotential A_mdx_T
+    "Molar adsorption potential: T_adsorpt and x - dx";
+
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp
+    "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT
+    "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential and temperature at constant pressure";
+
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_pdp_T
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    T_adsorpt and p + dp";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_mdp_T
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    T_adsorpt and p + dp";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_pdT_p
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    p_adsorpt and T + dT";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_mdT_p
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    p_adsorpt and T - dT";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_pdT_x
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    x_adsorpt and T + dT";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_mdT_x
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    x_adsorpt and T - dT";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_pdx_T
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    T_adsorpt and x + dx";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_mdx_T
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    T_adsorpt and x + dx";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 0.75 * dc_dT[1]
+    "Predecsriped slope of p_adsorpt";
+  der(T_adsorpt) = 90/20
+    "Predecsriped slope of T_adsorpt";
+
+  //
+  // Calculate coefficients of the isotherm model
+  //
+  c[1] = state_bubble_T.p;
+  c[2] = state_bubble_T.d;
+  c[3] = 5.072313e-1 / 1000;
+  c[4] = 1.305531e2 * 1000 * 0.018;
+  c[5] = -8.492403e1 * 1000 * 0.018;
+  c[6] = 4.128962e-3 / 1000;
+
+  c_pdT[1] = sat_T_pdT.psat;
+  c_pdT[2] = Medium.bubbleDensity(sat=sat_T_pdT);
+  c_pdT[3] = 5.072313e-1 / 1000;
+  c_pdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_pdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_pdT[6] = 4.128962e-3 / 1000;
+
+  c_mdT[1] = sat_T_mdT.psat;
+  c_mdT[2] = Medium.bubbleDensity(sat=sat_T_mdT);
+  c_mdT[3] = 5.072313e-1 / 1000;
+  c_mdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_mdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_mdT[6] = 4.128962e-3 / 1000;
+
+  //
+  // Calculate partial derivatives of coefficients of the isotherm model w.r.t.
+  // temperature
+  //
+  dc_dT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T);
+  dc_dT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T) * dc_dT[1];
+  dc_dT[3] = 0;
+  dc_dT[4] = 0;
+  dc_dT[5] = 0;
+  dc_dT[6] = 0;
+
+  dc_dT_pdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_pdT);
+  dc_dT_pdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_pdT) * dc_dT_pdT[1];
+  dc_dT_pdT[3] = 0;
+  dc_dT_pdT[4] = 0;
+  dc_dT_pdT[5] = 0;
+  dc_dT_pdT[6] = 0;
+
+  dc_dT_mdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_mdT);
+  dc_dT_mdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_mdT) * dc_dT_mdT[1];
+  dc_dT_mdT[3] = 0;
+  dc_dT_mdT[4] = 0;
+  dc_dT_mdT[5] = 0;
+  dc_dT_mdT[6] = 0;
+
+  //
+  // Calculate second-order partial derivatives of coefficients of the isotherm
+  // model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (dc_dT_pdT[1] - dc_dT_mdT[1]) / (2*dT);
+  ddc_dT_dT[2] = (dc_dT_pdT[2] - dc_dT_mdT[2]) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Calculation of state properties
+  //
+  state_bubble_T_pdT = Medium.setBubbleState(sat=sat_T_pdT)
+    "State properties of bubble point at T_adsorpt: T + dT";
+  state_bubble_T_mdT = Medium.setBubbleState(sat=sat_T_mdT)
+    "State properties of bubble point at T_adsorpt: T - dT";
+
+  //
+  // Calculate properties
+  //
+  x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake";
+
+  dx_adsorpt_dp = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dT_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT,
+    ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  h_adsorptiveToLiquid = state_adsorptive_pT.h - state_bubble_T.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+  dh_adsorptiveToLiquid_dp = 1/state_adsorptive_pT.d * (1 - T_adsorpt *
+    Medium.isobaricExpansionCoefficient(state=state_adsorptive_pT)) - 0
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+  dh_adsorptiveToLiquid_dT =
+    Medium.specificHeatCapacityCp(state=state_adsorptive_pT) -
+    Medium.specificHeatCapacityCp(state=state_bubble_T)
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+  beta_adsorpt = Medium.isobaricExpansionCoefficient(state=state_bubble_T)
+    "Isobaric expansion coefficient of the adsorpt phase";
+  dbeta_adsorpt_dT =
+    (Medium.isobaricExpansionCoefficient(state=state_bubble_T_pdT) -
+     Medium.isobaricExpansionCoefficient(state=state_bubble_T_mdT)) /(2*dT)
+    "Partial derivative of the ssobaric expansion coefficient of the adsorpt phase
+    w.r.t. temperature at constant pressure";
+
+  A =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Molar adsorption potential";
+  dA_dp =SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+    p_adsorpt=p_adsorpt,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+  dA_dT =SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+    p_adsorpt=p_adsorpt,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt,
+    dp_sat_dT_adsorpt=dc_dT[1])
+    "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+  dW_dA = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A,
+    c=c)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  ddW_dA_dA = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dA(
+    A=A,
+    c=c)
+    "Second-order prtial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  ddW_dA_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    A=A,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    and temperature at constant pressure";
+
+  h_ads = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+    v_adsorpt=1/state_bubble_T.d,
+    beta_adsorpt=beta_adsorpt,
+    A=A,
+    dW_dA=dW_dA)
+    "Molar adsorption enthalpy";
+
+  dh_ads_dp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+    dh_adsorptiveToLiquid_dp=dh_adsorptiveToLiquid_dp,
+    v_adsorpt=1/state_bubble_T.d,
+    dv_adsorpt_dp=0,
+    beta_adsorpt=beta_adsorpt,
+    dbeta_adsorpt_dp=0,
+    dA_dp=dA_dp,
+    dW_dA=dW_dA,
+    ddW_dA_dA=ddW_dA_dA)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at
+    constant temperature";
+  dh_ads_dT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+    dh_adsorptiveToLiquid_dT=dh_adsorptiveToLiquid_dT,
+    v_adsorpt=1/state_bubble_T.d,
+    dv_adsorpt_dT=-1/state_bubble_T.d^2 * dc_dT[2],
+    beta_adsorpt=beta_adsorpt,
+    dbeta_adsorpt_dT=dbeta_adsorpt_dT,
+    dA_dT=dA_dT,
+    dW_dA=dW_dA,
+    ddW_dA_dT=ddW_dA_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant pressure";
+
+  //
+  // Calculate loadings for numerical derivatives
+  //
+  x_adsorpt_pdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(
+    p_adsorpt=p_adsorpt+dp,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake: T_adsorpt and p + dp";
+  x_adsorpt_mdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(
+    p_adsorpt=p_adsorpt-dp,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake: p_adsorpt and p - dp";
+
+  x_adsorpt_pdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake: p_adsorpt and T + dT";
+  x_adsorpt_mdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake: p_adsorpt and T - dT";
+
+  //
+  // Calculate pressures for numerical derivatives
+  //
+  p_adsorpt_pdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt and T_adsorpt + dT";
+  p_adsorpt_mdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt and T_adsorpt - dT";
+
+  p_adsorpt_pdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt+dx,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at T_adsorpt and x_adsorpt + dx";
+  p_adsorpt_mdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt-dx,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at T_adsorpt and x_adsorpt - dx";
+
+  //
+  // Calculate further properties for numerical derivatives
+  //
+  h_adsorptiveToLiquid_pdp = state_adsorptive_pT_pdp.h - state_bubble_T.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): p + dp";
+  h_adsorptiveToLiquid_mdp = state_adsorptive_pT_mdp.h - state_bubble_T.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): p - dp";
+
+  h_adsorptiveToLiquid_pdT = state_adsorptive_pT_pdT.h - state_bubble_T_pdT.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): T + dT";
+  h_adsorptiveToLiquid_mdT = state_adsorptive_pT_mdT.h - state_bubble_T_mdT.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): T - dT";
+
+  h_adsorptiveToLiquid_pdT_x = Medium.specificEnthalpy_pT(
+     p=p_adsorpt_pdT_x, T=T_adsorpt+dT) - state_bubble_T_pdT.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): x_adsorpt and T + dT";
+  h_adsorptiveToLiquid_mdT_x = Medium.specificEnthalpy_pT(
+     p=p_adsorpt_mdT_x, T=T_adsorpt-dT) - state_bubble_T_mdT.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): x_adsorpt and T - dT";
+
+  h_adsorptiveToLiquid_pdx_T = Medium.specificEnthalpy_pT(
+     p=p_adsorpt_pdx_T, T=T_adsorpt) - state_bubble_T.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): x_adsorpt + dx and T";
+  h_adsorptiveToLiquid_mdx_T = Medium.specificEnthalpy_pT(
+     p=p_adsorpt_mdx_T, T=T_adsorpt) - state_bubble_T.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point): x_adsorpt - dx and T";
+
+
+  A_pdp_T =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt+dp,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Molar adsorption potential: T_adsorpt p + dp";
+  A_mdp_T =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt-dp,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Molar adsorption potential: T_adsorpt and p - dp";
+
+  A_pdT_p =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt,
+    p_sat=c_pdT[1],
+    T_adsorpt=T_adsorpt+dT)
+    "Molar adsorption potential: p_adsorpt and T + dT";
+  A_mdT_p =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt,
+    p_sat=c_mdT[1],
+    T_adsorpt=T_adsorpt-dT)
+    "Molar adsorption potential: p_adsorpt and T - dT";
+
+  A_pdT_x =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt_pdT_x,
+    p_sat=c_pdT[1],
+    T_adsorpt=T_adsorpt+dT)
+    "Molar adsorption potential: x_adsorpt and T + dT";
+  A_mdT_x =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt_mdT_x,
+    p_sat=c_mdT[1],
+    T_adsorpt=T_adsorpt-dT)
+    "Molar adsorption potential: x_adsorpt and T - dT";
+
+  A_pdx_T =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt_pdx_T,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Molar adsorption potential: T_adsorpt and x + dx";
+  A_mdx_T =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt_mdx_T,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Molar adsorption potential: T_adsorpt and x - dx";
+
+  dW_dA_pdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A_pdp_T,
+    c=c)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    T_adsorpt and p + dp";
+  dW_dA_mdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A_mdp_T,
+    c=c)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    T_adsorpt and p + dp";
+
+  dW_dA_pdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A_pdT_p,
+    c=c_pdT)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    p_adsorpt and T + dT";
+  dW_dA_mdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A_mdT_p,
+    c=c_mdT)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    p_adsorpt and T + dT";
+
+  dW_dA_pdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A_pdT_x,
+    c=c_pdT)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    x_adsorpt and T + dT";
+  dW_dA_mdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A_mdT_x,
+    c=c_mdT)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    x_adsorpt and T + dT";
+
+  dW_dA_pdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A_pdx_T,
+    c=c)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    T_adsorpt and x + dx";
+  dW_dA_mdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A_mdx_T,
+    c=c)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential: 
+    T_adsorpt and x + dx";
+
+  //
+  // Calculate molar adsorption potentials for numerical derivatives
+  //
+  h_ads_pdp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt_pdp_T,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid_pdp,
+    v_adsorpt=1/state_bubble_T.d,
+    beta_adsorpt=Medium.isobaricExpansionCoefficient(state=state_bubble_T),
+    A=A_pdp_T,
+    dW_dA=dW_dA_pdp_T)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: p + dp";
+  h_ads_mdp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt_mdp_T,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid_mdp,
+    v_adsorpt=1/state_bubble_T.d,
+    beta_adsorpt=Medium.isobaricExpansionCoefficient(state=state_bubble_T),
+    A=A_mdp_T,
+    dW_dA=dW_dA_mdp_T)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: p - dp";
+
+  h_ads_pdT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt+dT,
+    x_adsorpt=x_adsorpt_pdT_p,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid_pdT,
+    v_adsorpt=1/state_bubble_T_pdT.d,
+    beta_adsorpt=Medium.isobaricExpansionCoefficient(state=state_bubble_T_pdT),
+    A=A_pdT_p,
+    dW_dA=dW_dA_pdT_p)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: T + dT";
+  h_ads_mdT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt-dT,
+    x_adsorpt=x_adsorpt_mdT_p,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid_mdT,
+    v_adsorpt=1/state_bubble_T_mdT.d,
+    beta_adsorpt=Medium.isobaricExpansionCoefficient(state=state_bubble_T_mdT),
+    A=A_mdT_p,
+    dW_dA=dW_dA_mdT_p)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: T - dT";
+
+  h_ads_pdT_x = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt+dT,
+    x_adsorpt=x_adsorpt,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid_pdT_x,
+    v_adsorpt=1/state_bubble_T_pdT.d,
+    beta_adsorpt=Medium.isobaricExpansionCoefficient(state=state_bubble_T_pdT),
+    A=A_pdT_x,
+    dW_dA=dW_dA_pdT_x)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt, T+dT) and T_adsorpt: T + dT";
+  h_ads_mdT_x = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt-dT,
+    x_adsorpt=x_adsorpt,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid_mdT_x,
+    v_adsorpt=1/state_bubble_T_mdT.d,
+    beta_adsorpt=Medium.isobaricExpansionCoefficient(state=state_bubble_T_mdT),
+    A=A_mdT_x,
+    dW_dA=dW_dA_mdT_x)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt, T-dT) and T_adsorpt: T - dT";
+
+  h_ads_pdx_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt+dx,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid_pdx_T,
+    v_adsorpt=1/state_bubble_T.d,
+    beta_adsorpt=Medium.isobaricExpansionCoefficient(state=state_bubble_T),
+    A=A_pdx_T,
+    dW_dA=dW_dA_pdx_T)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt+dx) and T_adsorpt";
+  h_ads_mdx_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt-dx,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid_mdx_T,
+    v_adsorpt=1/state_bubble_T.d,
+    beta_adsorpt=Medium.isobaricExpansionCoefficient(state=state_bubble_T),
+    A=A_mdx_T,
+    dW_dA=dW_dA_mdx_T)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt-dx) and T_adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'h_ads_Dubinin' function and its 
+partial derivative with resprect to temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>h_ads_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_h_ads_Dubinin;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads_clausiusClapeyron.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads_clausiusClapeyron.mo
new file mode 100644
index 0000000..374443f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/Test_h_ads_clausiusClapeyron.mo
@@ -0,0 +1,430 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.Testers;
+model Test_h_ads_clausiusClapeyron
+  "Tester for the function 'h_ads_clausiusClapeyron' and all corresponding functions"
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialTestPure(
+    final no_coefficients = 6);
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt_pdT_x
+    "Pressure at x_adsorpt and T_adsorpt + dT";
+  Modelica.Units.SI.Pressure p_adsorpt_mdT_x
+    "Pressure at x_adsorpt and T_adsorpt - dT";
+
+  Modelica.Units.SI.Pressure p_adsorpt_pdx_T
+    "Pressure at T_adsorpt and x_adsorpt + xT";
+  Modelica.Units.SI.Pressure p_adsorpt_mdx_T
+    "Pressure at T_adsorpt and x_adsorpt - xT";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_pdT_p
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T + dT";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_mdT_p
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T - dT";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_pdp_T
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: p + dp";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_mdp_T
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: p - dp";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_pdT_x
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x_adsorpt
+    and T + dT";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_mdT_x
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x_adsorpt
+    and T - dT";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_pdx_T
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x + dx";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_mdx_T
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x - dx";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_pdT_p
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T + dT";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_mdT_p
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T - dT";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_pdp_T
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: p + dp";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_mdp_T
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: p - dp";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_pdT_x
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x_adsorpt
+    and T + dT";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_mdT_x
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x_adsorpt
+    and T - dT";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_pdx_T
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x + dx";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_mdx_T
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x - dx";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 0.75 * dc_dT[1]
+    "Predecsriped slope of p_adsorpt";
+  der(T_adsorpt) = 90/20
+    "Predecsriped slope of T_adsorpt";
+
+  //
+  // Calculate coefficients of the isotherm model
+  //
+  c[1] = state_bubble_T.p;
+  c[2] = state_bubble_T.d;
+  c[3] = 5.072313e-1 / 1000;
+  c[4] = 1.305531e2 * 1000 * 0.018;
+  c[5] = -8.492403e1 * 1000 * 0.018;
+  c[6] = 4.128962e-3 / 1000;
+
+  c_pdT[1] = sat_T_pdT.psat;
+  c_pdT[2] = Medium.bubbleDensity(sat=sat_T_pdT);
+  c_pdT[3] = 5.072313e-1 / 1000;
+  c_pdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_pdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_pdT[6] = 4.128962e-3 / 1000;
+
+  c_mdT[1] = sat_T_mdT.psat;
+  c_mdT[2] = Medium.bubbleDensity(sat=sat_T_mdT);
+  c_mdT[3] = 5.072313e-1 / 1000;
+  c_mdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_mdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_mdT[6] = 4.128962e-3 / 1000;
+
+  //
+  // Calculate partial derivatives of coefficients of the isotherm model w.r.t.
+  // temperature
+  //
+  dc_dT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T);
+  dc_dT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T) * dc_dT[1];
+  dc_dT[3] = 0;
+  dc_dT[4] = 0;
+  dc_dT[5] = 0;
+  dc_dT[6] = 0;
+
+  dc_dT_pdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_pdT);
+  dc_dT_pdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_pdT) * dc_dT_pdT[1];
+  dc_dT_pdT[3] = 0;
+  dc_dT_pdT[4] = 0;
+  dc_dT_pdT[5] = 0;
+  dc_dT_pdT[6] = 0;
+
+  dc_dT_mdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_mdT);
+  dc_dT_mdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_mdT) * dc_dT_mdT[1];
+  dc_dT_mdT[3] = 0;
+  dc_dT_mdT[4] = 0;
+  dc_dT_mdT[5] = 0;
+  dc_dT_mdT[6] = 0;
+
+  //
+  // Calculate second-order partial derivatives of coefficients of the isotherm
+  // model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (dc_dT_pdT[1] - dc_dT_mdT[1]) / (2*dT);
+  ddc_dT_dT[2] = (dc_dT_pdT[2] - dc_dT_mdT[2]) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Calculate properties
+  //
+  x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake";
+
+  dx_adsorpt_dp = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dT_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT,
+    ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  h_ads = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar adsorption enthalpy";
+
+  dh_ads_dp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+    ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at
+    constant temperature";
+  dh_ads_dT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+    ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant pressure";
+
+  //
+  // Calculate pressures for numerical derivatives
+  //
+  p_adsorpt_pdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt and T_adsorpt + dT";
+  p_adsorpt_mdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt and T_adsorpt - dT";
+
+  p_adsorpt_pdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt+dx,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at T_adsorpt and x_adsorpt + dx";
+  p_adsorpt_mdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(
+    x_adsorpt=x_adsorpt-dx,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Pressure at T_adsorpt and x_adsorpt - dx";
+
+  //
+  // Calculate partial derivatives of uptake w.r.t. pressure at constant temperature
+  // for numerical derivatives
+  //
+  dx_adsorpt_dp_pdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt+dp,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: p + dp";
+  dx_adsorpt_dp_mdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt-dp,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: p - dp";
+
+  dx_adsorpt_dp_pdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T + dT";
+  dx_adsorpt_dp_mdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T - dT";
+
+  dx_adsorpt_dp_pdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt_pdT_x,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x_adsorpt 
+    and T + dT";
+  dx_adsorpt_dp_mdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt_mdT_x,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: x_adsorpt 
+    and T - dT";
+
+  dx_adsorpt_dp_pdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt_pdx_T,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T_adsorpt 
+    and x + dx";
+  dx_adsorpt_dp_mdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt_mdx_T,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature: T_adsorpt 
+    and x - dx";
+
+  //
+  // Calculate partial derivatives of uptake w.r.t. temperature at constant pressure
+  // for numerical derivatives
+  //
+  dx_adsorpt_dT_pdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt+dp,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: p + dp";
+  dx_adsorpt_dT_mdp_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt-dp,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: p - dp";
+
+  dx_adsorpt_dT_pdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT,
+    dc_dT_adsorpt=dc_dT_pdT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T + dT";
+  dx_adsorpt_dT_mdT_p = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT,
+    dc_dT_adsorpt=dc_dT_mdT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T - dT";
+
+  dx_adsorpt_dT_pdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt_pdT_x,
+    T_adsorpt=T_adsorpt+dT,
+    c=c_pdT,
+    dc_dT_adsorpt=dc_dT_pdT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x_adsorpt
+    and T + dT";
+  dx_adsorpt_dT_mdT_x = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt_mdT_x,
+    T_adsorpt=T_adsorpt-dT,
+    c=c_mdT,
+    dc_dT_adsorpt=dc_dT_mdT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: x_adsorpt
+    and T - dT";
+
+  dx_adsorpt_dT_pdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt_pdx_T,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T_adsorpt
+    and x + dx";
+  dx_adsorpt_dT_mdx_T = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt_mdx_T,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure: T_adsorpt
+    and x - dx";
+
+  //
+  // Calculate molar adsorption potentials for numerical derivatives
+  //
+  h_ads_pdp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt+dp,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp_pdp_T,
+    dx_adsorpt_dT=dx_adsorpt_dT_pdp_T)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: p + dp";
+  h_ads_mdp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt-dp,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp_mdp_T,
+    dx_adsorpt_dT=dx_adsorpt_dT_mdp_T)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: p - dp";
+
+  h_ads_pdT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt+dT,
+    dx_adsorpt_dp=dx_adsorpt_dp_pdT_p,
+    dx_adsorpt_dT=dx_adsorpt_dT_pdT_p)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: T + dT";
+  h_ads_mdT_p = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt-dT,
+    dx_adsorpt_dp=dx_adsorpt_dp_mdT_p,
+    dx_adsorpt_dT=dx_adsorpt_dT_mdT_p)
+    "Molar adsorption enthalpy at p_adsorpt and T_adsorpt: T - dT";
+
+  h_ads_pdT_x = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt_pdT_x,
+    T_adsorpt=T_adsorpt+dT,
+    dx_adsorpt_dp=dx_adsorpt_dp_pdT_x,
+    dx_adsorpt_dT=dx_adsorpt_dT_pdT_x)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt, T+dT) and T_adsorpt: T + dT";
+  h_ads_mdT_x = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt_mdT_x,
+    T_adsorpt=T_adsorpt-dT,
+    dx_adsorpt_dp=dx_adsorpt_dp_mdT_x,
+    dx_adsorpt_dT=dx_adsorpt_dT_mdT_x)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt, T-dT) and T_adsorpt: T - dT";
+
+  h_ads_pdx_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt_pdx_T,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp_pdx_T,
+    dx_adsorpt_dT=dx_adsorpt_dT_pdx_T)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt+dx) and T_adsorpt";
+  h_ads_mdx_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt_mdx_T,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp_mdx_T,
+    dx_adsorpt_dT=dx_adsorpt_dT_mdx_T)
+    "Molar adsorption enthalpy at p_adsorpt(x_adsorpt-dx) and T_adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'h_ads_ClausiusClaperon' function and its 
+partial derivative with resprect to temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>h_ads_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_h_ads_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/package.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/package.mo
new file mode 100644
index 0000000..a8441be
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+package Testers "Models to test and varify functions for sorption enthalpies for pure components"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions and models of the
+'PureComponents' package. The test models check the implementation of the functions 
+and models and enable verification of their behavior. In addition, the test models 
+demonstrate the functions' and models' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/package.order b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/package.order
new file mode 100644
index 0000000..037c8ae
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/Testers/package.order
@@ -0,0 +1,3 @@
+Test_h_ads
+Test_h_ads_clausiusClapeyron
+Test_h_ads_Dubinin
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT.mo
new file mode 100644
index 0000000..f456727
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT.mo
@@ -0,0 +1,79 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function dh_ads_dT
+  "Partial derivative of molar adsorption w.r.t. temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_dh_ads_dT;
+
+  input Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorptive_dT
+    "Partial derivative of specific volume of the adsorptive w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+    "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dh_ads_dT :=
+    (M_adsorptive * (v_adsorptive - v_adsorpt) *
+      (-dx_adsorpt_dT / dx_adsorpt_dp)) +
+    (T_adsorpt * M_adsorptive *
+      (-dx_adsorpt_dT / dx_adsorpt_dp)) * dv_adsorptive_dT +
+    (-T_adsorpt * M_adsorptive *
+      (-dx_adsorpt_dT / dx_adsorpt_dp)) * dv_adsorpt_dT +
+    (T_adsorpt * M_adsorptive * (v_adsorptive - v_adsorpt) *
+      (-1 / dx_adsorpt_dp)) * ddx_adsorpt_dT_dT +
+    (T_adsorpt * M_adsorptive * (v_adsorptive - v_adsorpt) *
+      (dx_adsorpt_dT / dx_adsorpt_dp^2)) * ddx_adsorpt_dp_dT
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'h_ads' with respect to 
+the temperature at constant pressure. For full details of the original function 
+'h_ads,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dT;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT_Dubinin.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT_Dubinin.mo
new file mode 100644
index 0000000..986bfb4
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT_Dubinin.mo
@@ -0,0 +1,92 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function dh_ads_dT_Dubinin
+  "Partial derivative of molar adsorption enthalpy according to the model of Dubinin w.r.t. temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_dh_ads_dT;
+
+  input SorpLib.Units.Uptake x_adsorpt
+    "Uptake"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+    "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+    "Isobaric expansion coefficient of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_adsorpt_dT
+    "Partial derivative of isobaric expansion coefficient of the adsorpt phase
+    w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT
+    "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+    "Second-order partial derivative of filled pore volume w.r.t. molar 
+    adsorption potential and temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dh_ads_dT :=
+    (M_adsorptive) * dh_adsorptiveToLiquid_dT +
+    (1) * dA_dT +
+    (-beta_adsorpt * v_adsorpt * x_adsorpt / dW_dA) * 1 +
+    (-T_adsorpt * v_adsorpt * x_adsorpt / dW_dA) * dbeta_adsorpt_dT +
+    (-beta_adsorpt * T_adsorpt * x_adsorpt / dW_dA) * dv_adsorpt_dT +
+    (-beta_adsorpt * T_adsorpt * v_adsorpt / dW_dA) * dx_adsorpt_dT +
+    (beta_adsorpt * T_adsorpt * v_adsorpt * x_adsorpt / dW_dA^2) * ddW_dA_dT
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'h_ads_Dubinin' 
+with respect to the temperature at constant pressure. For full details 
+of the original function 'h_ads_Dubinin,' check the documentation of the 
+function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dT_Dubinin;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT_clausiusClapeyron.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT_clausiusClapeyron.mo
new file mode 100644
index 0000000..3fa57dc
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dT_clausiusClapeyron.mo
@@ -0,0 +1,59 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function dh_ads_dT_clausiusClapeyron
+  "Partial derivative of molar adsorption enthalpy according to Clausius Clapeyron w.r.t. temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_dh_ads_dT;
+
+  input SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dh_ads_dT :=
+    (2 * Modelica.Constants.R * T_adsorpt / p_adsorpt *
+      (-dx_adsorpt_dT / dx_adsorpt_dp)) +
+    (Modelica.Constants.R * T_adsorpt^2 / p_adsorpt * (-1 / dx_adsorpt_dp)) *
+      ddx_adsorpt_dT_dT +
+    (Modelica.Constants.R * T_adsorpt^2 / p_adsorpt *
+      (dx_adsorpt_dT / dx_adsorpt_dp^2)) * ddx_adsorpt_dp_dT
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'h_ads_clausiusClapeyron' 
+with respect to the temperature at constant pressure. For full details of the 
+original function 'h_ads_clausiusClapeyron,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dT_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp.mo
new file mode 100644
index 0000000..7592fbe
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp.mo
@@ -0,0 +1,77 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function dh_ads_dp
+  "Partial derivative of molar adsorption w.r.t. pressure at constant temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_dh_ads_dp;
+
+  input Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerSpecificVolumeByPressure dv_adsorptive_dp
+    "Partial derivative of specific volume of the adsorptive w.r.t. pressure
+    at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+    "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dh_ads_dp :=
+    (T_adsorpt * M_adsorptive *
+      (-dx_adsorpt_dT / dx_adsorpt_dp)) * dv_adsorptive_dp +
+    (-T_adsorpt * M_adsorptive *
+      (-dx_adsorpt_dT / dx_adsorpt_dp)) * dv_adsorpt_dp +
+    (T_adsorpt * M_adsorptive * (v_adsorptive - v_adsorpt) *
+      (-1 / dx_adsorpt_dp)) * ddx_adsorpt_dp_dT +
+    (T_adsorpt * M_adsorptive * (v_adsorptive - v_adsorpt) *
+      (dx_adsorpt_dT / dx_adsorpt_dp^2)) * ddx_adsorpt_dp_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'h_ads' with respect to 
+the pressure at constant temperature. For full details of the original function 
+'h_ads,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dp;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp_Dubinin.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp_Dubinin.mo
new file mode 100644
index 0000000..39c0173
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp_Dubinin.mo
@@ -0,0 +1,91 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function dh_ads_dp_Dubinin
+  "Partial derivative of molar adsorption enthalpy according to the model of Dubinin w.r.t. pressure at constant temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_dh_ads_dp;
+
+  input SorpLib.Units.Uptake x_adsorpt
+    "Uptake"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+    "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+    "Isobaric expansion coefficient of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerIsobaricExpansionCoefficientByPressure dbeta_adsorpt_dp
+    "Partial derivative of isobaric expansion coefficient of the adsorpt phase
+    w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp
+    "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+    "Second-order partial derivative of filled pore volume w.r.t. molar 
+    adsorption potential and temperature at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dh_ads_dp :=
+    (M_adsorptive) * dh_adsorptiveToLiquid_dp +
+    (1) * dA_dp +
+    (-T_adsorpt * v_adsorpt * x_adsorpt / dW_dA) * dbeta_adsorpt_dp +
+    (-beta_adsorpt * T_adsorpt * x_adsorpt / dW_dA) * dv_adsorpt_dp +
+    (-beta_adsorpt * T_adsorpt * v_adsorpt / dW_dA) * dx_adsorpt_dp +
+    (beta_adsorpt * T_adsorpt * v_adsorpt * x_adsorpt / dW_dA^2) * ddW_dA_dA * dA_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at
+    constant temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'h_ads_Dubinin' 
+with respect to the pressure at constant temperature. For full details 
+of the original function 'h_ads_Dubinin,' check the documentation of the 
+function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dp_Dubinin;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp_clausiusClapeyron.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp_clausiusClapeyron.mo
new file mode 100644
index 0000000..a437b9c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/dh_ads_dp_clausiusClapeyron.mo
@@ -0,0 +1,59 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function dh_ads_dp_clausiusClapeyron
+  "Partial derivative of molar adsorption enthalpy according to Clausius Clapeyron w.r.t. pressure at constant temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_dh_ads_dp;
+
+  input SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dh_ads_dp :=
+    (-Modelica.Constants.R * T_adsorpt^2 / p_adsorpt^2 *
+      (-dx_adsorpt_dT / dx_adsorpt_dp)) +
+    (Modelica.Constants.R * T_adsorpt^2 / p_adsorpt * (-1 / dx_adsorpt_dp)) *
+      ddx_adsorpt_dp_dT +
+    (Modelica.Constants.R * T_adsorpt^2 / p_adsorpt *
+      (dx_adsorpt_dT / dx_adsorpt_dp^2)) * ddx_adsorpt_dp_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at
+    constant temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'h_ads_clausiusClapeyron' 
+with respect to the pressure at constant temperature. For full details of the 
+original function 'h_ads_clausiusClapeyron,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dp_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads.mo
new file mode 100644
index 0000000..638744d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads.mo
@@ -0,0 +1,93 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function h_ads
+  "Molar adsorption enthalpy"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_h_ads;
+
+  input Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  h_ads := T_adsorpt * M_adsorptive * (v_adsorptive - v_adsorpt) *
+    (-dx_adsorpt_dT / dx_adsorpt_dp)
+    "Molar adsorption enthalpy";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the molar adsorption enthalpy.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> = T * M<sub>adsorptive</sub> * (v<sub>adsorptive</sub> - v<sub>adsorpt</sub>) (dp/dT) &asymp; T * M<sub>adsorptive</sub> * (v<sub>adsorptive</sub> - v<sub>adsorpt</sub>) * (-(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>);
+</pre>
+<p>
+Herein, <i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive, <i>T</i> 
+is the temperature, <i>v<sub>adsorptive</sub></i> ist the specific volume of the 
+adsorptive, <i>v<sub>adsorpt</sub></i> ist the specific volume of the adsorpt, 
+<i>dx/dp</i> is the partial derivative of the uptake with respect to the pressure
+at constant temperature, and <i>dx/dT</i> is the partial derivative of the uptake 
+with respect to the temperature at constant pressure.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Inert sorbent.
+  </li>
+  <li>
+  Neglecting the term <i>(&part;p/&part;x)<sub>T</sub> * (dx/dp)</i> of term 
+  <i>dp/dT = -(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub> +
+  (&part;p/&part;x)<sub>T</sub> * 
+  (dx/dp)</i>.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Chakraborty, A. and Saha, B.B. and Ng, K.C. and Koyama (2006). On the thermodynamic modeling of the isosteric heat of adsorption and comparison with experiments, Applied Physics Letters, 89:171901. DOI: http://doi.org/10.1063/1.2360925.
+  </li>
+  <li>
+  Chakraborty, A. and Saha, B.B. and Ng, K.C. and Koyama, S. and Srinivasan, K. (2009). Theoretical Insight of Physical Adsorption for a Single-Component Adsorbent + Adsorbate System: I. Thermodynamic Property Surfaces, Langmuir, 25:2204-221. DOI: http://doi.org/10.1021/la803289p.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end h_ads;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads_Dubinin.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads_Dubinin.mo
new file mode 100644
index 0000000..8afa6f7
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads_Dubinin.mo
@@ -0,0 +1,93 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function h_ads_Dubinin
+  "Molar adsorption enthalpy according to the model of Dubinin"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_h_ads;
+  input SorpLib.Units.Uptake x_adsorpt
+    "Uptake"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+    "Isobaric expansion coefficient of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  h_ads := M_adsorptive * h_adsorptiveToLiquid + A -
+    beta_adsorpt * T_adsorpt * v_adsorpt * x_adsorpt / dW_dA
+    "Molar adsorption enthalpy";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the molar adsorption enthalpy according to the model of
+Dubinin.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> = M<sub>adsorptive</sub> * &Delta;h<sub>adsorptiveToLiquid</sub> + A - &beta; * T * v<sub>adsorpt</sub> * x * 1 / (&part;W/&part;A)<sub>p,T</sub>;
+</pre>
+<p>
+Herein, <i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive, <i>T</i> 
+is the temperature, <i>x</i> is the uptake, <i>v<sub>adsorpt</sub></i> is the specific 
+volume of the adsorpt, <i>&beta;</i> is the isobaric expansion coefficient of the 
+adsorpt, <i>&Delta;h<sub>adsorptiveToLiquid</sub></i> is the specific enthalpy difference
+between adsorptive phase and saturated liquid phase (i.e., bubble point), <i>A</i> is 
+the molar adsorption potential, and <i>(&part;W/&part;A)<sub>p,T</sub></i> is the partial 
+derivative of the filled pore volume with respect to the molar adsorption potential at 
+constant pressure and temperature.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schwamberger, V. (2016). Thermodynamic and numerical investigation of a novel sorption cycle for application in adsorption heat pumps and chillers (in German), PhD thesis, Karlsruhe.
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end h_ads_Dubinin;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads_clausiusClapeyron.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads_clausiusClapeyron.mo
new file mode 100644
index 0000000..844e3ac
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/h_ads_clausiusClapeyron.mo
@@ -0,0 +1,82 @@
+within SorpLib.Media.Functions.SorptionEnthalpies.PureComponents;
+function h_ads_clausiusClapeyron
+  "Molar adsorption enthalpy according to Clausius Clapeyron"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SorptionEnthalpies.BasesClasses.PartialPure_h_ads;
+
+  input SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  h_ads := Modelica.Constants.R * T_adsorpt^2 / p_adsorpt *
+    (-dx_adsorpt_dT / dx_adsorpt_dp)
+    "Molar adsorption enthalpy";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the molar adsorption enthalpy according to Clausius
+Clapeyron assumptions.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> = R * T<sup>2</sup> / p * (&part;p/&part;T)<sub>x</sub> = R * T<sup>2</sup> / p * (-(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>);
+</pre>
+<p>
+Herein, <i>R</i> is the ideal gas constant, <i>p</i> is the pressure, <i>T</i> is
+the temperature, <i>(&part;x/&part;p)<sub>T</sub></i> is the partial derivative of 
+the uptake with respect to the pressure at constant temperature, and 
+<i>(&part;x/&part;T)<sub>p</sub></i> is the partial derivative  of the uptake with 
+respect to the temperature at constant pressure.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The specific volume of the adsorpt phase can be neglected compared to the specific
+  volume of the adsorptive phase.
+  </li>
+  <li>
+  The adsorptive can be treated as an ideal gas (i.e., p * V = n * R * T).
+  </li>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 17, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end h_ads_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/package.mo b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/package.mo
new file mode 100644
index 0000000..011f70b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/package.mo
@@ -0,0 +1,34 @@
+within SorpLib.Media.Functions.SorptionEnthalpies;
+package PureComponents "Functions required to calculate sorption enthalpies for pure components"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models to calculate sorption enthalpies for pure component 
+adsorption.
+</p>
+
+<h4>Implemented functions for each sorption enthalpy model</h4>
+<p>
+The following functions are provided for each sorption enthalpy model:
+</p>
+<ul>
+  <li>
+  Sorption enthalpy.
+  </li>
+  <li>
+  Partial derivative of sorption enthalpy w.r.t. pressure at constant temperature.
+  </li>
+  <li>
+  Partial derivative of sorption enthalpy w.r.t. temperature at constant pressure.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PureComponents;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/package.order b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/package.order
new file mode 100644
index 0000000..c16ccf9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/PureComponents/package.order
@@ -0,0 +1,10 @@
+h_ads
+dh_ads_dp
+dh_ads_dT
+h_ads_clausiusClapeyron
+dh_ads_dp_clausiusClapeyron
+dh_ads_dT_clausiusClapeyron
+h_ads_Dubinin
+dh_ads_dp_Dubinin
+dh_ads_dT_Dubinin
+Testers
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/package.mo b/SorpLib/Media/Functions/SorptionEnthalpies/package.mo
new file mode 100644
index 0000000..037845e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.Functions;
+package SorptionEnthalpies "Functions required to calculate sorption enthalpies"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains sorption enthalpy models for pure component and multi-component 
+adsorption. Please check the documentation of the individual packages for more 
+details on the implemented sorption enthalpy models .
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end SorptionEnthalpies;
diff --git a/SorpLib/Media/Functions/SorptionEnthalpies/package.order b/SorpLib/Media/Functions/SorptionEnthalpies/package.order
new file mode 100644
index 0000000..34e1288
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEnthalpies/package.order
@@ -0,0 +1,3 @@
+BasesClasses
+PureComponents
+MultiComponents
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti.mo
new file mode 100644
index 0000000..b0b1ce0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti.mo
@@ -0,0 +1,52 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMulti
+  "Base function for isotherm models of multi components"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real[:,:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_threshold_min = 0
+    "Threshold for partial pressures of all components: If a partial pressure is
+    below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of multi components. Such models can be extended pure component 
+isotherm models or specifically developed multi component isotherm models. 
+<br/><br/>
+This partial function defines the equilibrium temperature <i>T_adsorpt</i> and the 
+coefficients of the isotherm model <i>c</i> as inputs. The coefficients of the 
+isotherm model <i>c</i> are a matrix: The columns contain the coefficients of the 
+different components. The rows contain the actual coefficients, i.e, the row size 
+depends on the selected isotherm model. Different components may require different 
+numbers of coefficients, which is why the row size depends on the component with 
+the most coefficients. The coefficients of the isotherm model <i>c</i> may depend 
+on the equilibrium temperature <i>T_adsorpt</i>. Optional input regarding numerics 
+is the threshold <i>p_threshold_min</i> to regulate the minimal values of all 
+partial pressures.
+<br/><br/>
+Functions that inherit properties from this partial function may have to 
+implement further inputs, the output, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMulti;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST.mo
new file mode 100644
index 0000000..0500196
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST.mo
@@ -0,0 +1,115 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMultiIAST
+  "Base function for isotherm models based on the ideal adsorbed solution theory"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.MolarMass[:] M_i
+    "Molar masses of the components"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+  input Real[:] c_1
+    "Coefficients of the isotherm model of the first component"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+  input Real[:] c_2
+    "Coefficients of the isotherm model of the second component"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_1
+    "Uptake of the first component as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_1
+    "Pressure of the first component as function of uptake and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_1
+    "Partial derivative of the uptake of the first component w.r.t. the equilibrium 
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_1
+    "Reduced spreading pressure of the first component as function of pressure 
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_1
+    "Pressure of the first component as function of reduced spreading pressure
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_2
+    "Uptake of the second component as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_2
+    "Pressure of the second component as function of uptake and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_2
+    "Partial derivative of the uptake of the second component w.r.t. the equilibrium 
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_2
+    "Reduced spreading pressure of the second component as function of pressure 
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_2
+    "Pressure of the second component as function of reduced spreading pressure
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST num
+    "Record definining numerics of the IAST algorithms"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_1
+    "Record definining numerics of the first component's isotherm model"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_2
+    "Record definining numerics of the second component's isotherm model"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models based on
+the ideal adsorbed solution theory (IAST) describing the adsorption of multi 
+components.
+<br/><br/>
+This partial function defines the equilibrium temperature <i>T_adsorpt</i>, the
+molar masses <i>M_i</i>, and the coefficients of the isotherm model of the first
+component <i>c_1</i> and second component <i>c_2</i> as inputs. The coefficients 
+of the isotherm model <i>c_i</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. 
+Further inputs are functions describing the pure component isotherm models. These
+functional arguments are <i>func_x_pT_1</i>, <i>func_p_xT_1</i>, <i>func_dx_dp_1</i>, 
+<i>func_pi_pT_1</i>, and <i>func_p_piT_1</i> for component 1 (i.e., <i>i = 1</i>) and 
+2 (i.e., <i>i = 2</i>). Optional input regarding numerics define the setup of the
+IAST algorithm <i>num</i> and the pure component isotherm models <i>num_comp_i</i>.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement 
+further inputs, the output, and the function algorithm. Further inputs are 
+particulary required when developing IAST functions for more than two components.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMultiIAST;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dT.mo
new file mode 100644
index 0000000..da669c1
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dT.mo
@@ -0,0 +1,89 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMultiIAST_dx_dT
+  "Base function for isotherm models based on the ideal adsorbed solution theory: Partial derivative of uptakes w.r.t. temperature at contsant pressure and mole fractions"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real[size(c_1,1)] c_pdT_1
+    "Coefficients of the isotherm model of the first component: T + dT"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+  input Real[size(c_1,1)] c_mdT_1
+    "Coefficients of the isotherm model of the first component: T - dT"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+  input Real[size(c_2,1)] c_pdT_2
+    "Coefficients of the isotherm model of the second component: T + dT"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+  input Real[size(c_2,1)] c_mdT_2
+    "Coefficients of the isotherm model of the second component: T - dT"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+
+  input Modelica.Units.SI.TemperatureDifference dT = 1e-4
+    "Temperature difference used to calculate partial derivatives w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of outputs
+  //
+  output
+    SorpLib.Units.DerUptakeByMolarFraction[size(M_i,1)] dx_adsorpt_dT_adsorpt
+    "Partial derivatives of the uptakes w.r.t. the temperature at contsant pressure 
+    and mole fractions"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+    "Mole fractions of all components in the vapor or gas phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models based on
+the ideal adsorbed solution theory (IAST) describing the adsorption of multi 
+components.
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+in of the equilibrium uptakes w.r.t. the temperature at contsant pressure and mole 
+fractions <i>dx_adsorpt_dT</i> as a function of the equilibrium pressure <i>p_adsorpt</i>, 
+the mole fractions of the independent components in the gas or vapor phase <i>y_i</i>, 
+the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients 
+of the isotherm model of the first component <i>c_1</i> and second component 
+<i>c_2</i>. The coefficients of the isotherm model <i>c_i</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Further inputs are functions describing 
+the pure component isotherm models. These functional arguments are <i>func_x_pT_1</i>, 
+<i>func_p_xT_1</i>, <i>func_dx_dp_1</i>, <i>func_pi_pT_1</i>, and <i>func_p_piT_1</i> 
+for component 1 (i.e., <i>i = 1</i>) and 2 (i.e., <i>i = 2</i>). Optional input 
+regarding numerics define the setup of the IAST algorithm <i>num</i>, the pure 
+component isotherm models <i>num_comp_i</i>, and the infinitesimal difference
+<i>dT</i> to calculate the partial derivatives.
+<br/><br/>
+The partial derivatives of the equilibrium uptakes w.r.t. the temperature at contsant 
+pressure and mole fractions <i>dx_adsorpt_dT</i> are defined as the outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm. Further inputs are particulary required 
+when developing IAST functions for more than two components.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMultiIAST_dx_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dp.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dp.mo
new file mode 100644
index 0000000..9284d04
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dp.mo
@@ -0,0 +1,76 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMultiIAST_dx_dp
+  "Base function for isotherm models based on the ideal adsorbed solution theory: Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.PressureDifference dp = 1e-4
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerUptakeByPressure[size(M_i,1)] dx_adsorpt_dp_adsorpt
+    "Partial derivatives of the uptakes w.r.t. pressure at constant mole fractions 
+    and temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+    "Mole fractions of all components in the vapor or gas phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models based on
+the ideal adsorbed solution theory (IAST) describing the adsorption of multi 
+components.
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+of the equilibrium uptakes w.r.t. the equilibrium uptake at constant mole fractions 
+and temperature <i>dx_adsorpt_dp_adsorpt</i> as a function of the equilibrium 
+pressure <i>p_adsorpt</i>, the mole fractions of the independent components in 
+the gas or vapor phase <i>y_i</i>, the equilibrium temperature <i>T_adsorpt</i>. 
+Further inputs are the coefficients of the isotherm model of the first component 
+<i>c_1</i> and second component <i>c_2</i>. The coefficients of the isotherm model 
+<i>c_i</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. Further 
+inputs are functions describing the pure component isotherm models. These functional 
+arguments are <i>func_x_pT_1</i>, <i>func_p_xT_1</i>, <i>func_dx_dp_1</i>, 
+<i>func_pi_pT_1</i>, and <i>func_p_piT_1</i> for component 1 (i.e., <i>i = 1</i>) 
+and 2 (i.e., <i>i = 2</i>). Optional input regarding numerics define the setup of 
+the IAST algorithm <i>num</i>, the pure component isotherm models <i>num_comp_i</i>, 
+and the infinitesimal difference <i>dp</i> to calculate the partial derivatives.
+<br/><br/>
+The partial derivatives of the equilibrium uptakes w.r.t. the equilibrium pressure
+at constant mole fractions and temperature <i>dx_adsorpt_dp_adsorpt</i> are defined 
+as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm. Further inputs are particulary required 
+when developing IAST functions for more than two components.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMultiIAST_dx_dp;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dy.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dy.mo
new file mode 100644
index 0000000..30399ae
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_dx_dy.mo
@@ -0,0 +1,79 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMultiIAST_dx_dy
+  "Base function for isotherm models based on the ideal adsorbed solution theory: Partial derivative of uptakes w.r.t. molar fractions of independent gas phase components at constant temperature and pressure"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real dy = 1e-4
+    "Mole fraction difference used to calculate partial derivatives w.r.t. independent
+    mole fractions"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of outputs
+  //
+  output
+    SorpLib.Units.DerUptakeByMolarFraction[size(M_i,1),size(M_i,1)-1] dx_adsorpt_dy_i
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    gas phase components at constant temperature and pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+    "Mole fractions of all components in the vapor or gas phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models based on
+the ideal adsorbed solution theory (IAST) describing the adsorption of multi 
+components.
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+in of the equilibrium uptakes w.r.t. the molar fractions of the independent components
+the gas or vapor phase at constant temperature and pressure <i>dx_adsorpt_dy_i</i> 
+as a function of the equilibrium pressure <i>p_adsorpt</i>, the mole fractions of 
+the independent components in the gas or vapor phase <i>y_i</i>, the equilibrium 
+temperature <i>T_adsorpt</i>. Further inputs are the coefficients of the isotherm 
+model of the first component <i>c_1</i> and second component <i>c_2</i>. The 
+coefficients of the isotherm model <i>c_i</i> may depend on the equilibrium temperature 
+<i>T_adsorpt</i>. Further inputs are functions describing the pure component isotherm 
+models. These functional arguments are <i>func_x_pT_1</i>, <i>func_p_xT_1</i>, 
+<i>func_dx_dp_1</i>, <i>func_pi_pT_1</i>, and <i>func_p_piT_1</i> for component 1 
+(i.e., <i>i = 1</i>) and 2 (i.e., <i>i = 2</i>). Optional input regarding numerics 
+define the setup of the IAST algorithm <i>num</i>, the pure component isotherm models 
+<i>num_comp_i</i>, and the infinitesimal difference <i>dy</i> to calculate the
+partial derivatives.
+<br/><br/>
+The partial derivatives of the equilibrium uptakes w.r.t. the molar fractions of 
+the independent components the gas or vapor phase at constant temperature and pressure
+<i>dx_adsorpt_dy_i</i> are defined as the outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm. Further inputs are particulary required 
+when developing IAST functions for more than two components.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMultiIAST_dx_dy;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_p_xyT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_p_xyT.mo
new file mode 100644
index 0000000..c4d747f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_p_xyT.mo
@@ -0,0 +1,60 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMultiIAST_p_xyT
+  "Base function for isotherm models based on the ideal adsorbed solution theory: Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models based on
+the ideal adsorbed solution theory (IAST) describing the adsorption of multi 
+components.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium uptakes 
+<i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>, the
+mole fractions of the independent components in the gas or vapor phase <i>y_i</i>, 
+the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients 
+of the isotherm model of the first component <i>c_1</i> and second component 
+<i>c_2</i>. The coefficients of the isotherm model <i>c_i</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Further inputs are functions describing 
+the pure component isotherm models. These functional arguments are <i>func_x_pT_1</i>, 
+<i>func_p_xT_1</i>, <i>func_dx_dp_1</i>, <i>func_pi_pT_1</i>, and <i>func_p_piT_1</i> 
+for component 1 (i.e., <i>i = 1</i>) and 2 (i.e., <i>i = 2</i>). Optional input 
+regarding numerics define the setup of the IAST algorithm <i>num</i> and the pure 
+component isotherm models <i>num_comp_i</i>.
+<br/><br/>
+The equilibrium pressure <i>p_adsorpt</i> is defined as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm. Further inputs are particulary required 
+when developing IAST functions for more than two components.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMultiIAST_p_xyT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_py_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_py_xT.mo
new file mode 100644
index 0000000..0d3bf5b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_py_xT.mo
@@ -0,0 +1,61 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMultiIAST_py_xT
+  "Base function for isotherm models based on the ideal adsorbed solution theory: Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models based on
+the ideal adsorbed solution theory (IAST) describing the adsorption of multi 
+components.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium uptakes 
+<i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>, the
+mole fractions of the independent components in the gas or vapor phase <i>y_i</i>, 
+the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients 
+of the isotherm model of the first component <i>c_1</i> and second component 
+<i>c_2</i>. The coefficients of the isotherm model <i>c_i</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Further inputs are functions describing 
+the pure component isotherm models. These functional arguments are <i>func_x_pT_1</i>, 
+<i>func_p_xT_1</i>, <i>func_dx_dp_1</i>, <i>func_pi_pT_1</i>, and <i>func_p_piT_1</i> 
+for component 1 (i.e., <i>i = 1</i>) and 2 (i.e., <i>i = 2</i>). Optional input 
+regarding numerics define the setup of the IAST algorithm <i>num</i> and the pure 
+component isotherm models <i>num_comp_i</i>.
+<br/><br/>
+The equilibrium pressure <i>p_adsorpt</i> and the mole fractions of the independent 
+components in the gas or vapor phase <i>y_i</i> are defined as the outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm. Further inputs are particulary required 
+when developing IAST functions for more than two components.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMultiIAST_py_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_x_pyT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_x_pyT.mo
new file mode 100644
index 0000000..02ece7b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_x_pyT.mo
@@ -0,0 +1,60 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMultiIAST_x_pyT
+  "Base function for isotherm models based on the ideal adsorbed solution theory: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models based on
+the ideal adsorbed solution theory (IAST) describing the adsorption of multi 
+components.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium uptakes 
+<i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>, the
+mole fractions of the independent components in the gas or vapor phase <i>y_i</i>, 
+the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients 
+of the isotherm model of the first component <i>c_1</i> and second component 
+<i>c_2</i>. The coefficients of the isotherm model <i>c_i</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Further inputs are functions describing 
+the pure component isotherm models. These functional arguments are <i>func_x_pT_1</i>, 
+<i>func_p_xT_1</i>, <i>func_dx_dp_1</i>, <i>func_pi_pT_1</i>, and <i>func_p_piT_1</i> 
+for component 1 (i.e., <i>i = 1</i>) and 2 (i.e., <i>i = 2</i>). Optional input 
+regarding numerics define the setup of the IAST algorithm <i>num</i> and the pure 
+component isotherm models <i>num_comp_i</i>.
+<br/><br/>
+The equilibrium uptakes <i>x_adsorpt</i> are defined as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm. Further inputs are particulary required 
+when developing IAST functions for more than two components.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMultiIAST_x_pyT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_y_pxT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_y_pxT.mo
new file mode 100644
index 0000000..f09174c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMultiIAST_y_pxT.mo
@@ -0,0 +1,61 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMultiIAST_y_pxT
+  "Base function for isotherm models based on the ideal adsorbed solution theory: Mole fractions of independent gas phase components as function of pressure, uptakes, and temperature"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.MoleFraction[size(M_i,1)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models based on
+the ideal adsorbed solution theory (IAST) describing the adsorption of multi 
+components.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium uptakes 
+<i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>, the
+mole fractions of the independent components in the gas or vapor phase <i>y_i</i>, 
+the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients 
+of the isotherm model of the first component <i>c_1</i> and second component 
+<i>c_2</i>. The coefficients of the isotherm model <i>c_i</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Further inputs are functions describing 
+the pure component isotherm models. These functional arguments are <i>func_x_pT_1</i>, 
+<i>func_p_xT_1</i>, <i>func_dx_dp_1</i>, <i>func_pi_pT_1</i>, and <i>func_p_piT_1</i> 
+for component 1 (i.e., <i>i = 1</i>) and 2 (i.e., <i>i = 2</i>). Optional input 
+regarding numerics define the setup of the IAST algorithm <i>num</i> and the pure 
+component isotherm models <i>num_comp_i</i>.
+<br/><br/>
+The mole fractions of the independent components in the gas or vapor phase 
+<i>y_i</i> are defined as the outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm. Further inputs are particulary required 
+when developing IAST functions for more than two components.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialMultiIAST_y_pxT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dT.mo
new file mode 100644
index 0000000..fa09e6c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dT.mo
@@ -0,0 +1,74 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMulti_dx_dT
+  "Base function for isotherm models of multi components: Partial derivative of uptakes w.r.t. temperature at contsant pressure and mole fractions"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(c,2)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[size(c,1), size(c,2)] dc_dT_adsorpt
+    "Partial derivatives of coefficients of isotherm model w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output
+    SorpLib.Units.DerUptakeByMolarFraction[size(c,2)] dx_adsorpt_dT_adsorpt
+    "Partial derivatives of the uptakes w.r.t. the temperature at contsant 
+    pressure and mole fractions"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction[size(c,2)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+    "Mole fractions of all components in the vapor or gas phase";
+  Modelica.Units.SI.Pressure[size(c,2)] p_i = p_adsorpt .* y_i_
+    "Partial pressures of all components";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of multi components. Such models can be extended pure component 
+isotherm models or specifically developed multi component isotherm models. 
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+in of the equilibrium uptakes w.r.t. the temperature at contsant pressure and mole 
+fractions <i>dx_adsorpt_dT</i> as a function of the equilibrium pressure <i>p_adsorpt</i>, 
+the mole fractions of the independent components in the gas or vapor phase <i>y_i</i>, 
+the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients of 
+the isotherm model <i>c</i>. The coefficients of the isotherm model <i>c</i> may 
+depend on the equilibrium temperature <i>T_adsorpt</i>. The coefficients of the 
+isotherm model <i>c</i> are a matrix: The columns contain the coefficients of the 
+different components. The rows contain the actual coefficients, i.e, the row size 
+depends on the selected isotherm model. Different components may require different 
+numbers of coefficients, which is why the row size depends on the component with 
+the most coefficients. Optional input regarding numerics is the threshold 
+<i>p_threshold_min</i> to regulate the minimal values of all partial pressures.
+<br/><br/>
+The partial derivatives of the equilibrium uptakes w.r.t. the temperature at contsant 
+pressure and mole fractions <i>dx_adsorpt_dT</i> are defined as the outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMulti_dx_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dp.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dp.mo
new file mode 100644
index 0000000..ecc4f57
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dp.mo
@@ -0,0 +1,72 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMulti_dx_dp
+  "Base function for isotherm models of multi components: Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(c,2)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerUptakeByPressure[size(c,2)] dx_adsorpt_dp_adsorpt
+    "Partial derivatives of the uptakes w.r.t. pressure at constant mole fractions
+    and temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction[size(c,2)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+    "Mole fractions of all components in the vapor or gas phase";
+  Modelica.Units.SI.Pressure[size(c,2)] p_i = p_adsorpt .* y_i_
+    "Partial pressures of all components";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of multi components. Such models can be extended pure component 
+isotherm models or specifically developed multi component isotherm models. 
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+of the equilibrium uptakes w.r.t. the equilibrium uptake at constant mole fractions 
+and temperature <i>dx_adsorpt_dp_adsorpt</i> as a function of the equilibrium 
+pressure <i>p_adsorpt</i>, the mole fractions of the independent components in 
+the gas or vapor phase <i>y_i</i>, the equilibrium temperature <i>T_adsorpt</i>. 
+Further inputs are the coefficients of the isotherm model <i>c</i>. The coefficients 
+of the isotherm model <i>c</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. 
+The coefficients of the isotherm model <i>c</i> are a matrix: The columns contain 
+the coefficients of the different components. The rows contain the actual 
+coefficients, i.e, the row size depends on the selected isotherm model. Different 
+components may require different numbers of coefficients, which is why the row 
+size depends on the component with the most coefficients. Optional input regarding 
+numerics is the threshold <i>p_threshold_min</i> to regulate the minimal values 
+of all partial pressures.
+<br/><br/>
+The partial derivatives of the equilibrium uptakes w.r.t. the equilibrium pressure
+at constant mole fractions and temperature <i>dx_adsorpt_dp_adsorpt</i> are 
+defined as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMulti_dx_dp;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dy.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dy.mo
new file mode 100644
index 0000000..055f354
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_dx_dy.mo
@@ -0,0 +1,73 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMulti_dx_dy
+  "Base function for isotherm models of multi components: Partial derivative of uptakes w.r.t. molar fractions of independent gas phase components at constant temperature and pressure"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(c,2)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output
+    SorpLib.Units.DerUptakeByMolarFraction[size(c,2),size(c,2)-1] dx_adsorpt_dy_i
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    gas phase components at constant temperature and pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction[size(c,2)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+    "Mole fractions of all components in the vapor or gas phase";
+  Modelica.Units.SI.Pressure[size(c,2)] p_i = p_adsorpt .* y_i_
+    "Partial pressures of all components";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of multi components. Such models can be extended pure component 
+isotherm models or specifically developed multi component isotherm models.  
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+in of the equilibrium uptakes w.r.t. the molar fractions of the independent components
+the gas or vapor phase at constant temperature and pressure <i>dx_adsorpt_dy_i</i> 
+as a function of the equilibrium pressure <i>p_adsorpt</i>, the mole fractions of 
+the independent components in the gas or vapor phase <i>y_i</i>, the equilibrium 
+temperature <i>T_adsorpt</i>. Further inputs are the coefficients of the isotherm 
+model <i>c</i>. The coefficients of the isotherm model <i>c</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. The coefficients of the isotherm model 
+<i>c</i> are a matrix: The columns contain the coefficients of the different components. 
+The rows contain the actual coefficients, i.e, the row size depends on the selected 
+isotherm model. Different components may require different numbers of coefficients, 
+which is why the row size depends on the component with the most coefficients. 
+Optional input regarding numerics is the threshold <i>p_threshold_min</i> to 
+regulate the minimal values of all partial pressures.
+<br/><br/>
+The partial derivatives of the equilibrium uptakes w.r.t. the molar fractions of 
+the independent components the gas or vapor phase at constant temperature and pressure
+<i>dx_adsorpt_dy_i</i> are defined as the outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMulti_dx_dy;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_p_xyT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_p_xyT.mo
new file mode 100644
index 0000000..559bc64
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_p_xyT.mo
@@ -0,0 +1,82 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMulti_p_xyT
+  "Base function for isotherm models of multi components: Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(c,2)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start = 1
+    "Lower bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start = 10
+    "Upper bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (required if pressure is calculated
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Partial pressures of all components";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of multi components. Such models can be extended pure component 
+isotherm models or specifically developed multi component isotherm models. 
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium 
+pressure <i>p_adsorpt</i> as function of the equilibrium uptakes <i>x_adsorpt</i>, 
+the mole fractions of the independent components in the gas or vapor phase 
+<i>y_i</i>, and the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the 
+coefficients of the isotherm model <i>c</i>. The coefficients of the isotherm 
+model <i>c</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. The 
+coefficients of the isotherm model <i>c</i> are a matrix: The columns contain the 
+coefficients of the different components. The rows contain the actual coefficients, 
+i.e, the row size depends on the selected isotherm model. Different components may 
+require different numbers of coefficients, which is why the row size depends on 
+the component with the most coefficients. Optional input regarding numerics is 
+the threshold <i>p_threshold_min</i> to regulate the minimal values of all partial 
+pressures. Further optional inputs regarding numerics are the lower bound 
+(<i>p_adsorpt_lb_start</i>) and upper bound (<i>p_adsorpt_ub_start</i>) of the 
+equilibrium pressure and the tolerance (<i>tolerance</i>), only required if this 
+function cannot be solved analytically.
+<br/><br/>
+The equilibrium pressure <i>p_adsorpt</i> is defined as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMulti_p_xyT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_py_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_py_xT.mo
new file mode 100644
index 0000000..cba24e4
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_py_xT.mo
@@ -0,0 +1,83 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMulti_py_xT
+  "Base function for isotherm models of multi components: Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start = 1
+    "Lower bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start = 10
+    "Upper bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (required if pressure is calculated
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.MoleFraction[size(c,2)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Partial pressures of all components";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of multi components. Such models can be extended pure component 
+isotherm models or specifically developed multi component isotherm models. 
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium 
+pressure <i>p_adsorpt</i> and the mole fractions of the independent components in 
+the gas or vapor phase <i>y_i</i> as function of the equilibrium uptakes <i>x_adsorpt</i>
+and the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients of 
+the isotherm model <i>c</i>. The coefficients of the isotherm model <i>c</i> may 
+depend on the equilibrium temperature <i>T_adsorpt</i>. The coefficients of the 
+isotherm model <i>c</i> are a matrix: The columns contain the coefficients of the 
+different components. The rows contain the actual coefficients, i.e, the row size 
+depends on the selected isotherm model. Different components may require different 
+numbers of coefficients, which is why the row size depends on the component with 
+the most coefficients. Optional input regarding numerics is the threshold 
+<i>p_threshold_min</i> to regulate the minimal values of all partial pressures.
+Further optional inputs regarding numerics are the lower bound (<i>p_adsorpt_lb_start</i>) 
+and upper bound (<i>p_adsorpt_ub_start</i>) of the equilibrium pressure and the 
+tolerance (<i>tolerance</i>), only required if this function cannot be solved 
+analytically.
+<br/><br/>
+The equilibrium pressure <i>p_adsorpt</i> and the mole fractions of the independent 
+components in the gas or vapor phase <i>y_i</i> are defined as the outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMulti_py_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_x_pyT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_x_pyT.mo
new file mode 100644
index 0000000..d6e8d77
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_x_pyT.mo
@@ -0,0 +1,84 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMulti_x_pyT
+  "Base function for isotherm models of multi components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[size(c,2)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start = 1
+    "Lower bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start = 10
+    "Upper bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (required if pressure is calculated
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction[size(c,2)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+    "Mole fractions of all components in the vapor or gas phase";
+  Modelica.Units.SI.Pressure[size(c,2)] p_i = p_adsorpt .* y_i_
+    "Partial pressures of all components";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of multi components. Such models can be extended pure component 
+isotherm models or specifically developed multi component isotherm models. 
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium uptakes 
+<i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>, the
+mole fractions of the independent components in the gas or vapor phase <i>y_i</i>, 
+the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients of 
+the isotherm model <i>c</i>. The coefficients of the isotherm model <i>c</i> may 
+depend on the equilibrium temperature <i>T_adsorpt</i>. The coefficients of the 
+isotherm model <i>c</i> are a matrix: The columns contain the coefficients of the 
+different components. The rows contain the actual coefficients, i.e, the row size 
+depends on the selected isotherm model. Different components may require different 
+numbers of coefficients, which is why the row size depends on the component with 
+the most coefficients. Optional input regarding numerics is the threshold 
+<i>p_threshold_min</i> to regulate the minimal values of all partial pressures. 
+Further optional inputs regarding numerics are the lower bound (<i>p_adsorpt_lb_start</i>) 
+and upper bound (<i>p_adsorpt_ub_start</i>) of the equilibrium pressure and the 
+tolerance (<i>tolerance</i>), only required if the inverse of this function cannot 
+be solved analytically.
+<br/><br/>
+The equilibrium uptakes <i>x_adsorpt</i> are defined as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMulti_x_pyT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_y_pxT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_y_pxT.mo
new file mode 100644
index 0000000..4c297c1
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialMulti_y_pxT.mo
@@ -0,0 +1,83 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialMulti_y_pxT
+  "Base function for isotherm models of multi components: Mole fractions of independent gas phase components as function of pressure, uptakes, and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start = 1
+    "Lower bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start = 10
+    "Upper bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (required if pressure is calculated
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.MoleFraction[size(c,2)-1] y_i
+    "Mole fractions of independent components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Partial pressures of all components";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of multi components. Such models can be extended pure component 
+isotherm models or specifically developed multi component isotherm models. 
+<br/><br/>
+This partial function is the basic function for calculating the mole fractions of 
+the independent components in the gas or vapor phase <i>y_i</i> as function of the 
+equilibrium pressure <i>p_adsorpt</i>, equilibrium uptakes <i>x_adsorpt</i>, and
+the equilibrium temperature <i>T_adsorpt</i>. Further inputs are the coefficients of 
+the isotherm model <i>c</i>. The coefficients of the isotherm model <i>c</i> may 
+depend on the equilibrium temperature <i>T_adsorpt</i>. The coefficients of the 
+isotherm model <i>c</i> are a matrix: The columns contain the coefficients of the 
+different components. The rows contain the actual coefficients, i.e, the row size 
+depends on the selected isotherm model. Different components may require different 
+numbers of coefficients, which is why the row size depends on the component with 
+the most coefficients. Optional input regarding numerics is the threshold 
+<i>p_threshold_min</i> to regulate the minimal values of all partial pressures. 
+Further optional inputs regarding numerics are the lower bound (<i>p_adsorpt_lb_start</i>) 
+and upper bound (<i>p_adsorpt_ub_start</i>) of the equilibrium pressure and the 
+tolerance (<i>tolerance</i>), only required if this function cannot be solved 
+analytically.
+<br/><br/>
+The mole fractions of the independent components in the gas or vapor phase 
+<i>y_i</i> are defined as the outputs.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMulti_y_pxT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure.mo
new file mode 100644
index 0000000..600a7d0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure
+  "Base function for isotherm models of pure components"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores. 
+<br/><br/>
+This partial function defines the equilibrium temperature <i>T_adsorpt</i> and
+the coefficients of the isotherm model <i>c</i> as inputs. The coefficients of 
+the isotherm model <i>c</i> may depend on the equilibrium temperature 
+<i>T_adsorpt</i>.
+<br/><br/>
+Functions that inherit properties from this partial function may have to 
+implement further inputs, the output, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_A_W.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_A_W.mo
new file mode 100644
index 0000000..23acdad
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_A_W.mo
@@ -0,0 +1,68 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_A_W
+  "Base function for isotherm models of pure components: Molar adsorption potential as function of filled pore volume"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.FilledPoreVolume W
+    "Filled pore volume"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.MolarAdsorptionPotential A_lb_start=10
+  "Lower bound of molar adsorption potential (required if molar adsorption potential
+  is calculated numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input SorpLib.Units.MolarAdsorptionPotential A_ub_start=100
+  "Upper bound of molar adsorption potential ((required if molar adsorption potential
+  is calculated numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (required if molar adsorption potential
+  is calculated numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.MolarAdsorptionPotential A "Molar adsorption potential"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models must be based on filled pores
+(i.e., Dubinin theory).
+<br/><br/>
+This partial function is the basic function for calculating the molar adsorption 
+potential <i>A</i> as a function of the filled pore volume <i>W</i>. Defined inputs 
+are the filled pore volume <i>W</i> and the coefficients of the isotherm model <i>c</i>. 
+The coefficients of the isotherm model <i>c</i> may depend on the equilibrium
+temperature <i>T_adsorpt</i>. Optional inputs regarding numerics are the lower 
+bound (<i>A_lb_start</i>) and upper bound (<i>A_ub_start</i>) of the molar 
+adsorption potential and the tolerance (<i>tolerance</i>), only required  if this 
+function cannot be solved analytically. The defined output is the molar adsorption 
+potential <i>A</i>.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_A_W;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_A_W_num.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_A_W_num.mo
new file mode 100644
index 0000000..5e4991d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_A_W_num.mo
@@ -0,0 +1,151 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_A_W_num
+  "Base function for isotherm models of pure components: Molar adsorption potential as function of filled pore volume (numerical solution)"
+   extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_A_W;
+
+  //
+  // Definition of protected replacable functions
+  //
+protected
+  replaceable function func_W_A =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.W_A
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_W_A
+    "Filled pore volume as function of molar adsorption potential"
+    annotation (Dialog(tab="General", group="Functions"));
+
+  //
+  // Definition of functions
+  //
+protected
+  function func_A_num
+    "Function used to find root (i.e., A) numerically"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input SorpLib.Units.FilledPoreVolume W
+      "Filled pore volume";
+    input Real c[:]
+      "Coefficients of isotherm model";
+  algorithm
+    y := func_W_A(A=u, c=c) - W
+     "Function '0 = W(A, c) - W' used to find root (i.e., A) numerically";
+  end func_A_num;
+
+  //
+  // Definition of variables
+  //
+  Boolean bound_ok = false
+    "= true, if bounds are found such that func_A_num(lb) > 0 and func_A_num(ub) < 0";
+
+  SorpLib.Units.MolarAdsorptionPotential A_lb=A_lb_start
+    "Current best lower bound of molar adsorption potential";
+  SorpLib.Units.MolarAdsorptionPotential A_ub=A_ub_start
+    "Current best upper bound of molar adsorption potential";
+
+  SorpLib.Units.FilledPoreVolume W_lb = func_W_A(A=A_lb, c=c)
+    "Filled pore volume at current best lower bound of molar adsorption potential";
+  SorpLib.Units.FilledPoreVolume W_ub = func_W_A(A=A_ub, c=c)
+    "Filled pore volume at current best upper bound of molar adsorption potential";
+
+algorithm
+  //
+  // Find start values such that func_A_num(lb) > 0 and func_A_num(ub) < 0
+  //
+  // Reducing A increases W -> func_A_num(W) can become > 0
+  // Increasing A reduces W -> func_A_num(W) can become < 0
+  //
+  while not bound_ok loop
+    if Modelica.Math.isEqual(s1=W_lb, s2=W, eps=tolerance) then
+      A := A_lb;
+      bound_ok := true;
+      return;
+
+    elseif Modelica.Math.isEqual(s1=W_ub, s2=W, eps=tolerance) then
+      A := A_ub;
+      bound_ok := true;
+      return;
+
+    elseif W_lb-W < 0 and W_ub-W < 0 then
+      A_ub := A_lb;
+      W_ub := W_lb;
+
+      A_lb := if A_lb > Modelica.Constants.small then A_lb*0.1 else 0;
+      W_lb := func_W_A(A=A_lb, c=c);
+
+    elseif W_lb-W > 0 and W_ub-W > 0 then
+      A_lb := A_ub;
+      W_lb := W_ub;
+
+      A_ub := A_ub*10;
+      W_ub := func_W_A(A=A_ub, c=c);
+
+    else
+      bound_ok := true;
+
+    end if;
+
+    //
+    // Check if func_W_A is not strictly monotonic with A (i.e., unfavourable
+    // parameterisation or function approach selected)
+    //
+    if Modelica.Math.isEqual(s1=A_lb, s2=A_ub, eps=tolerance) or A_lb > 1e15 then
+      A := if A_lb > 1e15 then 1e15 else 0
+        "Set A to bound";
+      Modelica.Utilities.Streams.print("Characteristic curbe W(A) is not strictly monotonic with A: Inverse A(W) cannot be found!");
+      return;
+    end if;
+  end while;
+
+  //
+  // Find root in the interval lb <= root <= up
+  //
+  A := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+    f = function func_A_num(W=W, c=c),
+    u_min = A_lb,
+    u_max = A_ub,
+    tolerance = tolerance)
+    "Calculation of the molar adsorption potential";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models must be based on filled pores
+(i.e., Dubinin theory).
+<br/><br/>
+This partial function is the basic function for calculating the molar adsorption 
+potential <i>A</i> as a function of the filled pore volume <i>W</i>. Defined 
+inputs are the filled pore volume <i>W</i> and the coefficients of the isotherm 
+model <i>c</i>. The coefficients of the isotherm model <i>c</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Inputs regarding numerics are the lower 
+bound (<i>A_lb_start</i>) and upper bound (<i>A_ub_start</i>) of the molar 
+adsorption potential and the tolerance (<i>tolerance</i>). The defined output is 
+molar the adsorption potential <i>A</i>.
+<br/><br/>
+With this function, the eadsorption potential <i>A</i> is determined numerically 
+by solving a zero problem. The zero problem is as follows:
+</p>
+<pre>
+    f(A) = 0 => 0 = func_W_A(A=A, c=c) - W;
+</pre>
+<p>
+The zero problem is solved using the numerically very efficient function 
+<a href=\"Modelica://Modelica.Math.Nonlinear.solveOneNonlinearEquation\">Modelica.Math.Nonlinear.solveOneNonlinearEquation</a>.
+For the application of this function, it must be ensured that <i>f(A)</i> 
+has a different sign for the upper and lower limits of <i>A</i>. To ensure 
+the different signs, the upper and lower limits are determined in an upstream loop.
+<br/><br/>
+Functions that inherit properties from this partial function have to redeclare
+the function <i>func_W_A</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_A_W_num;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_W_A.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_W_A.mo
new file mode 100644
index 0000000..e43f9ca
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_W_A.mo
@@ -0,0 +1,65 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_W_A
+  "Base function for isotherm models of pure components: Filled pore volume as function of molar adsorption potential"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.MolarAdsorptionPotential A "Molar adsorption potential"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Units.MolarAdsorptionPotential A_lb_start=0
+  "Lower bound of molar adsorption potential (required if inverse is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input SorpLib.Units.MolarAdsorptionPotential A_ub_start=10
+  "Upper bound of molar adsorption potential (required if inverse is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (required if inverse is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.FilledPoreVolume W
+    "Filled pore volume"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models must be based on filled pores
+(i.e., Dubinin theory).
+<br/><br/>
+This partial function is the basic function for calculating the filled pore volume
+<i>W</i> as a function of the molar adsorption potential <i>A</i>. Defined inputs 
+are the molar adsorption potential <i>A</i> and the coefficients of the isotherm 
+model <i>c</i>. The coefficients of the isotherm model <i>c</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Optional  inputs regarding numerics are 
+the lower bound (<i>A_lb_start</i>) and upper bound (<i>A_ub_start</i>) of the 
+molar adsorption potential and the tolerance (<i>tolerance</i>), only required if 
+the inverse of this function cannot be solved analytically. The defined output is 
+the filled pore volume <i>W</i>.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_W_A;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dW_dA.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dW_dA.mo
new file mode 100644
index 0000000..09addce
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dW_dA.mo
@@ -0,0 +1,56 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_dW_dA
+  "Base function for isotherm models of pure components: Partial derivative of filled pore volume w.r.t. molar adsorption potential at constant pressure and temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential 
+    at constant pressure and temperature"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models must be based on filled pores
+(i.e., Dubinin theory).
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+of the filled pore volume with respect to the molar adsorption potential at constant 
+pressure and temperature <i>dW_dA</i> as a function of the molar adsorption potential 
+<i>A</i>. Defined inputs are the molar  adsorption potential <i>A</i> and the 
+coefficients of the isotherm model <i>c</i>. The coefficients of the isotherm model 
+<i>c</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. The defined 
+output is the partial derivative of the filled pore volume with respect to the molar 
+adsorption potential at constant pressure and temperature <i>dW_dA</i>.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_dW_dA;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddW_dA_dA.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddW_dA_dA.mo
new file mode 100644
index 0000000..990b041
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddW_dA_dA.mo
@@ -0,0 +1,58 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_ddW_dA_dA
+  "Base function for isotherm models of pure components: Second-order partial derivative of filled pore volume w.r.t. molar adsorption potential at constant pressure and temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential at constant pressure and temperature"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models must be based on filled pores
+(i.e., Dubinin theory).
+<br/><br/>
+This partial function is the basic function for calculating the second-order partial 
+derivative of the filled pore volume with respect to the molar adsorption potential 
+at constant pressure and temperature <i>ddW_dA_dA</i> as a function of the molar 
+adsorption potential <i>A</i>. Defined inputs are the molar  adsorption potential 
+<i>A</i> and the coefficients of the isotherm model <i>c</i>. The coefficients of 
+the isotherm model <i>c</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. 
+The defined output is the second-order partial derivative of the filled pore volume 
+with respect to the molar adsorption potential at constant pressure and temperature
+<i>ddW_dA_dA</i>.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_ddW_dA_dA;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddW_dA_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddW_dA_dT.mo
new file mode 100644
index 0000000..c5c5748
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddW_dA_dT.mo
@@ -0,0 +1,68 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_ddW_dA_dT
+  "Base function for isotherm models of pure components: Second-order partial derivative of filled pore volume w.r.t. molar adsorption potential and temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[:] dc_dT_adsorpt
+    "Partial derivatives of coefficients of isotherm model w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models must be based on filled pores
+(i.e., Dubinin theory).
+<br/><br/>
+This partial function is the basic function for calculating the second-order partial
+derivative of the filled pore volume with respect to the molar adsorption potential 
+and temperature at constant pressure <i>ddW_dA_dT</i> as a function of the molar 
+adsorption potential <i>A</i>. Defined inputs are the equilibrium pressure <i>p_adsorpt</i>, 
+equilibrium temperature <i>T_adsorpt</i>, molar adsorption potential <i>A</i>, the 
+coefficients of the isotherm model <i>c</i>, and the partial derivatives ot the 
+coefficients with respect to the equilibrium temperatre <i>dc_dT_adsorpt</i>. The 
+coefficients of the isotherm model <i>c</i> may depend on the equilibrium temperature 
+<i>T_adsorpt</i>. The defined output is the second-order partial derivative of the 
+filled pore volume with respect to the molar adsorption potential and temperature 
+at constant pressure and temperature <i>ddW_dA_dT</i>.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_ddW_dA_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dT_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dT_dT.mo
new file mode 100644
index 0000000..6f9c5e3
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dT_dT.mo
@@ -0,0 +1,62 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_ddx_dT_dT
+  "Base function for isotherm models of pure components: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+  input Real[:] dc_dT_adsorpt
+    "Partial derivatives of coefficients of isotherm model w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real[:] ddc_dT_adsorpt_dT_adsorpt
+    "Second-order partial derivatives of coefficients of isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerUptakeByTemperatureTemperature
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the second-order 
+partial derivative of the equilibrium uptake with respect to the equilibrium 
+temperature at constant pressure <i>ddx_adsorpt_dT_adsorpt_dT_adsorpt</i> as a 
+function of the equilibrium pressure <i>p_adsorpt</i> and equilibrium temperature 
+<i>T_adsorpt</i>. Defined inputs are the equilibrium pressure <i>p_adsorpt</i>, the 
+equilibrium temperature <i>T_adsorpt</i>, the coefficients of the isotherm model 
+<i>c</i>, the partial derivatives ot the coefficients with respect to the equilibrium 
+temperatre <i>dc_dT_adsorpt</i>, and the second-order partial derivatives ot the 
+coefficients with respect to the equilibrium temperatre <i>ddc_dT_adsorpt_dT_adsorpt</i>. 
+The coefficients of the isotherm model <i>c</i> may depend on the equilibrium 
+temperature <i>T_adsorpt</i>. Besides, this partial function defines the second-
+order partial derivative of the equilibrium uptake with respect to the equilibrium 
+temperature at constant pressure <i>ddx_adsorpt_dT_adsorpt_dT_adsorpt</i> as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement 
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_ddx_dT_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dp_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dp_dT.mo
new file mode 100644
index 0000000..2831f83
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dp_dT.mo
@@ -0,0 +1,57 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_ddx_dp_dT
+  "Base function for isotherm models of pure components: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+  input Real[:] dc_dT_adsorpt
+    "Partial derivatives of coefficients of isotherm model w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerUptakeByPressureTemperature
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the second-order 
+partial derivative of the equilibrium uptake with respect to the equilibrium 
+pressure and temperature <i>ddx_adsorpt_dp_adsorpt_dT_adsorpt</i> as a function 
+of the equilibrium pressure <i>p_adsorpt</i> and equilibrium temperature
+<i>T_adsorpt</i>. Defined inputs are the equilibrium pressure <i>p_adsorpt</i>,
+the equilibrium temperature <i>T_adsorpt</i>, the coefficients of the isotherm
+model <i>c</i>, and the partial derivatives ot the coefficients with respect to
+the equilibrium temperatre <i>dc_dT_adsorpt</i>. The coefficients of the isotherm 
+model <i>c</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. The 
+second-order partial derivative of the equilibrium uptake with respect to the 
+equilibrium pressure and temperature <i>ddx_adsorpt_dp_adsorpt_dT_adsorpt</i> is 
+defined as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_ddx_dp_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dp_dp.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dp_dp.mo
new file mode 100644
index 0000000..9b7803b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_ddx_dp_dp.mo
@@ -0,0 +1,52 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_ddx_dp_dp
+  "Base function for isotherm models of pure components: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_adsorpt_dp_adsorpt
+    "Second-order partial derivative of the uptake w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the second-order partial 
+derivative of the equilibrium uptake with respect to the equilibrium pressure at 
+constant temperature <i>ddx_adsorpt_dp_adsorpt_dp_adsorpt</i> as a function of 
+the equilibrium pressure <i>p_adsorpt</i> and equilibrium temperature <i>T_adsorpt</i>. 
+Defined inputs are the equilibrium pressure <i>p_adsorpt</i>, the equilibrium 
+temperature <i>T_adsorpt</i>, and the coefficients of the isotherm model <i>c</i>. 
+The coefficients of the isotherm model <i>c</i> may depend on the equilibrium 
+temperature <i>T_adsorpt</i>. The second-order partial derivative of the 
+equilibrium uptake with respect to the equilibrium pressure 
+<i>ddx_adsorpt_dp_adsorpt_dp_adsorpt</i> is defined as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_ddx_dp_dp;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dx_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dx_dT.mo
new file mode 100644
index 0000000..9bb6a55
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dx_dT.mo
@@ -0,0 +1,55 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_dx_dT
+  "Base function for isotherm models of pure components: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+  input Real[:] dc_dT_adsorpt
+    "Partial derivatives of coefficients of isotherm model w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_adsorpt
+    "Partial derivative of the uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+of the equilibrium uptake with respect to the equilibrium temperature at constant 
+pressure <i>dx_adsorpt_dT_adsorpt</i> as a function of the equilibrium pressure 
+<i>p_adsorpt</i> and equilibrium temperature <i>T_adsorpt</i>. Defined inputs are 
+the equilibrium pressure <i>p_adsorpt</i>, the equilibrium temperature <i>T_adsorpt</i>, 
+the coefficients of the isotherm model <i>c</i>, and the partial derivatives ot the 
+coefficients with respect to the equilibrium temperatre <i>dc_dT_adsorpt</i>. The 
+coefficients of the isotherm model <i>c</i> may depend on the equilibrium temperature 
+<i>T_adsorpt</i>. Besides, this partial function defines the partial derivative of 
+the equilibrium uptake with respect to the equilibrium temperature at constant pressure
+<i>dx_adsorpt_dT_adsorpt</i> as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement 
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_dx_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dx_dp.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dx_dp.mo
new file mode 100644
index 0000000..b39d4cb
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_dx_dp.mo
@@ -0,0 +1,50 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_dx_dp
+  "Base function for isotherm models of pure components: Partial derivative of uptake w.r.t. pressure at constant temperature"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_adsorpt
+    "Partial derivative of the uptake w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the partial derivative
+of the equilibrium uptake with respect to the equilibrium pressure at constant temperature
+<i>dx_adsorpt_dp_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i> 
+and equilibrium temperature <i>T_adsorpt</i>. Defined inputs are the equilibrium 
+pressure <i>p_adsorpt</i>, the equilibrium temperature <i>T_adsorpt</i>, and the 
+coefficients of the isotherm model <i>c</i>. The coefficients of the isotherm model 
+<i>c</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. The partial 
+derivative of the equilibrium uptake with respect to the equilibrium pressure at 
+constant temperature<i>dx_adsorpt_dp_adsorpt</i> is defined as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_dx_dp;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_piT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_piT.mo
new file mode 100644
index 0000000..2b88185
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_piT.mo
@@ -0,0 +1,85 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_p_piT
+  "Base function for isotherm models of pure components: Pressure as function of reduced spreading pressure and temperature"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.ReducedSpreadingPressure pi "Reduced spreading pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start
+    "Lower bound of equilibrium pressure (required if pressure is calculated  
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start
+    "Upper bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  input Modelica.Units.SI.Pressure integral_pi_lb
+    "Lower limit of integral when calculating the reduced spreading pressure
+    numerically (should be 0)"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  input Real tolerance_p_adsorpt
+    "Tolerance for numerical calculation of equilibrium pressure (required if 
+    pressure is calculated numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance_pi
+    "Tolerance for numerical calculation of reduced spreading pressure (required 
+    if reduced spreading pressure is calculated numerically (i.e., integral))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  /* Note that optional numerical inputs do not have default values as this 
+  function is used as functional input argument within the "Ideal Adsorbed
+  Solution Theory," a multi-component adsorption isotherm model. Using default
+  values resulted in translation errors. */
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium pressure 
+<i>p_adsorpt</i> as a function of the reduced spreading pressure <i>pi</i> and 
+equilibrium temperature <i>T_adsorpt</i>. Defined inputs are the molar mass of 
+the adsorptive <i>M_adsorptive</i>, the reduced spreading pressure <i>pi</i>, 
+the equilibrium temperature <i>T_adsorpt</i>, and the coefficients of the isotherm 
+model <i>c</i>. The coefficients of the isotherm model <i>c</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Optional inputs regarding numerics are 
+the lower bound (<i>p_adsorpt_lb_start</i>) and upper bound (<i>p_adsorpt_ub_start</i>) 
+of the equilibrium pressure and the tolerance (<i>tolerance_p_adsorpt</i>), only 
+required if this function cannot be solved analytically. Further optional inputs 
+regarding numerics are the lower integral bound (<i>integral_pi_lb</i>) and the 
+tolerance (<i>integral_pi_lb</i>), only required if the reduced spreading pressure 
+cannot be solved analytically. Besides, this partial function defines the equilibrium 
+pressure <i>p_adsorpt</i> as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement 
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_p_piT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_piT_num.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_piT_num.mo
new file mode 100644
index 0000000..d2d8dd2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_piT_num.mo
@@ -0,0 +1,181 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_p_piT_num
+  "Base function for isotherm models of pure components: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT;
+
+  //
+  // Definition of protected replacable functions
+  //
+protected
+  replaceable function func_pi_pT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.pi_pT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT
+    "Reduced spreading pressure as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"));
+
+  //
+  // Definition of functions
+  //
+protected
+  function func_p_num
+    "Function used to find root (i.e., p_adsorpt) numerically"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input SorpLib.Units.ReducedSpreadingPressure pi
+      "Reduced spreading pressure";
+    input Modelica.Units.SI.MolarMass M_adsorptive
+      "Molar mass of adsorptive";
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature";
+    input Real c[:]
+      "Coefficients of isotherm model";
+    input Modelica.Units.SI.Pressure integral_pi_lb
+      "Lower limit of integral when calculating the reduced spreading pressure
+      numerically (should be 0)";
+    input Real tolerance
+      "Tolerance for numerical calculation (required if reduced spreading pressure
+      is calculated numerically";
+  algorithm
+    y := func_pi_pT(M_adsorptive=M_adsorptive, p_adsorpt=u, T_adsorpt=T_adsorpt,
+      c=c, integral_pi_lb=integral_pi_lb, tolerance=tolerance) - pi
+     "Function '0 = pi(M_adsorptive, p_adsorpt, T_adsorpt, c) - pi' used to find  
+      root (i.e., p_adsorpt) numerically";
+  end func_p_num;
+
+  //
+  // Definition of variables
+  //
+  Boolean bound_ok = false
+    "= true, if bounds are found such that func_p_num(lb) < 0 and func_p_num(ub) > 0";
+
+  Modelica.Units.SI.Pressure p_adsorpt_lb = p_adsorpt_lb_start
+    "Current best lower bound of equilibrium pressure";
+  Modelica.Units.SI.Pressure p_adsorpt_ub = p_adsorpt_ub_start
+    "Current best upper bound of equilibrium pressure";
+
+  SorpLib.Units.ReducedSpreadingPressure pi_lb=func_pi_pT(
+      M_adsorptive=M_adsorptive,
+      p_adsorpt=p_adsorpt_lb,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      integral_pi_lb=integral_pi_lb,
+      tolerance=tolerance_pi)
+    "Reduced spreading pressure at current best lower bound of equilibrium pressure";
+  SorpLib.Units.ReducedSpreadingPressure pi_ub=func_pi_pT(
+      M_adsorptive=M_adsorptive,
+      p_adsorpt=p_adsorpt_ub,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      integral_pi_lb=integral_pi_lb,
+      tolerance=tolerance_pi)
+    "Reduced spreading pressure at current best upper bound of equilibrium pressure";
+
+algorithm
+  //
+  // Find start values such that func_p_num(lb) < 0 and func_p_num(ub) > 0
+  //
+  // Reducing p_adsorpt reduces pi -> func_p_num(p_adsorpt) can become < 0
+  // Increasing p_adsorpt increases pi -> func_p_num(p_adsorpt) can become > 0
+  //
+  while not bound_ok loop
+    if Modelica.Math.isEqual(s1=pi_lb, s2=pi, eps=tolerance_p_adsorpt) then
+      p_adsorpt := p_adsorpt_lb;
+      bound_ok := true;
+      return;
+
+    elseif Modelica.Math.isEqual(s1=pi_ub, s2=pi, eps=tolerance_p_adsorpt) then
+      p_adsorpt := p_adsorpt_ub;
+      bound_ok := true;
+      return;
+
+    elseif pi_lb-pi < 0 and pi_ub-pi < 0 then
+      p_adsorpt_lb := p_adsorpt_ub;
+      pi_lb := pi_ub;
+
+      p_adsorpt_ub := p_adsorpt_ub*10;
+      pi_ub := func_pi_pT(M_adsorptive=M_adsorptive,
+        p_adsorpt=p_adsorpt_ub, T_adsorpt=T_adsorpt, c=c,
+        integral_pi_lb=integral_pi_lb, tolerance=tolerance_pi);
+
+    elseif pi_lb-pi > 0 and pi_ub-pi > 0 then
+      p_adsorpt_ub := p_adsorpt_lb;
+      pi_ub := pi_lb;
+
+      p_adsorpt_lb := if p_adsorpt_lb > Modelica.Constants.small then
+        p_adsorpt_lb*0.1 else 0;
+      pi_lb := func_pi_pT(M_adsorptive=M_adsorptive,
+        p_adsorpt=p_adsorpt_lb, T_adsorpt=T_adsorpt, c=c,
+        integral_pi_lb=integral_pi_lb, tolerance=tolerance_pi);
+
+    else
+      bound_ok := true;
+
+    end if;
+  end while;
+
+  //
+  // Find root in the interval lb <= root <= up
+  //
+  p_adsorpt := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+    f = function func_p_num(
+      pi=pi,
+      M_adsorptive=M_adsorptive,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      integral_pi_lb=integral_pi_lb,
+      tolerance=tolerance_pi),
+    u_min=p_adsorpt_lb,
+    u_max=p_adsorpt_ub,
+    tolerance=tolerance_p_adsorpt)
+    "Calculation of the equilibrium pressure of the adsorpt phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium pressure 
+<i>p_adsorpt</i> as a function of the reduced spreading pressure <i>pi</i> and 
+equilibrium temperature <i>T_adsorpt</i>. Defined inputs are the molar mass of 
+the adsorptive <i>M_adsorptive</i>, the reduced spreading pressure <i>pi</i>, 
+the equilibrium temperature <i>T_adsorpt</i>, and the coefficients of the isotherm 
+model <i>c</i>. The coefficients of the isotherm model <i>c</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Optional inputs regarding numerics are 
+the lower bound (<i>p_adsorpt_lb_start</i>) and upper bound (<i>p_adsorpt_ub_start</i>) 
+of the equilibrium pressure and the tolerance (<i>tolerance_p_adsorpt</i>), only 
+required if this function cannot be solved analytically. Further optional inputs 
+regarding numerics are the lower integral bound (<i>integral_pi_lb</i>) and the 
+tolerance (<i>integral_pi_lb</i>), only required if the reduced spreading pressure 
+cannot be solved analytically. Besides, this partial function defines the equilibrium 
+pressure <i>p_adsorpt</i> as the output.
+<br/><br/>
+With this function, the equilibrium pressure <i>p_adsorpt</i> is determined 
+numerically by solving a zero problem. The zero problem is as follows:
+</p>
+<pre>
+    f(p_adsorpt) = 0 => 0 = func_pi_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt, c=c) - pi;
+</pre>
+<p>
+The zero problem is solved using the numerically very efficient function 
+<a href=\"Modelica://Modelica.Math.Nonlinear.solveOneNonlinearEquation\">Modelica.Math.Nonlinear.solveOneNonlinearEquation</a>.
+For the application of this function, it must be ensured that <i>f(p_adsorpt)</i> 
+has a different sign for the upper and lower limits of <i>p_adsorpt</i>. To ensure 
+the different signs, the upper and lower limits are determined in an upstream loop.
+<br/><br/>
+Functions that inherit properties from this partial function have to redeclare
+the function <i>func_pi_pT</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_p_piT_num;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_xT.mo
new file mode 100644
index 0000000..ba44712
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_xT.mo
@@ -0,0 +1,70 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_p_xT
+  "Base function for isotherm models of pure components: Pressure as function of uptake and temperature"
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake x_adsorpt
+    "Equilibrium uptake of adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start
+    "Lower bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start
+    "Upper bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance
+    "Tolerance for numerical calculation (required if pressure is calculated
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  /* Note that optional numerical inputs do not have default values as this 
+  function is used as functional input argument within the "Ideal Adsorbed
+  Solution Theory," a multi-component adsorption isotherm model. Using default
+  values resulted in translation errors. */
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium 
+pressure <i>p_adsorpt</i> as a function of the equilibrium uptake <i>x_adsorpt</i> 
+and equilibrium temperature <i>T_adsorpt</i>. Defined inputs are the equilibrium 
+uptake <i>x_adsorpt</i>, the equilibrium temperature <i>T_adsorpt</i>, and the 
+coefficients of the isotherm model <i>c</i> as inputs. The coefficients of the
+isotherm model <i>c</i> may depend on the equilibrium temperature <i>T_adsorpt</i>.
+Optional inputs regarding numerics are the lower bound (<i>p_adsorpt_lb_start</i>) 
+and upper bound (<i>p_adsorpt_ub_start</i>) of the equilibrium pressure and the 
+tolerance (<i>tolerance</i>), only required if this function cannot be solved 
+analytically. Besides, the equilibrium pressure <i>p_adsorpt</i> is defined as 
+the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_p_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_xT_num.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_xT_num.mo
new file mode 100644
index 0000000..d329a16
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_p_xT_num.mo
@@ -0,0 +1,161 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_p_xT_num
+  "Base function for isotherm models of pure components: Pressure as function of uptake and temperature (numerical solution)"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT;
+
+  //
+  // Definition of protected replacable functions
+  //
+protected
+  replaceable function func_x_pT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.x_pT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT
+    "Calculates uptake as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"));
+
+  //
+  // Definition of functions
+  //
+protected
+  function func_p_num
+    "Function used to find root (i.e., p_adsorpt) numerically"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input SorpLib.Units.Uptake x_adsorpt
+      "Equilibrium uptake";
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature";
+    input Real c[:]
+      "Coefficients of isotherm model";
+  algorithm
+    y := func_x_pT(p_adsorpt=u, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps) - x_adsorpt
+     "Function '0 = x(p_adsorpt, T_adsorpt, c) - x_adsorpt' used to find root 
+      (i.e., p_adsorpt) numerically";
+  end func_p_num;
+
+  //
+  // Definition of variables
+  //
+  Boolean bound_ok = false
+    "= true, if bounds are found such that func_p_num(lb) < 0 and func_p_num(ub) > 0";
+
+  Modelica.Units.SI.Pressure p_adsorpt_lb = p_adsorpt_lb_start
+    "Current best lower bound of equilibrium pressure";
+  Modelica.Units.SI.Pressure p_adsorpt_ub = p_adsorpt_ub_start
+    "Current best upper bound of equilibrium pressure";
+
+  SorpLib.Units.Uptake x_adsorpt_lb = func_x_pT(
+    p_adsorpt=p_adsorpt_lb, T_adsorpt=T_adsorpt, c=c,
+    p_adsorpt_lb_start=1, p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Equilibrium uptake at current best lower bound of equilibrium pressure";
+  SorpLib.Units.Uptake x_adsorpt_ub = func_x_pT(
+    p_adsorpt=p_adsorpt_ub, T_adsorpt=T_adsorpt, c=c,
+    p_adsorpt_lb_start=1, p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Equilibrium uptake at current best upper bound of equilibrium pressure";
+
+algorithm
+  //
+  // Find start values such that func_p_num(lb) < 0 and func_p_num(ub) > 0
+  //
+  // Reducing p_adsorpt reduces x_adsorpt -> func_p_num(p_adsorpt) can become < 0
+  // Increasing p_adsorpt increases x_adsorpt -> func_p_num(p_adsorpt) can become > 0
+  //
+  while not bound_ok loop
+    if Modelica.Math.isEqual(s1=x_adsorpt_lb, s2=x_adsorpt, eps=tolerance) then
+      p_adsorpt := p_adsorpt_lb;
+      bound_ok := true;
+      return;
+
+    elseif Modelica.Math.isEqual(s1=x_adsorpt_ub, s2=x_adsorpt, eps=tolerance) then
+      p_adsorpt := p_adsorpt_ub;
+      bound_ok := true;
+      return;
+
+    elseif x_adsorpt_lb-x_adsorpt < 0 and x_adsorpt_ub-x_adsorpt < 0 then
+      p_adsorpt_lb := p_adsorpt_ub;
+      x_adsorpt_lb := x_adsorpt_ub;
+
+      p_adsorpt_ub := p_adsorpt_ub*10;
+      x_adsorpt_ub := func_x_pT(p_adsorpt=p_adsorpt_ub, T_adsorpt=T_adsorpt, c=c,
+        p_adsorpt_lb_start=1, p_adsorpt_ub_start=10,
+        tolerance=100*Modelica.Constants.eps);
+
+    elseif x_adsorpt_lb-x_adsorpt > 0 and x_adsorpt_ub-x_adsorpt > 0 then
+      p_adsorpt_ub := p_adsorpt_lb;
+      x_adsorpt_ub := x_adsorpt_lb;
+
+      p_adsorpt_lb := if p_adsorpt_lb > Modelica.Constants.small then
+        p_adsorpt_lb*0.1 else 0;
+      x_adsorpt_lb := func_x_pT(p_adsorpt=p_adsorpt_lb, T_adsorpt=T_adsorpt, c=c,
+        p_adsorpt_lb_start=1, p_adsorpt_ub_start=10,
+        tolerance=100*Modelica.Constants.eps);
+
+    else
+      bound_ok := true;
+
+    end if;
+  end while;
+
+  //
+  // Find root in the interval lb <= root <= up
+  //
+  p_adsorpt := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+    f = function func_p_num(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c),
+    u_min=p_adsorpt_lb,
+    u_max=p_adsorpt_ub,
+    tolerance=tolerance)
+    "Calculation of the equilibrium pressure of the adsorpt phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium 
+pressure <i>p_adsorpt</i> as a function of the equilibrium uptake <i>x_adsorpt</i> 
+and equilibrium temperature <i>T_adsorpt</i>. Defined inputs are the equilibrium 
+uptake <i>x_adsorpt</i>, the equilibrium temperature <i>T_adsorpt</i>, and the 
+coefficients of the isotherm model <i>c</i> as inputs. The coefficients of the
+isotherm model <i>c</i> may depend on the equilibrium temperature <i>T_adsorpt</i>. 
+Optional inputs regarding numerics are the lower bound (<i>p_adsorpt_lb_start</i>) 
+and upper bound (<i>p_adsorpt_ub_start</i>) of the equilibrium pressure and the 
+tolerance (<i>tolerance</i>). Besides, the equilibrium pressure <i>p_adsorpt</i> 
+is defined as the output.
+<br/><br/>
+With this function, the equilibrium pressure <i>p_adsorpt</i> is determined 
+numerically by solving a zero problem. The zero problem is as follows:
+</p>
+<pre>
+    f(p_adsorpt) = 0 => 0 = func_x_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt, c=c) - x_adsorpt;
+</pre>
+<p>
+The zero problem is solved using the numerically very efficient function 
+<a href=\"Modelica://Modelica.Math.Nonlinear.solveOneNonlinearEquation\">Modelica.Math.Nonlinear.solveOneNonlinearEquation</a>.
+For the application of this function, it must be ensured that <i>f(p_adsorpt)</i> 
+has a different sign for the upper and lower limits of <i>p_adsorpt</i>. To ensure 
+the different signs, the upper and lower limits are determined in an upstream loop.
+<br/><br/>
+Functions that inherit properties from this partial function have to redeclare
+the function <i>func_x_pT</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_p_xT_num;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_pi_pT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_pi_pT.mo
new file mode 100644
index 0000000..57376ca
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_pi_pT.mo
@@ -0,0 +1,68 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_pi_pT
+  "Base function for isotherm models of pure components: Reduced spreading pressure as function of pressure and temperature"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+
+  input Modelica.Units.SI.Pressure integral_pi_lb
+    "Lower limit of integral when calculating the reduced spreading pressure
+    numerically (should be 0)"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance
+    "Tolerance for numerical calculation (required if reduced spreading pressure
+    is calculated numerically (i.e., integral))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  /* Note that optional numerical inputs do not have default values as this 
+  function is used as functional input argument within the "Ideal Adsorbed
+  Solution Theory," a multi-component adsorption isotherm model. Using default
+  values resulted in translation errors. */
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the reduced spreading 
+pressure <i>pi</i> as a function of the equilibrium pressure <i>p_adsorpt</i> and 
+equilibrium temperature <i>T_adsorpt</i>. Defined inputs are the molar mass of 
+the adsorptive <i>M_adsorptive</i>, the equilibrium pressure <i>p_adsorpt</i>, 
+the equilibrium temperature <i>T_adsorpt</i>, and the coefficients of the isotherm 
+model <i>c</i>. The coefficients of the isotherm model <i>c</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Optional inputs regarding numerics are 
+the lower integral bound (<i>integral_pi_lb</i>) and the tolerance (<i>tolerance</i>), 
+only required if this function cannot be solved analytically. Besides, this partial 
+function defines the reduced spreading pressure <i>pi</i> as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement 
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_pi_pT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_pi_pT_num.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_pi_pT_num.mo
new file mode 100644
index 0000000..8cbc0b1
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_pi_pT_num.mo
@@ -0,0 +1,82 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_pi_pT_num
+  "Base function for isotherm models of pure components: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT;
+
+  //
+  // Definition of protected replacable functions
+  //
+protected
+  replaceable function func_x_pT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.x_pT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT
+    "Calculates uptake as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"));
+
+  //
+  // Definition of protected functions
+  //
+protected
+  function func_pi_num
+    "Integrand required for calculating the reduced spreading pressure numerically"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature";
+    input Real c[:]
+      "Coefficients of isotherm model";
+  algorithm
+    y := func_x_pT(p_adsorpt=u, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps) /
+      max(u, Modelica.Constants.small)
+      "Integrand 'x(p,T,c) / p' required for calculating the reduced spreading
+      pressure";
+  end func_pi_num;
+
+algorithm
+  pi := 1/M_adsorptive *
+    Modelica.Math.Nonlinear.quadratureLobatto(
+      f=function func_pi_num(T_adsorpt=T_adsorpt, c=c),
+      a=integral_pi_lb,
+      b=p_adsorpt,
+      tolerance=tolerance)
+    "Calculation of the reduced spreading pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the reduced spreading 
+pressure <i>pi</i> as a function of the equilibrium pressure <i>p_adsorpt</i> and 
+equilibrium temperature <i>T_adsorpt</i>. Defined inputs are the molar mass of 
+the adsorptive <i>M_adsorptive</i>, the equilibrium pressure <i>p_adsorpt</i>, 
+the equilibrium temperature <i>T_adsorpt</i>, and the coefficients of the isotherm 
+model <i>c</i>. The coefficients of the isotherm model <i>c</i> may depend on the 
+equilibrium temperature <i>T_adsorpt</i>. Optional inputs regarding numerics are 
+the lower integral bound (<i>integral_pi_lb</i>) and the tolerance (<i>tolerance</i>). 
+Besides, this partial function defines the reduced spreading pressure <i>pi</i> as 
+the output.
+<br/><br/>
+With this function, the reduced spreading pressure <i>pi</i> is determined 
+numerically by using the numerically very efficient function 
+<a href=\"Modelica://Modelica.Math.Nonlinear.quadratureLobatto\">Modelica.Math.Nonlinear.quadratureLobatto</a>.
+<br/><br/>
+Functions that inherit properties from this partial function have to redeclare
+the function <i>func_x_pT</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_pi_pT_num;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_x_pT.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_x_pT.mo
new file mode 100644
index 0000000..6983de3
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialPure_x_pT.mo
@@ -0,0 +1,70 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial function PartialPure_x_pT
+  "Base function for isotherm models of pure components: Uptake as function of pressure and temperature"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure;
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start
+    "Lower bound of equilibrium pressure (required if inverse is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start
+    "Upper bound of equilibrium pressure (required if inverse is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance
+    "Tolerance for numerical calculation (required if inverse is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  /* Note that optional numerical inputs do not have default values as this 
+  function is used as functional input argument within the "Ideal Adsorbed
+  Solution Theory," a multi-component adsorption isotherm model. Using default
+  values resulted in translation errors. */
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake x_adsorpt
+    "Equilibrium uptake of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores.
+<br/><br/>
+This partial function is the basic function for calculating the equilibrium uptake 
+<i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i> and 
+equilibrium temperature <i>T_adsorpt</i>. Defined inputs are the equilibrium pressure
+<i>p_adsorpt</i>, the equilibrium temperature <i>T_adsorpt</i>, and the coefficients 
+of the isotherm model <i>c</i>. The coefficients of the isotherm model <i>c</i> 
+may depend on the equilibrium temperature <i>T_adsorpt</i>. Optional inputs regarding 
+numerics are the lower bound (<i>p_adsorpt_lb_start</i>) and upper bound 
+(<i>p_adsorpt_ub_start</i>) of the equilibrium pressure and the tolerance 
+(<i>tolerance</i>), only required if the inverse of this function cannot be 
+solved analytically. Besides, the equilibrium uptake <i>x_adsorpt</i> is defined 
+as the output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to implement
+further inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPure_x_pT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMulti.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMulti.mo
new file mode 100644
index 0000000..afd39e3
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMulti.mo
@@ -0,0 +1,489 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial model PartialTestMulti
+  "Base model for testers of isotherm models describing multi component adsorption"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real p_adsorpt_der(unit="Pa/s") = 1
+    "Prescriped sloped of equilibrium pressure to test isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real T_adsorpt_der(unit="K/s") = 0
+    "Prescriped sloped of equilibrium temperature to test isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real[no_components-1] y_i_der(each unit="mol/(mol.s)")=
+    fill(0, no_components-1)
+    "Prescriped sloped of mole fractions of independent components in the gas or
+    vapor phase to test isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Pressure p_adsorpt_start = 0
+    "Start value of equilibrium pressure"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.MoleFraction[no_components-1] y_i_start=
+    fill(1/no_components, no_components-1)
+    "Start value of mole fractions of independent components in the gas or vapor
+    phase (sum must <= 1)"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_start = 298.15
+    "Start value of equilibrium temperature"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+
+  parameter Boolean print_asserts = true
+    "= true, if assertations shall be printed; otherwise, no assertations are printed"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_p_xyT = true
+    "= true, if function 'func_p_xyT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_y_pxT = true
+    "= true, if function 'func_y_pxT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_py_xT = true
+    "= true, if function 'func_py_xT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dx_dp = true
+    "= true, if function 'func_dx_dp' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dx_dy = true
+    "= true, if function 'func_dx_dy' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dx_dT = true
+    "= true, if function 'func_dx_dT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package IsothermModel =
+    SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponents
+    "Package providing all functions of the isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                choicesAllMatching=true);
+  parameter Integer no_components = 1
+    "Number of components of the isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Integer no_coefficients = 1
+    "Number of coefficients of the isotherm model (i.e., highest number among 
+    different components)"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.Pressure p_threshold_min = 0
+    "Threshold for partial pressures of all components: If a partial pressure is
+    below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="Numerics", group="Limiter"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-6
+    "Pressure difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="Numerics", group="Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real dy = 1e-6
+    "Mole fraction difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="Numerics", group="Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-6
+    "Temperature difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="Numerics", group="Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt(start=p_adsorpt_start, fixed=true)
+    "Equilibrium pressure";
+  Modelica.Units.SI.MoleFraction[no_components-1] y_i(start=y_i_start, each fixed=true)
+    "Independent mole fractions";
+  Modelica.Units.SI.Temperature T_adsorpt(start=T_adsorpt_start, fixed=true)
+    "Equilibrium temperature";
+
+  Modelica.Units.SI.Pressure p_adsorpt_inv_xyT
+    "Equilibrium pressure calculated via inverse function 'p_xyT'";
+  Modelica.Units.SI.Pressure p_adsorpt_inv_xT
+    "Equilibrium pressure calculated via inverse function 'p_xT'";
+
+  Modelica.Units.SI.MoleFraction[no_components-1] y_i_inv_pxT(each min=-1)
+    "Independent mole fractions calculated via inverse function 'p_pxT'";
+  Modelica.Units.SI.MoleFraction[no_components-1] y_i_inv_xT(each min=-1)
+    "Independent mole fractions calculated via inverse function 'p_xT'";
+
+  SorpLib.Units.Uptake[no_components] x_adsorpt
+    "Equilibrium uptakes";
+
+  SorpLib.Units.DerUptakeByPressure[no_components] dx_adsorpt_dp_adsorpt
+    "Partial derivative of the uptakes w.r.t. pressure at constant mole fractions
+    and temperature";
+  SorpLib.Units.DerUptakeByPressure[no_components] dx_adsorpt_dp_adsorpt_num
+    "Partial derivative of the uptakes w.r.t. pressure at constant mole fractions
+    and temperature calculated numerically";
+
+  SorpLib.Units.DerUptakeByMolarFraction[no_components,no_components-1] dx_adsorpt_dy_i
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    gas phase components at constant pressure and temperature";
+  SorpLib.Units.DerUptakeByMolarFraction[no_components,no_components-1] dx_adsorpt_dy_i_num
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    gas phase components at constant pressure and temperature calculated numerically";
+
+  SorpLib.Units.DerUptakeByTemperature[no_components] dx_adsorpt_dT_adsorpt
+    "Partial derivatives of the uptakes w.r.t. temperature at constant pressure 
+    and mole fractions";
+  SorpLib.Units.DerUptakeByTemperature[no_components] dx_adsorpt_dT_adsorpt_num
+    "Partial derivatives of the uptakes w.r.t. temperature at constant pressure 
+    and mole fractions calculated numerically";
+
+  Real[no_coefficients,no_components] c
+    "Coefficients of isotherm model";
+  Real[no_coefficients,no_components] dc_dT
+    "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+protected
+  Real[no_coefficients,no_components] c_pdT
+    "Coefficients of isotherm model: T + 1e-6 K";
+  Real[no_coefficients,no_components] c_mdT
+    "Coefficients of isotherm model: T - 1e-6 K";
+
+  function dx_dy_num
+    "Calculates partial derivatives of equilibrium uptakes w.r.t. independent mole
+    fractions numericalls at constant pressure and temperature"
+
+    //
+    // Note that this function is a workaround for OpenModelica because OpenModelica
+    // apparently cannot handle the assignment of a vector to the column of a
+    // matrix.
+    //
+
+    //
+    // Definition of inputs
+    //
+    input Real[:,:] c
+      "Coefficients of isotherm model";
+    input Real p_adsorpt
+      "Equilibrium pressure";
+    input Real[size(c,2)-1] y_i
+      "Independent mole fractions";
+    input Real T_adsorpt
+      "Equilibrium temperature";
+    input Real p_threshold_min
+      "Threshold for partial pressures of all components: If a partial pressure is
+      below the threshold, its value is set to the threshold";
+    input Real dy
+      "Mole fraction difference used to calculate partial derivatives numerically";
+
+    //
+    // Definition of outputs
+    //
+    output SorpLib.Units.DerUptakeByMolarFraction[size(c,2),size(c,2)-1] dx_adsorpt_dy_i_num
+      "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+      gas phase components calculated numerically";
+
+    //
+    // Definition of variables
+    //
+  protected
+    SorpLib.Units.DerUptakeByMolarFraction[size(c,2)] dx_adsorpt_dy_i_num_tmp
+      "Temporary partial derivatives of the uptakes w.r.t. the molar fraction 
+       of independent gas phase component at constant pressure and temperature
+       calculated numerically";
+
+  algorithm
+    for ind_y_i in 1:size(c,2)-1 loop
+      //
+      // Calculate partial darivatives for each independent mole fraction
+      //
+      dx_adsorpt_dy_i_num_tmp :=(IsothermModel.x_pyT(
+        p_adsorpt=p_adsorpt,
+        y_i=cat(1, y_i[1:ind_y_i - 1], {y_i[ind_y_i] + dy}, y_i[ind_y_i + 1:size(c,2) - 1]),
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min) .-
+        IsothermModel.x_pyT(
+        p_adsorpt=p_adsorpt,
+        y_i=cat(1, y_i[1:ind_y_i - 1], {y_i[ind_y_i] - dy}, y_i[ind_y_i + 1:size(c,2) - 1]),
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min)) ./ (2*dy)
+        "Temporary partial derivative of the uptake w.r.t. independent molar  
+        fraction at constant pressure and temeprature calculated numerically";
+
+        //
+        // Assign temporary results to output matrix
+        //
+        for ind_com in 1:size(c,2) loop
+          dx_adsorpt_dy_i_num[ind_com,ind_y_i] := dx_adsorpt_dy_i_num_tmp[ind_com]
+            "Partial derivatives of the uptakes w.r.t. the molar fractions of  
+            independent gas phase components at contant pressure and temperature
+            calculated numerically";
+        end for;
+    end for;
+  end dx_dy_num;
+
+equation
+  der(p_adsorpt) = p_adsorpt_der
+    "Predecsriped slope of p_adsorpt to demonstrate the isotherm model";
+  der(y_i) = y_i_der
+    "Predecsriped slope of y_i to demonstrate the isotherm model";
+  der(T_adsorpt) = T_adsorpt_der
+    "Predecsriped slope of T_adsorpt to demonstrate the isotherm model";
+
+  if check_func_p_xyT then
+    p_adsorpt_inv_xyT = IsothermModel.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt,
+      c=c, p_threshold_min=p_threshold_min)
+      "Equilibrium pressure calculated via the inverse function 'p_xyT'";
+  else
+    p_adsorpt_inv_xyT = -1
+      "Equilibrium pressure calculated via the inverse function 'p_xyT'";
+  end if;
+
+  if check_func_y_pxT then
+    y_i_inv_pxT = IsothermModel.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt,
+      c=c, p_threshold_min=p_threshold_min)
+      "Independent mole fractions calculated via the inverse function 'y_pxT'";
+  else
+    y_i_inv_pxT = fill(-1, no_components-1)
+      "Independent mole fractions calculated via the inverse function 'y_pxT'";
+  end if;
+
+  if check_func_py_xT then
+    (p_adsorpt_inv_xT, y_i_inv_xT) =
+      IsothermModel.py_xT(x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt,
+      c=c, p_threshold_min=p_threshold_min)
+      "Independent mole fractions calculated via the inverse function 'y_xT'";
+  else
+    p_adsorpt_inv_xT = -1
+      "Equilibrium pressure calculated via the inverse function 'p_xT'";
+    y_i_inv_xT = fill(-1, no_components-1)
+      "Independent mole fractions calculated via the inverse function 'y_xT'";
+  end if;
+
+  x_adsorpt = IsothermModel.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt,
+    c=c, p_threshold_min=p_threshold_min)
+    "Equilibrium uptakes";
+
+  if check_func_dx_dp then
+    dx_adsorpt_dp_adsorpt = IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt,
+      c=c, p_threshold_min=p_threshold_min)
+      "Partial derivative of the uptake w.r.t. pressure at constant mole fractions 
+      and temeprature";
+    dx_adsorpt_dp_adsorpt_num = (
+      IsothermModel.x_pyT(p_adsorpt=p_adsorpt+dp, y_i=y_i, T_adsorpt=T_adsorpt,
+      c=c, p_threshold_min=p_threshold_min) .-
+      IsothermModel.x_pyT(p_adsorpt=p_adsorpt-dp, y_i=y_i, T_adsorpt=T_adsorpt,
+      c=c, p_threshold_min=p_threshold_min)) ./
+      (2*dp)
+      "Partial derivative of the uptake w.r.t. pressure at constant mole fractions 
+      and temeprature calculated numerically";
+  else
+    dx_adsorpt_dp_adsorpt = fill(-1, no_components)
+      "Partial derivative of the uptake w.r.t. pressure at constant mole fractions 
+      and temeprature";
+    dx_adsorpt_dp_adsorpt_num = fill(-1, no_components)
+      "Partial derivative of the uptake w.r.t. pressure at constant mole fractions 
+      and temeprature calculated numerically";
+  end if;
+
+  if check_func_dx_dy then
+    dx_adsorpt_dy_i = IsothermModel.dx_dy(
+      p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt,
+      c=c, p_threshold_min=p_threshold_min)
+      "Partial derivative of the uptake w.r.t. independent molar fractions at 
+      constant pressure and temperature";
+
+    dx_adsorpt_dy_i_num = dx_dy_num(
+      p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c,
+      p_threshold_min=p_threshold_min,dy=dy)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure 
+      and temperature calculated numerically";
+  else
+    dx_adsorpt_dy_i = fill(-1, no_components, no_components-1)
+      "Partial derivative of the uptake w.r.t. independent molar fractions at 
+      constant pressure and temperature";
+    dx_adsorpt_dy_i_num = fill(-1, no_components, no_components-1)
+      "Partial derivative of the uptake w.r.t. independent molar fractions at 
+      constant pressure and temperature calculated numerically";
+  end if;
+
+  if check_func_dx_dT then
+    dx_adsorpt_dT_adsorpt = IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt,
+      c=c, dc_dT_adsorpt=dc_dT,
+      p_threshold_min=p_threshold_min)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure 
+      and mole fractions";
+    dx_adsorpt_dT_adsorpt_num = (
+      IsothermModel.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt+dT,
+      c=c_pdT, p_threshold_min=p_threshold_min) .-
+      IsothermModel.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt-dT,
+      c=c_mdT, p_threshold_min=p_threshold_min)) ./
+      (2*dT)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure 
+      and mole fractions calculated numerically";
+  else
+    dx_adsorpt_dT_adsorpt = fill(-1, no_components)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure 
+      and mole fractions";
+    dx_adsorpt_dT_adsorpt_num = fill(-1, no_components)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure 
+      and mole fractions calculated numerically";
+  end if;
+
+  //
+  // Definition of assertions: Check thermodynamics and numerical implementation
+  // of isotherm model
+  //
+  assert(1-sum(y_i) >= 0 and 1-sum(y_i) <= 1,
+    "Sum of mole fractions must be 1 mol/mol!",
+    level = AssertionLevel.error);
+
+  if print_asserts then
+    if check_func_p_xyT then
+      assert(abs(p_adsorpt-p_adsorpt_inv_xyT) < 1e-6,
+        "Inverse function of isotherm model is not valid: Deviation (|" +
+        String(abs(p_adsorpt-p_adsorpt_inv_xyT)) +
+        "|) is greater than 1e-6 Pa!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_y_pxT then
+      for ind_comp in 1:no_components-1 loop
+        assert(abs(y_i[ind_comp]-y_i_inv_pxT[ind_comp]) < 1e-6,
+          "Inverse function of isotherm model is not valid: For component " +
+          String(ind_comp) +
+          ", deviation (|" +
+          String(abs(y_i[ind_comp]-y_i_inv_pxT[ind_comp])) +
+          "|) is greater than 1e-6 mol/mol!",
+          level = AssertionLevel.warning);
+      end for;
+    end if;
+
+    if check_func_py_xT then
+      assert(abs(p_adsorpt-p_adsorpt_inv_xT) < 1e-6,
+        "Inverse function of isotherm model is not valid: Deviation (|" +
+        String(abs(p_adsorpt-p_adsorpt_inv_xT)) +
+        "|) is greater than 1e-6 Pa!",
+        level = AssertionLevel.warning);
+
+      for ind_comp in 1:no_components-1 loop
+        assert(abs(y_i[ind_comp]-y_i_inv_xT[ind_comp]) < 1e-6,
+          "Inverse function of isotherm model is not valid: For component " +
+          String(ind_comp) +
+          ", deviation (|" +
+          String(abs(y_i[ind_comp]-y_i_inv_xT[ind_comp])) +
+          "|) is greater than 1e-6 mol/mol!",
+          level = AssertionLevel.warning);
+      end for;
+    end if;
+
+    if check_func_dx_dp then
+      for ind_comp in 1:no_components loop
+        assert(abs(dx_adsorpt_dp_adsorpt[ind_comp]-dx_adsorpt_dp_adsorpt_num[ind_comp]) < 1e-6,
+          "Partial derivative of isotherm model w.r.t. pressure at constant " +
+          "mole fractions and temperature is not valid: For component " +
+          String(ind_comp) +
+          ", deviation (|"
+          + String(abs(dx_adsorpt_dp_adsorpt[ind_comp]-dx_adsorpt_dp_adsorpt_num[ind_comp])) +
+          "|) is greater than 1e-6 kg/(kg.Pa)!",
+          level = AssertionLevel.warning);
+      end for;
+    end if;
+
+    if check_func_dx_dy then
+      for ind_comp in 1:no_components loop
+        for ind_y_i in 1:no_components-1 loop
+          assert(abs(dx_adsorpt_dy_i[ind_comp,ind_y_i]-dx_adsorpt_dy_i_num[ind_comp,ind_y_i]) < 1e-6,
+            "Partial derivative of isotherm model w.r.t. pressure at constant " +
+            "pressure and temperature is not valid: For component " +
+            String(ind_comp) +
+            " and independent mole fraction " +
+            String(ind_y_i) +
+            ", deviation (|" +
+            String(abs(dx_adsorpt_dy_i[ind_comp,ind_y_i]-dx_adsorpt_dy_i_num[ind_comp,ind_y_i])) +
+            "|) is greater than 1e-6 kg.mol/(kg.mol)!",
+            level = AssertionLevel.warning);
+        end for;
+      end for;
+    end if;
+
+    if check_func_dx_dT then
+      for ind_comp in 1:no_components loop
+        assert(abs(dx_adsorpt_dT_adsorpt[ind_comp]-dx_adsorpt_dT_adsorpt_num[ind_comp]) < 1e-6,
+          "Partial derivative of isotherm model w.r.t. temperature at " +
+          "constant pressure and mole fractions is not valid: For component " +
+          String(ind_comp) +
+          ", deviation (|" +
+          String(abs(dx_adsorpt_dT_adsorpt[ind_comp]-dx_adsorpt_dT_adsorpt_num[ind_comp])) +
+          "|) is greater than 1e-6 kg/(kg.K)!",
+          level = AssertionLevel.warning);
+      end for;
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the basic model for all testers of isotherm models describing
+adsorption of multi components.
+<br/><br/>
+This partial model defines all relevant parameters, variables, and equations to
+check (1) the classical form of isotherm models, (2) the inverse forms of isotherm
+models, (3) the partial derivatives of the uptakes w.r.t. to pressure, (4) the 
+partial derivatives of the uptakes w.r.t. mole fractions of independent components
+in the gas or vapor phase, and (5) the partial derivatives of the uptake w.r.t. 
+temperature. All partial derivatives are also implemented as central finite 
+differences to check for the analytical implementation of the partial derivatives.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the number 
+of components and coefficients of the isotherm model <i>no_components</i> and
+<i>no_coefficients</i>, respectively, and have to redeclare the seven functions 
+of the isotherm model <i>func_x_pyT</i>, <i>func_p_xyT</i>, <i>func_y_pxT</i>, 
+<i>func_py_xT</i>, <i>func_dx_dp</i>, <i>func_dx_dy</i>, and <i>func_dx_dT</i>. 
+Besides, the coefficients of the isotherm model (i.e., <i>c</i>, <i>c_pdT</i>, 
+and <i>c_mdT</i>) and their partial derivatives with respect to temperature 
+(i.e., <i>dc_dT</i>) have to be implemented. Additionally, it has to be specified 
+whether the equilibrium pressure (<i>p_adsorpt_der</i>), the mole fractions of
+independent components in the gas or vapor phase (<i>y_i_der</i>), or the 
+equilibrium temperature (<i>T_adsorpt_der</i>) changes with time.
+</p>
+</html>"));
+end PartialTestMulti;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST.mo
new file mode 100644
index 0000000..f8df5e2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST.mo
@@ -0,0 +1,290 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial model PartialTestMultiIAST
+  "Base model for testers of isotherm models describing multi component adsorption based on the ideal adsorbed solution theory"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real p_adsorpt_der(unit="Pa/s") = 1
+    "Prescriped sloped of equilibrium pressure to test isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real T_adsorpt_der(unit="K/s") = 0
+    "Prescriped sloped of equilibrium temperature to test isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real[no_components-1] y_i_der(each unit="mol/(mol.s)")=
+    fill(0, no_components-1)
+    "Prescriped sloped of mole fractions of independent components in the gas or
+    vapor phase to test isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Pressure p_adsorpt_start = 0
+    "Start value of equilibrium pressure"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.MoleFraction[no_components-1] y_i_start=
+    fill(1/no_components, no_components-1)
+    "Start value of mole fractions of independent components in the gas or vapor
+    phase (sum must <= 1)"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_start = 298.15
+    "Start value of equilibrium temperature"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+
+  parameter Boolean print_asserts = true
+    "= true, if assertations shall be printed; otherwise, no assertations are printed"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_p_xyT = true
+    "= true, if function 'func_p_xyT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_y_pxT = true
+    "= true, if function 'func_y_pxT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_py_xT = true
+    "= true, if function 'func_py_xT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dx_dp = true
+    "= true, if function 'func_dx_dp' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dx_dy = true
+    "= true, if function 'func_dx_dy' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dx_dT = true
+    "= true, if function 'func_dx_dT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package IsothermModel =
+    SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponentsIAST
+    "Package providing all functions of the IAST isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                choicesAllMatching=true);
+  parameter Integer no_components = 1
+    "Number of components of the isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.MolarMass[no_components] M_i = fill(1, no_components)
+    "Molar masses of the components"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package IsothermModelComponent1 =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents
+    "Package providing all functions of the isotherm model of component 1"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                choicesAllMatching=true);
+  parameter Integer no_coefficients_1 = 1
+    "Number of coefficients of the first isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package IsothermModelComponent2 =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents
+    "Package providing all functions of the isotherm model of component 2"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                choicesAllMatching=true);
+  parameter Integer no_coefficients_2 = 1
+    "Number of coefficients of the second isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST num
+    "Record definining numerics of the IAST algorithms"
+    annotation (Dialog(tab="Numerics", group="IAST"),
+                choicesAllMatching=true);
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-4
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure"
+    annotation (Dialog(tab="Numerics", group="IAST"));
+  parameter Real dy = 1e-4
+    "Mole fraction difference used to calculate partial derivatives w.r.t. independent
+    mole fractions"
+    annotation (Dialog(tab="Numerics", group="IAST"));
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-4
+    "Temperature difference used to calculate partial derivatives w.r.t. temperature"
+    annotation (Dialog(tab="Numerics", group="IAST"));
+  parameter SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_1
+    "Record definining numerics of the first component's isotherm model"
+    annotation (Dialog(tab="Numerics", group="Components"),
+                choicesAllMatching=true);
+  parameter SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_2
+    "Record definining numerics of the second component's isotherm model"
+    annotation (Dialog(tab="Numerics", group="Components"),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt(start=p_adsorpt_start, fixed=true)
+    "Equilibrium pressure";
+  Modelica.Units.SI.MoleFraction[no_components-1] y_i(start=y_i_start, each fixed=true)
+    "Independent mole fractions";
+  Modelica.Units.SI.Temperature T_adsorpt(start=T_adsorpt_start, fixed=true)
+    "Equilibrium temperature";
+
+  Modelica.Units.SI.Pressure p_adsorpt_inv_xyT
+    "Equilibrium pressure calculated via inverse function 'p_xyT'";
+  Modelica.Units.SI.Pressure p_adsorpt_inv_xT
+    "Equilibrium pressure calculated via inverse function 'p_xT'";
+
+  Modelica.Units.SI.MoleFraction[no_components-1] y_i_inv_pxT(each min=-1)
+    "Independent mole fractions calculated via inverse function 'p_pxT'";
+  Modelica.Units.SI.MoleFraction[no_components-1] y_i_inv_xT(each min=-1)
+    "Independent mole fractions calculated via inverse function 'p_xT'";
+
+  SorpLib.Units.Uptake[no_components] x_adsorpt
+    "Equilibrium uptakes";
+
+  SorpLib.Units.DerUptakeByPressure[no_components] dx_adsorpt_dp_adsorpt
+    "Partial derivative of the uptakes w.r.t. pressure";
+  SorpLib.Units.DerUptakeByMolarFraction[no_components,no_components-1] dx_adsorpt_dy_i
+    "Partial derivatives of the uptakes w.r.t. the molar fractions of independent 
+    gas phase components";
+  SorpLib.Units.DerUptakeByTemperature[no_components] dx_adsorpt_dT_adsorpt
+    "Partial derivatives of the uptakes w.r.t. temperature";
+
+  Real[no_coefficients_1] c_1
+    "Coefficients of the first isotherm model";
+  Real[no_coefficients_2] c_2
+    "Coefficients of the second isotherm model";
+
+protected
+  Real[no_coefficients_1] c_pdT_1
+    "Coefficients of the first isotherm model: T + 1e-6 K";
+  Real[no_coefficients_1] c_mdT_1
+    "Coefficients of the first isotherm model: T - 1e-6 K";
+
+  Real[no_coefficients_2] c_pdT_2
+    "Coefficients of the second isotherm model: T + 1e-6 K";
+  Real[no_coefficients_2] c_mdT_2
+    "Coefficients of the second isotherm model: T - 1e-6 K";
+
+equation
+  der(p_adsorpt) = p_adsorpt_der
+    "Predecsriped slope of p_adsorpt to demonstrate the isotherm model";
+  der(y_i) = y_i_der
+    "Predecsriped slope of y_i to demonstrate the isotherm model";
+  der(T_adsorpt) = T_adsorpt_der
+    "Predecsriped slope of T_adsorpt to demonstrate the isotherm model";
+
+  //
+  // Definition of assertions: Check thermodynamics and numerical implementation
+  // of isotherm model
+  //
+  assert(1-sum(y_i) >= 0 and 1-sum(y_i) <= 1,
+    "Sum of mole fractions must be 1 mol/mol!",
+    level = AssertionLevel.error);
+
+  if print_asserts then
+    if check_func_p_xyT then
+      assert(abs(p_adsorpt-p_adsorpt_inv_xyT) < 1e-6,
+        "Inverse function of isotherm model is not valid: Deviation (|" +
+        String(abs(p_adsorpt-p_adsorpt_inv_xyT)) +
+        "|) is greater than 1e-6 Pa!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_y_pxT then
+      for ind_comp in 1:no_components-1 loop
+        assert(abs(y_i[ind_comp]-y_i_inv_pxT[ind_comp]) < 1e-6,
+          "Inverse function of isotherm model is not valid: For component " +
+          String(ind_comp) +
+          ", deviation (|" +
+          String(abs(y_i[ind_comp]-y_i_inv_pxT[ind_comp])) +
+          "|) is greater than 1e-6 mol/mol!",
+          level = AssertionLevel.warning);
+      end for;
+    end if;
+
+    if check_func_py_xT then
+      assert(abs(p_adsorpt-p_adsorpt_inv_xT) < 1e-6,
+        "Inverse function of isotherm model is not valid: Deviation (|" +
+        String(abs(p_adsorpt-p_adsorpt_inv_xT)) +
+        "|) is greater than 1e-6 Pa!",
+        level = AssertionLevel.warning);
+
+      for ind_comp in 1:no_components-1 loop
+        assert(abs(y_i[ind_comp]-y_i_inv_xT[ind_comp]) < 1e-6,
+          "Inverse function of isotherm model is not valid: For component " +
+          String(ind_comp) +
+          ", deviation (|" +
+          String(abs(y_i[ind_comp]-y_i_inv_xT[ind_comp])) +
+          "|) is greater than 1e-6 mol/mol!",
+          level = AssertionLevel.warning);
+      end for;
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the basic model for all testers of isotherm models 
+based on the ideal adsorbed solution theory (IAST) describing the adsorption 
+of multi components.
+<br/><br/>
+This partial model defines all relevant parameters, variables, and equations to
+check (1) the classical form of isotherm models, (2) the inverse forms of isotherm
+models, (3) the partial derivatives of the uptakes w.r.t. to pressure, (4) the 
+partial derivatives of the uptakes w.r.t. mole fractions of independent components
+in the gas or vapor phase, and (5) the partial derivatives of the uptake w.r.t. 
+temperature.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the number 
+of components <i>no_components</i> and number of coefficients for each pure 
+component isotherm model <i>no_coefficients_i</i>, respectively, and have to redeclare 
+all functions of the multi and pure component isotherm models <i>func_i</i>. 
+Besides, the coefficients of each isotherm model (i.e., <i>c_i</i>, <i>c_pdT_i</i>, 
+and <i>c_mdT_i</i>) have to be implemented. Additionally, it has to be specified 
+whether the equilibrium pressure (<i>p_adsorpt_der</i>), the mole fractions of
+independent components in the gas or vapor phase (<i>y_i_der</i>), or the 
+equilibrium temperature (<i>T_adsorpt_der</i>) changes with time. Finally, the
+algorithm has to be complemented such that the functions of the multi component
+isotherm model <i>func_i</i> are used.
+<br/><br/>
+Note that the parameters of this model only allow to check the IAST for two
+components. To check the IAST for more than two components, further paramters
+have to be added.
+</p>
+</html>"));
+end PartialTestMultiIAST;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST_N2.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST_N2.mo
new file mode 100644
index 0000000..1b88104
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST_N2.mo
@@ -0,0 +1,242 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial model PartialTestMultiIAST_N2
+  "Base model for testers of isotherm models describing two-component adsorption based on the ideal adsorbed solution theory"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST(
+      redeclare final package IsothermModel =
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2);
+
+equation
+  if check_func_p_xyT then
+    p_adsorpt_inv_xyT = IsothermModel.p_xyT(
+      x_adsorpt=x_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2)
+      "Equilibrium pressure calculated via the inverse function 'p_xyT'";
+  else
+    p_adsorpt_inv_xyT = -1
+      "Equilibrium pressure calculated via the inverse function 'p_xyT'";
+  end if;
+
+  if check_func_y_pxT then
+    y_i_inv_pxT = IsothermModel.y_pxT(
+      p_adsorpt=p_adsorpt,
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2)
+      "Independent mole fractions calculated via the inverse function 'y_pxT'";
+  else
+    y_i_inv_pxT = fill(-1, no_components-1)
+      "Independent mole fractions calculated via the inverse function 'y_pxT'";
+  end if;
+
+  if check_func_py_xT then
+    (p_adsorpt_inv_xT, y_i_inv_xT) = IsothermModel.py_xT(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2)
+      "Independent mole fractions calculated via the inverse function 'y_xT'";
+  else
+    p_adsorpt_inv_xT = -1
+      "Equilibrium pressure calculated via the inverse function 'p_xT'";
+    y_i_inv_xT = fill(-1, no_components-1)
+      "Independent mole fractions calculated via the inverse function 'y_xT'";
+  end if;
+
+  x_adsorpt = IsothermModel.x_pyT(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    M_i=M_i,
+    c_1=c_1,
+    c_2=c_2,
+    func_x_pT_1=IsothermModelComponent1.x_pT,
+    func_p_xT_1=IsothermModelComponent1.p_xT,
+    func_dx_dp_1=IsothermModelComponent1.dx_dp,
+    func_pi_pT_1=IsothermModelComponent1.pi_pT,
+    func_p_piT_1=IsothermModelComponent1.p_piT,
+    func_x_pT_2=IsothermModelComponent2.x_pT,
+    func_p_xT_2=IsothermModelComponent2.p_xT,
+    func_dx_dp_2=IsothermModelComponent2.dx_dp,
+    func_pi_pT_2=IsothermModelComponent2.pi_pT,
+    func_p_piT_2=IsothermModelComponent2.p_piT,
+    num=num,
+    num_comp_1=num_comp_1,
+    num_comp_2=num_comp_2)
+    "Equilibrium uptakes";
+
+  if check_func_dx_dp then
+    dx_adsorpt_dp_adsorpt = IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      dp=dp)
+      "Partial derivative of the uptake w.r.t. pressure at constant mole fractions
+      and temperature";
+  else
+    dx_adsorpt_dp_adsorpt = fill(-1, no_components)
+      "Partial derivative of the uptake w.r.t. pressure at constant mole fractions
+      and temperature";
+  end if;
+
+  if check_func_dx_dy then
+    dx_adsorpt_dy_i = IsothermModel.dx_dy(
+      p_adsorpt=p_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      dy=dy)
+      "Partial derivative of the uptake w.r.t. independent molar fractions at
+      constant pressure and temperature";
+  else
+    dx_adsorpt_dy_i = fill(-1, no_components, no_components-1)
+      "Partial derivative of the uptake w.r.t. independent molar fractions at
+      constant pressure and temperature";
+  end if;
+
+  if check_func_dx_dT then
+    dx_adsorpt_dT_adsorpt = IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_pdT_1=c_pdT_1,
+      c_mdT_1=c_mdT_1,
+      c_pdT_2=c_pdT_2,
+      c_mdT_2=c_mdT_2,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      dT=dT)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure
+      and mole fractions";
+  else
+    dx_adsorpt_dT_adsorpt = fill(-1, no_components)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure
+      and mole fractions";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the basic model for all testers of isotherm models 
+based on the ideal adsorbed solution theory (IAST) describing the adsorption 
+of two components.
+<br/><br/>
+This partial model defines all relevant parameters, variables, and equations to
+check (1) the classical form of isotherm models, (2) the inverse forms of isotherm
+models, (3) the partial derivatives of the uptakes w.r.t. to pressure, (4) the 
+partial derivatives of the uptakes w.r.t. mole fractions of independent components
+in the gas or vapor phase, and (5) the partial derivatives of the uptake w.r.t. 
+temperature.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the number 
+of components <i>no_components</i> and number of coefficients for each pure 
+component isotherm model <i>no_coefficients_i</i>, respectively, and have to redeclare 
+all functions of the multi and pure component isotherm models <i>func_i</i>. 
+Besides, the coefficients of each isotherm model (i.e., <i>c_i</i>, <i>c_pdT_i</i>, 
+and <i>c_mdT_i</i>) have to be implemented. Additionally, it has to be specified 
+whether the equilibrium pressure (<i>p_adsorpt_der</i>), the mole fractions of
+independent components in the gas or vapor phase (<i>y_i_der</i>), or the 
+equilibrium temperature (<i>T_adsorpt_der</i>) changes with time.
+</p>
+</html>"));
+end PartialTestMultiIAST_N2;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST_N3.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST_N3.mo
new file mode 100644
index 0000000..b868b5c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestMultiIAST_N3.mo
@@ -0,0 +1,326 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial model PartialTestMultiIAST_N3
+  "Base model for testers of isotherm models describing three-component adsorption based on the ideal adsorbed solution theory"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST(
+      redeclare final package IsothermModel =
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3);
+
+  //
+  // Definition of parameters
+  //
+  replaceable package IsothermModelComponent3 =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents
+    "Package providing all functions of the isotherm model of component 3"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                choicesAllMatching=true);
+  parameter Integer no_coefficients_3 = 1
+    "Number of coefficients of the third isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+    "Record definining numerics of the third component's isotherm model"
+    annotation (Dialog(tab="Numerics", group="Components"),
+                choicesAllMatching=true);
+
+  //
+  // Definition of variables
+  //
+  Real[no_coefficients_3] c_3
+    "Coefficients of the third isotherm model";
+
+protected
+  Real[no_coefficients_3] c_pdT_3
+    "Coefficients of the third isotherm model: T + 1e-6 K";
+  Real[no_coefficients_3] c_mdT_3
+    "Coefficients of the third isotherm model: T - 1e-6 K";
+
+equation
+  if check_func_p_xyT then
+    p_adsorpt_inv_xyT = IsothermModel.p_xyT(
+      x_adsorpt=x_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      func_x_pT_3=IsothermModelComponent3.x_pT,
+      func_p_xT_3=IsothermModelComponent3.p_xT,
+      func_dx_dp_3=IsothermModelComponent3.dx_dp,
+      func_pi_pT_3=IsothermModelComponent3.pi_pT,
+      func_p_piT_3=IsothermModelComponent3.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3)
+      "Equilibrium pressure calculated via the inverse function 'p_xyT'";
+  else
+    p_adsorpt_inv_xyT = -1
+      "Equilibrium pressure calculated via the inverse function 'p_xyT'";
+  end if;
+
+  if check_func_y_pxT then
+    y_i_inv_pxT = IsothermModel.y_pxT(
+      p_adsorpt=p_adsorpt,
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      func_x_pT_3=IsothermModelComponent3.x_pT,
+      func_p_xT_3=IsothermModelComponent3.p_xT,
+      func_dx_dp_3=IsothermModelComponent3.dx_dp,
+      func_pi_pT_3=IsothermModelComponent3.pi_pT,
+      func_p_piT_3=IsothermModelComponent3.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3)
+      "Independent mole fractions calculated via the inverse function 'y_pxT'";
+  else
+    y_i_inv_pxT = fill(-1, no_components-1)
+      "Independent mole fractions calculated via the inverse function 'y_pxT'";
+  end if;
+
+  if check_func_py_xT then
+    (p_adsorpt_inv_xT, y_i_inv_xT) = IsothermModel.py_xT(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      func_x_pT_3=IsothermModelComponent3.x_pT,
+      func_p_xT_3=IsothermModelComponent3.p_xT,
+      func_dx_dp_3=IsothermModelComponent3.dx_dp,
+      func_pi_pT_3=IsothermModelComponent3.pi_pT,
+      func_p_piT_3=IsothermModelComponent3.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3)
+      "Independent mole fractions calculated via the inverse function 'y_xT'";
+  else
+    p_adsorpt_inv_xT = -1
+      "Equilibrium pressure calculated via the inverse function 'p_xT'";
+    y_i_inv_xT = fill(-1, no_components-1)
+      "Independent mole fractions calculated via the inverse function 'y_xT'";
+  end if;
+
+  x_adsorpt = IsothermModel.x_pyT(
+    p_adsorpt=p_adsorpt,
+    y_i=y_i,
+    T_adsorpt=T_adsorpt,
+    M_i=M_i,
+    c_1=c_1,
+    c_2=c_2,
+    c_3=c_3,
+    func_x_pT_1=IsothermModelComponent1.x_pT,
+    func_p_xT_1=IsothermModelComponent1.p_xT,
+    func_dx_dp_1=IsothermModelComponent1.dx_dp,
+    func_pi_pT_1=IsothermModelComponent1.pi_pT,
+    func_p_piT_1=IsothermModelComponent1.p_piT,
+    func_x_pT_2=IsothermModelComponent2.x_pT,
+    func_p_xT_2=IsothermModelComponent2.p_xT,
+    func_dx_dp_2=IsothermModelComponent2.dx_dp,
+    func_pi_pT_2=IsothermModelComponent2.pi_pT,
+    func_p_piT_2=IsothermModelComponent2.p_piT,
+    func_x_pT_3=IsothermModelComponent3.x_pT,
+    func_p_xT_3=IsothermModelComponent3.p_xT,
+    func_dx_dp_3=IsothermModelComponent3.dx_dp,
+    func_pi_pT_3=IsothermModelComponent3.pi_pT,
+    func_p_piT_3=IsothermModelComponent3.p_piT,
+    num=num,
+    num_comp_1=num_comp_1,
+    num_comp_2=num_comp_2,
+    num_comp_3=num_comp_3)
+    "Equilibrium uptakes";
+
+  if check_func_dx_dp then
+    dx_adsorpt_dp_adsorpt = IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      func_x_pT_3=IsothermModelComponent3.x_pT,
+      func_p_xT_3=IsothermModelComponent3.p_xT,
+      func_dx_dp_3=IsothermModelComponent3.dx_dp,
+      func_pi_pT_3=IsothermModelComponent3.pi_pT,
+      func_p_piT_3=IsothermModelComponent3.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3,
+      dp=dp)
+      "Partial derivative of the uptake w.r.t. pressure at constant mole fractions
+      and temperature";
+  else
+    dx_adsorpt_dp_adsorpt = fill(-1, no_components)
+      "Partial derivative of the uptake w.r.t. pressure at constant mole fractions
+      and temperature";
+  end if;
+
+  if check_func_dx_dy then
+    dx_adsorpt_dy_i = IsothermModel.dx_dy(
+      p_adsorpt=p_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      func_x_pT_3=IsothermModelComponent3.x_pT,
+      func_p_xT_3=IsothermModelComponent3.p_xT,
+      func_dx_dp_3=IsothermModelComponent3.dx_dp,
+      func_pi_pT_3=IsothermModelComponent3.pi_pT,
+      func_p_piT_3=IsothermModelComponent3.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3,
+      dy=dy)
+      "Partial derivative of the uptake w.r.t. independent molar fractions at
+      constant pressure and temperature";
+  else
+    dx_adsorpt_dy_i = fill(-1, no_components, no_components-1)
+      "Partial derivative of the uptake w.r.t. independent molar fractions at
+      constant pressure and temperature";
+  end if;
+
+  if check_func_dx_dT then
+    dx_adsorpt_dT_adsorpt = IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      c_pdT_1=c_pdT_1,
+      c_mdT_1=c_mdT_1,
+      c_pdT_2=c_pdT_2,
+      c_mdT_2=c_mdT_2,
+      c_pdT_3=c_pdT_3,
+      c_mdT_3=c_mdT_3,
+      func_x_pT_1=IsothermModelComponent1.x_pT,
+      func_p_xT_1=IsothermModelComponent1.p_xT,
+      func_dx_dp_1=IsothermModelComponent1.dx_dp,
+      func_pi_pT_1=IsothermModelComponent1.pi_pT,
+      func_p_piT_1=IsothermModelComponent1.p_piT,
+      func_x_pT_2=IsothermModelComponent2.x_pT,
+      func_p_xT_2=IsothermModelComponent2.p_xT,
+      func_dx_dp_2=IsothermModelComponent2.dx_dp,
+      func_pi_pT_2=IsothermModelComponent2.pi_pT,
+      func_p_piT_2=IsothermModelComponent2.p_piT,
+      func_x_pT_3=IsothermModelComponent3.x_pT,
+      func_p_xT_3=IsothermModelComponent3.p_xT,
+      func_dx_dp_3=IsothermModelComponent3.dx_dp,
+      func_pi_pT_3=IsothermModelComponent3.pi_pT,
+      func_p_piT_3=IsothermModelComponent3.p_piT,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3,
+      dT=dT)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure
+      and mole fractions";
+  else
+    dx_adsorpt_dT_adsorpt = fill(-1, no_components)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure
+      and mole fractions";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the basic model for all testers of isotherm models 
+based on the ideal adsorbed solution theory (IAST) describing the adsorption 
+of three components.
+<br/><br/>
+This partial model defines all relevant parameters, variables, and equations to
+check (1) the classical form of isotherm models, (2) the inverse forms of isotherm
+models, (3) the partial derivatives of the uptakes w.r.t. to pressure, (4) the 
+partial derivatives of the uptakes w.r.t. mole fractions of independent components
+in the gas or vapor phase, and (5) the partial derivatives of the uptake w.r.t. 
+temperature.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the number 
+of components <i>no_components</i> and number of coefficients for each pure 
+component isotherm model <i>no_coefficients_i</i>, respectively, and have to redeclare 
+all functions of the multi and pure component isotherm models <i>func_i</i>. 
+Besides, the coefficients of each isotherm model (i.e., <i>c_i</i>, <i>c_pdT_i</i>, 
+and <i>c_mdT_i</i>) have to be implemented. Additionally, it has to be specified 
+whether the equilibrium pressure (<i>p_adsorpt_der</i>), the mole fractions of
+independent components in the gas or vapor phase (<i>y_i_der</i>), or the 
+equilibrium temperature (<i>T_adsorpt_der</i>) changes with time.
+</p>
+</html>"));
+end PartialTestMultiIAST_N3;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestPure.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestPure.mo
new file mode 100644
index 0000000..dc4ea9f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestPure.mo
@@ -0,0 +1,491 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial model PartialTestPure
+  "Base model for testers of isotherm models describing pure component adsorption"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real p_adsorpt_der(unit="Pa/s") = 1
+    "Prescriped sloped of equilibrium pressure to test isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real T_adsorpt_der(unit="K/s") = 0
+    "Prescriped sloped of equilibrium temperature to test isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Pressure p_adsorpt_start = 0
+    "Start value of equilibrium pressure"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_start = 298.15
+    "Start value of equilibrium temperature"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.MolarMass M_adsorptive = 0.018
+    "Molar mass of adsorptive"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean print_asserts = true
+    "= true, if assertations shall be printed; otherwise, no assertations are printed"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_p_xT = true
+    "= true, if function 'func_p_xT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dx_dp = true
+    "= true, if function 'func_dx_dp' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dx_dT = true
+    "= true, if function 'func_dx_dT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_ddx_dp_dp = true
+    "= true, if function 'func_ddx_dp_dp' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_ddx_dT_dT = true
+    "= true, if function 'func_ddx_dT_dT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_ddx_dp_dT = true
+    "= true, if function 'ddx_dp_dT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_pi_pT = true
+    "= true, if function 'func_pi_pT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_p_piT = true
+    "= true, if function 'func_p_piT' is checked; otherwise, function is not checked"
+    annotation (Dialog(tab="General", group="Checks", enable=check_func_pi_pT),
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package IsothermModel =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents
+    "Package providing all functions of the isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                choicesAllMatching=true);
+  parameter Integer no_coefficients = 1
+    "Number of coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Isotherm Model"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Real tolerance_p_inv = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation of equilibrium pressure via function 'p_xT'
+    (only used if required)"
+    annotation (Dialog(tab="Numerics", group="Tolerances"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_p_pi = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation of equilibrium pressure via function 'p_piT'
+    (only used if required)"
+    annotation (Dialog(tab="Numerics", group="Tolerances"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_pi = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation of reduced spreading pressure (only used 
+    if required)"
+    annotation (Dialog(tab="Numerics", group="Tolerances"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.Pressure p_lb_pi= 0
+    "Lower bound to calculate reduced spreading pressure (should be 0)"
+    annotation (Dialog(tab="Numerics", group="Reduced spreading pressure"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-6
+    "Pressure difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="Numerics", group="Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-6
+    "Temperature difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="Numerics", group="Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt(start=p_adsorpt_start, fixed=true)
+    "Equilibrium pressure";
+  Modelica.Units.SI.Temperature T_adsorpt(start=T_adsorpt_start, fixed=true)
+    "Equilibrium temperature";
+  SorpLib.Units.Uptake x_adsorpt
+    "Equilibrium uptake";
+
+  Modelica.Units.SI.Pressure p_adsorpt_inv
+    "Equilibrium pressure calculated via inverse function of the isotherm model";
+  Modelica.Units.SI.Pressure p_adsorpt_pi
+    "Equilibrium pressure calculated via reduced spreading pressure";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_adsorpt
+    "Partial derivative of the uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp_adsorpt_num
+    "Partial derivative of the uptake w.r.t. pressure at constant temperature
+    calculated numerically";
+
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_adsorpt
+    "Partial derivative of the uptake w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT_adsorpt_num
+    "Partial derivative of the uptake w.r.t. temperature at constant pressure
+    calculated numerically";
+
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_adsorpt_dp_adsorpt
+    "Second-order partial derivative of the uptake w.r.t. pressure at constant 
+    temperature";
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_adsorpt_dp_adsorpt_num
+    "Second-order partial derivative of the uptake w.r.t. pressure at constant 
+    temperature calculated numerically";
+
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_adsorpt_dT_adsorpt
+    "Second-order partial derivative of the uptake w.r.t. temperature at constant 
+    pressure";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_adsorpt_dT_adsorpt_num
+    "Second-order partial derivative of the uptake w.r.t. temperature at constant 
+    pressure calculated numerically";
+
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_adsorpt_dT_adsorpt
+    "Second-order partial derivative of the uptake w.r.t. pressure and temperature";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_adsorpt_dT_adsorpt_num
+    "Second-order partial derivative of the uptake w.r.t. pressure and temperature
+     calculated numerically";
+
+  SorpLib.Units.ReducedSpreadingPressure red_spreading_pressure
+    "Reduced spreading pressure";
+  SorpLib.Units.ReducedSpreadingPressure red_spreading_pressure_num
+    "Reduced spreading pressure calculated numerically";
+
+  Real[no_coefficients] c
+    "Coefficients of isotherm model";
+
+  Real[no_coefficients] dc_dT
+    "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+  Real[no_coefficients] dc_dT_num = (c_pdT .- c_mdT) ./ (2 * dT)
+    "Partial derivative of coefficients of isotherm model w.r.t. temperature
+    calculated numerically";
+
+  Real[no_coefficients] ddc_dT_dT
+    "Second-order partial derivative of coefficients of isotherm model w.r.t. 
+    temperature";
+  Real[no_coefficients] ddc_dT_dT_num = (c_pdT .- 2 .* c .+ c_mdT) ./ (dT ^ 2)
+    "Second-order partial derivative of coefficients of isotherm model w.r.t. 
+    temperature calculated numerically";
+
+protected
+  Real[no_coefficients] c_pdT
+    "Coefficients of isotherm model: T + 1e-6 K";
+  Real[no_coefficients] c_mdT
+    "Coefficients of isotherm model: T - 1e-6 K";
+
+  function func_pi_num
+    "Integrand required for calculating the reduced spreading pressure numerically"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Real T_adsorpt
+      "Equilibrium temperature";
+    input Real c[:]
+      "Coefficients of isotherm model";
+  algorithm
+    y :=  IsothermModel.x_pT(p_adsorpt=u, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps) /
+      max(u, Modelica.Constants.small)
+      "Integrand 'x(p,T,c) / p' required for calculating the reduced spreading
+      pressure";
+  end func_pi_num;
+
+equation
+  der(p_adsorpt) = p_adsorpt_der
+    "Predecsriped slope of p_adsorpt to demonstrate the isotherm model";
+  der(T_adsorpt) = T_adsorpt_der
+    "Predecsriped slope of T_adsorpt to demonstrate the isotherm model";
+
+  if check_func_p_xT then
+    p_adsorpt_inv = IsothermModel.p_xT(x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv)
+      "Equilibrium pressure calculated via the inverse function of the isotherm model";
+  else
+    p_adsorpt_inv = -1
+      "Equilibrium pressure calculated via the inverse function of the isotherm model";
+  end if;
+
+  if check_func_pi_pT and check_func_p_piT then
+    p_adsorpt_pi = IsothermModel.p_piT(M_adsorptive=M_adsorptive, pi=red_spreading_pressure,
+      T_adsorpt=T_adsorpt, c=c, p_adsorpt_lb_start=1, p_adsorpt_ub_start=10,
+      integral_pi_lb=p_lb_pi, tolerance_p_adsorpt=tolerance_p_pi,
+      tolerance_pi=tolerance_pi)
+      "Equilibrium pressure calculated via reduced spreading pressure";
+  else
+    p_adsorpt_pi = -1
+      "Equilibrium pressure calculated via reduced spreading pressure";
+  end if;
+
+  x_adsorpt = IsothermModel.x_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt, c=c,
+    p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv)
+    "Equilibrium uptake";
+
+  if check_func_dx_dp then
+    dx_adsorpt_dp_adsorpt = IsothermModel.dx_dp(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt,
+      c=c)
+      "Partial derivative of the uptake w.r.t. pressure at constant temperature";
+    dx_adsorpt_dp_adsorpt_num = (
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt+dp, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) -
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt-dp, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv)) /
+      (2*dp)
+      "Partial derivative of the uptake w.r.t. pressure at constant temperature
+      calculated numerically";
+  else
+    dx_adsorpt_dp_adsorpt = -1
+      "Partial derivative of the uptake w.r.t. pressure at constant temperature";
+    dx_adsorpt_dp_adsorpt_num = -1
+      "Partial derivative of the uptake w.r.t. pressure at constant temperature
+      calculated numerically";
+  end if;
+
+  if check_func_dx_dT then
+    dx_adsorpt_dT_adsorpt = IsothermModel.dx_dT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt,
+      c=c, dc_dT_adsorpt=dc_dT)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure";
+    dx_adsorpt_dT_adsorpt_num = (
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt+dT, c=c_pdT,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) -
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt-dT, c=c_mdT,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv)) /
+      (2*dT)
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure
+      calculated numerically";
+  else
+    dx_adsorpt_dT_adsorpt = -1
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure";
+    dx_adsorpt_dT_adsorpt_num = -1
+      "Partial derivative of the uptake w.r.t. temperature at constant pressure
+      calculated numerically";
+  end if;
+
+  if check_func_ddx_dp_dp then
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt = IsothermModel.ddx_dp_dp(p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt, c=c)
+      "Second-order partial derivative of the uptake w.r.t. pressure at constant
+       temperature";
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt_num = (
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt+dp, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) -
+      2 * IsothermModel.x_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) +
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt-dp, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv)) /
+      (dp^2)
+      "Second-order partial derivative of the uptake w.r.t. pressure at constant 
+      temperature numerically";
+  else
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt = -1
+      "Second-order partial derivative of the uptake w.r.t. temperature at constant 
+      temperature";
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt_num = -1
+      "Second-order partial derivative of the uptake w.r.t. temperature at constant 
+      temperature numerically";
+  end if;
+
+  if check_func_ddx_dT_dT then
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt = IsothermModel.ddx_dT_dT(p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt, c=c, dc_dT_adsorpt=dc_dT,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+      "Second-order partial derivative of the uptake w.r.t. temperature at constant
+      pressure";
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt_num = (
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt+dT, c=c_pdT,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) -
+      2 * IsothermModel.x_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt, c=c,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) +
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt-dT, c=c_mdT,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv)) /
+      (dT^2)
+      "Second-order partial derivative of the uptake w.r.t. temperature at constant 
+      pressure numerically";
+  else
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt = -1
+      "Second-order partial derivative of the uptake w.r.t. temperature at constant 
+      pressure";
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt_num = -1
+      "Second-order partial derivative of the uptake w.r.t. temperature at constant 
+      pressure numerically";
+  end if;
+
+  if check_func_ddx_dp_dT then
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt = IsothermModel.ddx_dp_dT(p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt, c=c, dc_dT_adsorpt=dc_dT)
+      "Second-order partial derivative of the uptake w.r.t. pressure and temperature";
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt_num = (
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt+dp, T_adsorpt=T_adsorpt+dT, c=c_pdT,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) -
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt+dp, T_adsorpt=T_adsorpt-dT, c=c_mdT,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) -
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt-dp, T_adsorpt=T_adsorpt+dT, c=c_pdT,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv) +
+      IsothermModel.x_pT(p_adsorpt=p_adsorpt-dp, T_adsorpt=T_adsorpt-dT, c=c_mdT,
+      p_adsorpt_lb_start=1, p_adsorpt_ub_start=10, tolerance=tolerance_p_inv)) /
+      (2*dp*2*dT)
+      "Second-order partial derivative of the uptake w.r.t. pressure and temperature
+       calculated numerically";
+  else
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt = -1
+      "Second-order partial derivative of the uptake w.r.t. pressure and temperature";
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt_num = -1
+      "Second-order partial derivative of the uptake w.r.t. pressure and temperature
+       calculated numerically";
+  end if;
+
+  if check_func_pi_pT then
+    red_spreading_pressure = IsothermModel.pi_pT(M_adsorptive=M_adsorptive, p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt, c=c, integral_pi_lb=p_lb_pi, tolerance=tolerance_pi)
+      "Reduced spreading pressure";
+    red_spreading_pressure_num = Modelica.Math.Nonlinear.quadratureLobatto(
+      f=function func_pi_num(T_adsorpt=T_adsorpt, c=c),
+      a=p_lb_pi,
+      b=p_adsorpt,
+      tolerance=tolerance_pi) / M_adsorptive
+      "Reduced spreading pressure calculated numerically";
+  else
+    red_spreading_pressure = -1
+      "Reduced spreading pressure";
+    red_spreading_pressure_num = -1
+      "Reduced spreading pressure calculated numerically";
+
+  end if;
+
+  //
+  // Definition of assertions: Check numerical implementation of isotherm model
+  //
+  if print_asserts then
+    if check_func_p_xT then
+      assert(abs(p_adsorpt-p_adsorpt_inv) < 1e-6,
+        "Inverse function of isotherm model is not valid: Deviation (|" +
+        String(abs(p_adsorpt-p_adsorpt_inv)) +
+        "|) is greater than 1e-6 Pa!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_pi_pT and check_func_p_piT then
+      assert(abs(p_adsorpt-p_adsorpt_pi) < 1e-6,
+        "Inverse function of reduced spreading pressure is not valid: Deviation (|" +
+        String(abs(p_adsorpt-p_adsorpt_pi)) +"|) is greater " +
+        "than 1e-6 Pa!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_pi_pT then
+      assert(abs(red_spreading_pressure-red_spreading_pressure_num) < 1e-6,
+        "Reduced spreading pressure is not valid: Deviation (|" +
+        String(abs(red_spreading_pressure-red_spreading_pressure_num)) +
+        "|) is greater than 1e-6 mol/kg!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_dx_dp then
+      assert(abs(dx_adsorpt_dp_adsorpt-dx_adsorpt_dp_adsorpt_num) < 1e-6,
+        "Partial derivative of isotherm model w.r.t. pressure at constant " +
+        "temperature is not valid: Deviation (|" +
+        String(abs(dx_adsorpt_dp_adsorpt-dx_adsorpt_dp_adsorpt_num)) +
+        "|) is greater than 1e-6 kg/(kg.Pa)!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_dx_dT then
+      assert(abs(dx_adsorpt_dT_adsorpt-dx_adsorpt_dT_adsorpt_num) < 1e-6,
+        "Partial derivative of isotherm model w.r.t. temperature at contant " +
+        "pressure is not valid: Deviation (|" +
+        String(abs(dx_adsorpt_dT_adsorpt-dx_adsorpt_dT_adsorpt_num)) +
+        "|) is greater than 1e-6 kg/(kg.K)!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_ddx_dp_dp then
+      assert(abs(ddx_adsorpt_dp_adsorpt_dp_adsorpt-ddx_adsorpt_dp_adsorpt_dp_adsorpt_num) < 1e-6,
+        "Second-order partial derivative of isotherm model w.r.t. pressure " +
+        "at constant temperature is not valid: Deviation (|" +
+        String(abs(ddx_adsorpt_dp_adsorpt_dp_adsorpt-ddx_adsorpt_dp_adsorpt_dp_adsorpt_num)) +
+        "|) is greater than 1e-6 kg/(kg.Pa2)!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_ddx_dT_dT then
+      assert(abs(ddx_adsorpt_dT_adsorpt_dT_adsorpt-ddx_adsorpt_dT_adsorpt_dT_adsorpt_num) < 1e-6,
+        "Second-order partial derivative of isotherm model w.r.t. temperature " +
+        "at constant pressure is not valid: Deviation (|" +
+        String(abs(ddx_adsorpt_dT_adsorpt_dT_adsorpt-ddx_adsorpt_dT_adsorpt_dT_adsorpt_num)) +
+        "|) is greater than 1e-6 kg/(kg.K2)!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_ddx_dp_dT then
+      assert(abs(ddx_adsorpt_dp_adsorpt_dT_adsorpt-ddx_adsorpt_dp_adsorpt_dT_adsorpt_num) < 1e-6,
+        "Second-order partial derivative of isotherm model w.r.t. pressure " +
+        "and temperature is not valid: Deviation (|" +
+        String(abs(ddx_adsorpt_dp_adsorpt_dT_adsorpt-ddx_adsorpt_dp_adsorpt_dT_adsorpt_num)) +
+        "|) is greater than 1e-6 kg/(kg.Pa.K)!",
+        level = AssertionLevel.warning);
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the basic model for all testers of isotherm models describing
+adsorption of pure components. Such isotherm models must be classical isotherm models,
+which are based on the assumption of a (plain) boundary surface.
+<br/><br/>
+This partial model defines all relevant parameters, variables, and equations to
+check (1) the classical form of isotherm models, (2) the inverse form of isotherm
+models, (3) the partial derivative of the uptake w.r.t. to pressure, (4) the
+partial derivative of the uptake w.r.t. pressure, (5) the partial derivative of the 
+uptake w.r.t. temperature, (6) the second-order partial derivative of the uptake w.r.t. 
+to pressure and temperature, (7) the second-order partial derivative of the uptake w.r.t. 
+to temperature, and (8) the reduced spreading pressure. All partial derivatives are also 
+implemented as central finite differences to check for the analytical implementation 
+of the partial derivatives. Additionally, the reduced spreading pressure is also calculated 
+numerically to check the numerical implementation of the reduced spreading pressure.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the number 
+of coefficients of the isotherm model <i>no_coefficients</i> and have to redeclare 
+the <i>IsotherModel</i> package. Besides, the coefficients of the isotherm model (i.e.,  
+<i>c</i>, <i>c_pdT</i>, and <i>c_mdT</i>) and their partial derivatives with respect to  
+temperature (i.e., <i>dc_dT</i> and <i>ddc_dT_dT</i>) have to be implemented. Additionally, 
+it has to be specified whether the equilibrium pressure (<i>p_adsorpt_der</i>) or the  
+equilibrium temperature (<i>T_adsorpt_der</i>) changes with time.
+</p>
+</html>"));
+end PartialTestPure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestPureDubinin.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestPureDubinin.mo
new file mode 100644
index 0000000..b3078ec
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/PartialTestPureDubinin.mo
@@ -0,0 +1,239 @@
+within SorpLib.Media.Functions.SorptionEquilibria.BaseClasses;
+partial model PartialTestPureDubinin
+  "Base model for testers of isotherm models describing pure component adsorption based on the Dubinin model"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+      redeclare replaceable package IsothermModel =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov
+        constrainedby
+      SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin);
+
+  //
+  // Definition of parameters
+  //
+  parameter Boolean check_func_A_W = true
+    "= true, if function 'func_A_W' is checked; otherwise, function is not 
+    checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_dW_dA = true
+    "= true, if function 'func_dW_dA' is checked; otherwise, function is not 
+    checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_ddW_dA_dA = true
+    "= true, if function 'func_ddW_dA_dA' is checked; otherwise, function is not 
+    checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean check_func_ddW_dA_dT = true
+    "= true, if function 'func_ddW_dA_dT' is checked; otherwise, function is not 
+    checked"
+    annotation (Dialog(tab="General", group="Checks"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter SorpLib.Units.MolarAdsorptionPotential dA=1e-6
+    "Molar adsorption potential difference used to calculate partial derivatives 
+    numerically" annotation (
+    Dialog(tab="Numerics", group="Derivatives"),
+    Evaluate=true,
+    HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Units.MolarAdsorptionPotential A "Molar adsorption potential";
+  SorpLib.Units.MolarAdsorptionPotential A_inv(min=-1)
+    "Molar adsorption potential calculated via inverse form of characteristic curve";
+  SorpLib.Units.AdsorptionPotential A_mass "Adsorption potential";
+
+  SorpLib.Units.FilledPoreVolume W
+    "Filled pore volume";
+
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential 
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_num
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential 
+    calculated at constant pressure and temperature numerically";
+
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA_num
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential at constant pressure and temperature calculated numerically";
+
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential and temperature at constant pressure";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_num
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential and temperature at constant pressure calculated numerically";
+
+protected
+  SorpLib.Units.MolarAdsorptionPotential A_pdT=
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt, p_sat=c_pdT[1], T_adsorpt=T_adsorpt+dT)
+    "Molar adsorption potential_ T + dT";
+  SorpLib.Units.MolarAdsorptionPotential A_mdT=
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt, p_sat=c_mdT[1], T_adsorpt=T_adsorpt-dT)
+    "Molar adsorption potential: T - dT";
+
+equation
+  A =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Molar adsorption potential";
+
+  if check_func_A_W then
+    A_inv = IsothermModel.A_W(W=W, c=c)
+      "Molar adsorption potential calculated via inverse form of characteristic curve";
+  else
+    A_inv = -1
+      "Molar adsorption potential calculated via inverse form of characteristic curve";
+  end if;
+
+  A_mass = A / M_adsorptive
+    "Adsorption potential";
+
+  W = IsothermModel.W_A(A=A, c=c)
+    "Filled pore volume";
+
+  if check_func_dW_dA then
+    dW_dA = IsothermModel.dW_dA(A=A, c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential 
+      at constant pressure and temperature";
+    dW_dA_num = (IsothermModel.W_A(A=A+dA, c=c) - IsothermModel.W_A(A=A-dA, c=c)) / (2*dA)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential 
+      at constant pressure and temperature calculated numerically";
+  else
+    dW_dA = -1
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential 
+      at constant pressure and temperature";
+    dW_dA_num = -1
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential 
+      at constant pressure and temperature calculated numerically";
+  end if;
+
+  if check_func_ddW_dA_dA then
+    ddW_dA_dA = IsothermModel.ddW_dA_dA(A=A, c=c)
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential at constant pressure and temperature";
+    ddW_dA_dA_num = (IsothermModel.W_A(A=A+dA, c=c) -
+      2 * IsothermModel.W_A(A=A, c=c) + IsothermModel.W_A(A=A-dA, c=c)) / (dA^2)
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential at constant pressure and temperature calculated numerically";
+  else
+    ddW_dA_dA = -1
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential at constant pressure and temperature";
+    ddW_dA_dA_num = -1
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential at constant pressure and temperature calculated numerically";
+  end if;
+
+  if check_func_ddW_dA_dT then
+    ddW_dA_dT = IsothermModel.ddW_dA_dT(p_adsorpt=p_adsorpt, T_adsorpt=T_adsorpt, A=A,
+      c=c, dc_dT_adsorpt=dc_dT)
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential and temperature at constant pressure";
+    ddW_dA_dT_num = (IsothermModel.dW_dA(A=A_pdT, c=c_pdT) - IsothermModel.dW_dA(A=A_mdT, c=c_mdT)) /
+      (2*dT)
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential and temperature at constant pressure calculated numerically";
+  else
+    ddW_dA_dT = -1
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential and temperature at constant pressure";
+    ddW_dA_dT_num = -1
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential and temperature at constant pressure calculated numerically";
+  end if;
+
+  //
+  // Definition of assertions: Check numerical implementation of isotherm model
+  //
+  if print_asserts then
+    if check_func_A_W then
+      assert(abs(A-A_inv) < 1e-6,
+        "Inverse function of characteristic curve is not valid: Deviation (|"
+        + String(abs(A-A_inv)) +
+        "|) is greater than 1e-6 J/mol!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_dW_dA then
+      assert(abs(dW_dA-dW_dA_num) < 1e-6,
+        "Partial derivative of filled pore volume wrt. adsorption potential " +
+        "at constant pressure and temperature is not valid: Deviation (|" +
+        String(abs(dW_dA-dW_dA_num)) +
+        "|) is greater than 1e-6 m3.mol/(kg.J)!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_ddW_dA_dA then
+      assert(abs(ddW_dA_dA-ddW_dA_dA_num) < 1e-6,
+        "Second-order partial derivative of filled pore volume wrt. adsorption " +
+        "potential at constant pressure and temperature is not valid: Deviation (|" +
+        String(abs(ddW_dA_dA-ddW_dA_dA_num)) +
+        "|) is greater than 1e-6 m3.mol2/(kg.J2)!",
+        level = AssertionLevel.warning);
+    end if;
+
+    if check_func_ddW_dA_dT then
+      assert(abs(ddW_dA_dT-ddW_dA_dT_num) < 1e-6,
+        "Second-order partial derivative of filled pore volume wrt. adsorption " +
+        "potential and temperature at constant pressure is not valid: Deviation (|" +
+        String(abs(ddW_dA_dT-ddW_dA_dT_num)) +
+        "|) is greater than 1e-6 m3.mol/(kg.J.K)!",
+        level = AssertionLevel.warning);
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial model is the basic model for all testers of isotherm models describing
+adsorption of pure components. Such isotherm models must be isotherm models, which 
+are based on the assumpation of filled pores.
+<br/><br/>
+This partial model defines all relevant parameters, variables, and equations to
+check (1) the classical form of isotherm models, (2) the inverse form of isotherm
+models, (3) the partial derivative of the uptake w.r.t. to pressure, (4) the
+partial derivative of the uptake w.r.t. pressure, (5) the partial derivative of the 
+uptake w.r.t. temperature, (6) the second-order partial derivative of the uptake w.r.t. 
+to pressure and temperature, (7) the second-order partial derivative of the uptake w.r.t. 
+to temperature, (8) the reduced spreading pressure, (9) the characteristic curve, (10) 
+the inverse form of the characteristic curve, and (11) partial derivative of the 
+characteristic curve w.r.t. molar adsorption potential. All partial derivatives are 
+also implemented as central finite  differences to check for the analytical implementation 
+of the partial derivatives. Additionally, the reduced spreading pressure is also 
+calculated numerically to check the numerical implementation of the reduced spreading 
+pressure.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the number 
+of coefficients of the isotherm model <i>no_coefficients</i> and have to redeclare 
+the <i>IsotherModel</i> package. Besides, the coefficients of the isotherm 
+model (i.e., <i>c</i>, <i>c_pdT</i>, and <i>c_mdT</i>) and their partial derivatives 
+with respect to temperature (i.e., <i>dc_dT</i>) have to be implemented. Additionally, 
+it has to specify whether the equilibrium pressure (<i>p_adsorpt_der</i>) or the 
+equilibrium temperature (<i>T_adsorpt_der</i>) changes with time.
+</p>
+</html>"));
+end PartialTestPureDubinin;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/package.mo
new file mode 100644
index 0000000..ecb0da5
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions.SorptionEquilibria;
+package BaseClasses "Base classes used to build new functions calculating sorption equlibria"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial basic functions and models. These partial functions
+and models contain fundamental definitions of all isotherm models and corresponding
+test models, covering pure and multi-component adsorption. The content of this package 
+is only of interest when adding new isotherm models to the library.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/package.order b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/package.order
new file mode 100644
index 0000000..085367e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/BaseClasses/package.order
@@ -0,0 +1,41 @@
+PartialPure
+PartialPure_x_pT
+PartialPure_p_xT
+PartialPure_p_xT_num
+PartialPure_dx_dp
+PartialPure_dx_dT
+PartialPure_ddx_dp_dp
+PartialPure_ddx_dT_dT
+PartialPure_ddx_dp_dT
+PartialPure_pi_pT
+PartialPure_pi_pT_num
+PartialPure_p_piT
+PartialPure_p_piT_num
+PartialPure_W_A
+PartialPure_A_W
+PartialPure_A_W_num
+PartialPure_dW_dA
+PartialPure_ddW_dA_dA
+PartialPure_ddW_dA_dT
+PartialMulti
+PartialMulti_x_pyT
+PartialMulti_p_xyT
+PartialMulti_y_pxT
+PartialMulti_py_xT
+PartialMulti_dx_dp
+PartialMulti_dx_dy
+PartialMulti_dx_dT
+PartialMultiIAST
+PartialMultiIAST_x_pyT
+PartialMultiIAST_p_xyT
+PartialMultiIAST_y_pxT
+PartialMultiIAST_py_xT
+PartialMultiIAST_dx_dp
+PartialMultiIAST_dx_dy
+PartialMultiIAST_dx_dT
+PartialTestPure
+PartialTestPureDubinin
+PartialTestMulti
+PartialTestMultiIAST
+PartialTestMultiIAST_N2
+PartialTestMultiIAST_N3
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponents/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponents/package.mo
new file mode 100644
index 0000000..5bbde56
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponents/package.mo
@@ -0,0 +1,99 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Interfaces;
+partial package PartialMultiComponents "Base package for all isotherm models of multi components"
+  extends Modelica.Icons.FunctionsPackage;
+
+  //
+  // Basic isotherm equations
+  //
+  replaceable partial function x_pyT
+    "Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti_x_pyT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end x_pyT;
+
+  replaceable partial function p_xyT
+    "Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti_p_xyT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end p_xyT;
+
+  replaceable partial function y_pxT
+    "Mole fractions of independent gas phase components as function of pressure, uptakes, and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti_y_pxT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end y_pxT;
+
+  replaceable partial function py_xT
+    "Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti_py_xT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end py_xT;
+
+  replaceable partial function dx_dp
+    "Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti_dx_dp;
+  end dx_dp;
+
+  replaceable partial function dx_dy
+    "Partial derivative of uptakes w.r.t. molar fractions of independent gas phase components at constant temperature and pressure"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti_dx_dy;
+  end dx_dy;
+
+  replaceable partial function dx_dT
+    "Partial derivative of uptakes w.r.t. temperature at contsant pressure and mole fractions"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti_dx_dT;
+  end dx_dT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package is the basic package for all isotherm models describing 
+the adsorption of multi components.
+<br/><br/>
+This partial package contains all declarations for a multi-component isotherm
+model. This means that functions are defined that every multi-component isotherm
+model must support. A multi-component isotherm model inherits from this partial
+package and must provide the isotherm equations by redeclaring all partial
+functions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMultiComponents;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponents/package.order b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponents/package.order
new file mode 100644
index 0000000..9591cab
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponents/package.order
@@ -0,0 +1,7 @@
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponentsIAST/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponentsIAST/package.mo
new file mode 100644
index 0000000..0ff5072
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponentsIAST/package.mo
@@ -0,0 +1,100 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Interfaces;
+partial package PartialMultiComponentsIAST "Base package for all isotherm models of multi components based on the IAST"
+  extends Modelica.Icons.FunctionsPackage;
+
+  //
+  // Basic isotherm equations
+  //
+  replaceable partial function x_pyT
+    "Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST_x_pyT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end x_pyT;
+
+  replaceable partial function p_xyT
+    "Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST_p_xyT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end p_xyT;
+
+  replaceable partial function y_pxT
+    "Mole fractions of independent gas phase components as function of pressure, uptakes, and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST_y_pxT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end y_pxT;
+
+  replaceable partial function py_xT
+    "Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST_py_xT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end py_xT;
+
+  replaceable partial function dx_dp
+    "Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST_dx_dp;
+  end dx_dp;
+
+  replaceable partial function dx_dy
+    "Partial derivative of uptakes w.r.t. molar fractions of independent gas phase components at constant temperature and pressure"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST_dx_dy;
+  end dx_dy;
+
+  replaceable partial function dx_dT
+    "Partial derivative of uptakes w.r.t. temperature at contsant pressure and mole fractions"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST_dx_dT;
+  end dx_dT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package is the basic package for all isotherm models describing 
+the adsorption of multi components based on the ideal adsorption solution
+theory.
+<br/><br/>
+This partial package contains all declarations for a multi-component isotherm
+model. This means that functions are defined that every multi-component isotherm
+model must support. A multi-component isotherm model inherits from this partial
+package and must provide the isotherm equations by redeclaring all partial
+functions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialMultiComponentsIAST;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponentsIAST/package.order b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponentsIAST/package.order
new file mode 100644
index 0000000..9591cab
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialMultiComponentsIAST/package.order
@@ -0,0 +1,7 @@
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponents/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponents/package.mo
new file mode 100644
index 0000000..cd8c9e7
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponents/package.mo
@@ -0,0 +1,100 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Interfaces;
+partial package PartialPureComponents "Base package for all isotherm models of pure components"
+  extends Modelica.Icons.FunctionsPackage;
+
+  //
+  // Basic isotherm equations
+  //
+  replaceable partial function x_pT
+    "Uptake as function of pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end x_pT;
+
+  replaceable partial function p_xT
+    "Pressure as function of uptake and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end p_xT;
+
+  replaceable partial function dx_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp;
+  end dx_dp;
+
+  replaceable partial function dx_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dT;
+  end dx_dT;
+
+  replaceable partial function ddx_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dp;
+  end ddx_dp_dp;
+
+  replaceable partial function ddx_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dT_dT;
+  end ddx_dT_dT;
+
+  replaceable partial function ddx_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dT;
+  end ddx_dp_dT;
+  //
+  // Equations regarding reduced spreading pressure
+  //
+  replaceable partial function pi_pT
+    "Reduced spreading pressure as function of pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT;
+  end pi_pT;
+
+  replaceable partial function p_piT
+    "Pressure as function of reduced spreading pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT;
+  end p_piT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package is the basic package for all isotherm models describing 
+the adsorption of pure components. Such models can be classical isotherm models 
+based on a (plain) boundary surface or isotherm models based on filled pores. 
+<br/><br/>
+This partial package contains all declarations for a pure component isotherm
+model. This means that functions are defined that every pure component isotherm
+model must support. A pure component isotherm model inherits from this partial
+package and must provide the isotherm equations by redeclaring all partial
+functions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPureComponents;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponents/package.order b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponents/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponents/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponentsDubinin/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponentsDubinin/package.mo
new file mode 100644
index 0000000..c93e9af
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponentsDubinin/package.mo
@@ -0,0 +1,214 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Interfaces;
+partial package PartialPureComponentsDubinin "Base package for all isotherm models of pure components based on the model of Dubinin"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  //
+  // Dubinin-specific isotherm equations
+  //
+  replaceable partial function W_A
+    "Filled pore volume as function of molar adsorption potential"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_W_A;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end W_A;
+
+  replaceable partial function A_W
+    "Molar adsorption potential as function of filled pore volume"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_A_W;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end A_W;
+
+  replaceable partial function dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential at constant pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dW_dA;
+  end dW_dA;
+
+  replaceable partial function ddW_dA_dA
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption potential at constant pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dA;
+  end ddW_dA_dA;
+
+  replaceable partial function ddW_dA_dT
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption potential and temperature at constant pressure"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dT;
+  end ddW_dA_dT;
+  //
+  // Redeclare basic isotherm equations
+  //
+  redeclare replaceable function extends x_pT
+    "Uptake as function of pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.FilledPoreVolume W=W_A(
+      A=A,
+      c=c)
+      "Filled pore volume";
+
+  algorithm
+    x_adsorpt := c[2] * W
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end x_pT;
+
+  redeclare replaceable function extends p_xT
+    "Pressure as function of uptake and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=A_W(
+       W=x_adsorpt/c[2],
+       c=c)
+       "Adsorption potential";
+
+  algorithm
+    p_adsorpt :=SorpLib.Media.Functions.SorptionEquilibria.Utilities.p_ApsT(
+      A=A,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Calculation of the equilibrium pressure of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true);
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Partial derivative of adsorption potential w.r.t. to pressure at
+      constant temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_=dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+
+  algorithm
+    dx_adsorpt_dp_adsorpt := c[2] * dW_dA_*dA_dp_adsorpt
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+       equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends ddx_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Partial derivative of adsorption potential w.r.t. to pressure at constant
+      temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressurePressure ddA_dp_adsorpt_dp_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dp(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Second-order partial derivative of adsorption potential w.r.t. to pressure
+      at constant temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA_=dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temeprature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA_=ddW_dA_dA(
+      A=A,
+      c=c)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+      potential at constant pressure and temeprature";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt :=
+      (c[2] * dA_dp_adsorpt) * ddW_dA_dA_*dA_dp_adsorpt +
+      (c[2] * dW_dA_) * ddA_dp_adsorpt_dp_adsorpt
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+      w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package is the basic package for all isotherm models describing 
+the adsorption of pure components based on the model of Dubinin. Such models
+describe the adsorption based on filled pores. 
+<br/><br/>
+This partial package contains all declarations for a pure component isotherm
+model. This means that functions are defined that every pure component isotherm
+model must support. A pure component isotherm model inherits from this partial
+package and must provide the isotherm equations by redeclaring all partial
+functions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PartialPureComponentsDubinin;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponentsDubinin/package.order b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponentsDubinin/package.order
new file mode 100644
index 0000000..a757168
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/PartialPureComponentsDubinin/package.order
@@ -0,0 +1,9 @@
+W_A
+A_W
+dW_dA
+ddW_dA_dA
+ddW_dA_dT
+x_pT
+p_xT
+dx_dp
+ddx_dp_dp
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/package.mo
new file mode 100644
index 0000000..e35a074
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Media.Functions.SorptionEquilibria;
+package Interfaces "Interfaces for sorption equilibria models"
+  extends Modelica.Icons.InterfacesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package provides definitions of basic interfaces for sorption equilibria models. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Interfaces;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/package.order b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/package.order
new file mode 100644
index 0000000..c028d2f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Interfaces/package.order
@@ -0,0 +1,4 @@
+PartialPureComponents
+PartialPureComponentsDubinin
+PartialMultiComponents
+PartialMultiComponentsIAST
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/package.mo
new file mode 100644
index 0000000..a56b646
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the IAST for
+two components. Thus, redundancy of code shall be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/package.order
new file mode 100644
index 0000000..28701d4
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/package.order
@@ -0,0 +1,4 @@
+x_pyT_NewtonRaphson
+x_pyT_NestedLoop
+x_pyT_FastIAST
+py_xT_NewtonRaphson
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/py_xT_NewtonRaphson.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/py_xT_NewtonRaphson.mo
new file mode 100644
index 0000000..54c4350
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/py_xT_NewtonRaphson.mo
@@ -0,0 +1,327 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals;
+function py_xT_NewtonRaphson
+  "IAST for two components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature using the standard 'Newton-Raphson' algorithm"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean flag_startValues = false
+    " = true, if start values are given; otherwise, estimate start values"
+    annotation (Dialog(tab="General", group="Inputs - Start values"));
+  input SorpLib.Units.ReducedSpreadingPressure pi_0 = 1
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i
+    "Mole fractions of components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] pi_i
+    "Reduced spreading pressures";
+
+  Integer no_iteration = 1
+    "Counter of loop";
+  Real error = 1
+    "Error of loop";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_i = x_adsorpt ./ M_i
+    "Molar equilibrium uptakes at hypothetical pure component pressures";
+  Real[size(M_i,1)] dq_adsorpt_i_dp_i_pure(each unit="mol/(kg.Pa)")
+    "Partical derivatives of molar equilibrium uptakes at hypothetical pure 
+    component pressures w.r.t. hypothetical pure component pressures";
+
+  Real delta_sum_q_adsorpt(unit="kg/mol")
+    "Satisfaction of total molar uptake";
+  Real ddelta_sum_q_adsorpt_dpi(unit="kg.kg/(mol.mol)")
+    "Partial derivative of satisfaction of total molar uptake w.r.t. to reduced 
+    spreading pressure of all components";
+
+  SorpLib.Units.MolarUptake q_adsorpt = sum(q_adsorpt_i)
+    "Total molar equilibrium uptake";
+
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] z_i = q_adsorpt_i ./ q_adsorpt
+    "Mole fractions of the adsorpt phase";
+
+algorithm
+  if flag_startValues then
+    //
+    // Use start values
+    //
+    pi := pi_0
+      "Reduced spreading pressure of all components";
+
+  else
+    //
+    // Caclulate initial guesses ensuring convergence: Equilibrium pressures
+    //
+    p_i_pure[1] := func_p_xT_1(x_adsorpt=x_adsorpt[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Pure component pressure of the first component (not at hypothetical pressure)";
+    p_i_pure[2] := func_p_xT_2(x_adsorpt=x_adsorpt[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Pure component pressure of the second component (not at hypothetical pressure)";
+
+    //
+    // Caclulate initial guesses ensuring convergence: Reduced spreading pressures
+    //
+    pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance=num_comp_1.tolerance_pi)
+      "Reduced spreading pressure of the first component";
+    pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance=num_comp_2.tolerance_pi)
+      "Reduced spreading pressure of the second component";
+
+    pi := sum(z_i .* pi_i)
+      "Reduced spreading pressure of all components";
+
+  end if;
+
+  //
+  // Loop to solve the inverse of the IAST
+  //
+  while error >= num.tolerance_inv and no_iteration <= num.no_max_inv loop
+    //
+    // Calculate hypothetical pure component pressures
+    //
+    p_i_pure[1] := func_p_piT_1(
+      M_adsorptive=M_i[1],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_1.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_1.tolerance_pi)
+      "Hypothetical pure component pressure of the first component";
+    p_i_pure[2] := func_p_piT_2(
+      M_adsorptive=M_i[2],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_2.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_2.tolerance_pi)
+      "Hypothetical pure component pressure of the first component";
+
+    //
+    // Calculate molar uptakes
+    //
+    q_adsorpt_i[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      first component";
+    q_adsorpt_i[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      second component";
+
+    //
+    // Calculate partial derivatives of molar uptakes w.r.t. hypothetical pure
+    // component pressures
+    //
+    dq_adsorpt_i_dp_i_pure[1] := 1/M_i[1] * func_dx_dp_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      first component";
+    dq_adsorpt_i_dp_i_pure[2] := 1/M_i[2] * func_dx_dp_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      second component";
+
+    //
+    // Apply Newton-Raphson method
+    //
+    delta_sum_q_adsorpt := sum(z_i ./ q_adsorpt_i) - 1 / q_adsorpt
+      "Satisfaction of total molar uptake";
+    ddelta_sum_q_adsorpt_dpi := -sum(z_i .* p_i_pure ./ q_adsorpt_i .^ 3 .*
+      dq_adsorpt_i_dp_i_pure)
+      "Partial derivative of satisfaction of total molar uptake w.r.t. to reduced 
+      spreading pressure of all components";
+
+    pi := if pi - delta_sum_q_adsorpt / ddelta_sum_q_adsorpt_dpi > 0 then
+      pi - delta_sum_q_adsorpt / ddelta_sum_q_adsorpt_dpi else pi / 2
+      "Update reduced spreading pressure of all components";
+
+    //
+    // Check for convergence
+    //
+    no_iteration := no_iteration + 1
+      "Counter of loop";
+    error := abs(delta_sum_q_adsorpt)
+      "Error of loop";
+
+  end while;
+
+  //
+  // Calculate final ouputs
+  //
+  p_adsorpt := sum(z_i .* p_i_pure)
+    "Equilibrium pressure of the adsorpt phase";
+
+  y_i := z_i .* p_i_pure ./ p_adsorpt
+    "Mole fractions of components in the vapor or gas phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function provides an algorithm for solving the inverse of the IAST for two 
+components. The pressure <i>p_adsorpt</i> and molar composition of the gas/vapour 
+phase <i>y_i</i> are calculated as a function of the uptakes <i>x_adsorpt</i> 
+and the temperature <i>T_adsorpt</i>. The algorithm uses a Newton-Raphson method 
+to solve the system of equations of the inverse of the IAST. 
+</p>
+
+<h4>Main equations</h4>
+<p>
+The algorithm consists of 13 steps:
+</p>
+<ol>
+  <li>
+  Calculate the pure component pressures of each component <i>i</i>:
+  <pre>p<sub>adsorpt,<i>i</i></sub> = f(x<sub>adsorpt,<i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sub>adsorpt,<i>i</i></sub>, T<sub>adsorpt</sub>),</pre>
+  where <i>M<sub><i>i</i></sub></i> is the molar mass.
+  <br>
+  </li>
+  </li>
+  <li>
+  Calculate the initial guess of the reduced spreading pressure:
+  <pre>&pi; = &sum;<sub><i>i</i></sub> z<sub><i>i</i></sub> * &pi;<sub><i>i</i></sub>,</pre>
+  where <i>z<sub><i>i</i></sub></i> is the molar molar composition of each component 
+  <i>i</i> in the adsorpt phase
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, &pi;, T<sub>adsorpt</sub>).</pre>
+  This formula is an inverse of the reduced spreading pressure, which often
+  has to be calculated numerically.
+  <br>
+  </li>
+  <li>
+  Calculate the molar uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate partial derivatives of the molar uptake of each component <i>i</i>
+  with respect to the hypothetical pure component pressures of each component 
+  <i>i</i>:
+  <pre>dq<sub>adsorpt,<i>i</i></sub>/dp<sup>*</sup><sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * dx<sub>adsorpt,<i>i</i></sub>/dp<sub>adsorpt</sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>),</pre>
+  where <i>dx<sub>adsorpt,<i>i</i></sub>/dp<sub>adsorpt</sub></i> is the partial
+  derivative of the uptake with respect to the pressure.
+  <br>
+  </li>
+  <li>
+  Calculate the satisfaction of the total molar uptake:
+  <pre>F = &sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>] - 1 / &sum;<sub><i>i</i></sub> [x<sub>adsorpt,<i>i</i></sub> / M<sub><i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the partial derivative of the total molar uptake with respect to the 
+  reduced spreading pressure:
+  <pre>dF/d&pi; = -&sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> * p<sup>*</sup><sub><i>i</i></sub> / (q<sup>3</sup><sub>adsorpt,<i>i</i></sub>) * dq<sub>adsorpt,<i>i</i></sub>/dp<sup>*</sup><sub><i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressure of the next iteration step:
+  <pre>&pi;<sub>next</sub> = <strong>if</strong> &pi; - F / dF/d&pi; > 0 <strong>then</strong> &pi; - F / dF/d&pi; > 0 <strong>else</strong> &pi;/2.</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence:
+  <pre>|F| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 4. It the convergence
+  criterion is fulfilled, got to step 11.
+  <br>
+  </li>
+  <li>
+  Calculate the partial pressure of each component <i>i</i>:
+  <pre>p<sub>adsorpt,<i>i</i></sub> = z<sub><i>i</i></sub> * p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the pressure:
+  <pre>p<sub>adsorpt</sub> = &sum;<sub><i>i</i></sub> p<sub>adsorpt,<i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the molar fractions each component <i>i</i> in the gas/vapor
+  phase:
+  <pre>y<sub><i>i</i></sub> = p<sub>adsorpt,<i>i</i></sub> / p<sub>adsorpt</sub>.</pre>
+  </li>
+</ol>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end py_xT_NewtonRaphson;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_FastIAST.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_FastIAST.mo
new file mode 100644
index 0000000..bad9ea7
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_FastIAST.mo
@@ -0,0 +1,462 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals;
+function x_pyT_FastIAST
+  "IAST for two components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature using the 'FastIAST' algorithm"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[:] y_i
+    "Mole fractions of the components in the gas or vapor phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean flag_startValues = false
+    " = true, if start values are given; otherwise, estimate start values"
+    annotation (Dialog(tab="General", group="Inputs - Start values"));
+  input Real[size(M_i,1)] Kp_i_0(each unit="1/Pa") = fill(1, size(M_i,1))
+    "Auxiliary variable for reduced pressues of the components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+  input Real[size(M_i,1)] eta_i_0(each unit="1") = fill(1, size(M_i,1))
+    "Reduced pressures of the components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real[size(M_i,1)] Kp_i(each unit="1/Pa")
+    "Auxiliary variable for reduced pressues of the components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real[size(M_i,1)] eta_i(each unit="1")
+    "Reduced pressures of the components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(M_i,1)] K_i(each unit="mol/(kg.Pa)")
+    "Henry constants of the components";
+  Real K_avg(unit="mol/(kg.Pa)")
+    "Average Henry constant";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_sat
+    "Saturation uptakes of the components";
+
+  Integer no_iteration = 1
+    "Counter of loop";
+  Real error = 1
+    "Error of loop";
+
+  Real[size(M_i,1)] Jac_last_row
+    "Jacobian matrix: Elements of the last row";
+  Real[size(M_i,1)] Jac_diagonal
+    "Jacobian matrix: Elements of the diagonal";
+
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] pi_i
+    "Reduced spreading pressures";
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] delta_pi_i
+    "Difference between reduced spreading pressures and reduced spreading pressure
+    of last component";
+
+  Real[size(M_i,1)] delta_eta_i(each unit="1")
+    "Newton steps for reduced pressures of the components";
+
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] z_i
+    "Mole fractions of the adsorpt phase";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_i
+    "Molar equilibrium uptakes at hypothetical pure component pressures";
+  SorpLib.Units.MolarUptake q_adsorpt
+    "Total molar equilibrium uptake";
+
+algorithm
+  if flag_startValues then
+    //
+    // Use start values
+    //
+    Kp_i := Kp_i_0
+      "Auxiliary variable for reduced pressues of the components";
+
+    eta_i := eta_i_0
+      "Reduced pressures of the components";
+
+  else
+    //
+    // Caclulate initial guesses ensuring convergence: Henry constants
+    //
+    K_i[1] := 1/M_i[1] * func_dx_dp_1(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_1)
+      "Henry constant of the first component";
+    K_i[2] := 1/M_i[2] * func_dx_dp_2(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_2)
+      "Henry constant of the second component";
+
+    K_avg := sum(y_i .* K_i)
+      "Average Henry constant";
+
+    //
+    // Calculate initial guesses ensuring convergence: Saturation uptakes
+    //
+    q_adsorpt_sat[1] := 1/M_i[1] * func_x_pT_1(
+      p_adsorpt=num.p_sat_0,
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Saturation uptake of the first component";
+    q_adsorpt_sat[2] := 1/M_i[2] * func_x_pT_2(
+      p_adsorpt=num.p_sat_0,
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Saturation uptake of the second component";
+
+    //
+    // Calculate initial guesses ensuring convergence: Reduced pressures
+    //
+    Kp_i := K_i ./ q_adsorpt_sat
+      "Auxiliary variable for reduced pressues of the components";
+
+    eta_i := {min(Kp_i[i] / K_i[i] * p_adsorpt * K_avg, p_adsorpt * Kp_i[i])
+      for i in 1:size(M_i,1)}
+      "Reduced pressures of the components";
+
+  end if;
+
+  //
+  // Loop to solve the IAST
+  //
+  while error >= num.tolerance and no_iteration <= num.no_max loop
+    //
+    // Calculate the Jacobian matrix: Last row
+    //
+    Jac_last_row := Kp_i .* p_adsorpt .* y_i ./ eta_i.^2
+      "Jacobian matrix: Elements of the last row";
+
+    //
+    // Calculate hypothetical pure component pressures
+    //
+    p_i_pure := eta_i ./ Kp_i
+      "Hypothetical pure component pressures";
+
+    //
+    // Calculate the Jacobian matrix: Diagonal
+    //
+    Jac_diagonal[1] := 1 / (M_i[1] * eta_i[1]) * func_x_pT_1(
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Diagonale of the Jacobian matrix: Component 1";
+    Jac_diagonal[2] := 1 / (M_i[2] * eta_i[2]) * func_x_pT_2(
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Diagonale of the Jacobian matrix: Component 2";
+
+    //
+    // Calculate the Jacobian matrix: Correct last element of the diagonal
+    //
+    Jac_diagonal[end] := Jac_last_row[end] + Jac_diagonal[end] *
+      sum(Jac_last_row[1:end-1] ./ Jac_diagonal[1:end-1])
+      "Diagonale of the Jacobian matrix: Last element of the diagonal";
+
+    //
+    // Calculate recuded spreading pressures
+    //
+    pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance=num_comp_1.tolerance_pi)
+      "Reduced spreading pressure of the first component";
+    pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance=num_comp_2.tolerance_pi)
+      "Reduced spreading pressure of the second component";
+
+    //
+    // Calculate residuals
+    //
+    delta_pi_i := pi_i .- pi_i[end]
+      "Difference between reduced spreading pressures and reduced spreading pressure
+      of last component";
+    delta_pi_i[end] := 1 - sum(Kp_i .* p_adsorpt .* y_i ./ eta_i) -
+      sum(Jac_last_row[1:end-1] ./ Jac_diagonal[1:end-1] .* delta_pi_i[1:end-1])
+      "Difference between reduced spreading pressures and reduced spreading pressure
+      of last component: Last element";
+
+    //
+    // Apply Newton-Raphson method
+    //
+    delta_eta_i[end] := -delta_pi_i[end] / Jac_diagonal[end]
+      "Newton steps for reduced pressures of the components: Last component";
+    delta_eta_i[1:end-1] := (-delta_pi_i[1:end-1] .+ Jac_diagonal[end] *
+      delta_eta_i[end]) ./ Jac_diagonal[1:end-1]
+      "Newton steps for reduced pressures of the components: Remaining components";
+
+    for i in 1:size(M_i,1) loop
+      if eta_i[i] + delta_eta_i[i] < 0 then
+        eta_i[i] := eta_i[i] / 2
+          "Update reduced pressure";
+
+      else
+        eta_i[i] := eta_i[i] + delta_eta_i[i]
+          "Update reduced pressure";
+
+      end if;
+    end for;
+
+    //
+    // Check for convergence
+    //
+    no_iteration := no_iteration + 1
+      "Counter of loop";
+    error := sum(abs(delta_eta_i))
+      "Error of loop";
+
+  end while;
+
+  //
+  // Return final results
+  //
+  if error >= num.tolerance or no_iteration > num.no_max or max(p_i_pure) >= 1e30 then
+    //
+    // Calculation failed: Use 'Nested Loop' algorithm as fallback solution
+    //
+   (x_adsorpt,p_i_pure,pi) :=
+     SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NestedLoop(
+     p_adsorpt=p_adsorpt,
+     y_i=y_i,
+     T_adsorpt=T_adsorpt,
+     M_i=M_i,
+     c_1=c_1,
+     c_2=c_2,
+     func_x_pT_1=func_x_pT_1,
+     func_p_xT_1=func_p_xT_1,
+     func_dx_dp_1=func_dx_dp_1,
+     func_pi_pT_1=func_pi_pT_1,
+     func_p_piT_1=func_p_piT_1,
+     func_x_pT_2=func_x_pT_2,
+     func_p_xT_2=func_p_xT_2,
+     func_dx_dp_2=func_dx_dp_2,
+     func_pi_pT_2=func_pi_pT_2,
+     func_p_piT_2=func_p_piT_2,
+     num=num,
+     num_comp_1=num_comp_1,
+     num_comp_2=num_comp_2) "'Nested Loop' algorithm to solve IAST";
+
+    else
+    //
+    // Calculate mole fractions of adsorpt phase
+    //
+    z_i := y_i .* p_adsorpt ./ p_i_pure
+      "Mole fractions of the adsorpt phase";
+
+    //
+    // Calculate equilibrium uptakes
+    //
+    q_adsorpt_i[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      first component";
+    q_adsorpt_i[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+    "Molar equilibrium uptake at hypothetical pure component pressure of the 
+    second component";
+
+    q_adsorpt := 1 / sum(z_i ./ q_adsorpt_i)
+    "Total molar equilibrium uptake";
+
+    //
+    // Calculate final ouputs
+    //
+    x_adsorpt := q_adsorpt .* z_i .* M_i
+      "Equilibrium uptakes of the adsorpt phase";
+
+    pi := pi_i[end]
+      "Reduced spreading pressure of all components";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function provides an algorithm for solving the IAST for two components. The 
+uptakes <i>x_adsorpt</i> are calculated as a function of the pressure <i>p_adsorpt</i>, 
+the molar composition of the gas/vapour phase <i>y_i</i>, and the temperature 
+<i>T_adsorpt</i>. The algorithm uses one loops to iterate simultaneously over the 
+reduced spreading pressure <i>&pi;</i> and the molar composition of the adsorpt phase
+<i>z<sub><I>i</i></sub></i>. The algorithm exploits that all relevant information can 
+be written into a Jacobian matrix in which all elements are zero except the last row, 
+the last column, and the diagonal. For the calculation, only the information of the 
+last row and diagonal is required, which reduces the computational effort.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The algorithm consists of 20 steps:
+</p>
+<ol>
+  <li>
+  Calculate the Henry's constant of each component <i>i</i>:
+  <pre>K<sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub>,</pre>
+  where <i>M<sub><i>i</i></sub></i> is the molar mass and <i>dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub></i> 
+  is the partial derivative of the uptake with respect to the pressure.
+  <br>
+  </li>
+  <li>
+  Calculate the average Henry's constant:
+  <pre>K<sub>avg</sub> = &sum;<sub><i>i</i></sub> y<sub><i>i</i></sub> * K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the molar saturation uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,sat,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p &rarr; &infin;, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate auxiliary variable of each component <i>i</i>:
+  <pre>Kp<sub><i>i</i></sub> = K<sub><i>i</i></sub> / q<sub>adsorpt,sat,<i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the initial guess of the reduced pressure of each component <i>i</i>:
+  <pre>&eta;<sub><i>i</i></sub> = <strong>min</strong>(Kp<sub><i>i</i></sub> / K<sub><i>i</i></sub> * p<sub>adsorpt</sub> * K<sub>avg</sub>, Kp<sub><i>i</i></sub> * p<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the last row of the Jacobian matrix for each column <i>i</i>:
+  <pre>Jac<sub>last row,<i>i</i></sub> = Kp<sub><i>i</i></sub> * p<sub>adsorpt</sub> * y<sub><i>i</i></sub> / &eta;<sup>2</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = &eta;<sub><i>i</i></sub> / Kp<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the diagonal of the Jacobian matrix for each component <i>i</i>:
+  <pre>Jac<sub>diagonal,<i>i</i></sub> = 1 / (M<sub><i>i</i></sub> * &eta;<sub><i>i</i></sub>) * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Correct the last element of the diagonal of the Jacobian matrix:
+  <pre>Jac<sub>diagonal,last</sub> = Jac<sub>last row,last</sub> + Jac<sub>diagonal,last</sub> * &sum;<sub><i>i</i></sub><sup>N-1</sup> [Jac<sub>last row,<i>i</i></sub> / Jac<sub>diagonal,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the differences between the reduced spreading pressure of each 
+  component <i>i</i> and the reduced spreading pressure of the last component:
+  <pre>&Delta;&pi;<sub><i>i</i></sub> = &pi;<sub><i>i</i></sub> - &pi;<sub>last</sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Correct the last element of the differences between the reduced spreading pressure 
+  of each component <i>i</i> and the reduced spreading pressure of the last component:
+  <pre>&Delta;&pi;<sub>last</sub> =1 - &sum;<sub><i>i</i></sub> [Kp<sub><i>i</i></sub> * p<sub>adsorpt</sub> * y<sub><i>i</i></sub> / &eta;<sub><i>i</i></sub>] - &sum;<sub><i>i</i></sub><sup>N-1</sup> [Jac<sub>last row,<i>i</i></sub> / Jac<sub>diagonal,<i>i</i></sub> * &Delta;&pi;<sub><i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the change of the reduced pressure of the last component:
+  <pre>&Delta;&eta;<sub>last</sub> = &Delta;&pi;<sub>last</sub> / Jac<sub>diagonal,last</sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the change of the reduced pressure of the remaining components <i>i</i>:
+  <pre>&Delta;&eta;<sub><i>i</i></sub> = (-&Delta;&pi;<sub><i>i</i></sub>  + Jac<sub>diagonal,last</sub> * &Delta;&eta;<sub>last</sub>) / Jac<sub>diagonal,<i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced pressure of the next iteration step of each component <i>i</i>:
+  <pre>&eta;<sub>next,<i>i</i></sub> = <strong>if</strong> &eta;<sub><i>i</i></sub> + &Delta;&eta;<sub><i>i</i></sub> > 0 <strong>then</strong> &eta;<sub><i>i</i></sub> + &Delta;&eta;<sub><i>i</i></sub> <strong>else</strong> &eta;<sub><i>i</i></sub>/2.</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence:
+  <pre>&sum; |&Delta;&eta;<sub><i>i</i></sub>| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 6. It the convergence
+  criterion is fulfilled, got to step 17.
+  <br>
+  </li>
+  <li>
+  Calculate the molar composition of each component <i>i</i> in the adsorpt
+  phase:
+  <pre>z<sub><i>i</i></sub> = y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the molar uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the total molar uptake:
+  <pre>q<sub>adsorpt,total</sub> = 1 / &sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the uptakes of each component <i>i</i>:
+  <pre>x<sub>adsorpt,<i>i</i></sub> = M<sub><i>i</i></sub> * z<sub><i>i</i></sub> * q<sub>adsorpt,total</sub>.</pre>
+  </li>
+</ol>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Mangano E., Friedrich, D., and Brandani, S. (2015). Robust algorithms for the solution of the ideal adsorbed solution theory equations. AIChE Journal, 61(3): 981–991. DOI: 10.1002/aic.14684.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_pyT_FastIAST;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_NestedLoop.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_NestedLoop.mo
new file mode 100644
index 0000000..4c1feef
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_NestedLoop.mo
@@ -0,0 +1,389 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals;
+function x_pyT_NestedLoop
+  "IAST for two components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature using the 'Nested Loop' algorithm"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[:] y_i
+    "Mole fractions of the components in the gas or vapor phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean flag_startValues = false
+    " = true, if start values are given; otherwise, estimate start values"
+    annotation (Dialog(tab="General", group="Inputs - Start values"));
+  input Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure_0=
+    fill(1, size(M_i,1))
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+  input SorpLib.Units.ReducedSpreadingPressure pi_0 = 1
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(M_i,1)] K_i(each unit="mol/(kg.Pa)")
+    "Henry constants of the components";
+  Real K_avg(unit="mol/(kg.Pa)")
+    "Average Henry constant";
+
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] pi_i
+    "Reduced spreading pressures";
+
+  Integer no_inner = 1
+    "Counter of inner loop";
+  Integer no_outer = 1
+    "Counter of outer loop";
+
+  SorpLib.Units.ReducedSpreadingPressure error_inner = 1
+    "Error of inner loop";
+  Modelica.Units.SI.MoleFraction error_outer = 1
+    "Error of outer loop";
+
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] delta_pi_i
+    "Difference between reduced spreading pressures and reduced spreading pressure
+    of all components";
+  Real[size(M_i,1)] ddelta_pi_i_dp_i_pure(each unit="mol/(kg.Pa)")
+    "Partial derivative of difference between reduced spreading pressures and 
+    reduced spreading pressure of all components w.r.t. the hypothetical pure
+    component pressures";
+
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] z_i
+    "Mole fractions of the adsorpt phase";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_i
+    "Molar equilibrium uptakes at hypothetical pure component pressures";
+  SorpLib.Units.MolarUptake q_adsorpt
+    "Total molar equilibrium uptake";
+
+algorithm
+  if flag_startValues then
+    //
+    // Use start values
+    //
+    p_i_pure := p_i_pure_0
+      "Hypothetical pure component pressures";
+    pi := pi_0
+      "Reduced spreading pressure of all components";
+
+  else
+    //
+    // Caclulate initial guesses ensuring convergence: Henry constants
+    //
+    K_i[1] := 1/M_i[1] * func_dx_dp_1(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_1)
+      "Henry constant of the first component";
+    K_i[2] := 1/M_i[2] * func_dx_dp_2(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_2)
+      "Henry constant of the second component";
+
+    K_avg := sum(y_i .* K_i)
+      "Average Henry constant";
+
+    //
+    // Caclulate initial guesses ensuring convergence: Reduced spreading pressures
+    // and hypothetical pure component pressures
+    //
+    p_i_pure := p_adsorpt .* K_avg ./ K_i
+      "Hypothetical pure component pressures";
+
+    pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance=num_comp_1.tolerance_pi)
+      "Reduced spreading pressure of the first component";
+    pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance=num_comp_2.tolerance_pi)
+      "Reduced spreading pressure of the second component";
+
+    pi := min(pi_i)
+      "Reduced spreading pressure of all components";
+    p_i_pure := pi ./ K_i
+      "Hypothetical pure component pressures";
+
+  end if;
+
+  //
+  // Outer loop: Ensure mass conservation
+  //
+  while error_outer >= num.tolerance_outer and no_outer <= num.no_max_outer loop
+    //
+    // Inner loop: Ensure identical spreading pressures
+    //
+    no_inner :=1
+      "Counter of inner loop";
+    error_inner :=1
+      "Error of inner loop";
+
+    while error_inner >= num.tolerance_inner and no_inner <= num.no_max_inner loop
+      //
+      // Calculate reduced spreading pressures
+      //
+      pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+        p_adsorpt=p_i_pure[1],
+        T_adsorpt=T_adsorpt,
+        c=c_1,
+        integral_pi_lb=num_comp_1.integral_pi_lb,
+        tolerance=num_comp_1.tolerance_pi)
+        "Reduced spreading pressure of the first component";
+      pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+        p_adsorpt=p_i_pure[2],
+        T_adsorpt=T_adsorpt,
+        c=c_2,
+        integral_pi_lb=num_comp_2.integral_pi_lb,
+        tolerance=num_comp_2.tolerance_pi)
+        "Reduced spreading pressure of the second component";
+
+      //
+      // Apply Newton-Raphson method
+      //
+      delta_pi_i := pi_i .- pi
+        "Difference betwenn reduced spreading pressures and reduced spreading pressure
+        of all components";
+
+      ddelta_pi_i_dp_i_pure[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+        T_adsorpt=T_adsorpt,
+        c=c_1,
+        p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+        p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+        tolerance=num_comp_1.tolerance_p_adsorpt) / p_i_pure[1]
+        "Partial derivative of difference between reduced spreading pressure of the
+        first component and reduced spreading pressure of all components w.r.t. the 
+        hypothetical pure component pressure of the first component";
+      ddelta_pi_i_dp_i_pure[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+        T_adsorpt=T_adsorpt,
+        c=c_2,
+        p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+        p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+        tolerance=num_comp_2.tolerance_p_adsorpt) / p_i_pure[2]
+        "Partial derivative of difference between reduced spreading pressure of the
+        second component and reduced spreading pressure of all components w.r.t. the 
+        hypothetical pure component pressure of the second component";
+
+      p_i_pure := p_i_pure .- delta_pi_i ./ ddelta_pi_i_dp_i_pure
+        "Hypothetical pure component pressures";
+
+      //
+      // Check for convergence
+      //
+      no_inner := no_inner + 1
+        "Counter of inner loop";
+      error_inner := sum(abs(delta_pi_i))
+        "Error of inner loop";
+
+    end while;
+
+    //
+    // Calculate mole fractions of adsorpt phase
+    //
+    z_i := y_i .* p_adsorpt ./ p_i_pure
+      "Mole fractions of the adsorpt phase";
+
+    //
+    // Calculate equilibrium uptakes
+    //
+    q_adsorpt_i[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure compoment pressure of the 
+      first component";
+    q_adsorpt_i[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure compoment pressure of the 
+      second component";
+
+    q_adsorpt := 1 / sum(z_i ./ q_adsorpt_i)
+      "Total molar equilibrium uptake";
+
+    //
+    // Apply Newton-Raphson method
+    //
+    pi := pi + (-(1 - sum(z_i)) / (1/q_adsorpt))
+      "Reduced spreading pressure of all components";
+
+    //
+    // Check for convergence
+    //
+    no_outer := no_outer + 1
+      "Counter of outer loop";
+    error_outer := abs(1 - sum(z_i))
+      "Error of outer loop";
+
+  end while;
+
+  //
+  // Calculate final ouputs
+  //
+  x_adsorpt := q_adsorpt .* z_i .* M_i
+    "Equilibrium uptakes of the adsorpt phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function provides an algorithm for solving the IAST for two components. The 
+uptakes <i>x_adsorpt</i> are calculated as a function of the pressure <i>p_adsorpt</i>, 
+the molar composition of the gas/vapour phase <i>y_i</i>, and the temperature 
+<i>T_adsorpt</i>. The algorithm uses two loops, with the inner loop nested in the
+outer loop. Hence, the algorithm is called 'Nested Loop.' The inner loop iterates
+over the reduced spreading pressure <i>&pi;</i>, while the outer loop iterates over
+the molar composition of the adsorpt phase <i>z<sub><I>i</i></sub></i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The algorithm consists of 17 steps:
+</p>
+<ol>
+  <li>
+  Calculate the Henry's constant of each component <i>i</i>:
+  <pre>K<sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub>,</pre>
+  where <i>M<sub><i>i</i></sub></i> is the molar mass and <i>dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub></i> 
+  is the partial derivative of the uptake with respect to the pressure.
+  <br>
+  </li>
+  <li>
+  Calculate the average Henry's constant:
+  <pre>K<sub>avg</sub> = &sum;<sub><i>i</i></sub> y<sub><i>i</i></sub> * K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = p<sub>adsorpt</sub> * K<sub>avg</sub> / K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the initial guess of the reduced spreading pressure:
+  <pre>&pi; = <strong>min</strong>(&pi;<sub><i>i</i></sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the initial guesses of the hypothetical pure component pressures of each 
+  component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = &pi; / K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the differences between the reduced spreading pressure of each 
+  component <i>i</i> and the reduced spreading pressure of the last component:
+  <pre>&Delta;&pi;<sub><i>i</i></sub> = &pi;<sub><i>i</i></sub> - &pi;<sub>last</sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the partial derivatives of the differences between the reduced 
+  spreading pressure of each component <i>i</i> and the reduced spreading 
+  pressure of the last component with respect to the hypothetical pure
+  component pressures:
+  <pre>d&Delta;&pi;<sub><i>i</i></sub>/dp<sup>*</sup><sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>) / p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component 
+  <i>i</i> of the next iteration step:
+  <pre>p<sup>*</sup><sub>next,<i>i</i></sub> = p<sup>*</sup><sub><i>i</i></sub> - &Delta;&pi;<sub><i>i</i></sub> / d&Delta;&pi;<sub><i>i</i></sub>/dp<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence of the inner loop:
+  <pre>&sum;<sub><i>i</i></sub> |&Delta;&pi;<sub><i>i</i></sub>| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 7. It the convergence
+  criterion is fulfilled, got to step 12.
+  <br>
+  </li>
+  <li>
+  Calculate the molar composition of each component <i>i</i> in the adsorpt
+  phase:
+  <pre>z<sub><i>i</i></sub> = y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the molar uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the total molar uptake:
+  <pre>q<sub>adsorpt,total</sub> = 1 / &sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressure of the next iteration step:
+  <pre>&pi;<sub>next</sub> = &pi; - (1 - &sum; z<sub><i>i</i></sub>) / (1 / q<sub>adsorpt,total</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence of the outer loop:
+  <pre>|1 - &sum;<sub><i>i</i></sub> z<sub><i>i</i></sub>| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 7. It the convergence
+  criterion is fulfilled, got to step 17.
+  <br>
+  </li>
+  <li>
+  Calculate the uptakes of each component <i>i</i>:
+  <pre>x<sub>adsorpt,<i>i</i></sub> = M<sub><i>i</i></sub> * z<sub><i>i</i></sub> * q<sub>adsorpt,total</sub>.</pre>
+  </li>
+</ol>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Mangano E., Friedrich, D., and Brandani, S. (2015). Robust algorithms for the solution of the ideal adsorbed solution theory equations. AIChE Journal, 61(3): 981–991. DOI: 10.1002/aic.14684.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_pyT_NestedLoop;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_NewtonRaphson.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_NewtonRaphson.mo
new file mode 100644
index 0000000..1ab9a7c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/Internals/x_pyT_NewtonRaphson.mo
@@ -0,0 +1,322 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals;
+function x_pyT_NewtonRaphson
+  "IAST for two components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature using the standard 'Newton-Raphson' algorithm"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[:] y_i
+    "Mole fractions of the components in the gas or vapor phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean flag_startValues = false
+    " = true, if start values are given; otherwise, estimate start values"
+    annotation (Dialog(tab="General", group="Inputs - Start values"));
+  input SorpLib.Units.ReducedSpreadingPressure pi_0 = 1
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(M_i,1)] K_i(each unit="mol/(kg.Pa)")
+    "Henry constants of the components";
+  Real K_avg(unit="mol/(kg.Pa)")
+    "Average Henry constant";
+
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] pi_i
+    "Reduced spreading pressures";
+
+  Integer no_iteration = 1
+    "Counter of loop";
+  Real error = 1
+    "Error of loop";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_i
+    "Molar equilibrium uptakes at hypothetical pure component pressures";
+
+  Modelica.Units.SI.MoleFraction delta_sum_z_i
+    "Satisfaction of molar composition of adsorpt phase";
+  Real ddelta_sum_z_i_dpi(unit="kg/mol")
+    "Partial derivative of satisfaction of molar composition of adsorpt phase
+    w.r.t. to reduced spreading pressure of all components";
+
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] z_i
+    "Mole fractions of the adsorpt phase";
+
+  SorpLib.Units.MolarUptake q_adsorpt
+    "Total molar equilibrium uptake";
+
+algorithm
+  if flag_startValues then
+    //
+    // Use start values
+    //
+    pi := pi_0
+      "Reduced spreading pressure of all components";
+
+  else
+    //
+    // Caclulate initial guesses ensuring convergence: Henry constants
+    //
+    K_i[1] := 1/M_i[1] * func_dx_dp_1(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_1)
+      "Henry constant of the first component";
+    K_i[2] := 1/M_i[2] * func_dx_dp_2(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_2)
+      "Henry constant of the second component";
+
+    K_avg := sum(y_i .* K_i)
+      "Average Henry constant";
+
+    //
+    // Caclulate initial guesses ensuring convergence: Reduced spreading pressures
+    // and hypothetical pure component pressures
+    //
+    p_i_pure := p_adsorpt .* K_avg ./ K_i
+      "Hypothetical pure component pressures";
+
+    pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance=num_comp_1.tolerance_pi)
+      "Reduced spreading pressure of the first component";
+    pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance=num_comp_2.tolerance_pi)
+      "Reduced spreading pressure of the second component";
+
+    pi := min(pi_i)
+      "Reduced spreading pressure of all components";
+
+  end if;
+
+  //
+  // Loop to solve the IAST
+  //
+  while error >= num.tolerance and no_iteration <= num.no_max loop
+    //
+    // Calculate hypothetical pure component pressures
+    //
+    p_i_pure[1] := func_p_piT_1(
+      M_adsorptive=M_i[1],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_1.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_1.tolerance_pi)
+      "Hypothetical pure component pressure of the first component";
+    p_i_pure[2] := func_p_piT_2(
+      M_adsorptive=M_i[2],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_2.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_2.tolerance_pi)
+      "Hypothetical pure component pressure of the first component";
+
+    //
+    // Calculate molar uptakes
+    //
+    q_adsorpt_i[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      first component";
+    q_adsorpt_i[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      second component";
+
+    //
+    // Apply Newton-Raphson method
+    //
+    delta_sum_z_i := sum((p_adsorpt .* y_i) ./ p_i_pure) - 1
+      "Satisfaction of molar composition of adsorpt phase";
+    ddelta_sum_z_i_dpi := -sum((p_adsorpt .* y_i) ./ (p_i_pure .* q_adsorpt_i))
+      "Partial derivative of satisfaction of molar composition of adsorpt phase
+      w.r.t. to reduced spreading pressure of all components";
+
+    pi := if pi - delta_sum_z_i / ddelta_sum_z_i_dpi > 0 then
+      pi - delta_sum_z_i / ddelta_sum_z_i_dpi else pi / 2
+      "Update reduced spreading pressure of all components";
+
+    //
+    // Check for convergence
+    //
+    no_iteration := no_iteration + 1
+      "Counter of loop";
+    error := abs(delta_sum_z_i)
+      "Error of loop";
+
+  end while;
+
+  //
+  // Calculate mole fractions of adsorpt phase
+  //
+  z_i := y_i .* p_adsorpt ./ p_i_pure
+    "Mole fractions of the adsorpt phase";
+
+  //
+  // Calculate equilibrium uptake
+  //
+  q_adsorpt := 1 / sum(z_i ./ q_adsorpt_i)
+  "Total molar equilibrium uptake";
+
+  //
+  // Calculate final ouputs
+  //
+  x_adsorpt := q_adsorpt .* z_i .* M_i
+    "Equilibrium uptakes of the adsorpt phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function provides an algorithm for solving the IAST for two components. The 
+uptakes <i>x_adsorpt</i> are calculated as a function of the pressure <i>p_adsorpt</i>, 
+the molar composition of the gas/vapour phase <i>y_i</i>, and the temperature 
+<i>T_adsorpt</i>. The algorithm uses a Newton-Raphson method to solve the system 
+of equations of the IAST. 
+</p>
+
+<h4>Main equations</h4>
+<p>
+The algorithm consists of 14 steps:
+</p>
+<ol>
+  <li>
+  Calculate the Henry's constant of each component <i>i</i>:
+  <pre>K<sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub>,</pre>
+  where <i>M<sub><i>i</i></sub></i> is the molar mass and <i>dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub></i> 
+  is the partial derivative of the uptake with respect to the pressure.
+  <br>
+  </li>
+  <li>
+  Calculate the average Henry's constant:
+  <pre>K<sub>avg</sub> = &sum;<sub><i>i</i></sub> y<sub><i>i</i></sub> * K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = p<sub>adsorpt</sub> * K<sub>avg</sub> / K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the initial guess of the reduced spreading pressure:
+  <pre>&pi; = <strong>min</strong>(&pi;<sub><i>i</i></sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, &pi;, T<sub>adsorpt</sub>).</pre>
+  This formula is an inverse of the reduced spreading pressure, which often
+  has to be calculated numerically.
+  <br>
+  </li>
+  <li>
+  Calculate the molar uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the satisfaction of the molar composition of the adsorpt phase:
+  <pre>F = &sum;<sub><i>i</i></sub> [y<sub><i>i</i></sub> * x<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>] - 1.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the partial derivative of the satisfaction of the adsorpt phase
+  with respect to the reduced spreading pressure:
+  <pre>dF/d&pi; = -&sum;<sub><i>i</i></sub> [y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / (p<sup>*</sup><sub><i>i</i></sub> * q<sub>adsorpt,<i>i</i></sub>)].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressure of the next iteration step:
+  <pre>&pi;<sub>next</sub> = <strong>if</strong> &pi; - F / dF/d&pi; > 0 <strong>then</strong> &pi; - F / dF/d&pi; > 0 <strong>else</strong> &pi;/2.</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence:
+  <pre>|F| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 6. It the convergence
+  criterion is fulfilled, got to step 12.
+  <br>
+  </li>
+  <li>
+  Calculate the molar composition of each component <i>i</i> in the adsorpt
+  phase:
+  <pre>z<sub><i>i</i></sub> = y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the total molar uptake:
+  <pre>q<sub>adsorpt,total</sub> = 1 / &sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the uptakes of each component <i>i</i>:
+  <pre>x<sub>adsorpt,<i>i</i></sub> = M<sub><i>i</i></sub> * z<sub><i>i</i></sub> * q<sub>adsorpt,total</sub>.</pre>
+  </li>
+</ol>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_pyT_NewtonRaphson;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/package.mo
new file mode 100644
index 0000000..6fe1699
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/package.mo
@@ -0,0 +1,805 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package IAST_N2 "Package containing all functions regarding the IAST for two components"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponentsIAST;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "IAST for two components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+      "Mole fractions of all components in the vapor or gas phase";
+
+  algorithm
+    //
+    // Select IAST algorithm
+    //
+    if num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson then
+      (x_adsorpt,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop then
+      (x_adsorpt,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'Nested Loop' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST then
+      (x_adsorpt,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'FASTIast' algorithm";
+    end if;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "IAST for two components: Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+      "Mole fractions of all components in the vapor or gas phase";
+
+  algorithm
+    (p_adsorpt,,) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.py_xT_NewtonRaphson(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      func_x_pT_1=func_x_pT_1,
+      func_p_xT_1=func_p_xT_1,
+      func_dx_dp_1=func_dx_dp_1,
+      func_pi_pT_1=func_pi_pT_1,
+      func_p_piT_1=func_p_piT_1,
+      func_x_pT_2=func_x_pT_2,
+      func_p_xT_2=func_p_xT_2,
+      func_dx_dp_2=func_dx_dp_2,
+      func_pi_pT_2=func_pi_pT_2,
+      func_p_piT_2=func_p_piT_2,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "IAST for two components: Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_
+      "Mole fractions of all components in the vapor or gas phase";
+
+  algorithm
+    //
+    // Solve inverse of IAST
+    //
+    (,y_i_,) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.py_xT_NewtonRaphson(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      func_x_pT_1=func_x_pT_1,
+      func_p_xT_1=func_p_xT_1,
+      func_dx_dp_1=func_dx_dp_1,
+      func_pi_pT_1=func_pi_pT_1,
+      func_p_piT_1=func_p_piT_1,
+      func_x_pT_2=func_x_pT_2,
+      func_p_xT_2=func_p_xT_2,
+      func_dx_dp_2=func_dx_dp_2,
+      func_pi_pT_2=func_pi_pT_2,
+      func_p_piT_2=func_p_piT_2,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+    //
+    // Assign correct output values
+    //
+    y_i := y_i_[1:end-1]
+      "Mole fractions of independent components in the gas or vapor phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2),
+          p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2)));
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "IAST for two components: Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_
+      "Mole fractions of all components in the vapor or gas phase";
+
+  algorithm
+    //
+    // Solve inverse of IAST
+    //
+    (p_adsorpt,y_i_,) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.py_xT_NewtonRaphson(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      func_x_pT_1=func_x_pT_1,
+      func_p_xT_1=func_p_xT_1,
+      func_dx_dp_1=func_dx_dp_1,
+      func_pi_pT_1=func_pi_pT_1,
+      func_p_piT_1=func_p_piT_1,
+      func_x_pT_2=func_x_pT_2,
+      func_p_xT_2=func_p_xT_2,
+      func_dx_dp_2=func_dx_dp_2,
+      func_pi_pT_2=func_pi_pT_2,
+      func_p_piT_2=func_p_piT_2,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+    //
+    // Assign correct output values
+    //
+    y_i := y_i_[1:end-1]
+      "Mole fractions of independent components in the gas or vapor phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "IAST for two components: Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature (numerical solution)"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_pdp
+      "Equilibrium uptakes of the adsorpt phase: p + dp";
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_mdp
+      "Equilibrium uptakes of the adsorpt phase: p - dp";
+
+  algorithm
+    //
+    // Select IAST algorithm
+    //
+    if num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson then
+      (x_adsorpt_pdp,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt + dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+      (x_adsorpt_mdp,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt - dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop then
+      (x_adsorpt_pdp,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt + dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'Nested Loop' algorithm";
+
+      (x_adsorpt_mdp,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt - dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'Nested Loop' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST then
+      (x_adsorpt_pdp,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt + dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'FASTIast' algorithm";
+
+      (x_adsorpt_mdp,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt - dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'FASTIast' algorithm";
+    end if;
+
+    //
+    // Calculate derivatives of loadings w.r.t. equilibrium pressure
+    //
+    dx_adsorpt_dp_adsorpt := (x_adsorpt_pdp .- x_adsorpt_mdp) ./ (2*dp)
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "IAST for two components: Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature (numerical solution)"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_pdy
+      "Equilibrium uptakes of the adsorpt phase: y + dy";
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_mdy
+      "Equilibrium uptakes of the adsorpt phase: y - dy";
+
+  algorithm
+    for ind_y_i in 1:size(M_i,1)-1 loop
+      //
+      // Select IAST algorithm
+      //
+      if num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson then
+        (x_adsorpt_pdy,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NewtonRaphson(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(1, y_i_[1:ind_y_i - 1], {y_i_[ind_y_i] + dy}, y_i_[ind_y_i + 1:size(M_i,1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+        (x_adsorpt_mdy,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NewtonRaphson(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(1, y_i_[1:ind_y_i - 1], {y_i_[ind_y_i] - dy}, y_i_[ind_y_i + 1:size(M_i,1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+      elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop then
+        (x_adsorpt_pdy,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NestedLoop(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(1, y_i_[1:ind_y_i - 1], {y_i_[ind_y_i] + dy}, y_i_[ind_y_i + 1:size(M_i,1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2) "'Nested Loop' algorithm";
+
+        (x_adsorpt_mdy,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NestedLoop(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(1, y_i_[1:ind_y_i - 1], {y_i_[ind_y_i] - dy}, y_i_[ind_y_i + 1:size(M_i,1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2) "'Nested Loop' algorithm";
+
+      elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST then
+        (x_adsorpt_pdy,,,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_FastIAST(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(1, y_i_[1:ind_y_i - 1], {y_i_[ind_y_i] + dy}, y_i_[ind_y_i + 1:size(M_i,1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2) "'FASTIast' algorithm";
+
+        (x_adsorpt_mdy,,,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_FastIAST(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(1, y_i_[1:ind_y_i - 1], {y_i_[ind_y_i] - dy}, y_i_[ind_y_i + 1:size(M_i,1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2) "'FASTIast' algorithm";
+      end if;
+
+      //
+      // Calculate partial darivatives for each independent mole fraction
+      //
+      dx_adsorpt_dy_i[:,ind_y_i] := (x_adsorpt_pdy .- x_adsorpt_mdy) ./ (2*dy)
+        "Partial derivatives of the uptakes w.r.t. the mole fractions of independent 
+      gas phase components at constant pressure and temperature";
+    end for;
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "IAST for two components: Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions (numerical solution)"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_pdT
+      "Equilibrium uptakes of the adsorpt phase: T + dT";
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_mdT
+      "Equilibrium uptakes of the adsorpt phase: T - dT";
+
+  algorithm
+    //
+    // Select IAST algorithm
+    //
+    if num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson then
+      (x_adsorpt_pdT,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt + dT,
+        M_i=M_i,
+        c_1=c_pdT_1,
+        c_2=c_pdT_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+      (x_adsorpt_mdT,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt - dT,
+        M_i=M_i,
+        c_1=c_mdT_1,
+        c_2=c_mdT_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "Standard 'Newton-Raphson' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop then
+      (x_adsorpt_pdT,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt + dT,
+        M_i=M_i,
+        c_1=c_pdT_1,
+        c_2=c_pdT_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'Nested Loop' algorithm";
+
+      (x_adsorpt_mdT,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt - dT,
+        M_i=M_i,
+        c_1=c_mdT_1,
+        c_2=c_mdT_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'Nested Loop' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST then
+      (x_adsorpt_pdT,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt + dT,
+        M_i=M_i,
+        c_1=c_pdT_1,
+        c_2=c_pdT_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'FASTIast' algorithm";
+
+      (x_adsorpt_mdT,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N2.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt - dT,
+        M_i=M_i,
+        c_1=c_mdT_1,
+        c_2=c_mdT_2,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2) "'FASTIast' algorithm";
+    end if;
+
+    //
+    // Calculate derivatives of loadings w.r.t. equilibrium pressure
+    //
+    dx_adsorpt_dT_adsorpt := (x_adsorpt_pdT .- x_adsorpt_mdT) ./ (2*dT)
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The IAST for two components calculates equilibrium uptakes <i>x_adsorpt</i> as a
+function of the equilibrium pressure <i>p_adsorpt</i>, mole fractions of independent 
+components in the gas or vapor phase <i>y_i</i>, and the equilibrium temperature 
+<i>T_adsorpt</i>. The IAST calculates the multi-component adsorption equilibrium based 
+on the pure component isotherm models. For this purpose, a system of equations is 
+solved using numerical methods.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The system of equations consists of 2 * <i>n_components</i> + 1 equations (i.e., 5), 
+which can be divided into 4 main equation types:
+</p>
+<ol>
+  <li>
+  Reduced spreading pressure <i>&pi;</i> that is the same for all components:
+  <pre>&pi; = &pi;<sub><i>i</i></sub> = &int;<sub>0</sub><sup>p<sup>*</sup><sub><i>i</i></sub></sup> [x<sub>adsorpt,<i>i</i></sub> / p<sub>adsorpt,<i>i</i></sub> * dp<sub>adsorpt,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Closing condition of the molar composition of the adsorpt phase <i>z<sub><i>i</i></sub></i>:
+  <pre>1 = &sum;<sub><i>i</i></sub> z<sub><i>i</i></sub> = &sum;<sub><i>i</i></sub> [y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Molar uptake of the adsorpt phase of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = z<sub><i>i</i></sub> * q<sub>total</sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Total molar uptake of the adsorpt phase:
+  <pre>q<sub>total</sub> = (&sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>]) ^ (-1).</pre>
+  <br>
+  </li>
+</ol>
+<p>
+Herein, for each component <i>i</i<>, <i>p<sup>*</sup><sub><i>i</i></sub></i> is the
+hypothetical pure component pressure at which the reduced spreading pressure of each
+component <i>&pi;<sub><i>i</i></sub></i> is identical (i.e., equilibrium condition).
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the IAST for two components for one parameter set. In the 
+upper sub-figure, the equilibrium pressure changes with time. In the centre sub-figure, 
+the independent mole fractions change with time. In the lower sub-figure, the 
+equilibrium temperature changes with time. The left side shows the uptake of component 
+1, and the right side shows the uptake of component 2. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_iast_n2.png\" alt=\"media_functions_equilibria_multi_iast_n2.png\">
+
+<h4>References</h4>
+<p>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Mangano E., Friedrich, D., and Brandani, S. (2015). Robust algorithms for the solution of the ideal adsorbed solution theory equations. AIChE Journal, 61(3): 981–991. DOI: 10.1002/aic.14684.
+  </li>
+</ul>
+</p>
+</html>"));
+end IAST_N2;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N2/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/package.mo
new file mode 100644
index 0000000..47a7a1b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the IAST for
+three components. Thus, redundancy of code shall be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/package.order
new file mode 100644
index 0000000..28701d4
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/package.order
@@ -0,0 +1,4 @@
+x_pyT_NewtonRaphson
+x_pyT_NestedLoop
+x_pyT_FastIAST
+py_xT_NewtonRaphson
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/py_xT_NewtonRaphson.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/py_xT_NewtonRaphson.mo
new file mode 100644
index 0000000..0db8156
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/py_xT_NewtonRaphson.mo
@@ -0,0 +1,398 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals;
+function py_xT_NewtonRaphson
+  "IAST for three components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature using the standard 'Newton-Raphson' algorithm"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real[:] c_3
+    "Coefficients of the isotherm model of the third component"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+    "Uptake of the third component as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+    "Pressure of the third component as function of uptake and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+    "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+    "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+    "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+    "Record definining numerics of the third component's isotherm model"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                choicesAllMatching=true);
+
+  input Boolean flag_startValues = false
+    " = true, if start values are given; otherwise, estimate start values"
+    annotation (Dialog(tab="General", group="Inputs - Start values"));
+  input SorpLib.Units.ReducedSpreadingPressure pi_0 = 1
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i
+    "Mole fractions of components in the vapor or gas phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] pi_i
+    "Reduced spreading pressures";
+
+  Integer no_iteration = 1
+    "Counter of loop";
+  Real error = 1
+    "Error of loop";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_i = x_adsorpt ./ M_i
+    "Molar equilibrium uptakes at hypothetical pure component pressures";
+  Real[size(M_i,1)] dq_adsorpt_i_dp_i_pure(each unit="mol/(kg.Pa)")
+    "Partical derivatives of molar equilibrium uptakes at hypothetical pure 
+    component pressures w.r.t. hypothetical pure component pressures";
+
+  Real delta_sum_q_adsorpt(unit="kg/mol")
+    "Satisfaction of total molar uptake";
+  Real ddelta_sum_q_adsorpt_dpi(unit="kg.kg/(mol.mol)")
+    "Partial derivative of satisfaction of total molar uptake w.r.t. to reduced 
+    spreading pressure of all components";
+
+  SorpLib.Units.MolarUptake q_adsorpt = sum(q_adsorpt_i)
+    "Total molar equilibrium uptake";
+
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] z_i = q_adsorpt_i ./ q_adsorpt
+    "Mole fractions of the adsorpt phase";
+
+algorithm
+  if flag_startValues then
+    //
+    // Use start values
+    //
+    pi := pi_0
+      "Reduced spreading pressure of all components";
+
+  else
+    //
+    // Caclulate initial guesses ensuring convergence: Equilibrium pressures
+    //
+    p_i_pure[1] := func_p_xT_1(x_adsorpt=x_adsorpt[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Pure component pressure of the first component (not at hypothetical pressure)";
+    p_i_pure[2] := func_p_xT_2(x_adsorpt=x_adsorpt[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Pure component pressure of the second component (not at hypothetical pressure)";
+    p_i_pure[3] := func_p_xT_3(x_adsorpt=x_adsorpt[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      tolerance=num_comp_3.tolerance_p_adsorpt)
+      "Pure component pressure of the third component (not at hypothetical pressure)";
+
+    //
+    // Caclulate initial guesses ensuring convergence: Reduced spreading pressures
+    //
+    pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance=num_comp_1.tolerance_pi)
+      "Reduced spreading pressure of the first component";
+    pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance=num_comp_2.tolerance_pi)
+      "Reduced spreading pressure of the second component";
+    pi_i[3] := func_pi_pT_3(M_adsorptive=M_i[3],
+      p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      integral_pi_lb=num_comp_3.integral_pi_lb,
+      tolerance=num_comp_3.tolerance_pi)
+      "Reduced spreading pressure of the third component";
+
+    pi := sum(z_i .* pi_i)
+      "Reduced spreading pressure of all components";
+
+  end if;
+
+  //
+  // Loop to solve the inverse of the IAST
+  //
+  while error >= num.tolerance_inv and no_iteration <= num.no_max_inv loop
+    //
+    // Calculate hypothetical pure component pressures
+    //
+    p_i_pure[1] := func_p_piT_1(
+      M_adsorptive=M_i[1],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_1.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_1.tolerance_pi)
+      "Hypothetical pure component pressure of the first component";
+    p_i_pure[2] := func_p_piT_2(
+      M_adsorptive=M_i[2],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_2.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_2.tolerance_pi)
+      "Hypothetical pure component pressure of the first component";
+    p_i_pure[3] := func_p_piT_3(
+      M_adsorptive=M_i[3],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_3.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_3.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_3.tolerance_pi)
+      "Hypothetical pure component pressure of the third component";
+
+    //
+    // Calculate molar uptakes
+    //
+    q_adsorpt_i[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      first component";
+    q_adsorpt_i[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      second component";
+    q_adsorpt_i[3] := 1/M_i[3] * func_x_pT_3(p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      tolerance=num_comp_3.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      third component";
+
+    //
+    // Calculate partial derivatives of molar uptakes w.r.t. hypothetical pure
+    // component pressures
+    //
+    dq_adsorpt_i_dp_i_pure[1] := 1/M_i[1] * func_dx_dp_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      first component";
+    dq_adsorpt_i_dp_i_pure[2] := 1/M_i[2] * func_dx_dp_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      second component";
+    dq_adsorpt_i_dp_i_pure[3] := 1/M_i[3] * func_dx_dp_3(p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      third component";
+
+    //
+    // Apply Newton-Raphson method
+    //
+    delta_sum_q_adsorpt := sum(z_i ./ q_adsorpt_i) - 1 / q_adsorpt
+      "Satisfaction of total molar uptake";
+    ddelta_sum_q_adsorpt_dpi := -sum(z_i .* p_i_pure ./ q_adsorpt_i .^ 3 .*
+      dq_adsorpt_i_dp_i_pure)
+      "Partial derivative of satisfaction of total molar uptake w.r.t. to reduced 
+      spreading pressure of all components";
+
+    pi := if pi - delta_sum_q_adsorpt / ddelta_sum_q_adsorpt_dpi > 0 then
+      pi - delta_sum_q_adsorpt / ddelta_sum_q_adsorpt_dpi else pi / 2
+      "Update reduced spreading pressure of all components";
+
+    //
+    // Check for convergence
+    //
+    no_iteration := no_iteration + 1
+      "Counter of loop";
+    error := abs(delta_sum_q_adsorpt)
+      "Error of loop";
+
+  end while;
+
+  //
+  // Calculate final ouputs
+  //
+  p_adsorpt := sum(z_i .* p_i_pure)
+    "Equilibrium pressure of the adsorpt phase";
+
+  y_i := z_i .* p_i_pure ./ p_adsorpt
+    "Mole fractions of components in the vapor or gas phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function provides an algorithm for solving the inverse of the IAST for three 
+components. The pressure <i>p_adsorpt</i> and molar composition of the gas/vapour 
+phase <i>y_i</i> are calculated as a function of the uptakes <i>x_adsorpt</i> 
+and the temperature <i>T_adsorpt</i>. The algorithm uses a Newton-Raphson method 
+to solve the system of equations of the inverse of the IAST. 
+</p>
+
+<h4>Main equations</h4>
+<p>
+The algorithm consists of 13 steps:
+</p>
+<ol>
+  <li>
+  Calculate the pure component pressures of each component <i>i</i>:
+  <pre>p<sub>adsorpt,<i>i</i></sub> = f(x<sub>adsorpt,<i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sub>adsorpt,<i>i</i></sub>, T<sub>adsorpt</sub>),</pre>
+  where <i>M<sub><i>i</i></sub></i> is the molar mass.
+  <br>
+  </li>
+  </li>
+  <li>
+  Calculate the initial guess of the reduced spreading pressure:
+  <pre>&pi; = &sum;<sub><i>i</i></sub> z<sub><i>i</i></sub> * &pi;<sub><i>i</i></sub>,</pre>
+  where <i>z<sub><i>i</i></sub></i> is the molar molar composition of each component 
+  <i>i</i> in the adsorpt phase
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, &pi;, T<sub>adsorpt</sub>).</pre>
+  This formula is an inverse of the reduced spreading pressure, which often
+  has to be calculated numerically.
+  <br>
+  </li>
+  <li>
+  Calculate the molar uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate partial derivatives of the molar uptake of each component <i>i</i>
+  with respect to the hypothetical pure component pressures of each component 
+  <i>i</i>:
+  <pre>dq<sub>adsorpt,<i>i</i></sub>/dp<sup>*</sup><sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * dx<sub>adsorpt,<i>i</i></sub>/dp<sub>adsorpt</sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>),</pre>
+  where <i>dx<sub>adsorpt,<i>i</i></sub>/dp<sub>adsorpt</sub></i> is the partial
+  derivative of the uptake with respect to the pressure.
+  <br>
+  </li>
+  <li>
+  Calculate the satisfaction of the total molar uptake:
+  <pre>F = &sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>] - 1 / &sum;<sub><i>i</i></sub> [x<sub>adsorpt,<i>i</i></sub> / M<sub><i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the partial derivative of the total molar uptake with respect to the 
+  reduced spreading pressure:
+  <pre>dF/d&pi; = -&sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> * p<sup>*</sup><sub><i>i</i></sub> / (q<sup>3</sup><sub>adsorpt,<i>i</i></sub>) * dq<sub>adsorpt,<i>i</i></sub>/dp<sup>*</sup><sub><i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressure of the next iteration step:
+  <pre>&pi;<sub>next</sub> = <strong>if</strong> &pi; - F / dF/d&pi; > 0 <strong>then</strong> &pi; - F / dF/d&pi; > 0 <strong>else</strong> &pi;/2.</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence:
+  <pre>|F| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 4. It the convergence
+  criterion is fulfilled, got to step 11.
+  <br>
+  </li>
+  <li>
+  Calculate the partial pressure of each component <i>i</i>:
+  <pre>p<sub>adsorpt,<i>i</i></sub> = z<sub><i>i</i></sub> * p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the pressure:
+  <pre>p<sub>adsorpt</sub> = &sum;<sub><i>i</i></sub> p<sub>adsorpt,<i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the molar fractions each component <i>i</i> in the gas/vapor
+  phase:
+  <pre>y<sub><i>i</i></sub> = p<sub>adsorpt,<i>i</i></sub> / p<sub>adsorpt</sub>.</pre>
+  </li>
+</ol>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end py_xT_NewtonRaphson;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_FastIAST.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_FastIAST.mo
new file mode 100644
index 0000000..8d20c51
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_FastIAST.mo
@@ -0,0 +1,538 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals;
+function x_pyT_FastIAST
+  "IAST for three components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature using the 'FastIAST' algorithm"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[:] y_i
+    "Mole fractions of the components in the gas or vapor phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real[:] c_3
+    "Coefficients of the isotherm model of the third component"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+    "Uptake of the third component as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+    "Pressure of the third component as function of uptake and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+    "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+    "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+    "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+    "Record definining numerics of the third component's isotherm model"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                choicesAllMatching=true);
+
+  input Boolean flag_startValues = false
+    " = true, if start values are given; otherwise, estimate start values"
+    annotation (Dialog(tab="General", group="Inputs - Start values"));
+  input Real[size(M_i,1)] Kp_i_0(each unit="1/Pa") = fill(1, size(M_i,1))
+    "Auxiliary variable for reduced pressues of the components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+  input Real[size(M_i,1)] eta_i_0(each unit="1") = fill(1, size(M_i,1))
+    "Reduced pressures of the components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real[size(M_i,1)] Kp_i(each unit="1/Pa")
+    "Auxiliary variable for reduced pressues of the components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real[size(M_i,1)] eta_i(each unit="1")
+    "Reduced pressures of the components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(M_i,1)] K_i(each unit="mol/(kg.Pa)")
+    "Henry constants of the components";
+  Real K_avg(unit="mol/(kg.Pa)")
+    "Average Henry constant";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_sat
+    "Saturation uptakes of the components";
+
+  Integer no_iteration = 1
+    "Counter of loop";
+  Real error = 1
+    "Error of loop";
+
+  Real[size(M_i,1)] Jac_last_row
+    "Jacobian matrix: Elements of the last row";
+  Real[size(M_i,1)] Jac_diagonal
+    "Jacobian matrix: Elements of the diagonal";
+
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] pi_i
+    "Reduced spreading pressures";
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] delta_pi_i
+    "Difference between reduced spreading pressures and reduced spreading pressure
+    of last component";
+
+  Real[size(M_i,1)] delta_eta_i(each unit="1")
+    "Newton steps for reduced pressures of the components";
+
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] z_i
+    "Mole fractions of the adsorpt phase";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_i
+    "Molar equilibrium uptakes at hypothetical pure component pressures";
+  SorpLib.Units.MolarUptake q_adsorpt
+    "Total molar equilibrium uptake";
+
+algorithm
+  if flag_startValues then
+    //
+    // Use start values
+    //
+    Kp_i := Kp_i_0
+      "Auxiliary variable for reduced pressues of the components";
+
+    eta_i := eta_i_0
+      "Reduced pressures of the components";
+
+  else
+    //
+    // Caclulate initial guesses ensuring convergence: Henry constants
+    //
+    K_i[1] := 1/M_i[1] * func_dx_dp_1(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_1)
+      "Henry constant of the first component";
+    K_i[2] := 1/M_i[2] * func_dx_dp_2(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_2)
+      "Henry constant of the second component";
+    K_i[3] := 1/M_i[3] * func_dx_dp_3(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_3)
+      "Henry constant of the third component";
+
+    K_avg := sum(y_i .* K_i)
+      "Average Henry constant";
+
+    //
+    // Calculate initial guesses ensuring convergence: Saturation uptakes
+    //
+    q_adsorpt_sat[1] := 1/M_i[1] * func_x_pT_1(
+      p_adsorpt=num.p_sat_0,
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Saturation uptake of the first component";
+    q_adsorpt_sat[2] := 1/M_i[2] * func_x_pT_2(
+      p_adsorpt=num.p_sat_0,
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Saturation uptake of the second component";
+    q_adsorpt_sat[3] := 1/M_i[3] * func_x_pT_3(
+      p_adsorpt=num.p_sat_0,
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      tolerance=num_comp_3.tolerance_p_adsorpt)
+      "Saturation uptake of the third component";
+
+    //
+    // Calculate initial guesses ensuring convergence: Reduced pressures
+    //
+    Kp_i := K_i ./ q_adsorpt_sat
+      "Auxiliary variable for reduced pressues of the components";
+
+    eta_i := {min(Kp_i[i] / K_i[i] * p_adsorpt * K_avg, p_adsorpt * Kp_i[i])
+      for i in 1:size(M_i,1)}
+      "Reduced pressures of the components";
+
+  end if;
+
+  //
+  // Loop to solve the IAST
+  //
+  while error >= num.tolerance and no_iteration <= num.no_max loop
+    //
+    // Calculate the Jacobian matrix: Last row
+    //
+    Jac_last_row := Kp_i .* p_adsorpt .* y_i ./ eta_i.^2
+      "Jacobian matrix: Elements of the last row";
+
+    //
+    // Calculate hypothetical pure component pressures
+    //
+    p_i_pure := eta_i ./ Kp_i
+      "Hypothetical pure component pressures";
+
+    //
+    // Calculate the Jacobian matrix: Diagonal
+    //
+    Jac_diagonal[1] := 1 / (M_i[1] * eta_i[1]) * func_x_pT_1(
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Diagonale of the Jacobian matrix: Component 1";
+    Jac_diagonal[2] := 1 / (M_i[2] * eta_i[2]) * func_x_pT_2(
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Diagonale of the Jacobian matrix: Component 2";
+    Jac_diagonal[3] := 1 / (M_i[3] * eta_i[3]) * func_x_pT_3(
+      p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      tolerance=num_comp_3.tolerance_p_adsorpt)
+      "Diagonale of the Jacobian matrix: Component 3";
+
+    //
+    // Calculate the Jacobian matrix: Correct last element of the diagonal
+    //
+    Jac_diagonal[end] := Jac_last_row[end] + Jac_diagonal[end] *
+      sum(Jac_last_row[1:end-1] ./ Jac_diagonal[1:end-1])
+      "Diagonale of the Jacobian matrix: Last element of the diagonal";
+
+    //
+    // Calculate recuded spreading pressures
+    //
+    pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance=num_comp_1.tolerance_pi)
+      "Reduced spreading pressure of the first component";
+    pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance=num_comp_2.tolerance_pi)
+      "Reduced spreading pressure of the second component";
+    pi_i[3] := func_pi_pT_3(M_adsorptive=M_i[3],
+      p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      integral_pi_lb=num_comp_3.integral_pi_lb,
+      tolerance=num_comp_3.tolerance_pi)
+      "Reduced spreading pressure of the third component";
+
+    //
+    // Calculate residuals
+    //
+    delta_pi_i := pi_i .- pi_i[end]
+      "Difference between reduced spreading pressures and reduced spreading pressure
+      of last component";
+    delta_pi_i[end] := 1 - sum(Kp_i .* p_adsorpt .* y_i ./ eta_i) -
+      sum(Jac_last_row[1:end-1] ./ Jac_diagonal[1:end-1] .* delta_pi_i[1:end-1])
+      "Difference between reduced spreading pressures and reduced spreading pressure
+      of last component: Last element";
+
+    //
+    // Apply Newton-Raphson method
+    //
+    delta_eta_i[end] := -delta_pi_i[end] / Jac_diagonal[end]
+      "Newton steps for reduced pressures of the components: Last component";
+    delta_eta_i[1:end-1] := (-delta_pi_i[1:end-1] .+ Jac_diagonal[end] *
+      delta_eta_i[end]) ./ Jac_diagonal[1:end-1]
+      "Newton steps for reduced pressures of the components: Remaining components";
+
+    for i in 1:size(M_i,1) loop
+      if eta_i[i] + delta_eta_i[i] < 0 then
+        eta_i[i] := eta_i[i] / 2
+          "Update reduced pressure";
+
+      else
+        eta_i[i] := eta_i[i] + delta_eta_i[i]
+          "Update reduced pressure";
+
+      end if;
+    end for;
+
+    //
+    // Check for convergence
+    //
+    no_iteration := no_iteration + 1
+      "Counter of loop";
+    error := sum(abs(delta_eta_i))
+      "Error of loop";
+
+  end while;
+
+  //
+  // Return final results
+  //
+  if error >= num.tolerance or no_iteration > num.no_max or max(p_i_pure) >= 1e30 then
+    //
+    // Calculation failed: Use 'Nested Loop' algorithm as fallback solution
+    //
+    (x_adsorpt,p_i_pure,pi) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NestedLoop(
+      p_adsorpt=p_adsorpt,
+      y_i=y_i,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=func_x_pT_1,
+      func_p_xT_1=func_p_xT_1,
+      func_dx_dp_1=func_dx_dp_1,
+      func_pi_pT_1=func_pi_pT_1,
+      func_p_piT_1=func_p_piT_1,
+      func_x_pT_2=func_x_pT_2,
+      func_p_xT_2=func_p_xT_2,
+      func_dx_dp_2=func_dx_dp_2,
+      func_pi_pT_2=func_pi_pT_2,
+      func_p_piT_2=func_p_piT_2,
+      func_x_pT_3=func_x_pT_3,
+      func_p_xT_3=func_p_xT_3,
+      func_dx_dp_3=func_dx_dp_3,
+      func_pi_pT_3=func_pi_pT_3,
+      func_p_piT_3=func_p_piT_3,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3)
+      "'Nested Loop' algorithm to solve IAST";
+
+    else
+    //
+    // Calculate mole fractions of adsorpt phase
+    //
+    z_i := y_i .* p_adsorpt ./ p_i_pure
+      "Mole fractions of the adsorpt phase";
+
+    //
+    // Calculate equilibrium uptakes
+    //
+    q_adsorpt_i[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      first component";
+    q_adsorpt_i[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+    "Molar equilibrium uptake at hypothetical pure component pressure of the 
+    second component";
+    q_adsorpt_i[3] := 1/M_i[3] * func_x_pT_3(p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      tolerance=num_comp_3.tolerance_p_adsorpt)
+    "Molar equilibrium uptake at hypothetical pure component pressure of the 
+    second component";
+
+    q_adsorpt := 1 / sum(z_i ./ q_adsorpt_i)
+    "Total molar equilibrium uptake";
+
+    //
+    // Calculate final ouputs
+    //
+    x_adsorpt := q_adsorpt .* z_i .* M_i
+      "Equilibrium uptakes of the adsorpt phase";
+
+    pi := pi_i[end]
+      "Reduced spreading pressure of all components";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function provides an algorithm for solving the IAST for three components. The 
+uptakes <i>x_adsorpt</i> are calculated as a function of the pressure <i>p_adsorpt</i>, 
+the molar composition of the gas/vapour phase <i>y_i</i>, and the temperature 
+<i>T_adsorpt</i>. The algorithm uses one loops to iterate simultaneously over the 
+reduced spreading pressure <i>&pi;</i> and the molar composition of the adsorpt phase
+<i>z<sub><I>i</i></sub></i>. The algorithm exploits that all relevant information can 
+be written into a Jacobian matrix in which all elements are zero except the last row, 
+the last column, and the diagonal. For the calculation, only the information of the 
+last row and diagonal is required, which reduces the computational effort.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The algorithm consists of 20 steps:
+</p>
+<ol>
+  <li>
+  Calculate the Henry's constant of each component <i>i</i>:
+  <pre>K<sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub>,</pre>
+  where <i>M<sub><i>i</i></sub></i> is the molar mass and <i>dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub></i> 
+  is the partial derivative of the uptake with respect to the pressure.
+  <br>
+  </li>
+  <li>
+  Calculate the average Henry's constant:
+  <pre>K<sub>avg</sub> = &sum;<sub><i>i</i></sub> y<sub><i>i</i></sub> * K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the molar saturation uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,sat,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p &rarr; &infin;, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate auxiliary variable of each component <i>i</i>:
+  <pre>Kp<sub><i>i</i></sub> = K<sub><i>i</i></sub> / q<sub>adsorpt,sat,<i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the initial guess of the reduced pressure of each component <i>i</i>:
+  <pre>&eta;<sub><i>i</i></sub> = <strong>min</strong>(Kp<sub><i>i</i></sub> / K<sub><i>i</i></sub> * p<sub>adsorpt</sub> * K<sub>avg</sub>, Kp<sub><i>i</i></sub> * p<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the last row of the Jacobian matrix for each column <i>i</i>:
+  <pre>Jac<sub>last row,<i>i</i></sub> = Kp<sub><i>i</i></sub> * p<sub>adsorpt</sub> * y<sub><i>i</i></sub> / &eta;<sup>2</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = &eta;<sub><i>i</i></sub> / Kp<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the diagonal of the Jacobian matrix for each component <i>i</i>:
+  <pre>Jac<sub>diagonal,<i>i</i></sub> = 1 / (M<sub><i>i</i></sub> * &eta;<sub><i>i</i></sub>) * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Correct the last element of the diagonal of the Jacobian matrix:
+  <pre>Jac<sub>diagonal,last</sub> = Jac<sub>last row,last</sub> + Jac<sub>diagonal,last</sub> * &sum;<sub><i>i</i></sub><sup>N-1</sup> [Jac<sub>last row,<i>i</i></sub> / Jac<sub>diagonal,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the differences between the reduced spreading pressure of each 
+  component <i>i</i> and the reduced spreading pressure of the last component:
+  <pre>&Delta;&pi;<sub><i>i</i></sub> = &pi;<sub><i>i</i></sub> - &pi;<sub>last</sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Correct the last element of the differences between the reduced spreading pressure 
+  of each component <i>i</i> and the reduced spreading pressure of the last component:
+  <pre>&Delta;&pi;<sub>last</sub> =1 - &sum;<sub><i>i</i></sub> [Kp<sub><i>i</i></sub> * p<sub>adsorpt</sub> * y<sub><i>i</i></sub> / &eta;<sub><i>i</i></sub>] - &sum;<sub><i>i</i></sub><sup>N-1</sup> [Jac<sub>last row,<i>i</i></sub> / Jac<sub>diagonal,<i>i</i></sub> * &Delta;&pi;<sub><i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the change of the reduced pressure of the last component:
+  <pre>&Delta;&eta;<sub>last</sub> = &Delta;&pi;<sub>last</sub> / Jac<sub>diagonal,last</sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the change of the reduced pressure of the remaining components <i>i</i>:
+  <pre>&Delta;&eta;<sub><i>i</i></sub> = (-&Delta;&pi;<sub><i>i</i></sub>  + Jac<sub>diagonal,last</sub> * &Delta;&eta;<sub>last</sub>) / Jac<sub>diagonal,<i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced pressure of the next iteration step of each component <i>i</i>:
+  <pre>&eta;<sub>next,<i>i</i></sub> = <strong>if</strong> &eta;<sub><i>i</i></sub> + &Delta;&eta;<sub><i>i</i></sub> > 0 <strong>then</strong> &eta;<sub><i>i</i></sub> + &Delta;&eta;<sub><i>i</i></sub> <strong>else</strong> &eta;<sub><i>i</i></sub>/2.</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence:
+  <pre>&sum; |&Delta;&eta;<sub><i>i</i></sub>| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 6. It the convergence
+  criterion is fulfilled, got to step 17.
+  <br>
+  </li>
+  <li>
+  Calculate the molar composition of each component <i>i</i> in the adsorpt
+  phase:
+  <pre>z<sub><i>i</i></sub> = y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the molar uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the total molar uptake:
+  <pre>q<sub>adsorpt,total</sub> = 1 / &sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the uptakes of each component <i>i</i>:
+  <pre>x<sub>adsorpt,<i>i</i></sub> = M<sub><i>i</i></sub> * z<sub><i>i</i></sub> * q<sub>adsorpt,total</sub>.</pre>
+  </li>
+</ol>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Mangano E., Friedrich, D., and Brandani, S. (2015). Robust algorithms for the solution of the ideal adsorbed solution theory equations. AIChE Journal, 61(3): 981–991. DOI: 10.1002/aic.14684.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_pyT_FastIAST;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_NestedLoop.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_NestedLoop.mo
new file mode 100644
index 0000000..d10f163
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_NestedLoop.mo
@@ -0,0 +1,457 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals;
+function x_pyT_NestedLoop
+  "IAST for three components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature using the 'Nested Loop' algorithm"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[:] y_i
+    "Mole fractions of the components in the gas or vapor phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real[:] c_3
+    "Coefficients of the isotherm model of the third component"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+    "Uptake of the third component as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+    "Pressure of the third component as function of uptake and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+    "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+    "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+    "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+    "Record definining numerics of the third component's isotherm model"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                choicesAllMatching=true);
+
+  input Boolean flag_startValues = false
+    " = true, if start values are given; otherwise, estimate start values"
+    annotation (Dialog(tab="General", group="Inputs - Start values"));
+  input Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure_0=
+    fill(1, size(M_i,1))
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+  input SorpLib.Units.ReducedSpreadingPressure pi_0 = 1
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(M_i,1)] K_i(each unit="mol/(kg.Pa)")
+    "Henry constants of the components";
+  Real K_avg(unit="mol/(kg.Pa)")
+    "Average Henry constant";
+
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] pi_i
+    "Reduced spreading pressures";
+
+  Integer no_inner = 1
+    "Counter of inner loop";
+  Integer no_outer = 1
+    "Counter of outer loop";
+
+  SorpLib.Units.ReducedSpreadingPressure error_inner = 1
+    "Error of inner loop";
+  Modelica.Units.SI.MoleFraction error_outer = 1
+    "Error of outer loop";
+
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] delta_pi_i
+    "Difference between reduced spreading pressures and reduced spreading pressure
+    of all components";
+  Real[size(M_i,1)] ddelta_pi_i_dp_i_pure(each unit="mol/(kg.Pa)")
+    "Partial derivative of difference between reduced spreading pressures and 
+    reduced spreading pressure of all components w.r.t. the hypothetical pure
+    component pressures";
+
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] z_i
+    "Mole fractions of the adsorpt phase";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_i
+    "Molar equilibrium uptakes at hypothetical pure component pressures";
+  SorpLib.Units.MolarUptake q_adsorpt
+    "Total molar equilibrium uptake";
+
+algorithm
+  if flag_startValues then
+    //
+    // Use start values
+    //
+    p_i_pure := p_i_pure_0
+      "Hypothetical pure component pressures";
+    pi := pi_0
+      "Reduced spreading pressure of all components";
+
+  else
+    //
+    // Caclulate initial guesses ensuring convergence: Henry constants
+    //
+    K_i[1] := 1/M_i[1] * func_dx_dp_1(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_1)
+      "Henry constant of the first component";
+    K_i[2] := 1/M_i[2] * func_dx_dp_2(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_2)
+      "Henry constant of the second component";
+    K_i[3] := 1/M_i[3] * func_dx_dp_3(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_3)
+      "Henry constant of the third component";
+
+    K_avg := sum(y_i .* K_i)
+      "Average Henry constant";
+
+    //
+    // Caclulate initial guesses ensuring convergence: Reduced spreading pressures
+    // and hypothetical pure component pressures
+    //
+    p_i_pure := p_adsorpt .* K_avg ./ K_i
+      "Hypothetical pure component pressures";
+
+    pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance=num_comp_1.tolerance_pi)
+      "Reduced spreading pressure of the first component";
+    pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance=num_comp_2.tolerance_pi)
+      "Reduced spreading pressure of the second component";
+    pi_i[3] := func_pi_pT_3(M_adsorptive=M_i[3],
+      p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      integral_pi_lb=num_comp_3.integral_pi_lb,
+      tolerance=num_comp_3.tolerance_pi)
+      "Reduced spreading pressure of the third component";
+
+    pi := min(pi_i)
+      "Reduced spreading pressure of all components";
+    p_i_pure := pi ./ K_i
+      "Hypothetical pure component pressures";
+
+  end if;
+
+  //
+  // Outer loop: Ensure mass conservation
+  //
+  while error_outer >= num.tolerance_outer and no_outer <= num.no_max_outer loop
+    //
+    // Inner loop: Ensure identical spreading pressures
+    //
+    no_inner :=1
+      "Counter of inner loop";
+    error_inner :=1
+      "Error of inner loop";
+
+    while error_inner >= num.tolerance_inner and no_inner <= num.no_max_inner loop
+      //
+      // Calculate reduced spreading pressures
+      //
+      pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+        p_adsorpt=p_i_pure[1],
+        T_adsorpt=T_adsorpt,
+        c=c_1,
+        integral_pi_lb=num_comp_1.integral_pi_lb,
+        tolerance=num_comp_1.tolerance_pi)
+        "Reduced spreading pressure of the first component";
+      pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+        p_adsorpt=p_i_pure[2],
+        T_adsorpt=T_adsorpt,
+        c=c_2,
+        integral_pi_lb=num_comp_2.integral_pi_lb,
+        tolerance=num_comp_2.tolerance_pi)
+        "Reduced spreading pressure of the second component";
+      pi_i[3] := func_pi_pT_3(M_adsorptive=M_i[3],
+        p_adsorpt=p_i_pure[3],
+        T_adsorpt=T_adsorpt,
+        c=c_3,
+        integral_pi_lb=num_comp_3.integral_pi_lb,
+        tolerance=num_comp_3.tolerance_pi)
+        "Reduced spreading pressure of the third component";
+
+      //
+      // Apply Newton-Raphson method
+      //
+      delta_pi_i := pi_i .- pi
+        "Difference betwenn reduced spreading pressures and reduced spreading pressure
+        of all components";
+
+      ddelta_pi_i_dp_i_pure[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+        T_adsorpt=T_adsorpt,
+        c=c_1,
+        p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+        p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+        tolerance=num_comp_1.tolerance_p_adsorpt) / p_i_pure[1]
+        "Partial derivative of difference between reduced spreading pressure of the
+        first component and reduced spreading pressure of all components w.r.t. the 
+        hypothetical pure component pressure of the first component";
+      ddelta_pi_i_dp_i_pure[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+        T_adsorpt=T_adsorpt,
+        c=c_2,
+        p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+        p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+        tolerance=num_comp_2.tolerance_p_adsorpt) / p_i_pure[2]
+        "Partial derivative of difference between reduced spreading pressure of the
+        second component and reduced spreading pressure of all components w.r.t. the 
+        hypothetical pure component pressure of the second component";
+      ddelta_pi_i_dp_i_pure[3] := 1/M_i[3] * func_x_pT_3(p_adsorpt=p_i_pure[3],
+        T_adsorpt=T_adsorpt,
+        c=c_3,
+        p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+        p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+        tolerance=num_comp_3.tolerance_p_adsorpt) / p_i_pure[3]
+        "Partial derivative of difference between reduced spreading pressure of the
+        third component and reduced spreading pressure of all components w.r.t. the 
+        hypothetical pure component pressure of the third component";
+
+      p_i_pure := p_i_pure .- delta_pi_i ./ ddelta_pi_i_dp_i_pure
+        "Hypothetical pure component pressures";
+
+      //
+      // Check for convergence
+      //
+      no_inner := no_inner + 1
+        "Counter of inner loop";
+      error_inner := sum(abs(delta_pi_i))
+        "Error of inner loop";
+
+    end while;
+
+    //
+    // Calculate mole fractions of adsorpt phase
+    //
+    z_i := y_i .* p_adsorpt ./ p_i_pure
+      "Mole fractions of the adsorpt phase";
+
+    //
+    // Calculate equilibrium uptakes
+    //
+    q_adsorpt_i[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure compoment pressure of the 
+      first component";
+    q_adsorpt_i[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure compoment pressure of the 
+      second component";
+    q_adsorpt_i[3] := 1/M_i[3] * func_x_pT_3(p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      tolerance=num_comp_3.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure compoment pressure of the 
+      third component";
+
+    q_adsorpt := 1 / sum(z_i ./ q_adsorpt_i)
+      "Total molar equilibrium uptake";
+
+    //
+    // Apply Newton-Raphson method
+    //
+    pi := pi + (-(1 - sum(z_i)) / (1/q_adsorpt))
+      "Reduced spreading pressure of all components";
+
+    //
+    // Check for convergence
+    //
+    no_outer := no_outer + 1
+      "Counter of outer loop";
+    error_outer := abs(1 - sum(z_i))
+      "Error of outer loop";
+
+  end while;
+
+  //
+  // Calculate final ouputs
+  //
+  x_adsorpt := q_adsorpt .* z_i .* M_i
+    "Equilibrium uptakes of the adsorpt phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function provides an algorithm for solving the IAST for three components. The 
+uptakes <i>x_adsorpt</i> are calculated as a function of the pressure <i>p_adsorpt</i>, 
+the molar composition of the gas/vapour phase <i>y_i</i>, and the temperature 
+<i>T_adsorpt</i>. The algorithm uses two loops, with the inner loop nested in the
+outer loop. Hence, the algorithm is called 'Nested Loop.' The inner loop iterates
+over the reduced spreading pressure <i>&pi;</i>, while the outer loop iterates over
+the molar composition of the adsorpt phase <i>z<sub><I>i</i></sub></i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The algorithm consists of 17 steps:
+</p>
+<ol>
+  <li>
+  Calculate the Henry's constant of each component <i>i</i>:
+  <pre>K<sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub>,</pre>
+  where <i>M<sub><i>i</i></sub></i> is the molar mass and <i>dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub></i> 
+  is the partial derivative of the uptake with respect to the pressure.
+  <br>
+  </li>
+  <li>
+  Calculate the average Henry's constant:
+  <pre>K<sub>avg</sub> = &sum;<sub><i>i</i></sub> y<sub><i>i</i></sub> * K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = p<sub>adsorpt</sub> * K<sub>avg</sub> / K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the initial guess of the reduced spreading pressure:
+  <pre>&pi; = <strong>min</strong>(&pi;<sub><i>i</i></sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the initial guesses of the hypothetical pure component pressures of each 
+  component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = &pi; / K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the differences between the reduced spreading pressure of each 
+  component <i>i</i> and the reduced spreading pressure of the last component:
+  <pre>&Delta;&pi;<sub><i>i</i></sub> = &pi;<sub><i>i</i></sub> - &pi;<sub>last</sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the partial derivatives of the differences between the reduced 
+  spreading pressure of each component <i>i</i> and the reduced spreading 
+  pressure of the last component with respect to the hypothetical pure
+  component pressures:
+  <pre>d&Delta;&pi;<sub><i>i</i></sub>/dp<sup>*</sup><sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>) / p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component 
+  <i>i</i> of the next iteration step:
+  <pre>p<sup>*</sup><sub>next,<i>i</i></sub> = p<sup>*</sup><sub><i>i</i></sub> - &Delta;&pi;<sub><i>i</i></sub> / d&Delta;&pi;<sub><i>i</i></sub>/dp<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence of the inner loop:
+  <pre>&sum;<sub><i>i</i></sub> |&Delta;&pi;<sub><i>i</i></sub>| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 7. It the convergence
+  criterion is fulfilled, got to step 12.
+  <br>
+  </li>
+  <li>
+  Calculate the molar composition of each component <i>i</i> in the adsorpt
+  phase:
+  <pre>z<sub><i>i</i></sub> = y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the molar uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the total molar uptake:
+  <pre>q<sub>adsorpt,total</sub> = 1 / &sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressure of the next iteration step:
+  <pre>&pi;<sub>next</sub> = &pi; - (1 - &sum; z<sub><i>i</i></sub>) / (1 / q<sub>adsorpt,total</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence of the outer loop:
+  <pre>|1 - &sum;<sub><i>i</i></sub> z<sub><i>i</i></sub>| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 7. It the convergence
+  criterion is fulfilled, got to step 17.
+  <br>
+  </li>
+  <li>
+  Calculate the uptakes of each component <i>i</i>:
+  <pre>x<sub>adsorpt,<i>i</i></sub> = M<sub><i>i</i></sub> * z<sub><i>i</i></sub> * q<sub>adsorpt,total</sub>.</pre>
+  </li>
+</ol>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Mangano E., Friedrich, D., and Brandani, S. (2015). Robust algorithms for the solution of the ideal adsorbed solution theory equations. AIChE Journal, 61(3): 981–991. DOI: 10.1002/aic.14684.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_pyT_NestedLoop;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_NewtonRaphson.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_NewtonRaphson.mo
new file mode 100644
index 0000000..c948645
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/Internals/x_pyT_NewtonRaphson.mo
@@ -0,0 +1,385 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals;
+function x_pyT_NewtonRaphson
+  "IAST for two components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature using the standard 'Newton-Raphson' algorithm"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMultiIAST;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[:] y_i
+    "Mole fractions of the components in the gas or vapor phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real[:] c_3
+    "Coefficients of the isotherm model of the third component"
+    annotation (Dialog(tab="General", group="Inputs - Components"));
+
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+    "Uptake of the third component as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+    "Pressure of the third component as function of uptake and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+    "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+    "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+    "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+    "Record definining numerics of the third component's isotherm model"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                choicesAllMatching=true);
+
+  input Boolean flag_startValues = false
+    " = true, if start values are given; otherwise, estimate start values"
+    annotation (Dialog(tab="General", group="Inputs - Start values"));
+  input SorpLib.Units.ReducedSpreadingPressure pi_0 = 1
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Inputs - Start values",
+                enable=flag_startValues));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Modelica.Units.SI.Pressure[size(M_i,1)] p_i_pure
+    "Hypothetical pure component pressures"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output SorpLib.Units.ReducedSpreadingPressure pi
+    "Reduced spreading pressure of all components"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(M_i,1)] K_i(each unit="mol/(kg.Pa)")
+    "Henry constants of the components";
+  Real K_avg(unit="mol/(kg.Pa)")
+    "Average Henry constant";
+
+  SorpLib.Units.ReducedSpreadingPressure[size(M_i,1)] pi_i
+    "Reduced spreading pressures";
+
+  Integer no_iteration = 1
+    "Counter of loop";
+  Real error = 1
+    "Error of loop";
+
+  SorpLib.Units.MolarUptake[size(M_i,1)] q_adsorpt_i
+    "Molar equilibrium uptakes at hypothetical pure component pressures";
+
+  Modelica.Units.SI.MoleFraction delta_sum_z_i
+    "Satisfaction of molar composition of adsorpt phase";
+  Real ddelta_sum_z_i_dpi(unit="kg/mol")
+    "Partial derivative of satisfaction of molar composition of adsorpt phase
+    w.r.t. to reduced spreading pressure of all components";
+
+  Modelica.Units.SI.MoleFraction[size(M_i,1)] z_i
+    "Mole fractions of the adsorpt phase";
+
+  SorpLib.Units.MolarUptake q_adsorpt
+    "Total molar equilibrium uptake";
+
+algorithm
+  if flag_startValues then
+    //
+    // Use start values
+    //
+    pi := pi_0
+      "Reduced spreading pressure of all components";
+
+  else
+    //
+    // Caclulate initial guesses ensuring convergence: Henry constants
+    //
+    K_i[1] := 1/M_i[1] * func_dx_dp_1(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_1)
+      "Henry constant of the first component";
+    K_i[2] := 1/M_i[2] * func_dx_dp_2(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_2)
+      "Henry constant of the second component";
+    K_i[3] := 1/M_i[3] * func_dx_dp_3(p_adsorpt=num.p_K_0,
+      T_adsorpt=T_adsorpt,
+      c=c_3)
+      "Henry constant of the third component";
+
+    K_avg := sum(y_i .* K_i)
+      "Average Henry constant";
+
+    //
+    // Caclulate initial guesses ensuring convergence: Reduced spreading pressures
+    // and hypothetical pure component pressures
+    //
+    p_i_pure := p_adsorpt .* K_avg ./ K_i
+      "Hypothetical pure component pressures";
+
+    pi_i[1] := func_pi_pT_1(M_adsorptive=M_i[1],
+      p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance=num_comp_1.tolerance_pi)
+      "Reduced spreading pressure of the first component";
+    pi_i[2] := func_pi_pT_2(M_adsorptive=M_i[2],
+      p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance=num_comp_2.tolerance_pi)
+      "Reduced spreading pressure of the second component";
+    pi_i[3] := func_pi_pT_3(M_adsorptive=M_i[3],
+      p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      integral_pi_lb=num_comp_3.integral_pi_lb,
+      tolerance=num_comp_3.tolerance_pi)
+      "Reduced spreading pressure of the third component";
+
+    pi := min(pi_i)
+      "Reduced spreading pressure of all components";
+
+  end if;
+
+  //
+  // Loop to solve the IAST
+  //
+  while error >= num.tolerance and no_iteration <= num.no_max loop
+    //
+    // Calculate hypothetical pure component pressures
+    //
+    p_i_pure[1] := func_p_piT_1(
+      M_adsorptive=M_i[1],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_1.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_1.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_1.tolerance_pi)
+      "Hypothetical pure component pressure of the first component";
+    p_i_pure[2] := func_p_piT_2(
+      M_adsorptive=M_i[2],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_2.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_2.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_2.tolerance_pi)
+      "Hypothetical pure component pressure of the first component";
+    p_i_pure[3] := func_p_piT_3(
+      M_adsorptive=M_i[3],
+      pi=pi,
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      integral_pi_lb=num_comp_3.integral_pi_lb,
+      tolerance_p_adsorpt=num_comp_3.tolerance_p_adsorpt,
+      tolerance_pi=num_comp_3.tolerance_pi)
+      "Hypothetical pure component pressure of the third component";
+
+    //
+    // Calculate molar uptakes
+    //
+    q_adsorpt_i[1] := 1/M_i[1] * func_x_pT_1(p_adsorpt=p_i_pure[1],
+      T_adsorpt=T_adsorpt,
+      c=c_1,
+      p_adsorpt_lb_start=num_comp_1.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_1.p_adsorpt_ub_start,
+      tolerance=num_comp_1.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      first component";
+    q_adsorpt_i[2] := 1/M_i[2] * func_x_pT_2(p_adsorpt=p_i_pure[2],
+      T_adsorpt=T_adsorpt,
+      c=c_2,
+      p_adsorpt_lb_start=num_comp_2.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_2.p_adsorpt_ub_start,
+      tolerance=num_comp_2.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      second component";
+    q_adsorpt_i[3] := 1/M_i[3] * func_x_pT_3(p_adsorpt=p_i_pure[3],
+      T_adsorpt=T_adsorpt,
+      c=c_3,
+      p_adsorpt_lb_start=num_comp_3.p_adsorpt_lb_start,
+      p_adsorpt_ub_start=num_comp_3.p_adsorpt_ub_start,
+      tolerance=num_comp_3.tolerance_p_adsorpt)
+      "Molar equilibrium uptake at hypothetical pure component pressure of the 
+      third component";
+
+    //
+    // Apply Newton-Raphson method
+    //
+    delta_sum_z_i := sum((p_adsorpt .* y_i) ./ p_i_pure) - 1
+      "Satisfaction of molar composition of adsorpt phase";
+    ddelta_sum_z_i_dpi := -sum((p_adsorpt .* y_i) ./ (p_i_pure .* q_adsorpt_i))
+      "Partial derivative of satisfaction of molar composition of adsorpt phase
+      w.r.t. to reduced spreading pressure of all components";
+
+    pi := if pi - delta_sum_z_i / ddelta_sum_z_i_dpi > 0 then
+      pi - delta_sum_z_i / ddelta_sum_z_i_dpi else pi / 2
+      "Update reduced spreading pressure of all components";
+
+    //
+    // Check for convergence
+    //
+    no_iteration := no_iteration + 1
+      "Counter of loop";
+    error := abs(delta_sum_z_i)
+      "Error of loop";
+
+  end while;
+
+  //
+  // Calculate mole fractions of adsorpt phase
+  //
+  z_i := y_i .* p_adsorpt ./ p_i_pure
+    "Mole fractions of the adsorpt phase";
+
+  //
+  // Calculate equilibrium uptake
+  //
+  q_adsorpt := 1 / sum(z_i ./ q_adsorpt_i)
+  "Total molar equilibrium uptake";
+
+  //
+  // Calculate final ouputs
+  //
+  x_adsorpt := q_adsorpt .* z_i .* M_i
+    "Equilibrium uptakes of the adsorpt phase";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function provides an algorithm for solving the IAST for three components. The 
+uptakes <i>x_adsorpt</i> are calculated as a function of the pressure <i>p_adsorpt</i>, 
+the molar composition of the gas/vapour phase <i>y_i</i>, and the temperature 
+<i>T_adsorpt</i>. The algorithm uses a Newton-Raphson method to solve the system 
+of equations of the IAST. 
+</p>
+
+<h4>Main equations</h4>
+<p>
+The algorithm consists of 14 steps:
+</p>
+<ol>
+  <li>
+  Calculate the Henry's constant of each component <i>i</i>:
+  <pre>K<sub><i>i</i></sub> = 1 / M<sub><i>i</i></sub> * dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub>,</pre>
+  where <i>M<sub><i>i</i></sub></i> is the molar mass and <i>dx<sub><i>i</i></sub>/dp<sub><i>i</i></sub></i> 
+  is the partial derivative of the uptake with respect to the pressure.
+  <br>
+  </li>
+  <li>
+  Calculate the average Henry's constant:
+  <pre>K<sub>avg</sub> = &sum;<sub><i>i</i></sub> y<sub><i>i</i></sub> * K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = p<sub>adsorpt</sub> * K<sub>avg</sub> / K<sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressures of each component <i>i</i>:
+  <pre>&pi;<sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the initial guess of the reduced spreading pressure:
+  <pre>&pi; = <strong>min</strong>(&pi;<sub><i>i</i></sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the hypothetical pure component pressures of each component <i>i</i>:
+  <pre>p<sup>*</sup><sub><i>i</i></sub> = f(M<sub><i>i</i></sub>, &pi;, T<sub>adsorpt</sub>).</pre>
+  This formula is an inverse of the reduced spreading pressure, which often
+  has to be calculated numerically.
+  <br>
+  </li>
+  <li>
+  Calculate the molar uptake of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = 1 / M<sub><i>i</i></sub> * x<sub>adsorpt,<i>i</i></sub>(p<sup>*</sup><sub><i>i</i></sub>, T<sub>adsorpt</sub>).</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the satisfaction of the molar composition of the adsorpt phase:
+  <pre>F = &sum;<sub><i>i</i></sub> [y<sub><i>i</i></sub> * x<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>] - 1.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the partial derivative of the satisfaction of the adsorpt phase
+  with respect to the reduced spreading pressure:
+  <pre>dF/d&pi; = -&sum;<sub><i>i</i></sub> [y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / (p<sup>*</sup><sub><i>i</i></sub> * q<sub>adsorpt,<i>i</i></sub>)].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the reduced spreading pressure of the next iteration step:
+  <pre>&pi;<sub>next</sub> = <strong>if</strong> &pi; - F / dF/d&pi; > 0 <strong>then</strong> &pi; - F / dF/d&pi; > 0 <strong>else</strong> &pi;/2.</pre>
+  <br>
+  </li>
+  <li>
+  Check for convergence:
+  <pre>|F| &le; tolerance.</pre>
+  If the convergence criterion is not fulfilled, got to step 6. It the convergence
+  criterion is fulfilled, got to step 12.
+  <br>
+  </li>
+  <li>
+  Calculate the molar composition of each component <i>i</i> in the adsorpt
+  phase:
+  <pre>z<sub><i>i</i></sub> = y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the total molar uptake:
+  <pre>q<sub>adsorpt,total</sub> = 1 / &sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Calculate the uptakes of each component <i>i</i>:
+  <pre>x<sub>adsorpt,<i>i</i></sub> = M<sub><i>i</i></sub> * z<sub><i>i</i></sub> * q<sub>adsorpt,total</sub>.</pre>
+  </li>
+</ol>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_pyT_NewtonRaphson;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/package.mo
new file mode 100644
index 0000000..7e78100
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/package.mo
@@ -0,0 +1,1282 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package IAST_N3 "Package containing all functions regarding the IAST for three components"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponentsIAST;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "IAST for three components: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+
+    //
+    // Definition of inputs
+    //
+    input Real[:] c_3
+      "Coefficients of the isotherm model of the third component"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+      "Uptake of the third component as function of pressure and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+      "Pressure of the third component as function of uptake and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+      "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+      "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+      "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+    input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+      "Record definining numerics of the third component's isotherm model"
+      annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                  choicesAllMatching=true);
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+      "Mole fractions of all components in the vapor or gas phase";
+
+  algorithm
+    //
+    // Select IAST algorithm
+    //
+    if num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson then
+      (x_adsorpt,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "Standard 'Newton-Raphson' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop then
+      (x_adsorpt,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'Nested Loop' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST then
+      (x_adsorpt,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'FASTIast' algorithm";
+
+    end if;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, c_3=c_3, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, func_x_pT_3=func_x_pT_3, func_p_xT_3=func_p_xT_3, func_dx_dp_3=func_dx_dp_3, func_pi_pT_3=func_pi_pT_3, func_p_piT_3=func_p_piT_3, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2, num_comp_3=num_comp_3),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, c_3=c_3, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, func_x_pT_3=func_x_pT_3, func_p_xT_3=func_p_xT_3, func_dx_dp_3=func_dx_dp_3, func_pi_pT_3=func_pi_pT_3, func_p_piT_3=func_p_piT_3, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2, num_comp_3=num_comp_3)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "IAST for three components: Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+
+    //
+    // Definition of inputs
+    //
+    input Real[:] c_3
+      "Coefficients of the isotherm model of the third component"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+      "Uptake of the third component as function of pressure and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+      "Pressure of the third component as function of uptake and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+      "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+      "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+      "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+    input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+      "Record definining numerics of the third component's isotherm model"
+      annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                  choicesAllMatching=true);
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_ = cat(1, y_i, {1-sum(y_i)})
+      "Mole fractions of all components in the vapor or gas phase";
+
+  algorithm
+    (p_adsorpt,,) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.py_xT_NewtonRaphson(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=func_x_pT_1,
+      func_p_xT_1=func_p_xT_1,
+      func_dx_dp_1=func_dx_dp_1,
+      func_pi_pT_1=func_pi_pT_1,
+      func_p_piT_1=func_p_piT_1,
+      func_x_pT_2=func_x_pT_2,
+      func_p_xT_2=func_p_xT_2,
+      func_dx_dp_2=func_dx_dp_2,
+      func_pi_pT_2=func_pi_pT_2,
+      func_p_piT_2=func_p_piT_2,
+      func_x_pT_3=func_x_pT_3,
+      func_p_xT_3=func_p_xT_3,
+      func_dx_dp_3=func_dx_dp_3,
+      func_pi_pT_3=func_pi_pT_3,
+      func_p_piT_3=func_p_piT_3,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3)
+      "Standard 'Newton-Raphson' algorithm";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, c_3=c_3, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, func_x_pT_3=func_x_pT_3, func_p_xT_3=func_p_xT_3, func_dx_dp_3=func_dx_dp_3, func_pi_pT_3=func_pi_pT_3, func_p_piT_3=func_p_piT_3, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2, num_comp_3=num_comp_3),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, M_i=M_i, c_1=c_1, c_2=c_2, c_3=c_3, func_x_pT_1=func_x_pT_1, func_p_xT_1=func_p_xT_1, func_dx_dp_1=func_dx_dp_1, func_pi_pT_1=func_pi_pT_1, func_p_piT_1=func_p_piT_1, func_x_pT_2=func_x_pT_2, func_p_xT_2=func_p_xT_2, func_dx_dp_2=func_dx_dp_2, func_pi_pT_2=func_pi_pT_2, func_p_piT_2=func_p_piT_2, func_x_pT_3=func_x_pT_3, func_p_xT_3=func_p_xT_3, func_dx_dp_3=func_dx_dp_3, func_pi_pT_3=func_pi_pT_3, func_p_piT_3=func_p_piT_3, num=num, num_comp_1=num_comp_1, num_comp_2=num_comp_2, num_comp_3=num_comp_3)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "IAST for three components: Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+
+    //
+    // Definition of inputs
+    //
+    input Real[:] c_3
+      "Coefficients of the isotherm model of the third component"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+      "Uptake of the third component as function of pressure and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+      "Pressure of the third component as function of uptake and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+      "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+      "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+      "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+    input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+      "Record definining numerics of the third component's isotherm model"
+      annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                  choicesAllMatching=true);
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_
+      "Mole fractions of all components in the vapor or gas phase";
+
+  algorithm
+    //
+    // Solve inverse of IAST
+    //
+    (,y_i_,) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.py_xT_NewtonRaphson(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=func_x_pT_1,
+      func_p_xT_1=func_p_xT_1,
+      func_dx_dp_1=func_dx_dp_1,
+      func_pi_pT_1=func_pi_pT_1,
+      func_p_piT_1=func_p_piT_1,
+      func_x_pT_2=func_x_pT_2,
+      func_p_xT_2=func_p_xT_2,
+      func_dx_dp_2=func_dx_dp_2,
+      func_pi_pT_2=func_pi_pT_2,
+      func_p_piT_2=func_p_piT_2,
+      func_x_pT_3=func_x_pT_3,
+      func_p_xT_3=func_p_xT_3,
+      func_dx_dp_3=func_dx_dp_3,
+      func_pi_pT_3=func_pi_pT_3,
+      func_p_piT_3=func_p_piT_3,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3)
+      "Standard 'Newton-Raphson' algorithm";
+
+    //
+    // Assign correct output values
+    //
+    y_i := y_i_[1:end-1]
+      "Mole fractions of independent components in the gas or vapor phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "IAST for three components: Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+
+    //
+    // Definition of inputs
+    //
+    input Real[:] c_3
+      "Coefficients of the isotherm model of the third component"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+      "Uptake of the third component as function of pressure and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+      "Pressure of the third component as function of uptake and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+      "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+      "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+      "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+    input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+      "Record definining numerics of the third component's isotherm model"
+      annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                  choicesAllMatching=true);
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MoleFraction[size(M_i,1)] y_i_
+      "Mole fractions of all components in the vapor or gas phase";
+
+  algorithm
+    //
+    // Solve inverse of IAST
+    //
+    (p_adsorpt,y_i_,) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.py_xT_NewtonRaphson(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      M_i=M_i,
+      c_1=c_1,
+      c_2=c_2,
+      c_3=c_3,
+      func_x_pT_1=func_x_pT_1,
+      func_p_xT_1=func_p_xT_1,
+      func_dx_dp_1=func_dx_dp_1,
+      func_pi_pT_1=func_pi_pT_1,
+      func_p_piT_1=func_p_piT_1,
+      func_x_pT_2=func_x_pT_2,
+      func_p_xT_2=func_p_xT_2,
+      func_dx_dp_2=func_dx_dp_2,
+      func_pi_pT_2=func_pi_pT_2,
+      func_p_piT_2=func_p_piT_2,
+      func_x_pT_3=func_x_pT_3,
+      func_p_xT_3=func_p_xT_3,
+      func_dx_dp_3=func_dx_dp_3,
+      func_pi_pT_3=func_pi_pT_3,
+      func_p_piT_3=func_p_piT_3,
+      num=num,
+      num_comp_1=num_comp_1,
+      num_comp_2=num_comp_2,
+      num_comp_3=num_comp_3)
+      "Standard 'Newton-Raphson' algorithm";
+
+    //
+    // Assign correct output values
+    //
+    y_i := y_i_[1:end-1]
+      "Mole fractions of independent components in the gas or vapor phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "IAST for three components: Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature (numerical solution)"
+
+    //
+    // Definition of inputs
+    //
+    input Real[:] c_3
+      "Coefficients of the isotherm model of the third component"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+      "Uptake of the third component as function of pressure and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+      "Pressure of the third component as function of uptake and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+      "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+      "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+      "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+    input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+      "Record definining numerics of the third component's isotherm model"
+      annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                  choicesAllMatching=true);
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_pdp
+      "Equilibrium uptakes of the adsorpt phase: p + dp";
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_mdp
+      "Equilibrium uptakes of the adsorpt phase: p - dp";
+
+  algorithm
+    //
+    // Select IAST algorithm
+    //
+    if num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson then
+      (x_adsorpt_pdp,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt + dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "Standard 'Newton-Raphson' algorithm";
+
+      (x_adsorpt_mdp,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt - dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "Standard 'Newton-Raphson' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop then
+      (x_adsorpt_pdp,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt + dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'Nested Loop' algorithm";
+
+      (x_adsorpt_mdp,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt - dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'Nested Loop' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST then
+      (x_adsorpt_pdp,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt + dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'FASTIast' algorithm";
+
+      (x_adsorpt_mdp,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt - dp,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt,
+        M_i=M_i,
+        c_1=c_1,
+        c_2=c_2,
+        c_3=c_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'FASTIast' algorithm";
+
+    end if;
+
+    //
+    // Calculate derivatives of loadings w.r.t. equilibrium pressure
+    //
+    dx_adsorpt_dp_adsorpt := (x_adsorpt_pdp .- x_adsorpt_mdp) ./ (2*dp)
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "IAST for three components: Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature (numerical solution)"
+
+    //
+    // Definition of inputs
+    //
+    input Real[:] c_3
+      "Coefficients of the isotherm model of the third component"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+      "Uptake of the third component as function of pressure and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+      "Pressure of the third component as function of uptake and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+      "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+      "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+      "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+    input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+      "Record definining numerics of the third component's isotherm model"
+      annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                  choicesAllMatching=true);
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_pdy
+      "Equilibrium uptakes of the adsorpt phase: y + dy";
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_mdy
+      "Equilibrium uptakes of the adsorpt phase: y - dy";
+
+  algorithm
+    for ind_y_i in 1:size(M_i,1)-1 loop
+      //
+      // Select IAST algorithm
+      //
+      if num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson then
+        (x_adsorpt_pdy,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NewtonRaphson(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(
+            1,
+            y_i_[1:ind_y_i - 1],
+            {y_i_[ind_y_i] + dy},
+            y_i_[ind_y_i + 1:size(M_i, 1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          c_3=c_3,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          func_x_pT_3=func_x_pT_3,
+          func_p_xT_3=func_p_xT_3,
+          func_dx_dp_3=func_dx_dp_3,
+          func_pi_pT_3=func_pi_pT_3,
+          func_p_piT_3=func_p_piT_3,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2,
+          num_comp_3=num_comp_3)
+          "Standard 'Newton-Raphson' algorithm";
+
+        (x_adsorpt_mdy,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NewtonRaphson(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(
+            1,
+            y_i_[1:ind_y_i - 1],
+            {y_i_[ind_y_i] - dy},
+            y_i_[ind_y_i + 1:size(M_i, 1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          c_3=c_3,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          func_x_pT_3=func_x_pT_3,
+          func_p_xT_3=func_p_xT_3,
+          func_dx_dp_3=func_dx_dp_3,
+          func_pi_pT_3=func_pi_pT_3,
+          func_p_piT_3=func_p_piT_3,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2,
+          num_comp_3=num_comp_3)
+          "Standard 'Newton-Raphson' algorithm";
+
+      elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop then
+        (x_adsorpt_pdy,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NestedLoop(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(
+            1,
+            y_i_[1:ind_y_i - 1],
+            {y_i_[ind_y_i] + dy},
+            y_i_[ind_y_i + 1:size(M_i, 1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          c_3=c_3,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          func_x_pT_3=func_x_pT_3,
+          func_p_xT_3=func_p_xT_3,
+          func_dx_dp_3=func_dx_dp_3,
+          func_pi_pT_3=func_pi_pT_3,
+          func_p_piT_3=func_p_piT_3,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2,
+          num_comp_3=num_comp_3)
+          "'Nested Loop' algorithm";
+
+        (x_adsorpt_mdy,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NestedLoop(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(
+            1,
+            y_i_[1:ind_y_i - 1],
+            {y_i_[ind_y_i] - dy},
+            y_i_[ind_y_i + 1:size(M_i, 1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          c_3=c_3,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          func_x_pT_3=func_x_pT_3,
+          func_p_xT_3=func_p_xT_3,
+          func_dx_dp_3=func_dx_dp_3,
+          func_pi_pT_3=func_pi_pT_3,
+          func_p_piT_3=func_p_piT_3,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2,
+          num_comp_3=num_comp_3)
+          "'Nested Loop' algorithm";
+
+      elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST then
+        (x_adsorpt_pdy,,,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_FastIAST(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(
+            1,
+            y_i_[1:ind_y_i - 1],
+            {y_i_[ind_y_i] + dy},
+            y_i_[ind_y_i + 1:size(M_i, 1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          c_3=c_3,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          func_x_pT_3=func_x_pT_3,
+          func_p_xT_3=func_p_xT_3,
+          func_dx_dp_3=func_dx_dp_3,
+          func_pi_pT_3=func_pi_pT_3,
+          func_p_piT_3=func_p_piT_3,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2,
+          num_comp_3=num_comp_3)
+          "'FASTIast' algorithm";
+
+        (x_adsorpt_mdy,,,,) :=
+          SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_FastIAST(
+          p_adsorpt=p_adsorpt,
+          y_i=cat(
+            1,
+            y_i_[1:ind_y_i - 1],
+            {y_i_[ind_y_i] - dy},
+            y_i_[ind_y_i + 1:size(M_i, 1)]),
+          T_adsorpt=T_adsorpt,
+          M_i=M_i,
+          c_1=c_1,
+          c_2=c_2,
+          c_3=c_3,
+          func_x_pT_1=func_x_pT_1,
+          func_p_xT_1=func_p_xT_1,
+          func_dx_dp_1=func_dx_dp_1,
+          func_pi_pT_1=func_pi_pT_1,
+          func_p_piT_1=func_p_piT_1,
+          func_x_pT_2=func_x_pT_2,
+          func_p_xT_2=func_p_xT_2,
+          func_dx_dp_2=func_dx_dp_2,
+          func_pi_pT_2=func_pi_pT_2,
+          func_p_piT_2=func_p_piT_2,
+          func_x_pT_3=func_x_pT_3,
+          func_p_xT_3=func_p_xT_3,
+          func_dx_dp_3=func_dx_dp_3,
+          func_pi_pT_3=func_pi_pT_3,
+          func_p_piT_3=func_p_piT_3,
+          num=num,
+          num_comp_1=num_comp_1,
+          num_comp_2=num_comp_2,
+          num_comp_3=num_comp_3)
+          "'FASTIast' algorithm";
+
+      end if;
+
+      //
+      // Calculate partial darivatives for each independent mole fraction
+      //
+      dx_adsorpt_dy_i[:,ind_y_i] := (x_adsorpt_pdy .- x_adsorpt_mdy) ./ (2*dy)
+        "Partial derivatives of the uptakes w.r.t. the mole fractions of independent 
+      gas phase components at constant pressure and temperature";
+    end for;
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "IAST for three components: Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions (numerical solution)"
+
+    //
+    // Definition of inputs
+    //
+    input Real[:] c_3
+      "Coefficients of the isotherm model of the third component"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+    input Real[size(c_2,1)] c_pdT_3
+      "Coefficients of the isotherm model of the third component: T + dT"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+    input Real[size(c_2,1)] c_mdT_3
+      "Coefficients of the isotherm model of the third component: T - dT"
+      annotation (Dialog(tab="General", group="Inputs - Components"));
+
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT func_x_pT_3
+      "Uptake of the third component as function of pressure and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT_3
+      "Pressure of the third component as function of uptake and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp_3
+      "Partial derivative of the uptake of the third component w.r.t. the equilibrium 
+    pressure"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT func_pi_pT_3
+      "Reduced spreading pressure of the third component as function of pressure 
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+    input
+      SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT func_p_piT_3
+      "Pressure of the third component as function of reduced spreading pressure
+    and temperature"
+      annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+    input SorpLib.Media.Functions.SorptionEquilibria.Records.NumericsIAST_PureComponents num_comp_3
+      "Record definining numerics of the third component's isotherm model"
+      annotation (Dialog(tab="General", group="Inputs - Numerics"),
+                  choicesAllMatching=true);
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_pdT
+      "Equilibrium uptakes of the adsorpt phase: T + dT";
+    SorpLib.Units.Uptake[size(M_i,1)] x_adsorpt_mdT
+      "Equilibrium uptakes of the adsorpt phase: T - dT";
+
+  algorithm
+    //
+    // Select IAST algorithm
+    //
+    if num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson then
+      (x_adsorpt_pdT,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt + dT,
+        M_i=M_i,
+        c_1=c_pdT_1,
+        c_2=c_pdT_2,
+        c_3=c_pdT_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "Standard 'Newton-Raphson' algorithm";
+
+      (x_adsorpt_mdT,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NewtonRaphson(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt - dT,
+        M_i=M_i,
+        c_1=c_mdT_1,
+        c_2=c_mdT_2,
+        c_3=c_mdT_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "Standard 'Newton-Raphson' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop then
+      (x_adsorpt_pdT,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt + dT,
+        M_i=M_i,
+        c_1=c_pdT_1,
+        c_2=c_pdT_2,
+        c_3=c_pdT_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'Nested Loop' algorithm";
+
+      (x_adsorpt_mdT,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_NestedLoop(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt - dT,
+        M_i=M_i,
+        c_1=c_mdT_1,
+        c_2=c_mdT_2,
+        c_3=c_mdT_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'Nested Loop' algorithm";
+
+    elseif num.IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST then
+      (x_adsorpt_pdT,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt + dT,
+        M_i=M_i,
+        c_1=c_pdT_1,
+        c_2=c_pdT_2,
+        c_3=c_pdT_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'FASTIast' algorithm";
+
+      (x_adsorpt_mdT,,,,) :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.IAST_N3.Internals.x_pyT_FastIAST(
+        p_adsorpt=p_adsorpt,
+        y_i=y_i_,
+        T_adsorpt=T_adsorpt - dT,
+        M_i=M_i,
+        c_1=c_mdT_1,
+        c_2=c_mdT_2,
+        c_3=c_mdT_3,
+        func_x_pT_1=func_x_pT_1,
+        func_p_xT_1=func_p_xT_1,
+        func_dx_dp_1=func_dx_dp_1,
+        func_pi_pT_1=func_pi_pT_1,
+        func_p_piT_1=func_p_piT_1,
+        func_x_pT_2=func_x_pT_2,
+        func_p_xT_2=func_p_xT_2,
+        func_dx_dp_2=func_dx_dp_2,
+        func_pi_pT_2=func_pi_pT_2,
+        func_p_piT_2=func_p_piT_2,
+        func_x_pT_3=func_x_pT_3,
+        func_p_xT_3=func_p_xT_3,
+        func_dx_dp_3=func_dx_dp_3,
+        func_pi_pT_3=func_pi_pT_3,
+        func_p_piT_3=func_p_piT_3,
+        num=num,
+        num_comp_1=num_comp_1,
+        num_comp_2=num_comp_2,
+        num_comp_3=num_comp_3)
+        "'FASTIast' algorithm";
+
+    end if;
+
+    //
+    // Calculate derivatives of loadings w.r.t. equilibrium pressure
+    //
+    dx_adsorpt_dT_adsorpt := (x_adsorpt_pdT .- x_adsorpt_mdT) ./ (2*dT)
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The IAST for three components calculates equilibrium uptakes <i>x_adsorpt</i> as a
+function of the equilibrium pressure <i>p_adsorpt</i>, mole fractions of independent 
+components in the gas or vapor phase <i>y_i</i>, and the equilibrium temperature 
+<i>T_adsorpt</i>. The IAST calculates the multi-component adsorption equilibrium based 
+on the pure component isotherm models. For this purpose, a system of equations is 
+solved using numerical methods.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The system of equations consists of 2 * <i>n_components</i> + 1 equations (i.e., 5), 
+which can be divided into 4 main equation types:
+</p>
+<ol>
+  <li>
+  Reduced spreading pressure <i>&pi;</i> that is the same for all components:
+  <pre>&pi; = &pi;<sub><i>i</i></sub> = &int;<sub>0</sub><sup>p<sup>*</sup><sub><i>i</i></sub></sup> [x<sub>adsorpt,<i>i</i></sub> / p<sub>adsorpt,<i>i</i></sub> * dp<sub>adsorpt,<i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Closing condition of the molar composition of the adsorpt phase <i>z<sub><i>i</i></sub></i>:
+  <pre>1 = &sum;<sub><i>i</i></sub> z<sub><i>i</i></sub> = &sum;<sub><i>i</i></sub> [y<sub><i>i</i></sub> * p<sub>adsorpt</sub> / p<sup>*</sup><sub><i>i</i></sub>].</pre>
+  <br>
+  </li>
+  <li>
+  Molar uptake of the adsorpt phase of each component <i>i</i>:
+  <pre>q<sub>adsorpt,<i>i</i></sub> = z<sub><i>i</i></sub> * q<sub>total</sub>.</pre>
+  <br>
+  </li>
+  <li>
+  Total molar uptake of the adsorpt phase:
+  <pre>q<sub>total</sub> = (&sum;<sub><i>i</i></sub> [z<sub><i>i</i></sub> / q<sub>adsorpt,<i>i</i></sub>]) ^ (-1).</pre>
+  <br>
+  </li>
+</ol>
+<p>
+Herein, for each component <i>i</i<>, <i>p<sup>*</sup><sub><i>i</i></sub></i> is the
+hypothetical pure component pressure at which the reduced spreading pressure of each
+component <i>&pi;<sub><i>i</i></sub></i> is identical (i.e., equilibrium condition).
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the IAST for three components for one parameter set. In the 
+upper sub-figure, the equilibrium pressure changes with time. In the centre sub-figure, 
+the independent mole fractions change with time. In the lower sub-figure, the 
+equilibrium temperature changes with time. The left side shows the uptake of component 
+1, the middle shows the uptake of component 2, and the right side shows the uptake of 
+component 3. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_iast_n3.png\" alt=\"media_functions_equilibria_multi_iast_n3.png\">
+
+<h4>References</h4>
+<p>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Mangano E., Friedrich, D., and Brandani, S. (2015). Robust algorithms for the solution of the ideal adsorbed solution theory equations. AIChE Journal, 61(3): 981–991. DOI: 10.1002/aic.14684.
+  </li>
+</ul>
+</p>
+</html>"));
+end IAST_N3;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/IAST_N3/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/calc_p_i_num_i_den.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/calc_p_i_num_i_den.mo
new file mode 100644
index 0000000..059044c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/calc_p_i_num_i_den.mo
@@ -0,0 +1,70 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals;
+function calc_p_i_num_i_den
+  "Extended Langmuir isotherm model: Corrected partial pressures, numerators, denominator of the isotherm model"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real[:,:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_threshold_min = 0
+    "Threshold for partial pressures of all components: If a partial pressure is
+    below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i_regulated
+    "Regulated equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real[size(c,2)] num_i
+    "Individual numerator for each component of the isotherm model"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real den
+    "Identical denominator for each component of the isotherm model"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  den := 1
+    "Start value of the denominator";
+
+  for ind_comp in 1:size(c,2) loop
+    p_i_regulated[ind_comp] := max(p_i[ind_comp], p_threshold_min)
+      "Limiter of partial pressures to increase numerical stability";
+
+    num_i[ind_comp] := c[1,ind_comp] * c[2,ind_comp] * p_i_regulated[ind_comp]
+      "Individual numerators";
+
+    den := den + c[2,ind_comp] * p_i_regulated[ind_comp]
+      "Identical denominator";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function regulates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) so that they are equal or greater than <i>p_threshold_min</i>. Further,
+this function calculates the numerators <i>num_i</i> and denominator <i>den</i>
+of the extended Langmuir isotherm model. For full details of the extended Langmuir
+isotherm model, check the documentation of the package 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end calc_p_i_num_i_den;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/p_i_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/p_i_xT.mo
new file mode 100644
index 0000000..0b087cc
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/p_i_xT.mo
@@ -0,0 +1,79 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals;
+function p_i_xT
+  "Extended Langmuir isotherm model: Partial pressures as function of uptakes and temperature"
+   extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(c,2), size(c,2)] A
+    "Matrix A of A*z = -x_adsorpt";
+  Real[size(c,2)] z
+    "Vector z of A*z = -x_adsorpt (i.e., z = first substitution)";
+
+algorithm
+  //
+  // Set up matrix A and solve system of linear equations:
+  //
+  // To calculate the invesere function of the extended Langmuir isotherm regarding
+  // the equilibrium pressure and mole fractions of the independent components of
+  // the gas or vapor phase, the term ' c[2,ind] * p_i[ind]' is substituted by
+  // 'z.' Thus, a system of linear equations is created that can be solved.
+  // Re-substitution allows to calculate partial pressures p_i and, thus, the
+  // equilibrium pressure and mole fractions.
+  //
+  for ind in 1:size(c,2) loop
+    A[ind,:] := fill(x_adsorpt[ind], size(c,2))
+      "First, fill row with correct uptake";
+    A[ind,ind] := x_adsorpt[ind] - c[1,ind]
+      "Second, correct diagonale";
+  end for;
+
+  z := Modelica.Math.Matrices.solve(A, -1 .* x_adsorpt)
+    "Third, solve the system of linear equations";
+
+  //
+  // Calculate partial pressures
+  //
+  for ind in 1:size(c,2) loop
+    p_i[ind] := max(z[ind] / c[2,ind], p_threshold_min)
+      "Re-substituate values and consider threshold if necessary";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) as function of the equilibrium uptakes <i>x_adsorpt</i> and the 
+equilibrium temperature <i>T_adsorpt</i>. Thus, this function is a inverse of the 
+function 'x_pyT.' For full details of the original function 'x_pyT,' check the 
+documentation of the package 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end p_i_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/package.mo
new file mode 100644
index 0000000..6d907b1
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the extended Langmuir
+isotherm model. Thus, redundancy of code shall be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/package.order
new file mode 100644
index 0000000..e5d8b7b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/Internals/package.order
@@ -0,0 +1,2 @@
+calc_p_i_num_i_den
+p_i_xT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/package.mo
new file mode 100644
index 0000000..2e2535d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/package.mo
@@ -0,0 +1,387 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package Langmuir "Package containing all functions regarding the extended Langmuir isotherm"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponents;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "Extended Langmuir isotherm model: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real den
+      "Identical denominator for each component of the isotherm model";
+
+  algorithm
+    (p_i, num_i, den) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals.calc_p_i_num_i_den(
+      p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    x_adsorpt := num_i ./ den
+      "Calculate equilibrium uptakes of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "Extended Langmuir isotherm model: Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals.p_i_xT(
+       x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+      "Partial pressures";
+
+    p_adsorpt := sum(p_i)
+      "Equilibrium pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "Extended Langmuir isotherm model: Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals.p_i_xT(
+       x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+      "Partial pressures";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / max(p_adsorpt, p_threshold_min)
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "Extended Langmuir isotherm model: Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals.p_i_xT(
+       x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+      "Partial pressures";
+
+    p_adsorpt := max(sum(p_i), p_threshold_min)
+      "Equilibrium pressure";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / p_adsorpt
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "Extended Langmuir isotherm model: Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real den
+      "Identical denominator for each component of the isotherm model";
+
+    Real[size(c,2)] dnum_i_dp_adsorpt
+      "Partial derivatives of the numerators w.r.t. the equilibrium pressure";
+    Real dden_dp_adsorpt
+      "Partial derivative of the denominator w.r.t. the equilbrium pressure";
+
+  algorithm
+    (p_i, num_i, den) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals.calc_p_i_num_i_den(
+      p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives
+    //
+    dden_dp_adsorpt := 0
+      "Start value of the derivative of the denominator w.r.t. equilbrium pressure";
+
+    for ind_comp in 1:size(c,2) loop
+      dnum_i_dp_adsorpt[ind_comp] := c[1,ind_comp] * c[2,ind_comp] * y_i_[ind_comp]
+        "Partial derivatives of numerators w.r.t. equilibrium pressure";
+
+      dden_dp_adsorpt := dden_dp_adsorpt + c[2,ind_comp] * y_i_[ind_comp]
+        "Partial derivative of denominator w.r.t. equilibrium pressure";
+    end for;
+
+    //
+    // Calculate derivatives of loadings w.r.t. equilibrium pressure
+    //
+    dx_adsorpt_dp_adsorpt :=
+      (dnum_i_dp_adsorpt.* den .- num_i.* dden_dp_adsorpt) ./ den^2
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "Extended Langmuir isotherm model: Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real den
+      "Identical denominator for each component of the isotherm model";
+
+    Real[size(c,2),size(c,2)-1] dnum_i_dy_i
+      "Partial derivatives of the numerators w.r.t. the mole fractions of independent 
+    gas phase components";
+    Real[size(c,2)-1] dden_dy_i
+      "Partial derivative of the denominator w.r.t. the mole fractions of independent 
+    gas phase components";
+
+  algorithm
+    (p_i, num_i, den) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals.calc_p_i_num_i_den(
+      p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives of numerators, which varies with components and
+    // mole fractions of independent components
+    //
+    dnum_i_dy_i:=zeros(size(c, 2), size(c, 2) - 1)
+      "Partial derivatives of the numerators w.r.t. the mole fractions of independent 
+    gas phase components";
+
+    for ind_comp in 1:size(c,2) loop
+      if ind_comp < size(c,2) then
+        // Partial derivatives of independent components
+        //
+        dnum_i_dy_i[ind_comp,ind_comp] := c[1,ind_comp] * c[2,ind_comp] * p_adsorpt
+          "Partial derivatives of numerators w.r.t. the mole fractions of independent 
+        gas phase components";
+
+      else
+        // Partial derivatives of dependent component
+        //
+        for ind_y_i in 1:size(c,2)-1 loop
+          dnum_i_dy_i[ind_comp,ind_y_i] := c[1,ind_comp] * c[2,ind_comp] * (-p_adsorpt)
+          "Partial derivatives of numerators w.r.t. the mole fractions of independent 
+        gas phase components";
+
+        end for;
+      end if;
+    end for;
+
+    //
+    // Calculate partial derivatives of the denominator, which varies with components and
+    // mole fractions of independent components
+    //
+    dden_dy_i:=zeros(size(c, 2) - 1)
+      "Partial derivative of the denominator w.r.t. the mole fractions of independent 
+    gas phase components";
+
+    for ind_y_i in 1:size(c,2)-1 loop
+      dden_dy_i[ind_y_i] := dden_dy_i[ind_y_i] +
+        c[2,ind_y_i] * p_adsorpt +
+        c[2,size(c,2)] * (-p_adsorpt)
+        "Partial derivative of the denominator w.r.t. the mole fractions of independent 
+      gas phase components";
+    end for;
+
+    //
+    // Calculate partial derivatives of uptakes w.r.t. mole fractions of independent
+    // gas phase components
+    //
+    for ind_comp in 1:size(c,2) loop
+      for ind_y_i in 1:size(c,2)-1 loop
+        dx_adsorpt_dy_i[ind_comp,ind_y_i] :=
+          (dnum_i_dy_i[ind_comp,ind_y_i] * den -
+          num_i[ind_comp] * dden_dy_i[ind_y_i]) ./ den^2
+          "Partial derivatives of the uptakes w.r.t. the mole fractions of independent 
+        gas phase components at constant pressure and temperature";
+      end for;
+    end for;
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "Extended Langmuir isotherm model: Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real den
+      "Identical denominator for each component of the isotherm model";
+
+    Real[size(c,2)] dnum_i_dT_adsorpt
+      "Derivatives of the numerators w.r.t. the equilibrium temperature";
+    Real dden_dT_adsorpt
+      "Derivative of the denominator w.r.t. the equilbrium temperature";
+
+  algorithm
+    (p_i, num_i, den) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir.Internals.calc_p_i_num_i_den(
+      p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives
+    //
+    dden_dT_adsorpt := 0
+      "Start value of the derivative of the denominator w.r.t. equilbrium pressure";
+
+    for ind_comp in 1:size(c,2) loop
+      dnum_i_dT_adsorpt[ind_comp] :=
+        (c[2,ind_comp] * p_i[ind_comp]) * dc_dT_adsorpt[1,ind_comp] +
+        (c[1,ind_comp] * p_i[ind_comp]) * dc_dT_adsorpt[2,ind_comp]
+        "Derivatives of numerators w.r.t. equilibrium temperature";
+
+      dden_dT_adsorpt := dden_dT_adsorpt +
+        (p_i[ind_comp]) * dc_dT_adsorpt[2,ind_comp]
+        "Derivative of denominator w.r.t. equilibrium temperature";
+    end for;
+
+    //
+    // Calculate derivatives of uptakes wrt. total pressure
+    //
+    dx_adsorpt_dT_adsorpt :=
+      (dnum_i_dT_adsorpt.* den .- num_i.* dden_dT_adsorpt) ./ den^2
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The extended Langmuir isotherm model calculates equilibrium uptakes <i>x_adsorpt</i>
+as a function of the equilibrium pressure <i>p_adsorpt</i>, mole fractions of
+independent components in the gas or vapor phase <i>y_i</i>, and the equilibrium
+temperature <i>T_adsorpt</i>. Each component of the extended Langmuir isotherm model
+has two parameters.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The extended Langmuir isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt,<i>i</i></sub> = x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) * (b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,<i>i</i></sub>) / (1 + &sum;[b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,<i>i</i></sub>]);
+</pre>
+<p>
+Herein, for each component <i>i</i>, <i>x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>)</i> 
+is the saturation uptake and <i>b<sub><i>i</i></sub>(T<sub>adsorpt</sub>)</i> is the 
+Langmuir coefficient. Typical temperature dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) = a<sub>0,<i>i</i></sub> + a<sub>1,<i>i</i></sub>/T<sub>adsorpt</sub>;
+</pre>
+<pre>
+    b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) = b<sub>0,<i>i</i></sub> * <strong>exp</strong>(-&Delta;H<sub>ads,<i>i</i></sub>/(R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+Herein, for each component <i>i</i>, <i>a<sub>0,<i>i</i></sub></i>, <i>a<sub>1,
+<i>i</i></sub></i>, <i>b<sub>0,<i>i</i></sub></i>, and <i>&Delta;H<sub>ads,<i>i</i></sub></i> 
+are fiiting parameters. The parameter <i>&Delta;H<sub>ads,<i>i</i></sub></i> is the 
+isosteric adsorption heat, which is invariant with the surface uptake. Note that the 
+extended Langmuir isotherm model only consists of thermodynamic consistency if the 
+saturation uptake <i>x<sub>sat,<i>i</i></sub></i> is constant.
+</p>
+
+<h4>Required parameter order in function input c[:,no_components]:</h4>
+<p>
+For each component <i>i</i>, the required parameter order in the function input <i>c</i>
+is as follows:
+</p>
+<ul>
+  <li>
+  c[1,<i>i</i>] = x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2,<i>i</i>] = b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  All adsorption sites are energetically equivalent.
+  </li>
+  <li>
+  All adsorption sites can be occupied.
+  </li>
+  <li>
+  No interactions occur between the adsorbent molecules.
+  </li>
+  <li>
+  The adsorbent surface is covered monomolecularly.
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the extended Langmuir isotherm model for one parameter set
+and two components. In the upper sub-figure, the equilibrium pressure changes with 
+time. In the centre sub-figure, the independent mole fractions change with time.
+In the lower sub-figure, the equilibrium temperature changes with time. The left
+side shows the uptake of component 1, and the right side shows the uptake of
+component 2. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_langmuir.png\" alt=\"media_functions_equilibria_multi_langmuir.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Amrutha and Jeppu, G. and Girish, C.R. and Prabhu, B., and Mayer, K. (2023). Multi-component Adsorption Isotherms: Review and Modeling Studies, Environmental Processes, 10:38. DOI: https://doi.org/10.1007/s40710-023-00631-0.
+  </li>
+</ul>
+</html>"));
+end Langmuir;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Langmuir/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/dx_CO2_dp.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/dx_CO2_dp.mo
new file mode 100644
index 0000000..8750735
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/dx_CO2_dp.mo
@@ -0,0 +1,63 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals;
+function dx_CO2_dp
+  "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Partial derivative of uptake w.r.t. pressure as function of pressure and temperature"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp;
+
+  //
+  // Definition of inputs
+  //
+  input Real[:] dc_dp_adsorpt
+    "Partial derivatives of coefficients of isotherm model w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real dx_adsorpt_dc1 = c[2] * p_adsorpt /
+    ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+    "Derivative of uptake w.r.t. to first coefficient of Toth isotherm";
+  Real dx_adsorpt_dc2 = c[1] * p_adsorpt *
+    ((c[2]*p_adsorpt)^c[3] + 1) ^ (-1/c[3] - 1)
+    "Derivative of uptake w.r.t. to second coefficient of Toth isotherm";
+  Real dx_adsorpt_dc3 = c[1] * c[2] * p_adsorpt *
+    (log(1 + (c[2]*p_adsorpt)^c[3]) / c[3]^2 -
+    (c[2]*p_adsorpt)^c[3] * log(c[2]*p_adsorpt) /
+    (c[3] * (1 + (c[2]*p_adsorpt)^c[3]))) /
+    ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+    "Derivative of uptake w.r.t. to third coefficient of Toth isotherm";
+
+algorithm
+  dx_adsorpt_dp_adsorpt :=
+    c[1]*c[2] * ((c[2]*p_adsorpt)^c[3] + 1) ^ (-1/c[3] - 1) +
+    dx_adsorpt_dc1*dc_dp_adsorpt[1] +
+    dx_adsorpt_dc2*dc_dp_adsorpt[2] +
+    dx_adsorpt_dc3*dc_dp_adsorpt[3]
+    "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'x_pT' of the Toth isotherm
+model w.r.t.o the equilibrium pressure. For full details of the original function 'x_pT,' 
+check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT\">SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT</a>.
+<br>
+In contrast to the existing function 'dx_dp' of the Toth isotherm model, this function 
+recognises that the coefficients <i>c</i> can also depend on the equilibrium pressure. 
+Therefore, this function has the partial derivatives of the coefficients w.r.t. the
+equilibrium pressure <i>dc_dp_adsorpt</i> as an additional input.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dx_CO2_dp;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/p_i_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/p_i_xT.mo
new file mode 100644
index 0000000..53028e2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/p_i_xT.mo
@@ -0,0 +1,112 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals;
+function p_i_xT
+  "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Partial pressures as function of uptakes and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real Phi_available(unit="1")
+    "Fraction of sites available for adsorption";
+  Real A_CO2(unit="1/Pa")
+    "Enhancement factor of saturation uptake of CO2";
+
+  Real DH_avg(unit="J/mol")
+    "Average isosteric heat of adsorption";
+  Real B_CO2(unit="1/Pa")
+    "Toth coefficient";
+
+algorithm
+  //
+  // First, calculate the equilibrium pressure of component 1 (i.e., CO2)
+  //
+  Phi_available := c[3,1] - c[5,1] *
+    (1 - Modelica.Math.exp(-(c[7,1] * x_adsorpt[2]) ^ c[8,1]))
+    "Fraction of sites available for adsorption";
+  A_CO2 := (c[4,1] + (Phi_available - c[4,1]) *
+    Modelica.Math.exp(-c[6,1] / x_adsorpt[2])) / c[4,1]
+    "Enhancement factor of saturation uptake of CO2";
+
+  DH_avg := (1 - Modelica.Math.exp(-c[6,1] / x_adsorpt[2])) * c[10,1] +
+    Modelica.Math.exp(-c[6,1] / x_adsorpt[2]) * c[11,1]
+    "Average isosteric heat of adsorption";
+  B_CO2 := c[9,1] * Modelica.Math.exp(-DH_avg / (Modelica.Constants.R * T_adsorpt))
+    "Toth coefficient";
+
+  p_i[1] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.p_xT(
+    x_adsorpt=x_adsorpt[1],
+    T_adsorpt=T_adsorpt,
+    c={A_CO2 * c[1,1],
+       B_CO2,
+       c[2,1]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium pressure of CO2";
+
+  p_i[1] := max(p_i[1], p_threshold_min)
+    "Limit equilibrium pressure if necessary";
+
+  //
+  // Second, calculte the equilibrium pressure of component 2 (i.e., H2O)
+  //
+  //
+  p_i[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(
+    x_adsorpt=x_adsorpt[2],
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium pressure of H2O";
+
+  p_i[2] := max(p_i[2], p_threshold_min)
+    "Limit equilibrium pressure if necessary";
+
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) as function of the equilibrium uptakes <i>x_adsorpt</i> and the 
+equilibrium temperature <i>T_adsorpt</i>. Thus, this function is a inverse of the 
+function 'x_pyT.' For full details of the original function 'x_pyT,' check the 
+documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end p_i_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/package.mo
new file mode 100644
index 0000000..9a128b7
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the mechanistic 
+Toth-GAB isotherm model. Thus, redundancy of code shall be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/package.order
new file mode 100644
index 0000000..54b2b57
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/package.order
@@ -0,0 +1,3 @@
+dx_CO2_dp
+p_i_xT
+x_H20_pT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/x_H20_pT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/x_H20_pT.mo
new file mode 100644
index 0000000..3735144
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/Internals/x_H20_pT.mo
@@ -0,0 +1,86 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals;
+function x_H20_pT
+  "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Equilibrium uptake of component 2 (i.e., H2O) as function of partial pessures and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake x_adsorpt_H2O
+    "Equilibrium uptake of component 2 (i.e., H2O)"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.Uptake x_adsorpt_H2O_max=
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(
+    p_adsorpt=max(c[1,2], p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Maximal equilibrium uptake of H2O achieved at relative humidity of 1 (i.e.,
+    p_adsorpt_H2O = p_sat_H2O";
+
+algorithm
+  //
+  // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+  // is required to calculate the equilibrium uptake of component 1 (i.e., CO2)
+  //
+  //
+  x_adsorpt_H2O := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(
+    p_adsorpt=max(p_i[2], p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium uptake of H2O";
+
+  x_adsorpt_H2O := min(x_adsorpt_H2O, x_adsorpt_H2O_max)
+    "Limit equilibrium uptake of H2O to its maximal equilibrium uptake";
+
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium uptake of component 2 (i.e., H2O) 
+<i>x_adsorpt_H2O</i> as function of the partial equilibrium pressures <i>p_i</i>
+and the equilibrium temperature <i>T_adsorpt</i>. For full details of the isotherm 
+model, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_H20_pT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/package.mo
new file mode 100644
index 0000000..e76c528
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/package.mo
@@ -0,0 +1,939 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package MechanisticTothGAB "Package containing all functions regarding the mechanistic Toth-GAB isotherm developed by Young et al. (2021) for adsorption of CO2 & H2O"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponents;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real Phi_available(unit="1")
+      "Fraction of sites available for adsorption";
+    Real A_CO2(unit="1/Pa")
+      "Enhancement factor of saturation uptake of CO2";
+
+    Real DH_avg(unit="J/mol")
+      "Average isosteric heat of adsorption";
+    Real B_CO2(unit="1/Pa")
+      "Toth coefficient";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the equilibrium uptake of component 1 (i.e., CO2)
+    //
+    x_adsorpt[2] :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.x_H20_pT(
+        p_i=p_i,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate the equilibrium uptake of component 1 (i.e., CO2)
+    //
+    Phi_available := c[3,1] - c[5,1] *
+      (1 - Modelica.Math.exp(-(c[7,1] * x_adsorpt[2]) ^ c[8,1]))
+      "Fraction of sites available for adsorption";
+    A_CO2 := (c[4,1] + (Phi_available - c[4,1]) *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt[2])) / c[4,1]
+      "Enhancement factor of saturation uptake of CO2";
+
+    DH_avg := (1 - Modelica.Math.exp(-c[6,1] / x_adsorpt[2])) * c[10,1] +
+      Modelica.Math.exp(-c[6,1] / x_adsorpt[2]) * c[11,1]
+      "Average isosteric heat of adsorption";
+    B_CO2 := c[9,1] * Modelica.Math.exp(-DH_avg / (Modelica.Constants.R * T_adsorpt))
+      "Toth coefficient";
+
+    x_adsorpt[1] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={A_CO2 * c[1,1],
+         B_CO2,
+         c[2,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium uptake of CO2";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.p_i_xT(
+        x_adsorpt=x_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min) "Partial pressures";
+
+    p_adsorpt := sum(p_i)
+      "Equilibrium pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.p_i_xT(
+        x_adsorpt=x_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min) "Partial pressures";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / max(p_adsorpt, p_threshold_min)
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.p_i_xT(
+        x_adsorpt=x_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min) "Partial pressures";
+
+    p_adsorpt := max(sum(p_i), p_threshold_min)
+      "Equilibrium pressure";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / p_adsorpt
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real Phi_available(unit="1")
+      "Fraction of sites available for adsorption";
+    Real A_CO2(unit="1/Pa")
+      "Enhancement factor of saturation uptake of CO2";
+
+    Real DH_avg(unit="J/mol")
+      "Average isosteric heat of adsorption";
+    Real B_CO2(unit="1/Pa")
+      "Toth coefficient";
+
+    Real dA_CO2_dx_adsorpt_H2O(unit="kg/(Pa.kg)")
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    uptake of H2O";
+    Real dA_CO2_dPhi_available(unit="1/Pa")
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the fraction of sites available for adsorption";
+    Real dPhi_available_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    uptake of H2O";
+
+    Real dB_CO2_dH_avg(unit="mol/(Pa.J)")
+      "Partial derivative of Toth coefficient w.r.t. the average isosteric 
+    adsorption enthalpy";
+    Real dH_avg_dx_adsorpt_H20(unit="J.kg/(mol.kg)")
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    uptake of H2O";
+
+    Real dc_1_CO2_dp_adsorpt
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    Real dc_2_CO2_dp_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    Real dc_3_CO2_dp_adsorpt
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the equilibrium pressure of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.x_H20_pT(
+        p_i=p_i,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    // The existing derivative function of the GAB isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // equilibrium pressure (i.e., y_i_[2]).
+    //
+    dx_adsorpt_dp_adsorpt[2] := y_i_[2] *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dp(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant mole fractions and temperature";
+
+    //
+    // Note that for component 1, the coefficients of the isotherm model are
+    // enhanced by the uptake of component 2. Hence, the parameters c depend also
+    // on the partial pressure of component 2 and, thus, on the equilibrium
+    // pressure. Note that all coefficients are devided by 'y_i_[1]' to compensate
+    // the multiplication by 'y_i_[1],' which is the partial derivative of the
+    // partial pressure of component 1 w.r.t. the equilibrium pressure.
+    //
+    Phi_available := c[3,1] - c[5,1] *
+      (1 - Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^ c[8,1]))
+      "Fraction of sites available for adsorption";
+    A_CO2 := (c[4,1] + (Phi_available - c[4,1]) *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)) / c[4,1]
+      "Enhancement factor of saturation uptake of CO2";
+
+    DH_avg := (1 - Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)) *
+      c[10,1] + Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) * c[11,1]
+      "Average isosteric heat of adsorption";
+    B_CO2 := c[9,1] * Modelica.Math.exp(-DH_avg / (Modelica.Constants.R * T_adsorpt))
+      "Toth coefficient";
+
+    dA_CO2_dx_adsorpt_H2O := c[6,1] * (Phi_available - c[4,1]) *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) / (c[4,1] * x_adsorpt_H2O^2)
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    uptake of H2O";
+    dA_CO2_dPhi_available := Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) / c[4,1]
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the fraction of sites available for adsorption";
+    dPhi_available_dx_adsorpt_H2O := - c[5,1] * c[8,1] * (c[7,1] * x_adsorpt_H2O) ^
+      c[8,1] * Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^ c[8,1]) / x_adsorpt_H2O
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    uptake of H2O";
+
+    dB_CO2_dH_avg := -B_CO2 / (Modelica.Constants.R * T_adsorpt)
+      "Partial derivative of Toth coefficient w.r.t. the average isosteric 
+    adsorption enthalpy";
+    dH_avg_dx_adsorpt_H20 := c[6,1] * (c[11,1] - c[10,1]) / x_adsorpt_H2O^2 *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    uptake of H2O";
+
+    dc_1_CO2_dp_adsorpt := c[1,1] * (dA_CO2_dx_adsorpt_H2O +
+      dA_CO2_dPhi_available * dPhi_available_dx_adsorpt_H2O) *
+      dx_adsorpt_dp_adsorpt[2] / y_i_[1]
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    dc_2_CO2_dp_adsorpt := dB_CO2_dH_avg * dH_avg_dx_adsorpt_H20 *
+      dx_adsorpt_dp_adsorpt[2] / y_i_[1]
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    dc_3_CO2_dp_adsorpt := 0 / y_i_[1]
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+
+    dx_adsorpt_dp_adsorpt[1] := y_i_[1]*
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.dx_CO2_dp(
+        p_adsorpt=max(p_i[1], p_threshold_min),
+        T_adsorpt=T_adsorpt,
+        c={A_CO2 * c[1,1],
+           B_CO2,
+           c[2,1]},
+        dc_dp_adsorpt={dc_1_CO2_dp_adsorpt,
+                       dc_2_CO2_dp_adsorpt,
+                       dc_3_CO2_dp_adsorpt})
+     "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real Phi_available(unit="1")
+      "Fraction of sites available for adsorption";
+    Real A_CO2(unit="1/Pa")
+      "Enhancement factor of saturation uptake of CO2";
+
+    Real DH_avg(unit="J/mol")
+      "Average isosteric heat of adsorption";
+    Real B_CO2(unit="1/Pa")
+      "Toth coefficient";
+
+    Real dA_CO2_dx_adsorpt_H2O(unit="kg/(Pa.kg)")
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    uptake of H2O";
+    Real dA_CO2_dPhi_available(unit="1/Pa")
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the fraction of sites available for adsorption";
+    Real dPhi_available_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    uptake of H2O";
+
+    Real dB_CO2_dH_avg(unit="mol/(Pa.J)")
+      "Partial derivative of Toth coefficient w.r.t. the average isosteric 
+    adsorption enthalpy";
+    Real dH_avg_dx_adsorpt_H20(unit="J.kg/(mol.kg)")
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    uptake of H2O";
+
+    Real dc_1_CO2_dp_adsorpt
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    Real dc_2_CO2_dp_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    Real dc_3_CO2_dp_adsorpt
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the independent mole fractions of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.x_H20_pT(
+        p_i=p_i,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    // The existing derivative function of the GAB isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // independent mole fractions (i.e., -p_adsorpt)
+    //
+    dx_adsorpt_dy_i[2,1] := -p_adsorpt *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dp(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    independent mole fractions at constant pressure and temperature";
+
+    //
+    // Note that for component 1, the coefficients of the isotherm model are
+    // enhanced by the uptake of component 2. Hence, the parameters c depend also
+    // on the partial pressure of component 2 and, thus, on the equilibrium
+    // pressure. Note that all coefficients are devided by 'p_adsorpt' to compensate
+    // the multiplication by 'p_adsorpt,' which is the partial derivative of the
+    // partial pressure of component 1 w.r.t. the equilibrium pressure.
+    //
+    Phi_available := c[3,1] - c[5,1] *
+      (1 - Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^ c[8,1]))
+      "Fraction of sites available for adsorption";
+    A_CO2 := (c[4,1] + (Phi_available - c[4,1]) *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)) / c[4,1]
+      "Enhancement factor of saturation uptake of CO2";
+
+    DH_avg := (1 - Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)) *
+      c[10,1] + Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) * c[11,1]
+      "Average isosteric heat of adsorption";
+    B_CO2 := c[9,1] * Modelica.Math.exp(-DH_avg / (Modelica.Constants.R * T_adsorpt))
+      "Toth coefficient";
+
+    dA_CO2_dx_adsorpt_H2O := c[6,1] * (Phi_available - c[4,1]) *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) / (c[4,1] * x_adsorpt_H2O^2)
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    uptake of H2O";
+    dA_CO2_dPhi_available := Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) / c[4,1]
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the fraction of sites available for adsorption";
+    dPhi_available_dx_adsorpt_H2O := - c[5,1] * c[8,1] * (c[7,1] * x_adsorpt_H2O) ^
+      c[8,1] * Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^ c[8,1]) / x_adsorpt_H2O
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    uptake of H2O";
+
+    dB_CO2_dH_avg := -B_CO2 / (Modelica.Constants.R * T_adsorpt)
+      "Partial derivative of Toth coefficient w.r.t. the average isosteric 
+    adsorption enthalpy";
+    dH_avg_dx_adsorpt_H20 := c[6,1] * (c[11,1] - c[10,1]) / x_adsorpt_H2O^2 *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    uptake of H2O";
+
+    dc_1_CO2_dp_adsorpt := c[1,1] * (dA_CO2_dx_adsorpt_H2O +
+      dA_CO2_dPhi_available * dPhi_available_dx_adsorpt_H2O) *
+      dx_adsorpt_dy_i[2,1] / p_adsorpt
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    dc_2_CO2_dp_adsorpt := dB_CO2_dH_avg * dH_avg_dx_adsorpt_H20 *
+      dx_adsorpt_dy_i[2,1] / p_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    dc_3_CO2_dp_adsorpt := 0 / p_adsorpt
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+
+    dx_adsorpt_dy_i[1, 1] := p_adsorpt*
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.dx_CO2_dp(
+        p_adsorpt=max(p_i[1], p_threshold_min),
+        T_adsorpt=T_adsorpt,
+        c={A_CO2 * c[1,1],
+           B_CO2,
+           c[2,1]},
+        dc_dp_adsorpt={dc_1_CO2_dp_adsorpt,
+                       dc_2_CO2_dp_adsorpt,
+                       dc_3_CO2_dp_adsorpt})
+     "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    independent mole fractions at constant pressure and temperature";
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "Mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real Phi_available(unit="1")
+      "Fraction of sites available for adsorption";
+    Real A_CO2(unit="1/Pa")
+      "Enhancement factor of saturation uptake of CO2";
+
+    Real DH_avg(unit="J/mol")
+      "Average isosteric heat of adsorption";
+    Real B_CO2(unit="1/Pa")
+      "Toth coefficient";
+
+    Real dA_CO2_dc4(unit="1/Pa")
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the fourth coefficient of the Toth isotherm";
+    Real dA_CO2_dc6(unit="kg/(Pa.kg)")
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the sixth coefficient of the Toth isotherm";
+    Real dA_CO2_dPhi_available(unit="1/Pa")
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the fraction of sites available for adsorption";
+    Real dA_CO2_dx_adsorpt_H2O(unit="kg/(Pa.kg)")
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    uptake of H2O";
+
+    Real dPhi_available_dc3(unit="1")
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    third coefficient of the Toth isotherm";
+    Real dPhi_available_dc5(unit="1")
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    fivth coefficient of the Toth isotherm";
+    Real dPhi_available_dc7(unit="kg/kg")
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    seventh coefficient of the Toth isotherm";
+    Real dPhi_available_dc8(unit="kg/kg")
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    eigth coefficient of the Toth isotherm";
+    Real dPhi_available_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    uptake of H2O";
+    Real dPhi_available_dT_adsorpt(unit="1/K")
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    equilibrium temperature";
+
+    Real dB_CO2_dc9(unit="1")
+      "Partial derivative of Toth coefficient w.r.t. the nith coefficient of the
+    Toth isotherm";
+    Real dB_CO2_dH_avg(unit="mol/(Pa.J)")
+      "Partial derivative of Toth coefficient w.r.t. the average isosteric 
+    adsorption enthalpy";
+    Real dB_CO2_dT_adsorpt(unit="1/(Pa.K)")
+      "Partial derivative of Toth coefficient w.r.t. the equilibrium temperature";
+
+    Real dH_avg_dc6(unit="J.kg/(mol.kg)")
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    sixth coefficient of the Toth isotherm";
+    Real dH_avg_dc10(unit="1")
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    tenth coefficient of the Toth isotherm";
+    Real dH_avg_dc11(unit="1")
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    eleventh coefficient of the Toth isotherm";
+    Real dH_avg_dx_adsorpt_H20(unit="J.kg/(mol.kg)")
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    uptake of H2O";
+    Real dH_avg_dT_adsorpt(unit="J/(mol.K)")
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    equilibrium temperature";
+
+    Real dc_1_CO2_dT_adsorpt
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+    Real dc_2_CO2_dT_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+    Real dc_3_CO2_dT_adsorpt
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the equilibrium temperature of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB.Internals.x_H20_pT(
+        p_i=p_i,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The existing derivative functions of the Toth and GAB isotherm models
+    // correspond to partial derivatives w.r.t. the equilibrium temperature. Again,
+    // the partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    dx_adsorpt_dT_adsorpt[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dT(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]},
+      dc_dT_adsorpt={dc_dT_adsorpt[1,2],
+                     dc_dT_adsorpt[2,2],
+                     dc_dT_adsorpt[3,2],
+                     dc_dT_adsorpt[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant pressure and mole fractions";
+
+    //
+    // Note that for component 1, the coefficients of the isotherm model are
+    // enhanced by the uptake of component 2. Hence, the parameter dc_dT cannot
+    // directly be passed to the existing derivative function of the Toth isotherm
+    // model. Instead, the the correct derivative must be calculated first.
+    //
+    Phi_available := c[3,1] - c[5,1] *
+      (1 - Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^ c[8,1]))
+      "Fraction of sites available for adsorption";
+    A_CO2 := (c[4,1] + (Phi_available - c[4,1]) *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)) / c[4,1]
+      "Enhancement factor of saturation uptake of CO2";
+
+    DH_avg := (1 - Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)) *
+      c[10,1] + Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) * c[11,1]
+      "Average isosteric heat of adsorption";
+    B_CO2 := c[9,1] * Modelica.Math.exp(-DH_avg / (Modelica.Constants.R * T_adsorpt))
+      "Toth coefficient";
+
+    dA_CO2_dc4 := -Phi_available * Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) /
+      c[4,1] ^ 2
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the fourth coefficient of the Toth isotherm";
+    dA_CO2_dc6 :=(c[4, 1] - Phi_available)*Modelica.Math.exp(-c[6, 1]/
+      x_adsorpt_H2O)/(c[4, 1]*x_adsorpt_H2O)
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the sixth coefficient of the Toth isotherm";
+    dA_CO2_dPhi_available := Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) / c[4,1]
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    the fraction of sites available for adsorption";
+    dA_CO2_dx_adsorpt_H2O := c[6,1] * (Phi_available - c[4,1]) *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) / (c[4,1] * x_adsorpt_H2O^2)
+      "Partial derivative of enhancement factor of saturation uptake of CO2 w.r.t.
+    uptake of H2O";
+
+    dPhi_available_dc3 := 1
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    third coefficient of the Toth isotherm";
+    dPhi_available_dc5 := Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^ c[8,1]) - 1
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    fivth coefficient of the Toth isotherm";
+    dPhi_available_dc7 := - c[5,1] * c[8,1] * (c[7,1] * x_adsorpt_H2O) ^
+      c[8,1] * Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^ c[8,1]) / c[7,1]
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    seventh coefficient of the Toth isotherm";
+    dPhi_available_dc8 :=  c[5,1] * (c[7,1] * x_adsorpt_H2O) ^ c[8,1] *
+      log(c[7,1] * x_adsorpt_H2O) * Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^
+      c[8,1])
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    eigth coefficient of the Toth isotherm";
+    dPhi_available_dx_adsorpt_H2O := - c[5,1] * c[8,1] * (c[7,1] * x_adsorpt_H2O) ^
+      c[8,1] * Modelica.Math.exp(-(c[7,1] * x_adsorpt_H2O) ^ c[8,1]) / x_adsorpt_H2O
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    uptake of H2O";
+    dPhi_available_dT_adsorpt := dPhi_available_dc3 * dc_dT_adsorpt[3,1] +
+      dPhi_available_dc5 * dc_dT_adsorpt[5,1] +
+      dPhi_available_dc7 * dc_dT_adsorpt[7,1] +
+      dPhi_available_dc8 * dc_dT_adsorpt[8,1] +
+      dPhi_available_dx_adsorpt_H2O * dx_adsorpt_dT_adsorpt[2]
+      "Partial derivative of fraction of sites available for adsorption w.r.t. the
+    equilibrium temperature";
+
+    dB_CO2_dc9 := Modelica.Math.exp(-DH_avg / (Modelica.Constants.R * T_adsorpt))
+      "Partial derivative of Toth coefficient w.r.t. the nith coefficient of the
+    Toth isotherm";
+    dB_CO2_dH_avg := -B_CO2 / (Modelica.Constants.R * T_adsorpt)
+      "Partial derivative of Toth coefficient w.r.t. the average isosteric 
+    adsorption enthalpy";
+    dB_CO2_dT_adsorpt := B_CO2 * DH_avg / (Modelica.Constants.R * T_adsorpt^2)
+      "Partial derivative of Toth coefficient w.r.t. the equilibrium temperature";
+
+    dH_avg_dc6 := -(c[11,1] - c[10,1]) *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O) / x_adsorpt_H2O
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    sixth coefficient of the Toth isotherm";
+    dH_avg_dc10 := 1 - Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    tenth coefficient of the Toth isotherm";
+    dH_avg_dc11 :=  Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    eleventh coefficient of the Toth isotherm";
+    dH_avg_dx_adsorpt_H20 := c[6,1] * (c[11,1] - c[10,1]) / x_adsorpt_H2O^2 *
+      Modelica.Math.exp(-c[6,1] / x_adsorpt_H2O)
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    uptake of H2O";
+    dH_avg_dT_adsorpt := dH_avg_dc6 * dc_dT_adsorpt[6,1] +
+      dH_avg_dc10 * dc_dT_adsorpt[10,1] +
+      dH_avg_dc11 * dc_dT_adsorpt[11,1] +
+      dH_avg_dx_adsorpt_H20 * dx_adsorpt_dT_adsorpt[2]
+      "Partial derivative of average isosteric heat of adsorption w.r.t. the
+    equilibrium temperature";
+
+    dc_1_CO2_dT_adsorpt := A_CO2 * dc_dT_adsorpt[1,1] + c[1,1] * (
+      dA_CO2_dc4 * dc_dT_adsorpt[4,1] +
+      dA_CO2_dc6 * dc_dT_adsorpt[6,1] +
+      dA_CO2_dPhi_available * dPhi_available_dT_adsorpt +
+      dA_CO2_dx_adsorpt_H2O * dx_adsorpt_dT_adsorpt[2])
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+    dc_2_CO2_dT_adsorpt := dB_CO2_dc9 * dc_dT_adsorpt[9,1] +
+      dB_CO2_dH_avg * dH_avg_dT_adsorpt +
+      dB_CO2_dT_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+    dc_3_CO2_dT_adsorpt := dc_dT_adsorpt[2,1]
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+
+    dx_adsorpt_dT_adsorpt[1] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={A_CO2 * c[1,1],
+         B_CO2,
+         c[2,1]},
+      dc_dT_adsorpt={dc_1_CO2_dT_adsorpt,
+                     dc_2_CO2_dT_adsorpt,
+                     dc_3_CO2_dT_adsorpt})
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  Adaptations (e.g., object-orientied approach) due to restructuring the library
+  and documentation.
+  </li>
+  <li>
+  November, 2023, by Daniel Rezo:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The mechanistic Toth-GAB isotherm model calculates equilibrium uptakes <i>x_adsorpt</i> 
+of CO<sub>2</sub> and H<sub>2</sub>O on amine-functionalized sorbents as a function 
+of the equilibrium pressure <i>p_adsorpt</i>, mole fractions of independent 
+components in the gas or vapor phase <i>y_i</i>, and the equilibrium temperature 
+<i>T_adsorpt</i>. The model was developed by Young et al. (2021) for modeling of 
+direct air capture systems. A mechanistic Toth isotherm model describes  the 
+uptake of CO<sub>2</sub>, while a GAB isotherm model describes the uptake of 
+H<sub>2</sub>O.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The mechanistic Toth isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt,CO<sub>2</sub></sub> = A<sub>CO<sub>2</sub></sub>(x<sub>adsorpt,H<sub>2</sub>O</sub>) * x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) * B<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>, x<sub>adsorpt,H<sub>2</sub>O</sub>) * p<sub>adsorpt,CO<sub>2</sub></sub> / ((1 + (B<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>, x<sub>adsorpt,H<sub>2</sub>O</sub>) * p<sub>adsorpt,CO<sub>2</sub></sub>) ^ t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)) ^ (1/t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+with:
+</p>
+<pre>
+    A<sub>CO<sub>2</sub></sub>(x<sub>adsorpt,H<sub>2</sub>O</sub>) = (&Phi;<sub>dry</sub> + (&Phi;<sub>available</sub>(x<sub>adsorpt,H<sub>2</sub>O</sub>) - &Phi;<sub>dry</sub>) * <strong>exp</strong>(-C<sub>CO<sub>2</sub></sub> / x<sub>adsorpt,H<sub>2</sub>O</sub>)) / &Phi;<sub>dry</sub>;
+</pre>
+<pre>
+    &Phi;<sub>available</sub>(x<sub>adsorpt,H<sub>2</sub>O</sub>) = &Phi;<sub>max</sub> - f<sub>blocked</sub> = &Phi;<sub>max</sub> - f<sub>blocked,max</sub> * (1 - <strong>exp</strong>(-(k<sub>CO<sub>2</sub></sub> * x<sub>adsorpt,H<sub>2</sub>O</sub>) ^ n<sub>CO<sub>2</sub></sub>));
+</pre>
+<pre>
+    B<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>, x<sub>adsorpt,H<sub>2</sub>O</sub>) = b<sub>ref,CO<sub>2</sub></sub> * <strong>exp</strong>(-&Delta;H<sub>avg</sub></sub>(x<sub>adsorpt,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<pre>
+    &Delta;H<sub>avg</sub>(x<sub>adsorpt,H<sub>2</sub>O</sub>) = (1 - <strong>exp</strong>(-C<sub>CO<sub>2</sub></sub> / x<sub>adsorpt,H<sub>2</sub>O</sub>)) * &Delta;H<sub>dry</sub> + <strong>exp</strong>(-C<sub>CO<sub>2</sub></sub> / x<sub>adsorpt,H<sub>2</sub>O</sub>) * &Delta;H<sub>wet</sub>;
+</pre>
+<p>
+Herein, <i>x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> is the saturation 
+uptake, <i>B<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>, x<sub>adsorpt,H<sub>2</sub>O</sub>)</i> 
+is the Toth coefficient, and <i>t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> is 
+the Toth exponent. The coefficient <i>A<sub>CO<sub>2</sub></sub></i> describes the 
+enhancement of CO<sub>2</sub> uptake due to the presence of H<sub>2</sub>O (i.e., 
+H<sub>2</sub>O uptake). The coefficient A<sub>CO<sub>2</sub></sub> depends on the 
+fraction of sites available for adsorption <i>&Phi;<sub>available</sub></i>, the amine 
+efficiency under dry conditions <i>&Phi;<sub>dry</sub></i>, the critical water loading 
+<i>C<sub>CO<sub>2</sub></sub></i>, the maximal possible amine efficiency <i>&Phi;<sub>max</sub></i>, 
+the fraction of blocked adsorption sites <i>f<sub>blocked</sub></i>, the maximal fraction 
+of blocked adsorption sites <i>f<sub>blocked,max</sub></i> as well as the two parameters 
+<i>k<sub>CO<sub>2</sub></sub></i> and <i>n<sub>CO<sub>2</sub></sub></i>. The Toth coefficient 
+<i>B<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub></i> depends on the Toth coefficient
+<i>b<sub>ref,CO<sub>2</sub></sub></i> at reference temperature <i>T<sub>ref,CO<sub>2</sub></sub></i> 
+and the average isosteric adsorption enthalpy <i>&Delta;H<sub>avg</sub>(x<sub>adsorpt,H<sub>2</sub>O</sub>)</i>.
+The latter depends on the isosteric adsorption under dry conditions <i>&Delta;H<sub>dry</sub></i> 
+and wet conditions <i>&Delta;H<sub>wet</sub></i>. Typical temperature dependencies of the 
+saturation uptake <i>x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> and the Toth 
+coefficient <i>t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> may have the following 
+forms:
+</p>
+<pre>
+    x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) = x<sub>ref,CO<sub>2</sub></sub> * <strong>exp</strong>(&Chi;<sub>CO<sub>2</sub></sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,CO<sub>2</sub></sub>));
+</pre>
+<pre>
+    t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) = t<sub>ref,CO<sub>2</sub></sub> + &alpha;<sub>CO<sub>2</sub></sub> * (1 - T<sub>ref,CO<sub>2</sub></sub>/T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>ref,CO<sub>2</sub></sub></i> is the saturation uptake at reference 
+temperature <i>T<sub>ref,CO<sub>2</sub></sub></i> and <i>t<sub>ref,CO<sub>2</sub></sub></i> 
+is the Toth exponent at reference temperature. The parameter <i>&Chi;<sub>CO<sub>2</sub></sub></i> 
+describes the change of the saturation uptake with temperature, and the parameter 
+<i>&alpha;<sub>CO<sub>2</sub></sub></i> describes the change of the Toth exponent 
+with temperature.
+<br/>
+<p>
+The GAB isotherm model has the following form:
+</p>
+</p>
+<pre>
+    x<sub>adsorpt,H<sub>2</sub>O</sub> = x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) / ((1 - k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)) * (1 + (c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) - 1) * k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+with
+</p>
+<pre>
+    &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = p<sub>adsorpt</sub>/p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> is the monolayer 
+uptake and <i>c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> and 
+<i>k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> are affinity coefficients of 
+the GAB isotherm model. These three parameters can be modeled independent of temperature. 
+When assuming these three parameters to be dependent on temperature, typical temperature 
+dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) =  x<sub>mon,ref,H<sub>2</sub>O</sub> * <strong>exp</strong>(&Chi;<sub>H<sub>2</sub>O</sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,H<sub>2</sub>O</sub>));
+</pre>
+<pre>
+    c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>1,H<sub>2</sub>O</sub> - E<sub>10+,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<pre>
+    k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>2-9,H<sub>2</sub>O</sub> - E<sub>10+,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    E<sub>1,H<sub>2</sub>O</sub> = C<sub>H<sub>2</sub>O</sub> - <strong>exp</strong>(D<sub>H<sub>2</sub>O</sub> * T<sub>adsorpt</sub>);
+</pre>
+<pre>
+    E<sub>2-9,H<sub>2</sub>O</sub> = F<sub>H<sub>2</sub>O</sub> + G<sub>H<sub>2</sub>O</sub> * T<sub>adsorpt</sub>;
+</pre>
+<pre>
+    E<sub>10+,H<sub>2</sub>O</sub> = &Delta;h<sub>vap,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>mon,ref,H<sub>2</sub>O</sub></i> is the monolayer uptake at reference 
+temperature <i>T<sub>ref,H<sub>2</sub>O</sub></i> and  <i>&Chi;<sub>H<sub>2</sub>O</sub></i> 
+describes the change of the monolayer uptake with temperature. The coefficient 
+<i>E<sub>1,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption of the first layer 
+and <i>E<sub>2-9,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption of layers 
+2-9: These enthalpies of adsorption can be modeled temperature-dependent as shown 
+in the example above, with the four fitting parameters <i>C<sub>H<sub>2</sub>O</sub></i>, 
+<i>D<sub>H<sub>2</sub>O</sub></i>, <i>E<sub>H<sub>2</sub>O</sub></i>, and <i>F<sub>H<sub>2</sub>O</sub></i>. 
+The coefficient <i>E<sub>10+,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption 
+for layer 10 or higher layers and is assumed to correspond to the temperature-dependent 
+enthalpy of vaporization <i>&Delta;h<sub>vap,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i>.
+</p>
+
+<h4>Required parameter order in function input c[:,no_components]:</h4>
+<p>
+For component 1 (i.e., CO<sub>2</sub>), the required parameter order in the function 
+input <i>c</i> is as follows:
+</p>
+<ul>
+  <li>
+  c[1,1] = x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2,1] = t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[3,1] = &Phi;<sub>max</sub> in -
+  </li>
+  <li>
+  c[4,1] = &Phi;<sub>dry</sub> in -
+  </li>
+  <li>
+  c[5,1] = f<sub>blocked,max</sub> in -
+  </li>
+  <li>
+  c[6,1] = C<sub>CO<sub>2</sub></sub> in kg/kg
+  </li>
+  <li>
+  c[7,1] = k<sub>CO<sub>2</sub></sub> in kg/kg
+  </li>
+  <li>
+  c[8,1] = n<sub>CO<sub>2</sub></sub> in -
+  </li>
+  <li>
+  c[9,1] = b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[10,1] = &Delta;H<sub>dry</sub> in J/mol
+  </li>
+  <li>
+  c[11,1] = &Delta;H<sub>wet</sub> in J/mol
+  </li>
+</ul>
+<p>
+For component 2 (i.e., H<sub>2</sub>0), the required parameter order in the function 
+input <i>c</i> is as follows:
+</p>
+<ul>
+  <li>
+  c[1,2] = p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2,2] = x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[3,2] = c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[4,2] = k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[5,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[6,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[7,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[8,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[9,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[10,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[11,2] = 0 (i.e., not required)
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the mechanistic Toth-GAB isotherm model for one parameter set. 
+In the upper sub-figure, the equilibrium pressure changes with time. In the centre 
+sub-figure, the independent mole fractions change with time. In the lower sub-figure, 
+the equilibrium temperature changes with time. The left side shows the uptake of 
+component 1 (i.e., CO<sub>2</sub>), and the right side shows the uptake of component 
+2 (i.e., H<sub>2</sub>0). 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_mechanistic_toth_gab.png\" alt=\"media_functions_equilibria_multi_mechanistic_toth_gab.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  <li>
+  Young, J. and Garc&iacute;a-D&iacute;ez, E. and Garcia, S. and van der Spek, M. (2021). The impact of binary water–CO<sub>2</sub> isotherm models on the optimal performance of sorbent-based direct air capture processes, Energy & Environmental Science, 14:5377. DOI: http://doi.org/10.1039/d1ee01272j.
+  </li>
+</ul>
+</html>"));
+end MechanisticTothGAB;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/MechanisticTothGAB/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/calc_p_i_num_i_den.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/calc_p_i_num_i_den.mo
new file mode 100644
index 0000000..44fdab0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/calc_p_i_num_i_den.mo
@@ -0,0 +1,71 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals;
+function calc_p_i_num_i_den
+  "Extended Sips isotherm model: Corrected partial pressures, numerators, denominator of the isotherm model"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real[:,:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_threshold_min = 0
+    "Threshold for partial pressures of all components: If a partial pressure is
+    below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i_regulated
+    "Regulated equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real[size(c,2)] num_i
+    "Individual numerator for each component of the isotherm model"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real den
+    "Identical denominator for each component of the isotherm model"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  den := 1
+    "Start value of the denominator";
+
+  for ind_comp in 1:size(c,2) loop
+    p_i_regulated[ind_comp] := max(p_i[ind_comp], p_threshold_min)
+      "Limiter of partial pressures to increase numerical stability";
+
+    num_i[ind_comp] := c[1,ind_comp] * (c[2,ind_comp] *
+      p_i_regulated[ind_comp]) ^ (1/c[3,ind_comp])
+      "Individual numerators";
+
+    den := den + (c[2,ind_comp] * p_i_regulated[ind_comp]) ^ (1/c[3,ind_comp])
+      "Identical denominator";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function regulates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) so that they are equal or greater than <i>p_threshold_min</i>. Further,
+this function calculates the numerators <i>num_i</i> and denominator <i>den</i>
+of the extended Sips isotherm model. For full details of the extended Sips
+isotherm mode, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end calc_p_i_num_i_den;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/p_i_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/p_i_xT.mo
new file mode 100644
index 0000000..ead11ad
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/p_i_xT.mo
@@ -0,0 +1,75 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals;
+function p_i_xT
+  "Extended Sips isotherm model: Partial pressures as function of uptakes and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(c,2), size(c,2)] A
+    "Matrix A of A*z = -x_adsorpt";
+  Real[size(c,2)] z
+    "Vector z of A*z = -x_adsorpt (i.e., z = first substitution)";
+
+algorithm
+  //
+  // Set up matrix A and solve system of linear equations:
+  //
+  // To calculate the invesere function of the extended Sips isotherm regarding
+  // the equilibrium pressure and mole fractions of the independent components of
+  // the gas or vapor phase, the term ' (c[2,ind] * p_i[ind]) ^ (1/c[3,ind])' is
+  // substituted by 'z.' Thus, a system of linear equations is created that can
+  // be solved. Re-substitution allows to calculate partial pressures p_i and,
+  // thus, the equilibrium pressure and mole fractions.
+  //
+  for ind in 1:size(c,2) loop
+    A[ind,:] := fill(x_adsorpt[ind], size(c,2))
+      "First, fill row with correct uptake";
+    A[ind,ind] := x_adsorpt[ind] - c[1,ind]
+      "Second, correct diagonale";
+  end for;
+
+  z := Modelica.Math.Matrices.solve(A, -1 .* x_adsorpt)
+    "Third, solve the system of linear equations";
+
+  for ind in 1:size(c,2) loop
+    p_i[ind] := max(z[ind] ^ c[3,ind] / c[2,ind], p_threshold_min)
+      "Re-substituate values and consider threshold if necessary";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) as function of the equilibrium uptakes <i>x_adsorpt</i> and the 
+equilibrium temperature <i>T_adsorpt</i>. Thus, this function is a inverse of the 
+function 'x_pyT.' For full details of the original function 'x_pyT,' check the 
+documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end p_i_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/package.mo
new file mode 100644
index 0000000..23df589
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the extended Sips isotherm
+model. Thus, redundancy of code shall be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/package.order
new file mode 100644
index 0000000..e5d8b7b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/Internals/package.order
@@ -0,0 +1,2 @@
+calc_p_i_num_i_den
+p_i_xT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/package.mo
new file mode 100644
index 0000000..191be0f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/package.mo
@@ -0,0 +1,405 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package Sips "Package containing all functions regarding the extended Sips isotherm"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponents;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "Extended Sips isotherm model: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real den
+      "Identical denominator for each component of the isotherm model";
+
+  algorithm
+    (p_i, num_i, den) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals.calc_p_i_num_i_den(
+      p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    x_adsorpt := num_i ./ den
+      "Calculate equilibrium uptakes of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "Extended Sips isotherm model: Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals.p_i_xT(
+        x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+        "Partial pressures";
+
+    p_adsorpt := sum(p_i)
+      "Equilibrium pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "Extended Sips isotherm model: Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals.p_i_xT(
+       x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+       "Partial pressures";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / max(p_adsorpt, p_threshold_min)
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "Extended Sips isotherm model: Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals.p_i_xT(
+       x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+       "Partial pressures";
+
+    p_adsorpt := max(sum(p_i), p_threshold_min)
+      "Equilibrium pressure";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / p_adsorpt
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "Extended Sips isotherm model: Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real den
+      "Identical denominator for each component of the isotherm model";
+
+    Real[size(c,2)] dnum_i_dp_adsorpt
+      "Partial derivatives of the numerators w.r.t. the equilibrium pressure";
+    Real dden_dp_adsorpt
+      "Partial derivative of the denominator w.r.t. the equilbrium pressure";
+
+  algorithm
+    (p_i, num_i, den) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals.calc_p_i_num_i_den(
+      p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives
+    //
+    dden_dp_adsorpt := 0
+      "Start value of the derivative of the denominator w.r.t. equilbrium pressure";
+
+    for ind_comp in 1:size(c,2) loop
+      dnum_i_dp_adsorpt[ind_comp] := num_i[ind_comp] /
+        (c[3,ind_comp] * p_i[ind_comp]) * y_i_[ind_comp]
+        "Partial derivatives of numerators w.r.t. equilibrium pressure";
+
+      dden_dp_adsorpt := dden_dp_adsorpt + (c[2,ind_comp] * p_i[ind_comp]) ^
+        (1/c[3,ind_comp]) / (c[3,ind_comp] * p_i[ind_comp]) * y_i_[ind_comp]
+        "Partial derivative of denominator w.r.t. equilibrium pressure";
+    end for;
+
+    //
+    // Calculate derivatives of loadings w.r.t. equilibrium pressure
+    //
+    dx_adsorpt_dp_adsorpt :=
+      (dnum_i_dp_adsorpt.* den .- num_i.* dden_dp_adsorpt) ./ den^2
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "Extended Sips isotherm model: Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real den
+      "Identical denominator for each component of the isotherm model";
+
+    Real[size(c,2),size(c,2)-1] dnum_i_dy_i
+      "Partial derivatives of the numerators w.r.t. the mole fractions of independent 
+    gas phase components";
+    Real[size(c,2)-1] dden_dy_i
+      "Partial derivative of the denominator w.r.t. the mole fractions of independent 
+    gas phase components";
+
+  algorithm
+    (p_i, num_i, den) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals.calc_p_i_num_i_den(
+      p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives of numerators, which varies with components and
+    // mole fractions of independent components
+    //
+    dnum_i_dy_i:=zeros(size(c,2),size(c,2)-1)
+      "Partial derivatives of the numerators w.r.t. the mole fractions of independent 
+    gas phase components";
+
+    for ind_comp in 1:size(c,2) loop
+      if ind_comp < size(c,2) then
+        // Partial derivatives of independent components
+        //
+        dnum_i_dy_i[ind_comp,ind_comp] := num_i[ind_comp] /
+          (c[3,ind_comp] * p_i[ind_comp]) * p_adsorpt
+          "Partial derivatives of numerators w.r.t. the mole fractions of independent 
+        gas phase components";
+
+      else
+        // Partial derivatives of dependent component
+        //
+        for ind_y_i in 1:size(c,2)-1 loop
+          dnum_i_dy_i[ind_comp,ind_y_i] :=  num_i[ind_comp] /
+          (c[3,ind_comp] * p_i[ind_comp]) * (-p_adsorpt)
+          "Partial derivatives of numerators w.r.t. the mole fractions of independent 
+        gas phase components";
+
+        end for;
+      end if;
+    end for;
+
+    //
+    // Calculate partial derivatives of the denominator, which varies with components and
+    // mole fractions of independent components
+    //
+    dden_dy_i:=zeros(size(c, 2) - 1)
+      "Partial derivative of the denominator w.r.t. the mole fractions of independent 
+    gas phase components";
+
+    for ind_y_i in 1:size(c,2)-1 loop
+      dden_dy_i[ind_y_i] := dden_dy_i[ind_y_i] +
+        (c[2,ind_y_i] * p_i[ind_y_i]) ^ (1/c[3,ind_y_i]) /
+        (c[3,ind_y_i] * p_i[ind_y_i]) * p_adsorpt +
+        (c[2,size(c,2)] * p_i[size(c,2)]) ^ (1/c[3,size(c,2)]) /
+        (c[3,size(c,2)] * p_i[size(c,2)]) * (-p_adsorpt)
+        "Partial derivative of the denominator w.r.t. the mole fractions of independent 
+      gas phase components";
+    end for;
+
+    //
+    // Calculate partial derivatives of uptakes w.r.t. mole fractions of independent
+    // gas phase components
+    //
+    for ind_comp in 1:size(c,2) loop
+      for ind_y_i in 1:size(c,2)-1 loop
+        dx_adsorpt_dy_i[ind_comp,ind_y_i] :=
+          (dnum_i_dy_i[ind_comp,ind_y_i] * den -
+          num_i[ind_comp] * dden_dy_i[ind_y_i]) ./ den^2
+          "Partial derivatives of the uptakes w.r.t. the mole fractions of independent 
+        gas phase components at constant pressure and temperature";
+      end for;
+    end for;
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "Extended Sips isotherm model: Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real den
+      "Identical denominator for each component of the isotherm model";
+
+    Real[size(c,2)] dnum_i_dT_adsorpt
+      "Derivatives of the numerators w.r.t. the equilibrium temperature";
+    Real dden_dT_adsorpt
+      "Derivative of the denominator w.r.t. the equilbrium temperature";
+
+  algorithm
+    (p_i, num_i, den) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips.Internals.calc_p_i_num_i_den(
+      p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives
+    //
+    dden_dT_adsorpt := 0
+      "Start value of the derivative of the denominator w.r.t. equilbrium pressure";
+
+    for ind_comp in 1:size(c,2) loop
+      dnum_i_dT_adsorpt[ind_comp] :=
+        (num_i[ind_comp] / c[1,ind_comp]) * dc_dT_adsorpt[1,ind_comp] +
+        (num_i[ind_comp] / (c[2,ind_comp] * c[3,ind_comp])) *
+        dc_dT_adsorpt[2,ind_comp] +
+        (-num_i[ind_comp] * log(c[2,ind_comp] *p_i[ind_comp]) / c[3,ind_comp]^2) *
+        dc_dT_adsorpt[3,ind_comp]
+        "Derivatives of numerators w.r.t. equilibrium temperature";
+
+      dden_dT_adsorpt := dden_dT_adsorpt +
+        ((c[2,ind_comp] * p_i[ind_comp]) ^ (1/c[3,ind_comp]) /
+        (c[2,ind_comp] * c[3,ind_comp])) * dc_dT_adsorpt[2,ind_comp] +
+        (-(c[2,ind_comp] * p_i[ind_comp]) ^ (1/c[3,ind_comp]) *
+        log(c[2,ind_comp] * p_i[ind_comp]) / c[3,ind_comp]^2) *
+        dc_dT_adsorpt[3,ind_comp]
+        "Derivative of denominator w.r.t. equilibrium temperature";
+    end for;
+
+    //
+    // Calculate derivatives of uptakes wrt. total pressure
+    //
+    dx_adsorpt_dT_adsorpt :=
+      (dnum_i_dT_adsorpt.* den .- num_i.* dden_dT_adsorpt) ./ den^2
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The extended Sips isotherm model calculates equilibrium uptakes <i>x_adsorpt</i>
+as a function of the equilibrium pressure <i>p_adsorpt</i>, mole fractions of
+independent components in the gas or vapor phase <i>y_i</i>, and the equilibrium
+temperature <i>T_adsorpt</i>. Each component of the extended Sips isotherm model
+has three parameters.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The extended Sips isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt,<i>i</i></sub> = x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) * (b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,<i>i</i></sub>) ^ (1/n<sub><i>i</i></sub>(T<sub>adsorpt</sub>)) / (1 + &sum;[(b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,<i>i</i></sub>) ^ (1/n<sub><i>i</i></sub>(T<sub>adsorpt</sub>))]);
+</pre>
+<p>
+where <i>x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>)</i> is the saturation uptake
+of component <i>i</i>, <i>b<sub><i>i</i></sub>(T<sub>adsorpt</sub>)</i> is the Sips 
+coefficient of component <i>i</i>, and <i>n<sub><i>i</i></sub>(T<sub>adsorpt</sub>)</i>
+is the Sips exponent of component <i>i</i>. Typical temperature dependencies may 
+have the following forms:
+</p>
+<pre>
+    x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) =  x<sub>ref,<i>i</i></sub> * <strong>exp</strong>(&Chi;<sub><i>i</i></sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,<i>i</i></sub>));
+</pre>
+<pre>
+    b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) = b<sub>ref,<i>i</i></sub> * <strong>exp</strong>(Q<sub><i>i</i></sub>/(R * T<sub>ref,<i>i</i></sub>) * (T<sub>ref,<i>i</i></sub>/T<sub>adsorpt</sub> - 1));
+</pre>
+<pre>
+    n<sub><i>i</i></sub>(T<sub>adsorpt</sub>) = (1/n<sub>ref,<i>i</i></sub> + &alpha;<sub><i>i</i></sub> * (1 - T<sub>ref,<i>i</i></sub>/T<sub>adsorpt</sub>)) ^ (-1);
+</pre>
+<p>
+Herein, for each component <i>i</i>, <i>x<sub>ref,<i>i</i></sub></i> is the saturation 
+uptake at reference temperature <i>T<sub>ref,<i>i</i></sub></i>, <i>b<sub>ref,<i>i</i></sub></i> 
+is the Sips coefficient at reference temperature, and <i>n<sub>ref,<i>i</i></sub></i> 
+is the Sips exponent at reference temperature. The parameter <i>Q<sub><i>i</i></sub></i> 
+is a measure for the isosteric adsorption enthalpy at a fractional loading of 
+<i>x<sub>adsorpt,<i>i</i></sub>/x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) = 0.5</i>, 
+the parameter <i>&Chi;<sub><i>i</i></sub></i> describes the change of the saturation 
+uptake with temperature, and the parameter <i>&alpha;<sub><i>i</i></sub></i> describes 
+the change of the Sips exponent with temperature. All seven parameters can be used as 
+fitting parameters.
+<br/><br/>
+Note that the Sips exponent <i>n,<i>i</i>(T<sub>adsorpt</sub>)</i> is typically greater 
+than unity. For <i>n,<i>i</i>(T<sub>adsorpt</sub>) = 1</i>, the Sips isotherm becomes 
+the Langmuir isotherm. Hence, the Sips exponent <i>n,<i>i</i>(T<sub>adsorpt</sub>)</i> 
+can be interpreted as a parameter describing the heterogeneity of the adsorption system. 
+</p>
+
+<h4>Required parameter order in function input c[:,no_components]:</h4>
+<p>
+For each component <i>i</i>, the required parameter order in the function input <i>c</i>
+is as follows:
+</p>
+<ul>
+  <li>
+  c[1,<i>i</i>] = x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2,<i>i</i>] = b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[3,<i>i</i>] = n<sub><i>i</i></sub>(T<sub>adsorpt</sub>) in -
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  No proper Henry law behavior.
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the extended Sips isotherm model for one parameter set
+and two components. In the upper sub-figure, the equilibrium pressure changes with 
+time. In the centre sub-figure, the independent mole fractions change with time.
+In the lower sub-figure, the equilibrium temperature changes with time. The left
+side shows the uptake of component 1, and the right side shows the uptake of
+component 2. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_sips.png\" alt=\"media_functions_equilibria_multi_sips.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Amrutha and Jeppu, G. and Girish, C.R. and Prabhu, B., and Mayer, K. (2023). Multi-component Adsorption Isotherms: Review and Modeling Studies, Environmental Processes, 10:38. DOI: https://doi.org/10.1007/s40710-023-00631-0.
+  </li>
+</ul>
+</html>"));
+end Sips;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Sips/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_everything.mo
new file mode 100644
index 0000000..ce8097f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_everything.mo
@@ -0,0 +1,140 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.IAST_N2;
+model Test_changing_everything
+  "Tester for all functions of the IAST for two components: Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters of component 1
+  //
+  parameter SorpLib.Units.Uptake[2] a0_1 = {1.468 * 0.04401, 7.891 * 0.04401}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_1(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_1(each unit="1/Pa") = {0.024e-6, 0.001645e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_1(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2
+  //
+  parameter SorpLib.Units.Uptake[2] a0_2 = {2.847 * 0.044097, 2.223 * 0.044097}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_2(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_2(each unit="1/Pa") = {0.028e-6, 1.228e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_2(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST_N2(
+    final p_adsorpt_der=10000,
+    final y_i_der={-0.9/100},
+    final T_adsorpt_der=80/100,
+    final p_adsorpt_start=100,
+    final y_i_start={0.95},
+    final T_adsorpt_start=293.15,
+    final no_components=2,
+    final M_i={0.04401,0.044097},
+    final no_coefficients_1=4,
+    final no_coefficients_2=4,
+    redeclare final package IsothermModelComponent1 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent2 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    num(IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson),
+    num_comp_1(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_2(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2));
+
+equation
+  //
+  // Coefficients of the isotherm model of component 1
+  //
+  c_1[1] = a0_1[1] + a1_1[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_1[3] = a0_1[2] + a1_1[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 2
+  //
+  c_2[1] = a0_2[1] + a1_2[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_2[3] = a0_2[2] + a1_2[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the IAST for two components.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..b68100b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_mole_fractions.mo
@@ -0,0 +1,140 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.IAST_N2;
+model Test_changing_mole_fractions
+  "Tester for all functions of the IAST for two components: Changing independent mole fractions"
+
+  //
+  // Definition of parameters of component 1
+  //
+  parameter SorpLib.Units.Uptake[2] a0_1 = {1.468 * 0.04401, 7.891 * 0.04401}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_1(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_1(each unit="1/Pa") = {0.024e-6, 0.001645e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_1(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2
+  //
+  parameter SorpLib.Units.Uptake[2] a0_2 = {2.847 * 0.044097, 2.223 * 0.044097}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_2(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_2(each unit="1/Pa") = {0.028e-6, 1.228e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_2(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST_N2(
+    final p_adsorpt_der=0,
+    final y_i_der={-0.98/100},
+    final T_adsorpt_der=0,
+    final p_adsorpt_start=100000,
+    final y_i_start={0.99},
+    final T_adsorpt_start=293.15,
+    final no_components=2,
+    final M_i={0.04401,0.044097},
+    final no_coefficients_1=4,
+    final no_coefficients_2=4,
+    redeclare final package IsothermModelComponent1 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent2 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    num(IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson),
+    num_comp_1(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_2(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2));
+
+equation
+  //
+  // Coefficients of the isotherm model of component 1
+  //
+  c_1[1] = a0_1[1] + a1_1[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_1[3] = a0_1[2] + a1_1[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 2
+  //
+  c_2[1] = a0_2[1] + a1_2[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_2[3] = a0_2[2] + a1_2[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the IAST for two components.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>p_adsorpt</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).   
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_pressure.mo
new file mode 100644
index 0000000..36b267d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_pressure.mo
@@ -0,0 +1,139 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.IAST_N2;
+model Test_changing_pressure
+  "Tester for all functions of the IAST for two components: Changing pressure"
+
+  //
+  // Definition of parameters of component 1
+  //
+  parameter SorpLib.Units.Uptake[2] a0_1 = {1.468 * 0.04401, 7.891 * 0.04401}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_1(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_1(each unit="1/Pa") = {0.024e-6, 0.001645e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_1(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2
+  //
+  parameter SorpLib.Units.Uptake[2] a0_2 = {2.847 * 0.044097, 2.223 * 0.044097}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_2(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_2(each unit="1/Pa") = {0.028e-6, 1.228e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_2(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST_N2(
+    final p_adsorpt_der=10000,
+    final y_i_der={0},
+    final T_adsorpt_der=0,
+    final p_adsorpt_start=100,
+    final y_i_start={0.5},
+    final T_adsorpt_start=293.15,
+    final no_components=2,
+    final M_i={0.04401,0.044097},
+    final no_coefficients_1=4,
+    final no_coefficients_2=4,
+    redeclare final package IsothermModelComponent1 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent2 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    num(IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson),
+    num_comp_1(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_2(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2));
+
+equation
+  //
+  // Coefficients of the isotherm model of component 1
+  //
+  c_1[1] = a0_1[1] + a1_1[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_1[3] = a0_1[2] + a1_1[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 2
+  //
+  c_2[1] = a0_2[1] + a1_2[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_2[3] = a0_2[2] + a1_2[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the IAST for two components.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).   
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_temperature.mo
new file mode 100644
index 0000000..2937cca
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/Test_changing_temperature.mo
@@ -0,0 +1,139 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.IAST_N2;
+model Test_changing_temperature
+  "Tester for all functions of the IAST for two components: Changing temperature"
+
+  //
+  // Definition of parameters of component 1
+  //
+  parameter SorpLib.Units.Uptake[2] a0_1 = {1.468 * 0.04401, 7.891 * 0.04401}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_1(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_1(each unit="1/Pa") = {0.024e-6, 0.001645e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_1(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2
+  //
+  parameter SorpLib.Units.Uptake[2] a0_2 = {2.847 * 0.044097, 2.223 * 0.044097}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_2(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_2(each unit="1/Pa") = {0.028e-6, 1.228e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_2(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST_N2(
+    final p_adsorpt_der=0,
+    final y_i_der={0},
+    final T_adsorpt_der=80/100,
+    final p_adsorpt_start=1000,
+    final y_i_start={0.5},
+    final T_adsorpt_start=293.15,
+    final no_components=2,
+    final M_i={0.04401,0.044097},
+    final no_coefficients_1=4,
+    final no_coefficients_2=4,
+    redeclare final package IsothermModelComponent1 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent2 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    num(IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson),
+    num_comp_1(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_2(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2));
+
+equation
+  //
+  // Coefficients of the isotherm model of component 1
+  //
+  c_1[1] = a0_1[1] + a1_1[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_1[3] = a0_1[2] + a1_1[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 2
+  //
+  c_2[1] = a0_2[1] + a1_2[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_2[3] = a0_2[2] + a1_2[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the IAST for two components.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/package.mo
new file mode 100644
index 0000000..a28962f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package IAST_N2 "Models ot test and varify functions of the IAST for two components"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the IAST for two 
+components. The test models check the implementation of the functions and enable 
+verification of the function behavior. Four test models are implemented, in which the 
+pressure, mole fractions of independent components in the gas or vapor phase, and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IAST_N2;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N2/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_everything.mo
new file mode 100644
index 0000000..c4ec172
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_everything.mo
@@ -0,0 +1,190 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.IAST_N3;
+model Test_changing_everything
+  "Tester for all functions of the IAST for three components: Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters of component 1
+  //
+  parameter SorpLib.Units.Uptake[2] a0_1 = {1.468 * 0.04401, 7.891 * 0.04401}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_1(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_1(each unit="1/Pa") = {0.024e-6, 0.001645e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_1(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2
+  //
+  parameter SorpLib.Units.Uptake[2] a0_2 = {2.847 * 0.044097, 2.223 * 0.044097}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_2(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_2(each unit="1/Pa") = {0.028e-6, 1.228e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_2(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 3
+  //
+  parameter SorpLib.Units.Uptake[2] a0_3 = {2.581 * 0.042081, 2.901 * 0.042081}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_3(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_3(each unit="1/Pa") = {0.84e-6, 0.021e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_3(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST_N3(
+    final p_adsorpt_der=10000,
+    final y_i_der={-0.9/100,0.9/100/2},
+    final T_adsorpt_der=80/100,
+    final p_adsorpt_start=100,
+    final y_i_start={0.95,0.025},
+    final T_adsorpt_start=293.15,
+    final no_components=3,
+    final M_i={0.04401,0.044097,0.042081},
+    final no_coefficients_1=4,
+    final no_coefficients_2=4,
+    final no_coefficients_3=4,
+    redeclare final package IsothermModelComponent1 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent2 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent3 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    num(IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson),
+    num_comp_1(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_2(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_3(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2));
+
+equation
+  //
+  // Coefficients of the isotherm model of component 1
+  //
+  c_1[1] = a0_1[1] + a1_1[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_1[3] = a0_1[2] + a1_1[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 2
+  //
+  c_2[1] = a0_2[1] + a1_2[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_2[3] = a0_2[2] + a1_2[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 3
+  //
+  c_3[1] = a0_3[1] + a1_3[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_3[3] = a0_3[2] + a1_3[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_3[1] = a0_3[1] + a1_3[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_3[3] = a0_3[2] + a1_3[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_3[1] = a0_3[1] + a1_3[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_3[3] = a0_3[2] + a1_3[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the IAST for three components.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..7c2ea9f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_mole_fractions.mo
@@ -0,0 +1,190 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.IAST_N3;
+model Test_changing_mole_fractions
+  "Tester for all functions of the IAST for three components: Changing independent mole fractions"
+
+  //
+  // Definition of parameters of component 1
+  //
+  parameter SorpLib.Units.Uptake[2] a0_1 = {1.468 * 0.04401, 7.891 * 0.04401}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_1(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_1(each unit="1/Pa") = {0.024e-6, 0.001645e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_1(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2
+  //
+  parameter SorpLib.Units.Uptake[2] a0_2 = {2.847 * 0.044097, 2.223 * 0.044097}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_2(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_2(each unit="1/Pa") = {0.028e-6, 1.228e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_2(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 3
+  //
+  parameter SorpLib.Units.Uptake[2] a0_3 = {2.581 * 0.042081, 2.901 * 0.042081}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_3(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_3(each unit="1/Pa") = {0.84e-6, 0.021e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_3(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST_N3(
+    final p_adsorpt_der=0,
+    final y_i_der={-0.97/100,0.97/100/2},
+    final T_adsorpt_der=0,
+    final p_adsorpt_start=100000,
+    final y_i_start={0.98,0.01},
+    final T_adsorpt_start=293.15,
+    final no_components=3,
+    final M_i={0.04401,0.044097,0.042081},
+    final no_coefficients_1=4,
+    final no_coefficients_2=4,
+    final no_coefficients_3=4,
+    redeclare final package IsothermModelComponent1 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent2 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent3 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    num(IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson),
+    num_comp_1(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_2(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_3(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2));
+
+equation
+  //
+  // Coefficients of the isotherm model of component 1
+  //
+  c_1[1] = a0_1[1] + a1_1[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_1[3] = a0_1[2] + a1_1[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 2
+  //
+  c_2[1] = a0_2[1] + a1_2[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_2[3] = a0_2[2] + a1_2[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 3
+  //
+  c_3[1] = a0_3[1] + a1_3[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_3[3] = a0_3[2] + a1_3[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_3[1] = a0_3[1] + a1_3[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_3[3] = a0_3[2] + a1_3[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_3[1] = a0_3[1] + a1_3[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_3[3] = a0_3[2] + a1_3[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the IAST for three components.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>y_i</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).   
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_pressure.mo
new file mode 100644
index 0000000..f3a0b81
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_pressure.mo
@@ -0,0 +1,189 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.IAST_N3;
+model Test_changing_pressure
+  "Tester for all functions of the IAST for three components: Changing pressure"
+
+  //
+  // Definition of parameters of component 1
+  //
+  parameter SorpLib.Units.Uptake[2] a0_1 = {1.468 * 0.04401, 7.891 * 0.04401}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_1(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_1(each unit="1/Pa") = {0.024e-6, 0.001645e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_1(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2
+  //
+  parameter SorpLib.Units.Uptake[2] a0_2 = {2.847 * 0.044097, 2.223 * 0.044097}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_2(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_2(each unit="1/Pa") = {0.028e-6, 1.228e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_2(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 3
+  //
+  parameter SorpLib.Units.Uptake[2] a0_3 = {2.581 * 0.042081, 2.901 * 0.042081}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_3(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_3(each unit="1/Pa") = {0.84e-6, 0.021e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_3(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST_N3(
+    final p_adsorpt_der=10000,
+    final y_i_der={0,0},
+    final T_adsorpt_der=0,
+    final p_adsorpt_start=100,
+    final y_i_start={0.5,0.25},
+    final T_adsorpt_start=293.15,
+    final no_components=3,
+    final M_i={0.04401,0.044097,0.042081},
+    final no_coefficients_1=4,
+    final no_coefficients_2=4,
+    final no_coefficients_3=4,
+    redeclare final package IsothermModelComponent1 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent2 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent3 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    num(IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson),
+    num_comp_1(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_2(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_3(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2));
+
+equation
+  //
+  // Coefficients of the isotherm model of component 1
+  //
+  c_1[1] = a0_1[1] + a1_1[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_1[3] = a0_1[2] + a1_1[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 2
+  //
+  c_2[1] = a0_2[1] + a1_2[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_2[3] = a0_2[2] + a1_2[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 3
+  //
+  c_3[1] = a0_3[1] + a1_3[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_3[3] = a0_3[2] + a1_3[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_3[1] = a0_3[1] + a1_3[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_3[3] = a0_3[2] + a1_3[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_3[1] = a0_3[1] + a1_3[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_3[3] = a0_3[2] + a1_3[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the IAST for three components.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).   
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_temperature.mo
new file mode 100644
index 0000000..70b936f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/Test_changing_temperature.mo
@@ -0,0 +1,189 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.IAST_N3;
+model Test_changing_temperature
+  "Tester for all functions of the IAST for three components: Changing temperature"
+
+  //
+  // Definition of parameters of component 1
+  //
+  parameter SorpLib.Units.Uptake[2] a0_1 = {1.468 * 0.04401, 7.891 * 0.04401}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_1(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_1(each unit="1/Pa") = {0.024e-6, 0.001645e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_1(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2
+  //
+  parameter SorpLib.Units.Uptake[2] a0_2 = {2.847 * 0.044097, 2.223 * 0.044097}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_2(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_2(each unit="1/Pa") = {0.028e-6, 1.228e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_2(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 3
+  //
+  parameter SorpLib.Units.Uptake[2] a0_3 = {2.581 * 0.042081, 2.901 * 0.042081}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] a1_3(each unit="kg.K/kg") = {-1e-2, -1e-2}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] b0_3(each unit="1/Pa") = {0.84e-6, 0.021e-6}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[2] Delta_H_ads_3(each unit="J/mol") =  {-2e4, -2e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMultiIAST_N3(
+    final p_adsorpt_der=0,
+    final y_i_der={0,0},
+    final T_adsorpt_der=80/100,
+    final p_adsorpt_start=1000,
+    final y_i_start={0.5,0.25},
+    final T_adsorpt_start=293.15,
+    final no_components=3,
+    final M_i={0.04401,0.044097,0.042081},
+    final no_coefficients_1=4,
+    final no_coefficients_2=4,
+    final no_coefficients_3=4,
+    redeclare final package IsothermModelComponent1 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent2 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    redeclare final package IsothermModelComponent3 =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    num(IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson),
+    num_comp_1(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_2(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2),
+    num_comp_3(tolerance_p_adsorpt=1e-6, tolerance_pi=1e-2));
+
+equation
+  //
+  // Coefficients of the isotherm model of component 1
+  //
+  c_1[1] = a0_1[1] + a1_1[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_1[3] = a0_1[2] + a1_1[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_1[1] = a0_1[1] + a1_1[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[2] = b0_1[1]*exp(-Delta_H_ads_1[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_1[3] = a0_1[2] + a1_1[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_1[4] = b0_1[2]*exp(-Delta_H_ads_1[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 2
+  //
+  c_2[1] = a0_2[1] + a1_2[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_2[3] = a0_2[2] + a1_2[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_2[1] = a0_2[1] + a1_2[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[2] = b0_2[1]*exp(-Delta_H_ads_2[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_2[3] = a0_2[2] + a1_2[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_2[4] = b0_2[2]*exp(-Delta_H_ads_2[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Coefficients of the isotherm model of component 3
+  //
+  c_3[1] = a0_3[1] + a1_3[1] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+  c_3[3] = a0_3[2] + a1_3[2] / T_adsorpt
+    "Coefficients of isotherm model";
+  c_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * T_adsorpt))
+    "Coefficients of isotherm model";
+
+  c_pdT_3[1] = a0_3[1] + a1_3[1] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+  c_pdT_3[3] = a0_3[2] + a1_3[2] / (T_adsorpt+dT)
+    "Coefficients of isotherm model";
+  c_pdT_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Coefficients of isotherm model";
+
+  c_mdT_3[1] = a0_3[1] + a1_3[1] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_3[2] = b0_3[1]*exp(-Delta_H_ads_3[1] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+  c_mdT_3[3] = a0_3[2] + a1_3[2] / (T_adsorpt-dT)
+    "Coefficients of isotherm model";
+  c_mdT_3[4] = b0_3[2]*exp(-Delta_H_ads_3[2] / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Coefficients of isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 14, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the IAST for three components.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>T_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/package.mo
new file mode 100644
index 0000000..a9e52d0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package IAST_N3 "Models ot test and varify functions of the IAST for two components"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the IAST for three 
+components. The test models check the implementation of the functions and enable 
+verification of the function behavior. Four test models are implemented, in which the 
+pressure, mole fractions of independent components in the gas or vapor phase, and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IAST_N3;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/IAST_N3/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_everything.mo
new file mode 100644
index 0000000..51dc313
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_everything.mo
@@ -0,0 +1,98 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Langmuir;
+model Test_changing_everything
+  "Tester for all functions of the extended Langmuir isotherm model: Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] a0 = {0.35, 0.25, 0.15}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] a1(each unit="kg.K/kg") = {1e-4, 1e-4, 1e-4}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b0(each unit="1/Pa") = {5e-8, 5e-8, 5e-8}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Delta_H_ads(each unit="J/mol") =  {-2e4, -3e4, -1e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 1400,
+    final y_i_der = {0.97/100/3*2,0.97/100/3*1},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 1,
+    final y_i_start = {1e-2,1e-2},
+    final T_adsorpt_start = 298.15,
+    final no_components = 3,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/T_adsorpt
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -a1[ind_comp]/T_adsorpt^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = Delta_H_ads[ind_comp]/(Modelica.Constants.R*T_adsorpt^2) *
+      c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/(T_adsorpt+dT)
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*(T_adsorpt+dT)))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/(T_adsorpt-dT)
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*(T_adsorpt-dT)))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Langmuir isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..543e50b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_mole_fractions.mo
@@ -0,0 +1,99 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Langmuir;
+model Test_changing_mole_fractions
+  "Tester for all functions of the extended Langmuir isotherm model: Changing independent mole fractions"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] a0 = {0.35, 0.25}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] a1(each unit="kg.K/kg") = {1e-4, 1e-4}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b0(each unit="1/Pa") = {5e-8, 5e-8}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Delta_H_ads(each unit="J/mol") =  {-2e4, -3e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0.98/100},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 10000,
+    final y_i_start = {1e-2},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir,
+    p_threshold_min = 0);
+
+equation
+
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/T_adsorpt
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -a1[ind_comp]/T_adsorpt^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = Delta_H_ads[ind_comp]/(Modelica.Constants.R*T_adsorpt^2) *
+      c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/(T_adsorpt+dT)
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*(T_adsorpt+dT)))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/(T_adsorpt-dT)
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*(T_adsorpt-dT)))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Langmuir isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>p_adsorpt</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_pressure.mo
new file mode 100644
index 0000000..765cad5
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_pressure.mo
@@ -0,0 +1,97 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Langmuir;
+model Test_changing_pressure
+  "Tester for all functions of the extended Langmuir isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] a0 = {0.35, 0.25}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] a1(each unit="kg.K/kg") = {1e-4, 1e-4}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b0(each unit="1/Pa") = {5e-8, 5e-8}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Delta_H_ads(each unit="J/mol") =  {-2e4, -3e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 100,
+    final y_i_der = {0},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final y_i_start = {0.5},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/T_adsorpt
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -a1[ind_comp]/T_adsorpt^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = Delta_H_ads[ind_comp]/(Modelica.Constants.R*T_adsorpt^2) *
+      c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/(T_adsorpt+dT)
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*(T_adsorpt+dT)))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/(T_adsorpt-dT)
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*(T_adsorpt-dT)))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Langmuir isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_temperature.mo
new file mode 100644
index 0000000..d7c5c92
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/Test_changing_temperature.mo
@@ -0,0 +1,97 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Langmuir;
+model Test_changing_temperature
+  "Tester for all functions of the extended Langmuir isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] a0 = {0.35, 0.25}
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] a1(each unit="kg.K/kg") = {1e-4, 1e-4}
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b0(each unit="1/Pa") = {5e-8, 5e-8}
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Delta_H_ads(each unit="J/mol") =  {-2e4, -3e4}
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 10000,
+    final y_i_start = {0.5},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Langmuir,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/T_adsorpt
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -a1[ind_comp]/T_adsorpt^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = Delta_H_ads[ind_comp]/(Modelica.Constants.R*T_adsorpt^2) *
+      c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/(T_adsorpt+dT)
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*(T_adsorpt+dT)))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = a0[ind_comp] + a1[ind_comp]/(T_adsorpt-dT)
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b0[ind_comp]*exp(-Delta_H_ads[ind_comp]/
+      (Modelica.Constants.R*(T_adsorpt-dT)))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 7, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Langmuir isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/package.mo
new file mode 100644
index 0000000..9e414e4
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package Langmuir "Models ot test and varify functions of the extended Langmuir isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the extended Langmuir 
+isotherm model. The test models check the implementation of the functions and enable 
+verification of the function behavior. Four test models are implemented, in which the 
+pressure, mole fractions of independent components in the gas or vapor phase, and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Langmuir;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Langmuir/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_everything.mo
new file mode 100644
index 0000000..e1d3856
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_everything.mo
@@ -0,0 +1,321 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.MechanisticTothGAB;
+model Test_changing_everything
+  "Tester for all functions of the mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 4.86 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.209
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = 0.5823
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 2.85e-21
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_dry_CO2(unit="J/mol") = -117798
+    "Parameter describing the isosteric enthalpy of adsorption under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_wet_CO2(unit="J/mol") = -130155
+    "Parameter describing the isosteric enthalpy of adsorption under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Phi_max(unit="1") = 1
+    "Maximal possible amine efficiency"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Phi_dry(unit="1") = 1
+    "Amine efficiency under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real f_blocked_max(unit="1") = 0.433
+    "Maximal fraction of blocked adsorption sited"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_CO2(unit="kg/kg") = 1.535 * 0.018015267
+    "Critical water uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_CO2(unit="kg/kg") = 0.795 / 0.018015267
+    "First parameter describing change of fraction of blocked adsorption sites"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n_CO2(unit="1") = 1.425
+    "Second parameter describing change of fraction of blocked adsorption sites"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 3.63 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_H2O(unit="J/mol") = 47110
+    "First parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D_H2O(unit="1/K") = 0.023744
+    "Second parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F_H2O(unit="J/mol") = 57706
+    "First parameter of the adsorption enthalpy of the layers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G_H2O(unit="J/(mol.K)") = -47.814
+    "Second parameter of the adsorption enthalpy of the ayers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I_H2O(unit="J/mol") = 57220
+    "First parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real J_H2O(unit="J/(mol.K)") = -44.38
+    "Second parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = (1e5-12349)/100,
+    final y_i_der = {0},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 1,
+    final y_i_start = {1-0.5*12349/1e5},
+    final T_adsorpt_start = 273.15+25,
+    final no_components = 2,
+    final no_coefficients = 11,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = Phi_max + 1e-6 * (T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = Phi_dry + 1e-6 * (T_adsorpt)
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = f_blocked_max + 1e-6 * (T_adsorpt)
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = C_CO2 + 1e-6 * (T_adsorpt)
+    "Sixth coefficient of the Toth isotherm model";
+  c[7,1] = k_CO2 + 1e-6 * (T_adsorpt)
+    "Seventh coefficient of the Toth isotherm model";
+  c[8,1] = n_CO2 + 1e-6 * (T_adsorpt)
+    "Eigth coefficient of the Toth isotherm model";
+  c[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt)
+    "Ninth coefficient of the Toth isotherm model";
+  c[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt)
+    "Tenth coefficient of the Toth isotherm model";
+  c[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * T_adsorpt)) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * T_adsorpt) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2 / T_ref_CO2 * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = 1e-6
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 1e-6
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 1e-6
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = 1e-6
+    "Sixth coefficient of the Toth isotherm model";
+  dc_dT[7,1] = 1e-6
+    "Seventh coefficient of the Toth isotherm model";
+  dc_dT[8,1] = 1e-6
+    "Eigth coefficient of the Toth isotherm model";
+  dc_dT[9,1] = 1e-6
+    "Ninth coefficient of the Toth isotherm model";
+  dc_dT[10,1] = 1e-6
+    "Tenth coefficient of the Toth isotherm model";
+  dc_dT[11,1] = 1e-6
+    "Eleventh coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -((D_H2O*T_adsorpt - 1) * exp(D_H2O*T_adsorpt) - I_H2O + C_H2O) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = (I_H2O - F_H2O) / (Modelica.Constants.R*T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  dc_dT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  dc_dT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  dc_dT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  dc_dT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  dc_dT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = Phi_max + 1e-6 * (T_adsorpt+dT)
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = Phi_dry + 1e-6 * (T_adsorpt+dT)
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = f_blocked_max + 1e-6 * (T_adsorpt+dT)
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = C_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Sixth coefficient of the Toth isotherm model";
+  c_pdT[7,1] = k_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Seventh coefficient of the Toth isotherm model";
+  c_pdT[8,1] = n_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Eigth coefficient of the Toth isotherm model";
+  c_pdT[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Ninth coefficient of the Toth isotherm model";
+  c_pdT[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Tenth coefficient of the Toth isotherm model";
+  c_pdT[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt+dT))) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt+dT)) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_pdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c_pdT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c_pdT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c_pdT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c_pdT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = Phi_max + 1e-6 * (T_adsorpt-dT)
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = Phi_dry + 1e-6 * (T_adsorpt-dT)
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = f_blocked_max + 1e-6 * (T_adsorpt-dT)
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = C_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Sixth coefficient of the Toth isotherm model";
+  c_mdT[7,1] = k_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Seventh coefficient of the Toth isotherm model";
+  c_mdT[8,1] = n_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Eigth coefficient of the Toth isotherm model";
+  c_mdT[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Ninth coefficient of the Toth isotherm model";
+  c_mdT[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Tenth coefficient of the Toth isotherm model";
+  c_mdT[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt-dT))) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt-dT)) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_mdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c_mdT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c_mdT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c_mdT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c_mdT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the mechanistic Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..8004724
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_mole_fractions.mo
@@ -0,0 +1,321 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.MechanisticTothGAB;
+model Test_changing_mole_fractions
+  "Tester for all functions of the mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Changing independent mole fractions"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 4.86 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.209
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = 0.5823
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 2.85e-21
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_dry_CO2(unit="J/mol") = -117798
+    "Parameter describing the isosteric enthalpy of adsorption under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_wet_CO2(unit="J/mol") = -130155
+    "Parameter describing the isosteric enthalpy of adsorption under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Phi_max(unit="1") = 1
+    "Maximal possible amine efficiency"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Phi_dry(unit="1") = 1
+    "Amine efficiency under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real f_blocked_max(unit="1") = 0.433
+    "Maximal fraction of blocked adsorption sited"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_CO2(unit="kg/kg") = 1.535 * 0.018015267
+    "Critical water uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_CO2(unit="kg/kg") = 0.795 / 0.018015267
+    "First parameter describing change of fraction of blocked adsorption sites"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n_CO2(unit="1") = 1.425
+    "Second parameter describing change of fraction of blocked adsorption sites"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 3.63 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_H2O(unit="J/mol") = 47110
+    "First parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D_H2O(unit="1/K") = 0.023744
+    "Second parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F_H2O(unit="J/mol") = 57706
+    "First parameter of the adsorption enthalpy of the layers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G_H2O(unit="J/(mol.K)") = -47.814
+    "Second parameter of the adsorption enthalpy of the ayers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I_H2O(unit="J/mol") = 57220
+    "First parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real J_H2O(unit="J/(mol.K)") = -44.38
+    "Second parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0.96/100},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 25000,
+    final y_i_start = {0.02},
+    final T_adsorpt_start = 273.15+75,
+    final no_components = 2,
+    final no_coefficients = 11,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = Phi_max + 1e-6 * (T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = Phi_dry + 1e-6 * (T_adsorpt)
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = f_blocked_max + 1e-6 * (T_adsorpt)
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = C_CO2 + 1e-6 * (T_adsorpt)
+    "Sixth coefficient of the Toth isotherm model";
+  c[7,1] = k_CO2 + 1e-6 * (T_adsorpt)
+    "Seventh coefficient of the Toth isotherm model";
+  c[8,1] = n_CO2 + 1e-6 * (T_adsorpt)
+    "Eigth coefficient of the Toth isotherm model";
+  c[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt)
+    "Ninth coefficient of the Toth isotherm model";
+  c[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt)
+    "Tenth coefficient of the Toth isotherm model";
+  c[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * T_adsorpt)) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * T_adsorpt) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2 / T_ref_CO2 * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = 1e-6
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 1e-6
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 1e-6
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = 1e-6
+    "Sixth coefficient of the Toth isotherm model";
+  dc_dT[7,1] = 1e-6
+    "Seventh coefficient of the Toth isotherm model";
+  dc_dT[8,1] = 1e-6
+    "Eigth coefficient of the Toth isotherm model";
+  dc_dT[9,1] = 1e-6
+    "Ninth coefficient of the Toth isotherm model";
+  dc_dT[10,1] = 1e-6
+    "Tenth coefficient of the Toth isotherm model";
+  dc_dT[11,1] = 1e-6
+    "Eleventh coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -((D_H2O*T_adsorpt - 1) * exp(D_H2O*T_adsorpt) - I_H2O + C_H2O) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = (I_H2O - F_H2O) / (Modelica.Constants.R*T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  dc_dT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  dc_dT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  dc_dT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  dc_dT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  dc_dT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = Phi_max + 1e-6 * (T_adsorpt+dT)
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = Phi_dry + 1e-6 * (T_adsorpt+dT)
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = f_blocked_max + 1e-6 * (T_adsorpt+dT)
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = C_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Sixth coefficient of the Toth isotherm model";
+  c_pdT[7,1] = k_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Seventh coefficient of the Toth isotherm model";
+  c_pdT[8,1] = n_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Eigth coefficient of the Toth isotherm model";
+  c_pdT[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Ninth coefficient of the Toth isotherm model";
+  c_pdT[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Tenth coefficient of the Toth isotherm model";
+  c_pdT[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt+dT))) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt+dT)) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_pdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c_pdT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c_pdT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c_pdT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c_pdT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = Phi_max + 1e-6 * (T_adsorpt-dT)
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = Phi_dry + 1e-6 * (T_adsorpt-dT)
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = f_blocked_max + 1e-6 * (T_adsorpt-dT)
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = C_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Sixth coefficient of the Toth isotherm model";
+  c_mdT[7,1] = k_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Seventh coefficient of the Toth isotherm model";
+  c_mdT[8,1] = n_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Eigth coefficient of the Toth isotherm model";
+  c_mdT[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Ninth coefficient of the Toth isotherm model";
+  c_mdT[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Tenth coefficient of the Toth isotherm model";
+  c_mdT[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt-dT))) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt-dT)) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_mdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c_mdT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c_mdT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c_mdT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c_mdT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the mechanistic Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>p_adsorpt</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_pressure.mo
new file mode 100644
index 0000000..0303dd2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_pressure.mo
@@ -0,0 +1,320 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.MechanisticTothGAB;
+model Test_changing_pressure
+  "Tester for all functions of the mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Changing pressure"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 4.86 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.209
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = 0.5823
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 2.85e-21
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_dry_CO2(unit="J/mol") = -117798
+    "Parameter describing the isosteric enthalpy of adsorption under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_wet_CO2(unit="J/mol") = -130155
+    "Parameter describing the isosteric enthalpy of adsorption under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Phi_max(unit="1") = 1
+    "Maximal possible amine efficiency"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Phi_dry(unit="1") = 1
+    "Amine efficiency under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real f_blocked_max(unit="1") = 0.433
+    "Maximal fraction of blocked adsorption sited"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_CO2(unit="kg/kg") = 1.535 * 0.018015267
+    "Critical water uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_CO2(unit="kg/kg") = 0.795 / 0.018015267
+    "First parameter describing change of fraction of blocked adsorption sites"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n_CO2(unit="1") = 1.425
+    "Second parameter describing change of fraction of blocked adsorption sites"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 3.63 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_H2O(unit="J/mol") = 47110
+    "First parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D_H2O(unit="1/K") = 0.023744
+    "Second parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F_H2O(unit="J/mol") = 57706
+    "First parameter of the adsorption enthalpy of the layers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G_H2O(unit="J/(mol.K)") = -47.814
+    "Second parameter of the adsorption enthalpy of the ayers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I_H2O(unit="J/mol") = 57220
+    "First parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real J_H2O(unit="J/(mol.K)") = -44.38
+    "Second parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = (0.6e5-12349)/100,
+    final y_i_der = {0},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 12349,
+    final y_i_start = {1-0.5*12349/0.6e5},
+    final T_adsorpt_start = 273.15+50,
+    final no_components = 2,
+    final no_coefficients = 11,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = Phi_max + 1e-6 * (T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = Phi_dry + 1e-6 * (T_adsorpt)
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = f_blocked_max + 1e-6 * (T_adsorpt)
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = C_CO2 + 1e-6 * (T_adsorpt)
+    "Sixth coefficient of the Toth isotherm model";
+  c[7,1] = k_CO2 + 1e-6 * (T_adsorpt)
+    "Seventh coefficient of the Toth isotherm model";
+  c[8,1] = n_CO2 + 1e-6 * (T_adsorpt)
+    "Eigth coefficient of the Toth isotherm model";
+  c[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt)
+    "Ninth coefficient of the Toth isotherm model";
+  c[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt)
+    "Tenth coefficient of the Toth isotherm model";
+  c[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * T_adsorpt)) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * T_adsorpt) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2 / T_ref_CO2 * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = 1e-6
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 1e-6
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 1e-6
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = 1e-6
+    "Sixth coefficient of the Toth isotherm model";
+  dc_dT[7,1] = 1e-6
+    "Seventh coefficient of the Toth isotherm model";
+  dc_dT[8,1] = 1e-6
+    "Eigth coefficient of the Toth isotherm model";
+  dc_dT[9,1] = 1e-6
+    "Ninth coefficient of the Toth isotherm model";
+  dc_dT[10,1] = 1e-6
+    "Tenth coefficient of the Toth isotherm model";
+  dc_dT[11,1] = 1e-6
+    "Eleventh coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -((D_H2O*T_adsorpt - 1) * exp(D_H2O*T_adsorpt) - I_H2O + C_H2O) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = (I_H2O - F_H2O) / (Modelica.Constants.R*T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  dc_dT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  dc_dT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  dc_dT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  dc_dT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  dc_dT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = Phi_max + 1e-6 * (T_adsorpt+dT)
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = Phi_dry + 1e-6 * (T_adsorpt+dT)
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = f_blocked_max + 1e-6 * (T_adsorpt+dT)
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = C_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Sixth coefficient of the Toth isotherm model";
+  c_pdT[7,1] = k_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Seventh coefficient of the Toth isotherm model";
+  c_pdT[8,1] = n_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Eigth coefficient of the Toth isotherm model";
+  c_pdT[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Ninth coefficient of the Toth isotherm model";
+  c_pdT[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Tenth coefficient of the Toth isotherm model";
+  c_pdT[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt+dT))) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt+dT)) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_pdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c_pdT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c_pdT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c_pdT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c_pdT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = Phi_max + 1e-6 * (T_adsorpt-dT)
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = Phi_dry + 1e-6 * (T_adsorpt-dT)
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = f_blocked_max + 1e-6 * (T_adsorpt-dT)
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = C_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Sixth coefficient of the Toth isotherm model";
+  c_mdT[7,1] = k_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Seventh coefficient of the Toth isotherm model";
+  c_mdT[8,1] = n_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Eigth coefficient of the Toth isotherm model";
+  c_mdT[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Ninth coefficient of the Toth isotherm model";
+  c_mdT[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Tenth coefficient of the Toth isotherm model";
+  c_mdT[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt-dT))) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt-dT)) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_mdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c_mdT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c_mdT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c_mdT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c_mdT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the mechanistic Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_temperature.mo
new file mode 100644
index 0000000..4aaf2e3
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/Test_changing_temperature.mo
@@ -0,0 +1,320 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.MechanisticTothGAB;
+model Test_changing_temperature
+  "Tester for all functions of the mechanistic Toth-GAB isotherm model developed by Young et al. (2021): Changing temperature"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 4.86 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.209
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = 0.5823
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 2.85e-21
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_dry_CO2(unit="J/mol") = -117798
+    "Parameter describing the isosteric enthalpy of adsorption under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_wet_CO2(unit="J/mol") = -130155
+    "Parameter describing the isosteric enthalpy of adsorption under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Phi_max(unit="1") = 1
+    "Maximal possible amine efficiency"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Phi_dry(unit="1") = 1
+    "Amine efficiency under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real f_blocked_max(unit="1") = 0.433
+    "Maximal fraction of blocked adsorption sited"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_CO2(unit="kg/kg") = 1.535 * 0.018015267
+    "Critical water uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_CO2(unit="kg/kg") = 0.795 / 0.018015267
+    "First parameter describing change of fraction of blocked adsorption sites"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n_CO2(unit="1") = 1.425
+    "Second parameter describing change of fraction of blocked adsorption sites"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 3.63 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_H2O(unit="J/mol") = 47110
+    "First parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D_H2O(unit="1/K") = 0.023744
+    "Second parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F_H2O(unit="J/mol") = 57706
+    "First parameter of the adsorption enthalpy of the layers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G_H2O(unit="J/(mol.K)") = -47.814
+    "Second parameter of the adsorption enthalpy of the ayers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I_H2O(unit="J/mol") = 57220
+    "First parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real J_H2O(unit="J/(mol.K)") = -44.38
+    "Second parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0},
+    final T_adsorpt_der = 50/100,
+    final p_adsorpt_start = 0.6e5,
+    final y_i_start = {1-0.5*12349/0.6e5},
+    final T_adsorpt_start = 273.15+50,
+    final no_components = 2,
+    final no_coefficients = 11,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.MechanisticTothGAB,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = Phi_max + 1e-6 * (T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = Phi_dry + 1e-6 * (T_adsorpt)
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = f_blocked_max + 1e-6 * (T_adsorpt)
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = C_CO2 + 1e-6 * (T_adsorpt)
+    "Sixth coefficient of the Toth isotherm model";
+  c[7,1] = k_CO2 + 1e-6 * (T_adsorpt)
+    "Seventh coefficient of the Toth isotherm model";
+  c[8,1] = n_CO2 + 1e-6 * (T_adsorpt)
+    "Eigth coefficient of the Toth isotherm model";
+  c[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt)
+    "Ninth coefficient of the Toth isotherm model";
+  c[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt)
+    "Tenth coefficient of the Toth isotherm model";
+  c[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * T_adsorpt)) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * T_adsorpt) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2 / T_ref_CO2 * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = 1e-6
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 1e-6
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 1e-6
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = 1e-6
+    "Sixth coefficient of the Toth isotherm model";
+  dc_dT[7,1] = 1e-6
+    "Seventh coefficient of the Toth isotherm model";
+  dc_dT[8,1] = 1e-6
+    "Eigth coefficient of the Toth isotherm model";
+  dc_dT[9,1] = 1e-6
+    "Ninth coefficient of the Toth isotherm model";
+  dc_dT[10,1] = 1e-6
+    "Tenth coefficient of the Toth isotherm model";
+  dc_dT[11,1] = 1e-6
+    "Eleventh coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -((D_H2O*T_adsorpt - 1) * exp(D_H2O*T_adsorpt) - I_H2O + C_H2O) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = (I_H2O - F_H2O) / (Modelica.Constants.R*T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  dc_dT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  dc_dT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  dc_dT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  dc_dT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  dc_dT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = Phi_max + 1e-6 * (T_adsorpt+dT)
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = Phi_dry + 1e-6 * (T_adsorpt+dT)
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = f_blocked_max + 1e-6 * (T_adsorpt+dT)
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = C_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Sixth coefficient of the Toth isotherm model";
+  c_pdT[7,1] = k_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Seventh coefficient of the Toth isotherm model";
+  c_pdT[8,1] = n_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Eigth coefficient of the Toth isotherm model";
+  c_pdT[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Ninth coefficient of the Toth isotherm model";
+  c_pdT[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Tenth coefficient of the Toth isotherm model";
+  c_pdT[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt+dT)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt+dT))) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt+dT)) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_pdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c_pdT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c_pdT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c_pdT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c_pdT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = Phi_max + 1e-6 * (T_adsorpt-dT)
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = Phi_dry + 1e-6 * (T_adsorpt-dT)
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = f_blocked_max + 1e-6 * (T_adsorpt-dT)
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = C_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Sixth coefficient of the Toth isotherm model";
+  c_mdT[7,1] = k_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Seventh coefficient of the Toth isotherm model";
+  c_mdT[8,1] = n_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Eigth coefficient of the Toth isotherm model";
+  c_mdT[9,1] = b_ref_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Ninth coefficient of the Toth isotherm model";
+  c_mdT[10,1] = DH_dry_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Tenth coefficient of the Toth isotherm model";
+  c_mdT[11,1] = DH_wet_CO2 + 1e-6 * (T_adsorpt-dT)
+    "Eleventh coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt-dT))) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt-dT)) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_mdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+  c_mdT[8,2] = 0
+    "Eigth coefficient of the GAB isotherm model";
+  c_mdT[9,2] = 0
+    "Ninth coefficient of the GAB isotherm model";
+  c_mdT[10,2] = 0
+    "Tenth coefficient of the GAB isotherm model";
+  c_mdT[11,2] = 0
+    "Eleventh coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 1, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the mechanistic Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/package.mo
new file mode 100644
index 0000000..1f8af96
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package MechanisticTothGAB "Models to test and varify functions of the mechanistic Toth-GAB isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the mechanistic Toth-GAB
+isotherm model. The test models check the implementation of the functions and enable 
+verification of the function behavior. Four test models are implemented, in which the 
+pressure, mole fractions of independent components in the gas or vapor phase, and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end MechanisticTothGAB;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/MechanisticTothGAB/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_everything.mo
new file mode 100644
index 0000000..61011bf
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_everything.mo
@@ -0,0 +1,121 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Sips;
+model Test_changing_everything
+  "Tester for all functions of the extended Sips isotherm model: Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.32, 0.22, 0.11}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1, 0.2}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {1.075e-4, 1.075e-4, 1.075e-4}
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Q(each unit="J/mol") = {28.752e3, 28.752e3, 28.752e3}
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] n_ref(each unit="1") = {2.312, 2.812, 2.812}
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] alpha(each unit="1") = {0.5559, 0.5559, 0.5559}
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 1400,
+    final y_i_der = {0.97/100/3*2, 0.97/100/3*1},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 1,
+    final y_i_start = {1e-2, 1e-2},
+    final T_adsorpt_start = 298.15,
+    final no_components = 3,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = -T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2 /
+      (1/n_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt))^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt+dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt+dT) - 1))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt+dT)))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt-dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt-dT) - 1))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt-dT)))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Sips isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..c3af008
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_mole_fractions.mo
@@ -0,0 +1,121 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Sips;
+model Test_changing_mole_fractions
+  "Tester for all functions of the extended Sips isotherm model: Changing independent mole fractions"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.32, 0.22}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {1.075e-4, 1.075e-4}
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Q(each unit="J/mol") = {28.752e3, 28.752e3}
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] n_ref(each unit="1") = {2.312, 2.812}
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] alpha(each unit="1") = {0.5559, 0.5559}
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0.98/100},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 100000,
+    final y_i_start = {1e-2},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = -T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2 /
+      (1/n_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt))^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt+dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt+dT) - 1))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt+dT)))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt-dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt-dT) - 1))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt-dT)))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Sips isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>p_adsorpt</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_pressure.mo
new file mode 100644
index 0000000..1be28b1
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_pressure.mo
@@ -0,0 +1,120 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Sips;
+model Test_changing_pressure
+  "Tester for all functions of the extended Sips isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.32, 0.22}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {1.075e-4, 1.075e-4}
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Q(each unit="J/mol") = {28.752e3, 28.752e3}
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] n_ref(each unit="1") = {2.312, 2.812}
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] alpha(each unit="1") = {0.5559, 0.5559}
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 1400,
+    final y_i_der = {0},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final y_i_start = {0.5},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = -T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2 /
+      (1/n_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt))^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt+dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt+dT) - 1))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt+dT)))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt-dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt-dT) - 1))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt-dT)))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Sips isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_temperature.mo
new file mode 100644
index 0000000..4c36e78
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/Test_changing_temperature.mo
@@ -0,0 +1,120 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Sips;
+model Test_changing_temperature
+  "Tester for all functions of the extended Sips isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.32, 0.22}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {1.075e-4, 1.075e-4}
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Q(each unit="J/mol") = {28.752e3, 28.752e3}
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] n_ref(each unit="1") = {2.312, 2.812}
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] alpha(each unit="1") = {0.5559, 0.5559}
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 100000,
+    final y_i_start = {0.5},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Sips,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/T_adsorpt))
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = -T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2 /
+      (1/n_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt))^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt+dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt+dT) - 1))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt+dT)))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt-dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt-dT) - 1))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[3,ind_comp] = 1 / (1/n_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt-dT)))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Sips isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/package.mo
new file mode 100644
index 0000000..5e4a222
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package Sips "Models ot test and varify functions of the extended Sips isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the extended Sips 
+isotherm model. The test models check the implementation of the functions and enable 
+verification of the function behavior. Four test models are implemented, in which the 
+pressure, mole fractions of independent components in the gas or vapor phase, and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Sips;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Sips/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_everything.mo
new file mode 100644
index 0000000..7cbee37
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_everything.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Toth;
+model Test_changing_everything
+  "Tester for all functions of the extended Toth isotherm model: Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.38, 0.28, 0.18}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1, 0.2}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {10.54e-3, 10.54e-3, 10.54e-3}
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Q(each unit="J/mol") = {46.093e3, 36.093e3, 26.093e3}
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] t_ref(each unit="1") = {0.2842, 0.2842, 0.2842}
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] alpha(each unit="1") = {0.284, 0.284, 0.284}
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 1400,
+    final y_i_der = {0.97/100/3*2, 0.97/100/3*1},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 1,
+    final y_i_start = {1e-2, 1e-2},
+    final T_adsorpt_start = 298.15,
+    final no_components = 3,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt)
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt+dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt+dT) - 1))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt+dT))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt-dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt-dT) - 1))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt-dT))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 8, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Toth isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..5eecab2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_mole_fractions.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Toth;
+model Test_changing_mole_fractions
+  "Tester for all functions of the extended Toth isotherm model: Changing independent mole fractions"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.38, 0.28}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {10.54e-3, 10.54e-3}
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Q(each unit="J/mol") = {46.093e3, 36.093e3}
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] t_ref(each unit="1") = {0.2842, 0.2842}
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] alpha(each unit="1") = {0.284, 0.284}
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0.98/100},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 100000,
+    final y_i_start = {1e-2},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt)
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt+dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt+dT) - 1))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt+dT))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt-dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt-dT) - 1))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt-dT))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 8, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Toth isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>p_adsorpt</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_pressure.mo
new file mode 100644
index 0000000..b1322ef
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_pressure.mo
@@ -0,0 +1,118 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Toth;
+model Test_changing_pressure
+  "Tester for all functions of the extended Toth isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.38, 0.28}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {10.54e-3, 10.54e-3}
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Q(each unit="J/mol") = {46.093e3, 36.093e3}
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] t_ref(each unit="1") = {0.2842, 0.2842}
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] alpha(each unit="1") = {0.284, 0.284}
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 1400,
+    final y_i_der = {0},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final y_i_start = {0.5},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt)
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt+dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt+dT) - 1))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt+dT))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt-dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt-dT) - 1))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt-dT))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 8, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Toth isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_temperature.mo
new file mode 100644
index 0000000..a126422
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/Test_changing_temperature.mo
@@ -0,0 +1,118 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.Toth;
+model Test_changing_temperature
+  "Tester for all functions of the extended Toth isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake[no_components] x_ref = {0.38, 0.28}
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] chi(each unit="1") = {0, 0.1}
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] b_ref(each unit="1/Pa") = {10.54e-3, 10.54e-3}
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] Q(each unit="J/mol") = {46.093e3, 36.093e3}
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] t_ref(each unit="1") = {0.2842, 0.2842}
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real[no_components] alpha(each unit="1") = {0.284, 0.284}
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature[no_components] T_ref = {283, 283}
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 100000,
+    final y_i_start = {0.5},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth,
+    p_threshold_min = 0);
+
+equation
+  for ind_comp in 1:no_components loop
+    //
+    // Coefficients of the isotherm model
+    //
+    c[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - T_adsorpt/T_ref[ind_comp]))
+      "Coefficients of isotherm model";
+    c[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/T_adsorpt - 1))
+      "Coefficients of isotherm model";
+    c[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] * (1 - T_ref[ind_comp]/T_adsorpt)
+      "Coefficients of isotherm model";
+
+    //
+    // Partial derivative of coefficients of isotherm model w.r.t. temperature
+    //
+    dc_dT[1,ind_comp] = -chi[ind_comp]/T_ref[ind_comp] * c[1,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[2,ind_comp] = -Q[ind_comp]/Modelica.Constants.R/T_adsorpt^2 * c[2,ind_comp]
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+    dc_dT[3,ind_comp] = T_ref[ind_comp]*alpha[ind_comp]/T_adsorpt^2
+      "Partial derivative of coefficients of isotherm model w.r.t. temperature";
+
+    //
+    // Coefficients of the isotherm model: T + dT K
+    //
+    c_pdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt+dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt+dT) - 1))
+      "Coefficients of isotherm model: T + dT K";
+    c_pdT[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt+dT))
+      "Coefficients of isotherm model: T + dT K";
+
+    //
+    // Coefficients of the isotherm model: T - dT K
+    //
+    c_mdT[1,ind_comp] = x_ref[ind_comp] * exp(chi[ind_comp] *
+      (1 - (T_adsorpt-dT)/T_ref[ind_comp]))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[2,ind_comp] = b_ref[ind_comp] * exp(Q[ind_comp]/Modelica.Constants.R/T_ref[ind_comp] *
+      (T_ref[ind_comp]/(T_adsorpt-dT) - 1))
+      "Coefficients of isotherm model: T - dT K";
+    c_mdT[3,ind_comp] = t_ref[ind_comp] + alpha[ind_comp] *
+      (1 - T_ref[ind_comp]/(T_adsorpt-dT))
+      "Coefficients of isotherm model: T - dT K";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 8, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the extended Toth isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/package.mo
new file mode 100644
index 0000000..d32606c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package Toth "Models ot test and varify functions of the extended Toth isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the extended Toth 
+isotherm model. The test models check the implementation of the functions and enable 
+verification of the function behavior. Four test models are implemented, in which the 
+pressure, mole fractions of independent components in the gas or vapor phase, and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Toth;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/Toth/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_everything.mo
new file mode 100644
index 0000000..174c84b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_everything.mo
@@ -0,0 +1,224 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.TothGAB_Schellevis;
+model Test_changing_everything
+  "Tester for all functions of the Toth-GAB isotherm model developed by Schellevis (2023): Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 3.40 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 93e-5
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_CO2(unit="J/mol") = 95.3e3
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.37
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = 0.33
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real beta_CO2(unit="1") = 2.05
+    "First coefficient of the enhancement factor"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real gamma_CO2(unit="kg/kg") = -0.85 / 0.018015267
+    "Second coefficient of the enhancement factor"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 353.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 5.55 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real c_ref_H2O(unit="1") = 100
+    "First affinity coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_c_CO2(unit="J/mol") = -8.69e3
+    "Parameter describing the change of the first affinity coefficient with 
+    temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_ref_H2O(unit="1") = 0.92
+    "Second affinity coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_k_CO2(unit="J/mol") = -0.82e3
+    "Parameter describing the change of the second affinity coefficient with 
+    temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 353.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 100,
+    final y_i_der = {-0.90/100},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 1,
+    final y_i_start = {0.95},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / T_adsorpt - 1))
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = -chi_CO2 / T_ref_CO2 * c[2,1]
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = -Q_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[3,1]
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 0
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = 0
+    "Sixth coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -Q_c_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = -Q_k_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt+dT) - 1))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt-dT) - 1))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..0dd5fbf
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_mole_fractions.mo
@@ -0,0 +1,224 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.TothGAB_Schellevis;
+model Test_changing_mole_fractions
+  "Tester for all functions of the Toth-GAB isotherm model developed by Schellevis (2023): Changing independent mole fractions"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 3.40 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 93e-5
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_CO2(unit="J/mol") = 95.3e3
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.37
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = 0.33
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real beta_CO2(unit="1") = 2.05
+    "First coefficient of the enhancement factor"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real gamma_CO2(unit="kg/kg") = -0.85 / 0.018015267
+    "Second coefficient of the enhancement factor"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 353.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 5.55 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real c_ref_H2O(unit="1") = 100
+    "First affinity coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_c_CO2(unit="J/mol") = -8.69e3
+    "Parameter describing the change of the first affinity coefficient with 
+    temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_ref_H2O(unit="1") = 0.92
+    "Second affinity coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_k_CO2(unit="J/mol") = -0.82e3
+    "Parameter describing the change of the second affinity coefficient with 
+    temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 353.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0.98/100},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 10000,
+    final y_i_start = {1e-2},
+    final T_adsorpt_start = 323.15,
+    final no_components = 2,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / T_adsorpt - 1))
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = -chi_CO2 / T_ref_CO2 * c[2,1]
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = -Q_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[3,1]
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 0
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = 0
+    "Sixth coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -Q_c_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = -Q_k_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt+dT) - 1))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt-dT) - 1))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>p_adsorpt</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_pressure.mo
new file mode 100644
index 0000000..09d9f61
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_pressure.mo
@@ -0,0 +1,223 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.TothGAB_Schellevis;
+model Test_changing_pressure
+  "Tester for all functions of the Toth-GAB isotherm model developed by Schellevis (2023): Changing pressure"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 3.40 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 93e-5
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_CO2(unit="J/mol") = 95.3e3
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.37
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = 0.33
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real beta_CO2(unit="1") = 2.05
+    "First coefficient of the enhancement factor"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real gamma_CO2(unit="kg/kg") = -0.85 / 0.018015267
+    "Second coefficient of the enhancement factor"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 353.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 5.55 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real c_ref_H2O(unit="1") = 100
+    "First affinity coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_c_CO2(unit="J/mol") = -8.69e3
+    "Parameter describing the change of the first affinity coefficient with 
+    temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_ref_H2O(unit="1") = 0.92
+    "Second affinity coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_k_CO2(unit="J/mol") = -0.82e3
+    "Parameter describing the change of the second affinity coefficient with 
+    temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 353.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 100,
+    final y_i_der = {0},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final y_i_start = {0.75},
+    final T_adsorpt_start = 273.15 + 35,
+    final no_components = 2,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / T_adsorpt - 1))
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = -chi_CO2 / T_ref_CO2 * c[2,1]
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = -Q_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[3,1]
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 0
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = 0
+    "Sixth coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -Q_c_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = -Q_k_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt+dT) - 1))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt-dT) - 1))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_temperature.mo
new file mode 100644
index 0000000..9f19e78
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/Test_changing_temperature.mo
@@ -0,0 +1,223 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.TothGAB_Schellevis;
+model Test_changing_temperature
+  "Tester for all functions of the Toth-GAB isotherm model developed by Schellevis (2023): Changing temperature"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 3.40 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 93e-5
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_CO2(unit="J/mol") = 95.3e3
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.37
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = 0.33
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real beta_CO2(unit="1") = 2.05
+    "First coefficient of the enhancement factor"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real gamma_CO2(unit="kg/kg") = -0.85 / 0.018015267
+    "Second coefficient of the enhancement factor"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 353.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 5.55 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real c_ref_H2O(unit="1") = 100
+    "First affinity coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_c_CO2(unit="J/mol") = -8.69e3
+    "Parameter describing the change of the first affinity coefficient with 
+    temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_ref_H2O(unit="1") = 0.92
+    "Second affinity coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_k_CO2(unit="J/mol") = -0.82e3
+    "Parameter describing the change of the second affinity coefficient with 
+    temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 353.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 10000,
+    final y_i_start = {0.9},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / T_adsorpt - 1))
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = -chi_CO2 / T_ref_CO2 * c[2,1]
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = -Q_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[3,1]
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 0
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = 0
+    "Sixth coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -Q_c_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = -Q_k_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt+dT) - 1))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt-dT) - 1))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = gamma_CO2
+    "Sixth coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = c_ref_H2O * Modelica.Math.exp(Q_c_CO2/
+    (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = k_ref_H2O * Modelica.Math.exp(Q_k_CO2/
+    (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/package.mo
new file mode 100644
index 0000000..3342118
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package TothGAB_Schellevis "Models to test and varify functions of the Toth-GAB isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Toth-GAB
+isotherm model. The test models check the implementation of the functions and enable 
+verification of the function behavior. Four test models are implemented, in which the 
+pressure, mole fractions of independent components in the gas or vapor phase, and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TothGAB_Schellevis;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_Schellevis/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_everything.mo
new file mode 100644
index 0000000..579d8a0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_everything.mo
@@ -0,0 +1,194 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.TothGAB_StampiBombelli;
+model Test_changing_everything
+  "Tester for all functions of the Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 2.38 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 0.07074
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_CO2(unit="J/mol") = -57047
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.4148
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = -1.6060
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake gamma_CO2 = 0.0061 / 0.0440098
+    "Enhancement factor for saturation uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake beta_CO2 = 28.907 / 0.0440098
+    "Enhancement factor for Toth coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 296
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 36.48 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real c_H2O(unit="1") = 0.1489
+    "First affinity coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_H2O(unit="1") = 0.5751
+    "Second affinity coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 296
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 100,
+    final y_i_der = {-0.90/100},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 1,
+    final y_i_start = {0.95},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / T_adsorpt - 1))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2 / T_ref_CO2 * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = -Q_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[2,1]
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 0
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 0
+    "Fivth coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = 0
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = 0
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt+dT) - 1))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt-dT) - 1))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..f611844
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_mole_fractions.mo
@@ -0,0 +1,194 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.TothGAB_StampiBombelli;
+model Test_changing_mole_fractions
+  "Tester for all functions of the Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Changing independent mole fractions"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 2.38 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 0.07074
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_CO2(unit="J/mol") = -57047
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.4148
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = -1.6060
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake gamma_CO2 = 0.0061 / 0.0440098
+    "Enhancement factor for saturation uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake beta_CO2 = 28.907 / 0.0440098
+    "Enhancement factor for Toth coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 296
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 36.48 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real c_H2O(unit="1") = 0.1489
+    "First affinity coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_H2O(unit="1") = 0.5751
+    "Second affinity coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 296
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0.98/100},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 10000,
+    final y_i_start = {1e-2},
+    final T_adsorpt_start = 323.15,
+    final no_components = 2,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / T_adsorpt - 1))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2 / T_ref_CO2 * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = -Q_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[2,1]
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 0
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 0
+    "Fivth coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = 0
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = 0
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt+dT) - 1))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt-dT) - 1))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>p_adsorpt</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_pressure.mo
new file mode 100644
index 0000000..b1fb146
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_pressure.mo
@@ -0,0 +1,193 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.TothGAB_StampiBombelli;
+model Test_changing_pressure
+  "Tester for all functions of the Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Changing pressure"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 2.38 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 0.07074
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_CO2(unit="J/mol") = -57047
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.4148
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = -1.6060
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake gamma_CO2 = 0.0061 / 0.0440098
+    "Enhancement factor for saturation uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake beta_CO2 = 28.907 / 0.0440098
+    "Enhancement factor for Toth coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 296
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 36.48 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real c_H2O(unit="1") = 0.1489
+    "First affinity coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_H2O(unit="1") = 0.5751
+    "Second affinity coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 296
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 100,
+    final y_i_der = {0},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final y_i_start = {0.9},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / T_adsorpt - 1))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2 / T_ref_CO2 * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = -Q_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[2,1]
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 0
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 0
+    "Fivth coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = 0
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = 0
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt+dT) - 1))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt-dT) - 1))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_temperature.mo
new file mode 100644
index 0000000..4865760
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/Test_changing_temperature.mo
@@ -0,0 +1,193 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.TothGAB_StampiBombelli;
+model Test_changing_temperature
+  "Tester for all functions of the Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Changing temperature"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2 = 2.38 * 0.0440098
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2(unit="1/Pa") = 0.07074
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_CO2(unit="J/mol") = -57047
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2(unit="1") = 0.4148
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2(unit="1") = -1.6060
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake gamma_CO2 = 0.0061 / 0.0440098
+    "Enhancement factor for saturation uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake beta_CO2 = 28.907 / 0.0440098
+    "Enhancement factor for Toth coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2 = 296
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 36.48 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real c_H2O(unit="1") = 0.1489
+    "First affinity coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real k_H2O(unit="1") = 0.5751
+    "Second affinity coefficient"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 296
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 10000,
+    final y_i_start = {0.9},
+    final T_adsorpt_start = 298.15,
+    final no_components = 2,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - (T_adsorpt / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / T_adsorpt - 1))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2 / T_ref_CO2 * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = -Q_CO2 / (Modelica.Constants.R * T_adsorpt^2) * c[2,1]
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = alpha_CO2 * T_ref_CO2 / T_adsorpt^2
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 0
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = 0
+    "Fivth coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = 0
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = 0
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt+dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt+dT) - 1))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt+dT))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2 * Modelica.Math.exp(chi_CO2 * (1 - ((T_adsorpt-dT) / T_ref_CO2)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = b_ref_CO2 * Modelica.Math.exp(Q_CO2 /
+    (Modelica.Constants.R * T_ref_CO2) *(T_ref_CO2 / (T_adsorpt-dT) - 1))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = t_ref_CO2 + alpha_CO2 * (1 - T_ref_CO2 / (T_adsorpt-dT))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = gamma_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = beta_CO2
+    "Fivth coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = c_H2O
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = k_H2O
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth-GAB isotherm 
+model. Additionally, the implemented functions for the partial derivarives 'dx_dp,'
+'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/package.mo
new file mode 100644
index 0000000..2b8e320
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package TothGAB_StampiBombelli "Models to test and varify functions of the Toth-GAB isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Toth-GAB
+isotherm model. The test models check the implementation of the functions and enable 
+verification of the function behavior. Four test models are implemented, in which the 
+pressure, mole fractions of independent components in the gas or vapor phase, and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end TothGAB_StampiBombelli;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/TothGAB_StampiBombelli/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_everything.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_everything.mo
new file mode 100644
index 0000000..886d514
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_everything.mo
@@ -0,0 +1,278 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.WeightedAverageDualSiteTothGAB;
+model Test_changing_everything
+  "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Changing pressure, independent mole fractions, and temperature"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2_dry = 4.86 * 0.0440098
+    "Saturation uptake at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2_dry(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature
+     under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2_dry(unit="1/Pa") = 2.85e-21
+    "Toth coefficient at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_CO2_dry(unit="J/mol") = -117798
+    "Parameter describing the isosteric enthalpy of adsorption under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2_dry(unit="1") = 0.209
+    "Toth exponent at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2_dry(unit="1") = 0.5823
+    "Parameter describing the change of the Toth exponent with temperature under 
+    dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2_dry = 298.15
+    "Reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  parameter Real C_CO2(unit="kg/kg") = 1.532 * 0.018015267
+    "Critical water uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  parameter SorpLib.Units.Uptake x_ref_CO2_wet = 9.035 * 0.0440098
+    "Saturation uptake at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2_wet(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature
+     under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2_wet(unit="1/Pa") = 1.230e-18
+    "Toth coefficient at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_CO2_wet(unit="J/mol") = -203687
+    "Parameter describing the isosteric enthalpy of adsorption under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2_wet(unit="1") = 0.053
+    "Toth exponent at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2_wet(unit="1") = 0.053
+    "Parameter describing the change of the Toth exponent with temperature under 
+    wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2_wet = 298.15
+    "Reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 3.63 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_H2O(unit="J/mol") = 47110
+    "First parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D_H2O(unit="1/K") = 0.023744
+    "Second parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F_H2O(unit="J/mol") = 57706
+    "First parameter of the adsorption enthalpy of the layers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G_H2O(unit="J/(mol.K)") = -47.814
+    "Second parameter of the adsorption enthalpy of the ayers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I_H2O(unit="J/mol") = 57220
+    "First parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real J_H2O(unit="J/(mol.K)") = -44.38
+    "Second parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = (1e5-12349)/100,
+    final y_i_der = {0},
+    final T_adsorpt_der = 75/100,
+    final p_adsorpt_start = 1,
+    final y_i_start = {1-0.5*12349/1e5},
+    final T_adsorpt_start = 273.15+25,
+    final no_components = 2,
+    final no_coefficients = 7,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - (T_adsorpt / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * T_adsorpt))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - (T_adsorpt / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * T_adsorpt))
+    "Sixth coefficient of the Toth isotherm model";
+  c[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / T_adsorpt)
+    "Seventh coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * T_adsorpt)) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * T_adsorpt) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2_dry / T_ref_CO2_dry * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = DH_CO2_dry * c[2,1] / (Modelica.Constants.R * T_adsorpt^2)
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = alpha_CO2_dry * T_ref_CO2_dry / T_adsorpt^2
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 0
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = -chi_CO2_wet / T_ref_CO2_wet * c[5,1]
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = DH_CO2_wet * c[6,1] / (Modelica.Constants.R * T_adsorpt^2)
+    "Sixth coefficient of the Toth isotherm model";
+  dc_dT[7,1] = alpha_CO2_wet * T_ref_CO2_wet / T_adsorpt^2
+    "Seventh coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -((D_H2O*T_adsorpt - 1) * exp(D_H2O*T_adsorpt) - I_H2O + C_H2O) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = (I_H2O - F_H2O) / (Modelica.Constants.R*T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  dc_dT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - ((T_adsorpt+dT) / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / (T_adsorpt+dT))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - ((T_adsorpt+dT) / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Sixth coefficient of the Toth isotherm model";
+  c_pdT[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / (T_adsorpt+dT))
+    "Seventh coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt+dT))) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt+dT)) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_pdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - ((T_adsorpt-dT) / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / (T_adsorpt-dT))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - ((T_adsorpt-dT) / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Sixth coefficient of the Toth isotherm model";
+  c_mdT[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / (T_adsorpt-dT))
+    "Seventh coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt-dT))) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt-dT)) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_mdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the weighted-average dual site
+Toth-GAB isotherm model. Additionally, the implemented functions for the partial 
+derivarives 'dx_dp,' 'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure, independent mole fractions, and
+temperature with time. To  see the behavior of all functions, plot the variables 
+<i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and 
+<i>dx_adsorpt_dT_adsorpt</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_everything;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_mole_fractions.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_mole_fractions.mo
new file mode 100644
index 0000000..b9dfc2f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_mole_fractions.mo
@@ -0,0 +1,278 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.WeightedAverageDualSiteTothGAB;
+model Test_changing_mole_fractions
+  "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Changing independent mole fractions"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2_dry = 4.86 * 0.0440098
+    "Saturation uptake at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2_dry(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature
+     under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2_dry(unit="1/Pa") = 2.85e-21
+    "Toth coefficient at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_CO2_dry(unit="J/mol") = -117798
+    "Parameter describing the isosteric enthalpy of adsorption under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2_dry(unit="1") = 0.209
+    "Toth exponent at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2_dry(unit="1") = 0.5823
+    "Parameter describing the change of the Toth exponent with temperature under 
+    dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2_dry = 298.15
+    "Reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  parameter Real C_CO2(unit="kg/kg") = 1.532 * 0.018015267
+    "Critical water uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  parameter SorpLib.Units.Uptake x_ref_CO2_wet = 9.035 * 0.0440098
+    "Saturation uptake at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2_wet(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature
+     under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2_wet(unit="1/Pa") = 1.230e-18
+    "Toth coefficient at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_CO2_wet(unit="J/mol") = -203687
+    "Parameter describing the isosteric enthalpy of adsorption under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2_wet(unit="1") = 0.053
+    "Toth exponent at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2_wet(unit="1") = 0.053
+    "Parameter describing the change of the Toth exponent with temperature under 
+    wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2_wet = 298.15
+    "Reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 3.63 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_H2O(unit="J/mol") = 47110
+    "First parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D_H2O(unit="1/K") = 0.023744
+    "Second parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F_H2O(unit="J/mol") = 57706
+    "First parameter of the adsorption enthalpy of the layers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G_H2O(unit="J/(mol.K)") = -47.814
+    "Second parameter of the adsorption enthalpy of the ayers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I_H2O(unit="J/mol") = 57220
+    "First parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real J_H2O(unit="J/(mol.K)") = -44.38
+    "Second parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0.96/100},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 25000,
+    final y_i_start = {0.02},
+    final T_adsorpt_start = 273.15+75,
+    final no_components = 2,
+    final no_coefficients = 7,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - (T_adsorpt / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * T_adsorpt))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - (T_adsorpt / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * T_adsorpt))
+    "Sixth coefficient of the Toth isotherm model";
+  c[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / T_adsorpt)
+    "Seventh coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * T_adsorpt)) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * T_adsorpt) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2_dry / T_ref_CO2_dry * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = DH_CO2_dry * c[2,1] / (Modelica.Constants.R * T_adsorpt^2)
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = alpha_CO2_dry * T_ref_CO2_dry / T_adsorpt^2
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 0
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = -chi_CO2_wet / T_ref_CO2_wet * c[5,1]
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = DH_CO2_wet * c[6,1] / (Modelica.Constants.R * T_adsorpt^2)
+    "Sixth coefficient of the Toth isotherm model";
+  dc_dT[7,1] = alpha_CO2_wet * T_ref_CO2_wet / T_adsorpt^2
+    "Seventh coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -((D_H2O*T_adsorpt - 1) * exp(D_H2O*T_adsorpt) - I_H2O + C_H2O) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = (I_H2O - F_H2O) / (Modelica.Constants.R*T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  dc_dT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - ((T_adsorpt+dT) / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / (T_adsorpt+dT))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - ((T_adsorpt+dT) / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Sixth coefficient of the Toth isotherm model";
+  c_pdT[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / (T_adsorpt+dT))
+    "Seventh coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt+dT))) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt+dT)) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_pdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - ((T_adsorpt-dT) / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / (T_adsorpt-dT))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - ((T_adsorpt-dT) / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Sixth coefficient of the Toth isotherm model";
+  c_mdT[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / (T_adsorpt-dT))
+    "Seventh coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt-dT))) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt-dT)) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_mdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the weighted-average dual site
+Toth-GAB isotherm model. Additionally, the implemented functions for the partial 
+derivarives 'dx_dp,' 'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the independent mole fractions with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>,
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> 
+over the variable <i>p_adsorpt</i>. The simulation time is correctly preset 
+(Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_mole_fractions;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_pressure.mo
new file mode 100644
index 0000000..4d98ed2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_pressure.mo
@@ -0,0 +1,277 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.WeightedAverageDualSiteTothGAB;
+model Test_changing_pressure
+  "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Changing pressure"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2_dry = 4.86 * 0.0440098
+    "Saturation uptake at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2_dry(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature
+     under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2_dry(unit="1/Pa") = 2.85e-21
+    "Toth coefficient at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_CO2_dry(unit="J/mol") = -117798
+    "Parameter describing the isosteric enthalpy of adsorption under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2_dry(unit="1") = 0.209
+    "Toth exponent at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2_dry(unit="1") = 0.5823
+    "Parameter describing the change of the Toth exponent with temperature under 
+    dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2_dry = 298.15
+    "Reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  parameter Real C_CO2(unit="kg/kg") = 1.532 * 0.018015267
+    "Critical water uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  parameter SorpLib.Units.Uptake x_ref_CO2_wet = 9.035 * 0.0440098
+    "Saturation uptake at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2_wet(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature
+     under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2_wet(unit="1/Pa") = 1.230e-18
+    "Toth coefficient at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_CO2_wet(unit="J/mol") = -203687
+    "Parameter describing the isosteric enthalpy of adsorption under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2_wet(unit="1") = 0.053
+    "Toth exponent at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2_wet(unit="1") = 0.053
+    "Parameter describing the change of the Toth exponent with temperature under 
+    wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2_wet = 298.15
+    "Reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 3.63 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_H2O(unit="J/mol") = 47110
+    "First parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D_H2O(unit="1/K") = 0.023744
+    "Second parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F_H2O(unit="J/mol") = 57706
+    "First parameter of the adsorption enthalpy of the layers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G_H2O(unit="J/(mol.K)") = -47.814
+    "Second parameter of the adsorption enthalpy of the ayers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I_H2O(unit="J/mol") = 57220
+    "First parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real J_H2O(unit="J/(mol.K)") = -44.38
+    "Second parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = (0.6e5-12349)/100,
+    final y_i_der = {0},
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 12349,
+    final y_i_start = {1-0.55*12349/0.6e5},
+    final T_adsorpt_start = 273.15+50,
+    final no_components = 2,
+    final no_coefficients = 7,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - (T_adsorpt / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * T_adsorpt))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - (T_adsorpt / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * T_adsorpt))
+    "Sixth coefficient of the Toth isotherm model";
+  c[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / T_adsorpt)
+    "Seventh coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * T_adsorpt)) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * T_adsorpt) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2_dry / T_ref_CO2_dry * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = DH_CO2_dry * c[2,1] / (Modelica.Constants.R * T_adsorpt^2)
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = alpha_CO2_dry * T_ref_CO2_dry / T_adsorpt^2
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 0
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = -chi_CO2_wet / T_ref_CO2_wet * c[5,1]
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = DH_CO2_wet * c[6,1] / (Modelica.Constants.R * T_adsorpt^2)
+    "Sixth coefficient of the Toth isotherm model";
+  dc_dT[7,1] = alpha_CO2_wet * T_ref_CO2_wet / T_adsorpt^2
+    "Seventh coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -((D_H2O*T_adsorpt - 1) * exp(D_H2O*T_adsorpt) - I_H2O + C_H2O) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = (I_H2O - F_H2O) / (Modelica.Constants.R*T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  dc_dT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - ((T_adsorpt+dT) / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / (T_adsorpt+dT))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - ((T_adsorpt+dT) / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Sixth coefficient of the Toth isotherm model";
+  c_pdT[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / (T_adsorpt+dT))
+    "Seventh coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt+dT))) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt+dT)) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_pdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - ((T_adsorpt-dT) / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / (T_adsorpt-dT))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - ((T_adsorpt-dT) / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Sixth coefficient of the Toth isotherm model";
+  c_mdT[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / (T_adsorpt-dT))
+    "Seventh coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt-dT))) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt-dT)) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_mdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the weighted-average dual site
+Toth-GAB isotherm model. Additionally, the implemented functions for the partial 
+derivarives 'dx_dp,' 'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_temperature.mo
new file mode 100644
index 0000000..347e507
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/Test_changing_temperature.mo
@@ -0,0 +1,277 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers.WeightedAverageDualSiteTothGAB;
+model Test_changing_temperature
+  "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Changing temperature"
+
+  //
+  // Definition of parameters of component 1 (i.e., CO2)
+  //
+  parameter SorpLib.Units.Uptake x_ref_CO2_dry = 4.86 * 0.0440098
+    "Saturation uptake at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2_dry(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature
+     under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2_dry(unit="1/Pa") = 2.85e-21
+    "Toth coefficient at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_CO2_dry(unit="J/mol") = -117798
+    "Parameter describing the isosteric enthalpy of adsorption under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2_dry(unit="1") = 0.209
+    "Toth exponent at reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2_dry(unit="1") = 0.5823
+    "Parameter describing the change of the Toth exponent with temperature under 
+    dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2_dry = 298.15
+    "Reference temperature under dry conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  parameter Real C_CO2(unit="kg/kg") = 1.532 * 0.018015267
+    "Critical water uptake"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  parameter SorpLib.Units.Uptake x_ref_CO2_wet = 9.035 * 0.0440098
+    "Saturation uptake at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi_CO2_wet(unit="1") = 0
+    "Parameter describing the change of the saturation uptake with temperature
+     under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref_CO2_wet(unit="1/Pa") = 1.230e-18
+    "Toth coefficient at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real DH_CO2_wet(unit="J/mol") = -203687
+    "Parameter describing the isosteric enthalpy of adsorption under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref_CO2_wet(unit="1") = 0.053
+    "Toth exponent at reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha_CO2_wet(unit="1") = 0.053
+    "Parameter describing the change of the Toth exponent with temperature under 
+    wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_CO2_wet = 298.15
+    "Reference temperature under wet conditions"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of parameters of component 2 (i.e., H20)
+  //
+  parameter SorpLib.Units.Uptake x_mon_H2O = 3.63 * 0.018015267
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_H2O(unit="J/mol") = 47110
+    "First parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D_H2O(unit="1/K") = 0.023744
+    "Second parameter of the adsorption enthalpy of the first layer"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F_H2O(unit="J/mol") = 57706
+    "First parameter of the adsorption enthalpy of the layers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G_H2O(unit="J/(mol.K)") = -47.814
+    "Second parameter of the adsorption enthalpy of the ayers 2 to 9"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I_H2O(unit="J/mol") = 57220
+    "First parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real J_H2O(unit="J/(mol.K)") = -44.38
+    "Second parameter of the enthalpy of vaporization"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref_H2O = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestMulti(
+    final p_adsorpt_der = 0,
+    final y_i_der = {0},
+    final T_adsorpt_der = 50/100,
+    final p_adsorpt_start = 0.6e5,
+    final y_i_start = {1-0.5*12349/0.6e5},
+    final T_adsorpt_start = 273.15+50,
+    final no_components = 2,
+    final no_coefficients = 7,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB,
+    p_threshold_min = 0);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - (T_adsorpt / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * T_adsorpt))
+    "Second coefficient of the Toth isotherm model";
+  c[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / T_adsorpt)
+    "Third coefficient of the Toth isotherm model";
+  c[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - (T_adsorpt / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * T_adsorpt))
+    "Sixth coefficient of the Toth isotherm model";
+  c[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / T_adsorpt)
+    "Seventh coefficient of the Toth isotherm model";
+
+  c[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  c[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * T_adsorpt)) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Third coefficient of the GAB isotherm model";
+  c[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * T_adsorpt) -
+    (J_H2O * T_adsorpt + I_H2O)) / (Modelica.Constants.R * T_adsorpt))
+    "Fourth coefficient of the GAB isotherm model";
+  c[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1,1] = -chi_CO2_dry / T_ref_CO2_dry * c[1,1]
+    "First coefficient of the Toth isotherm model";
+  dc_dT[2,1] = DH_CO2_dry * c[2,1] / (Modelica.Constants.R * T_adsorpt^2)
+    "Second coefficient of the Toth isotherm model";
+  dc_dT[3,1] = alpha_CO2_dry * T_ref_CO2_dry / T_adsorpt^2
+    "Third coefficient of the Toth isotherm model";
+  dc_dT[4,1] = 0
+    "Fourth coefficient of the Toth isotherm model";
+  dc_dT[5,1] = -chi_CO2_wet / T_ref_CO2_wet * c[5,1]
+    "Fivth coefficient of the Toth isotherm model";
+  dc_dT[6,1] = DH_CO2_wet * c[6,1] / (Modelica.Constants.R * T_adsorpt^2)
+    "Sixth coefficient of the Toth isotherm model";
+  dc_dT[7,1] = alpha_CO2_wet * T_ref_CO2_wet / T_adsorpt^2
+    "Seventh coefficient of the Toth isotherm model";
+
+  dc_dT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "First coefficient of the GAB isotherm model";
+  dc_dT[2,2] = 0
+    "Second coefficient of the GAB isotherm model";
+  dc_dT[3,2] = -((D_H2O*T_adsorpt - 1) * exp(D_H2O*T_adsorpt) - I_H2O + C_H2O) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3,2]
+    "Third coefficient of the GAB isotherm model";
+  dc_dT[4,2] = (I_H2O - F_H2O) / (Modelica.Constants.R*T_adsorpt^2) * c[4,2]
+    "Fourth coefficient of the GAB isotherm model";
+  dc_dT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  dc_dT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  dc_dT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T + dT K
+  //
+  c_pdT[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - ((T_adsorpt+dT) / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c_pdT[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Second coefficient of the Toth isotherm model";
+  c_pdT[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / (T_adsorpt+dT))
+    "Third coefficient of the Toth isotherm model";
+  c_pdT[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_pdT[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - ((T_adsorpt+dT) / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c_pdT[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Sixth coefficient of the Toth isotherm model";
+  c_pdT[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / (T_adsorpt+dT))
+    "Seventh coefficient of the Toth isotherm model";
+
+  c_pdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "First coefficient of the GAB isotherm model";
+  c_pdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_pdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt+dT))) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_pdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt+dT)) -
+    (J_H2O * (T_adsorpt+dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt+dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_pdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_pdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_pdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Coefficients of the isotherm model: T - dT K
+  //
+  c_mdT[1,1] = x_ref_CO2_dry *
+    Modelica.Math.exp(chi_CO2_dry * (1 - ((T_adsorpt-dT) / T_ref_CO2_dry)))
+    "First coefficient of the Toth isotherm model";
+  c_mdT[2,1] = b_ref_CO2_dry *
+    Modelica.Math.exp(-DH_CO2_dry / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Second coefficient of the Toth isotherm model";
+  c_mdT[3,1] = t_ref_CO2_dry + alpha_CO2_dry * (1 - T_ref_CO2_dry / (T_adsorpt-dT))
+    "Third coefficient of the Toth isotherm model";
+  c_mdT[4,1] = C_CO2
+    "Fourth coefficient of the Toth isotherm model";
+  c_mdT[5,1] = x_ref_CO2_wet *
+    Modelica.Math.exp(chi_CO2_wet * (1 - ((T_adsorpt-dT) / T_ref_CO2_wet)))
+    "Fivth coefficient of the Toth isotherm model";
+  c_mdT[6,1] = b_ref_CO2_wet *
+    Modelica.Math.exp(-DH_CO2_wet / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Sixth coefficient of the Toth isotherm model";
+  c_mdT[7,1] = t_ref_CO2_wet + alpha_CO2_wet * (1 - T_ref_CO2_wet / (T_adsorpt-dT))
+    "Seventh coefficient of the Toth isotherm model";
+
+  c_mdT[1,2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "First coefficient of the GAB isotherm model";
+  c_mdT[2,2] = x_mon_H2O
+    "Second coefficient of the GAB isotherm model";
+  c_mdT[3,2] = Modelica.Math.exp(((C_H2O - Modelica.Math.exp(D_H2O * (T_adsorpt-dT))) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Third coefficient of the GAB isotherm model";
+  c_mdT[4,2] = Modelica.Math.exp(((F_H2O + G_H2O * (T_adsorpt-dT)) -
+    (J_H2O * (T_adsorpt-dT) + I_H2O)) / (Modelica.Constants.R * (T_adsorpt-dT)))
+    "Fourth coefficient of the GAB isotherm model";
+  c_mdT[5,2] = 0
+    "Fivth coefficient of the GAB isotherm model";
+  c_mdT[6,2] = 0
+    "Sixth coefficient of the GAB isotherm model";
+  c_mdT[7,2] = 0
+    "Seventh coefficient of the GAB isotherm model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the weighted-average dual site
+Toth-GAB isotherm model. Additionally, the implemented functions for the partial 
+derivarives 'dx_dp,' 'dx_dy,' and 'dx_dT' are checked via numerical calculations.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dy_i</i>, and <i>dx_adsorpt_dT_adsorpt</i> over the variable 
+<i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/package.mo
new file mode 100644
index 0000000..9eb74bb
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/package.mo
@@ -0,0 +1,22 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Testers;
+package WeightedAverageDualSiteTothGAB "Models to test and varify functions of the weighted-average dual site Toth-GAB isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the weighted-average 
+dual site Toth-GAB isotherm model. The test models check the implementation of the 
+functions and enable verification of the function behavior. Four test models are 
+implemented, in which the pressure, mole fractions of independent components in the 
+gas or vapor phase, and temperature change over time. In addition, the test models 
+demonstrate the functions' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end WeightedAverageDualSiteTothGAB;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/package.order
new file mode 100644
index 0000000..2df4763
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/WeightedAverageDualSiteTothGAB/package.order
@@ -0,0 +1,4 @@
+Test_changing_pressure
+Test_changing_mole_fractions
+Test_changing_temperature
+Test_changing_everything
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/package.mo
new file mode 100644
index 0000000..15bec77
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package Testers "This package contains test models to check and varify multi-component isotherm models"
+extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented isotherm models. Each
+isotherm model has its test models saved in a separate package.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/package.order
new file mode 100644
index 0000000..63b2987
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Testers/package.order
@@ -0,0 +1,9 @@
+Langmuir
+Sips
+Toth
+TothGAB_StampiBombelli
+TothGAB_Schellevis
+MechanisticTothGAB
+WeightedAverageDualSiteTothGAB
+IAST_N2
+IAST_N3
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/calc_p_i_num_i_den_i.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/calc_p_i_num_i_den_i.mo
new file mode 100644
index 0000000..261620f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/calc_p_i_num_i_den_i.mo
@@ -0,0 +1,82 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals;
+function calc_p_i_num_i_den_i
+  "Extended Toth isotherm model: Corrected partial pressures, numerators, denominators of the isotherm model"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real[:,:] c
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_threshold_min = 0
+    "Threshold for partial pressures of all components: If a partial pressure is
+    below the threshold, its value is set to the threshold"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i_regulated
+    "Regulated equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real[size(c,2)] num_i
+    "Individual numerator for each component of the isotherm model"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+  output Real[size(c,2)] den_i
+    "Individual denominator for each component of the isotherm model"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real den_tmp
+    "Identical temporary denominator for all components of the isotherm model";
+
+algorithm
+  den_tmp := 1
+    "Start value of the temporary denominator";
+
+  for ind_comp in 1:size(c,2) loop
+    p_i_regulated[ind_comp] := max(p_i[ind_comp], p_threshold_min)
+      "Limiter of partial pressures to increase numerical stability";
+
+    num_i[ind_comp] := c[1,ind_comp] * c[2,ind_comp] * p_i_regulated[ind_comp]
+      "Individual numerators";
+
+    den_tmp := den_tmp + (c[2,ind_comp] * p_i_regulated[ind_comp]) ^ c[3,ind_comp]
+      "Identical temporary denominator";
+  end for;
+
+  for ind_comp in 1:size(c,2) loop
+    den_i[ind_comp] := den_tmp ^ (1/c[3,ind_comp])
+      "Individual denominators";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function regulates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) so that they are equal or greater than <i>p_threshold_min</i>. Further,
+this function calculates the numerators <i>num_i</i> and denominators <i>den_i</i>
+of the extended Toth isotherm model. For full details of the extended Toth
+isotherm mode, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 8, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end calc_p_i_num_i_den_i;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/p_i_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/p_i_xT.mo
new file mode 100644
index 0000000..467d2e9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/p_i_xT.mo
@@ -0,0 +1,86 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals;
+function p_i_xT
+  "Extended Toth isotherm model: Partial pressures as function of uptakes and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real[size(c,2), size(c,2)] A
+    "Matrix A of A*zz = -x_adsorpt";
+  Real[size(c,2)] zz
+    "Vector zz of A*zz = -x_adsorpt (i.e., zz = second substitution)";
+  Real[size(c,2)] z
+    "Vector z (i.e., z = first substitution)";
+
+  SorpLib.Units.Uptake[size(c,2)] x_adsorpt_pow_c3
+    "Equilibrium uptakes of the adsorpt phase to the power of coefficient c3";
+
+algorithm
+  //
+  // Set up matrix A and solve system of linear equations:
+  //
+  // To calculate the invesere function of the extended Toth isotherm regarding
+  // the equilibrium pressure and mole fractions of the independent components of
+  // the gas or vapor phase, the term ' c[2,ind] * p_i[ind]' is substituted by 'z,'
+  // and the term 'z ^ c[3,ind] is substituted by 'zz.' Thus, a system of linear
+  // equations is created that canbe solved. Re-substitution allows to calculate
+  // partial pressures p_i and,thus, the equilibrium pressure and mole fractions.
+  //
+  for ind_comp in 1:size(c,2) loop
+    x_adsorpt_pow_c3[ind_comp] := x_adsorpt[ind_comp] ^ c[3, ind_comp]
+      "First, calculate equilibrium uptakes of the adsorpt phase to the power of 
+      coefficient c3";
+    A[ind_comp,:] := fill(x_adsorpt_pow_c3[ind_comp], size(c,2))
+      "Second, fill row with correct uptake";
+    A[ind_comp,ind_comp] :=  x_adsorpt_pow_c3[ind_comp] - c[1,ind_comp] ^ c[3,ind_comp]
+      "Third, correct diagonale";
+  end for;
+
+  zz := Modelica.Math.Matrices.solve(A, -1 .* x_adsorpt_pow_c3)
+    "Fourth, solve the system of linear equations";
+
+  for ind_comp in 1:size(c,2) loop
+    z[ind_comp] := zz[ind_comp] ^ (1/c[3, ind_comp])
+      "Re-substituate values and consider threshold if necessary";
+    p_i[ind_comp] := max(z[ind_comp] / c[2,ind_comp], p_threshold_min)
+      "Re-substituate values and consider threshold if necessary";
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) as function of the equilibrium uptakes <i>x_adsorpt</i> and the 
+equilibrium temperature <i>T_adsorpt</i>. Thus, this function is a inverse of the 
+function 'x_pyT.' For full details of the original function 'x_pyT,' check the 
+documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 8, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end p_i_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/package.mo
new file mode 100644
index 0000000..a133d03
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the extended Sips isotherm
+model. Thus, redundancy of code shall be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 9, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/package.order
new file mode 100644
index 0000000..c25a70b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/Internals/package.order
@@ -0,0 +1,2 @@
+calc_p_i_num_i_den_i
+p_i_xT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/package.mo
new file mode 100644
index 0000000..d9b2449
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/package.mo
@@ -0,0 +1,457 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package Toth "Package containing all functions regarding the extended Toth isotherm"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponents;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "Extended Toth isotherm model: Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real[size(c,2)] den_i
+      "Individual denominator for each component of the isotherm model";
+
+  algorithm
+    (p_i,num_i,den_i) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals.calc_p_i_num_i_den_i(
+       p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    x_adsorpt := num_i ./ den_i
+      "Calculate equilibrium uptakes of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "Extended Toth isotherm model: Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals.p_i_xT(
+        x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+        "Partial pressures";
+
+    p_adsorpt := sum(p_i)
+      "Equilibrium pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "Extended Toth isotherm model: Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals.p_i_xT(
+        x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+        "Partial pressures";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / max(p_adsorpt, p_threshold_min)
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)),
+  Documentation(info="<html>
+<p>
+This function is the inverse function of the function 'x_pyT.' For full details 
+of the original function 'x_pyT,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.x_pyT</a>.
+</p>
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 8, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "Extended Toth isotherm model: Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals.p_i_xT(
+        x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min)
+        "Partial pressures";
+
+    p_adsorpt := max(sum(p_i), p_threshold_min)
+      "Equilibrium pressure";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / p_adsorpt
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "Extended Toth isotherm model: Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real[size(c,2)] den_i
+      "Individual denominator for each component of the isotherm model";
+
+    Real[size(c,2)] dnum_i_dp_adsorpt
+      "Partial derivatives of the numerators w.r.t. the equilibrium pressure";
+    Real[size(c,2)] dden_i_dp_adsorpt
+      "Partial derivatives of the denominators w.r.t. the equilbrium pressure";
+
+    Real den_tmp
+      "Identical temporary denominator for all components of the isotherm model";
+    Real dden_tmp_dp_adsorpt
+      "Identical temporary partial derivative of the denominator w.r.t. the  
+    equilbrium pressure for all components of the isotherm model";
+
+  algorithm
+    (p_i,num_i,den_i) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals.calc_p_i_num_i_den_i(
+       p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives
+    //
+    den_tmp := 1
+      "Start value of the temporary denominator";
+    dden_tmp_dp_adsorpt := 0
+      "Start value of the temporary derivative of the denominator w.r.t. 
+    equilbrium pressure";
+
+    for ind_comp in 1:size(c,2) loop
+      dnum_i_dp_adsorpt[ind_comp] := c[1,ind_comp] * c[2,ind_comp] * y_i_[ind_comp]
+        "Partial derivatives of numerators w.r.t. equilibrium pressure";
+
+      den_tmp := den_tmp + (c[2,ind_comp] * p_i[ind_comp]) ^ c[3,ind_comp]
+        "Identical temporary denominator";
+
+      dden_tmp_dp_adsorpt := dden_tmp_dp_adsorpt + c[3,ind_comp] *
+        (c[2,ind_comp] * p_i[ind_comp]) ^ c[3,ind_comp] / p_i[ind_comp] * y_i_[ind_comp]
+          "Identical partial derivative of the denominator w.r.t. equilibrium 
+        pressure for all components";
+    end for;
+
+    for ind_comp in 1:size(c,2) loop
+      dden_i_dp_adsorpt[ind_comp] := 1 / c[3,ind_comp] *
+        den_tmp ^ (1 / c[3,ind_comp] - 1) * dden_tmp_dp_adsorpt
+        "Partial derivatives of the denominators w.r.t. the equilbrium pressure";
+    end for;
+
+    //
+    // Calculate derivatives of loadings w.r.t. equilibrium pressure
+    //
+    dx_adsorpt_dp_adsorpt :=
+      (dnum_i_dp_adsorpt .* den_i .- num_i .* dden_i_dp_adsorpt) ./ den_i.^2
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "Extended Toth isotherm model: Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real[size(c,2)] den_i
+      "Individual denominator for each component of the isotherm model";
+
+    Real[size(c,2),size(c,2)-1] dnum_i_dy_i
+      "Partial derivatives of the numerators w.r.t. the mole fractions of independent 
+    gas phase components";
+    Real[size(c,2),size(c,2)-1] dden_i_dy_i
+      "Partial derivatives of the denominators w.r.t. the mole fractions of independent 
+    gas phase components";
+
+    Real den_tmp = 1
+      "Identical temporary denominator for all components of the isotherm model";
+    Real[size(c,2)-1] dden_tmp_dy_i
+      "Temporary partial derivatives of the temporary denominator w.r.t. the 
+    independent gas phase components";
+
+  algorithm
+    (p_i,num_i,den_i) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals.calc_p_i_num_i_den_i(
+       p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives of numerators, which varies with components and
+    // mole fractions of independent components
+    //
+    dnum_i_dy_i:=zeros(size(c, 2), size(c, 2) - 1)
+      "Partial derivatives of the numerators w.r.t. the mole fractions of independent 
+    gas phase components";
+
+    for ind_comp in 1:size(c,2) loop
+      if ind_comp < size(c,2) then
+        // Partial derivatives of independent components
+        //
+        dnum_i_dy_i[ind_comp,ind_comp] := c[1,ind_comp] * c[2,ind_comp] * p_adsorpt
+          "Partial derivatives of numerators w.r.t. the mole fractions of independent 
+        gas phase components";
+
+      else
+        // Partial derivatives of dependent component
+        //
+        for ind_y_i in 1:size(c,2)-1 loop
+          dnum_i_dy_i[ind_comp,ind_y_i] := c[1,ind_comp] * c[2,ind_comp] * (-p_adsorpt)
+          "Partial derivatives of numerators w.r.t. the mole fractions of independent 
+        gas phase components";
+
+        end for;
+      end if;
+    end for;
+
+    //
+    // Calculate partial derivatives of the denominator, which varies with
+    // components and mole fractions of independent components
+    //
+    dden_i_dy_i:=zeros(size(c, 2), size(c, 2) - 1)
+      "Partial derivatives of the denominators w.r.t. the mole fractions of independent 
+    gas phase components";
+    dden_tmp_dy_i:=zeros(size(c, 2) - 1)
+      "Temporary partial derivatives of the temporary denominator w.r.t. the 
+    independent gas phase components";
+
+    for ind_comp in 1:size(c,2) loop
+      den_tmp := den_tmp + (c[2,ind_comp] * p_i[ind_comp]) ^ c[3,ind_comp]
+        "Identical temporary denominator";
+    end for;
+
+    for ind_y_i in 1:size(c,2)-1 loop
+      dden_tmp_dy_i[ind_y_i] := c[3,ind_y_i] * (c[2,ind_y_i] * p_i[ind_y_i]) ^
+        (c[3,ind_y_i] - 1) * c[2,ind_y_i] * p_adsorpt +
+        c[3,size(c,2)] * (c[2,size(c,2)] * p_i[size(c,2)]) ^
+        (c[3,size(c,2)] - 1) * c[2,size(c,2)] * (-p_adsorpt)
+        "Temporary partial derivatives of the temporary denominator w.r.t. the 
+      independent gas phase components";
+    end for;
+
+    for ind_comp in 1:size(c,2) loop
+        for ind_y_i in 1:size(c,2)-1 loop
+          dden_i_dy_i[ind_comp,ind_y_i] := 1/c[3,ind_comp] * den_tmp ^
+            (1/c[3,ind_comp] - 1) * dden_tmp_dy_i[ind_y_i]
+            "Partial derivatives of the denominators w.r.t. the mole fractions of  
+          independent gas phase components";
+        end for;
+    end for;
+
+    //
+    // Calculate partial derivatives of uptakes w.r.t. mole fractions of independent
+    // gas phase components
+    //
+    for ind_comp in 1:size(c,2) loop
+      for ind_y_i in 1:size(c,2)-1 loop
+        dx_adsorpt_dy_i[ind_comp,ind_y_i] :=
+          (dnum_i_dy_i[ind_comp,ind_y_i] * den_i[ind_comp] -
+          num_i[ind_comp] * dden_i_dy_i[ind_comp,ind_y_i]) ./ den_i[ind_comp]^2
+          "Partial derivatives of the uptakes w.r.t. the mole fractions of independent 
+        gas phase components at constant pressure and temperature";
+      end for;
+    end for;
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "Extended Toth isotherm model: Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real[size(c,2)] num_i
+      "Individual numerator for each component of the isotherm model";
+    Real[size(c,2)] den_i
+      "Individual denominator for each component of the isotherm model";
+
+    Real[size(c,2)] dnum_i_dT_adsorpt
+      "Derivatives of the numerators w.r.t. the equilibrium temperature";
+    Real[size(c,2)] dden_i_dT_adsorpt
+      "Derivatives of the denominators w.r.t. the equilbrium temperature";
+
+    Real den_tmp
+      "Identical temporary denominator for all components of the isotherm model";
+    Real dden_tmp_dT_adsorpt
+      "Identical temporary partial derivative of the denominator w.r.t. the  
+    equilbrium temperature for all components of the isotherm model";
+
+  algorithm
+    (p_i,num_i,den_i) :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.Toth.Internals.calc_p_i_num_i_den_i(
+       p_i=p_i, c=c, p_threshold_min=p_threshold_min)
+      "Regulated partial pressures and isotherm models' numerators and denominator";
+
+    //
+    // Calculate partial derivatives
+    //
+    den_tmp := 1
+      "Start value of the temporary denominator";
+    dden_tmp_dT_adsorpt := 0
+      "Start value of the temporary derivative of the denominator w.r.t. 
+    equilbrium pressure";
+
+    for ind_comp in 1:size(c,2) loop
+      den_tmp := den_tmp + (c[2,ind_comp] * p_i[ind_comp]) ^ c[3,ind_comp]
+        "Identical temporary denominator";
+
+      dden_tmp_dT_adsorpt := dden_tmp_dT_adsorpt +
+        (c[3,ind_comp] / c[2,ind_comp] * (c[2,ind_comp] * p_i[ind_comp]) ^ c[3,ind_comp]) *
+        dc_dT_adsorpt[2,ind_comp] +
+        ((c[2,ind_comp] * p_i[ind_comp]) ^ c[3,ind_comp] * log(c[2,ind_comp] * p_i[ind_comp])) *
+        dc_dT_adsorpt[3,ind_comp]
+        "Identical temporary partial derivative of the denominator w.r.t. the  
+      equilbrium temperature";
+
+    end for;
+
+    for ind_comp in 1:size(c,2) loop
+      dnum_i_dT_adsorpt[ind_comp] :=
+        (c[2,ind_comp] * p_i[ind_comp]) * dc_dT_adsorpt[1,ind_comp] +
+        (c[1,ind_comp] * p_i[ind_comp]) * dc_dT_adsorpt[2,ind_comp]
+        "Derivatives of numerators w.r.t. equilibrium temperature";
+
+      dden_i_dT_adsorpt[ind_comp] := den_i[ind_comp] *
+        ((1/den_tmp * dden_tmp_dT_adsorpt) * (1/c[3,ind_comp]) +
+        log(den_tmp) * (-1/c[3,ind_comp]^2 * dc_dT_adsorpt[3,ind_comp]))
+        "Derivatives of the denominators w.r.t. the equilbrium temperature";
+    end for;
+
+    //
+    // Calculate derivatives of uptakes wrt. total pressure
+    //
+    dx_adsorpt_dT_adsorpt :=
+      (dnum_i_dT_adsorpt .* den_i .- num_i .* dden_i_dT_adsorpt) ./ den_i.^2
+      "Calculation of the partial derivatives of the equilibrium uptakes w.r.t. the
+     equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 8, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The extended Toth isotherm model calculates equilibrium uptakes <i>x_adsorpt</i>
+as a function of the equilibrium pressure <i>p_adsorpt</i>, mole fractions of
+independent components in the gas or vapor phase <i>y_i</i>, and the equilibrium
+temperature <i>T_adsorpt</i>. Each component of the extended Toth isotherm model
+has three parameters.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The extended Toth isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt,<i>i</i></sub> = x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) * b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,<i>i</i></sub> / ((1 + &sum;[(b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,<i>i</i></sub>) ^ t<sub><i>i</i></sub>(T<sub>adsorpt</sub>)]) ^ (1/t<sub><i>i</i></sub>(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+Herein, for each component <i>i</i<>, <i>x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>)</i> 
+is the saturation uptake, <i>b<sub><i>i</i></sub>(T<sub>adsorpt</sub>)</i> is the Toth 
+coefficient, and <i>t<sub><i>i</i></sub>(T<sub>adsorpt</sub>)</i> is the Toth exponent. 
+Typical temperature dependencies may have the following forms:
+</p>
+</p>
+<pre>
+    x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) =  x<sub>ref,<i>i</i></sub> * <strong>exp</strong>(&Chi;<sub><i>i</i></sub>( * (1 - T<sub>adsorpt</sub>/T<sub>ref,<i>i</i></sub>));
+</pre>
+<pre>
+    b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) = b<sub>ref,<i>i</i></sub> * <strong>exp</strong>(Q<sub><i>i</i></sub>(/(R * T<sub>ref,<i>i</i></sub>) * (T<sub>ref,<i>i</i></sub>/T<sub>adsorpt</sub> - 1));
+</pre>
+<pre>
+    t<sub><i>i</i></sub>(T<sub>adsorpt</sub>) = t<sub>ref,<i>i</i></sub> + &alpha;<sub><i>i</i></sub>( * (1 - T<sub>ref,<i>i</i></sub>/T<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, for each component <i>i</i<>, <i>x<sub>ref,<i>i</i></sub></i> is the saturation 
+uptake at reference temperature <i>T<sub>ref,<i>i</i></sub></i>, <i>b<sub>ref,<i>i</i></sub></i> 
+is the Toth coefficient at reference temperature, and <i>t<sub>ref,<i>i</i></sub></i> is 
+the Toth exponent at reference temperature. The parameter <i>Q<sub><i>i</i></i> is a measure 
+for the isosteric adsorption enthalpy at a fractional loading of <i>x<sub>adsorpt,<i>i</i></sub>/
+x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) = 0.0</i>, the parameter <i>&Chi;<sub><i>i</i></i> 
+describes the change of the saturation uptake with temperature, and the parameter 
+<i>&alpha;<sub><i>i</i></i> describes the change of the Toth exponent with temperature. 
+All seven parameters can be used as fitting parameters.
+<br/><br/>
+Note that the Toth exponent <i>t<sub><i>i</i></sub>(T<sub>adsorpt</sub>)</i> is typically 
+lower than unity. For <i>t<sub><i>i</i></sub>(T<sub>adsorpt</sub>) = 1</i>, the Toth 
+isotherm becomes the Langmuir isotherm. Hence, the Toth exponent <i>t<sub><i>i</i></sub>(T<sub>adsorpt</sub>)</i> 
+can be interpreted as a parameter describing the heterogeneity of the adsorption system.
+</p>
+
+<h4>Required parameter order in function input c[:,no_components]:</h4>
+<p>
+For each component <i>i</i>, the required parameter order in the function input <i>c</i>
+is as follows:
+</p>
+<ul>
+  <li>
+  c[1,<i>i</i>] = x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2,<i>i</i>] = b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[3,<i>i</i>] = t<sub><i>i</i></sub>(T<sub>adsorpt</sub>) in -
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the extended Toth isotherm model for one parameter set
+and two components. In the upper sub-figure, the equilibrium pressure changes with 
+time. In the centre sub-figure, the independent mole fractions change with time.
+In the lower sub-figure, the equilibrium temperature changes with time. The left
+side shows the uptake of component 1, and the right side shows the uptake of
+component 2. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_toth.png\" alt=\"media_functions_equilibria_multi_toth.png\">
+
+</html>"));
+end Toth;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/Toth/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/p_i_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/p_i_xT.mo
new file mode 100644
index 0000000..eaa991b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/p_i_xT.mo
@@ -0,0 +1,214 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals;
+function p_i_xT
+  "Toth-GAB isotherm model developed by Schellevis (2023): Partial pressures as function of uptakes and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start = 1
+    "Lower bound of equilibrium pressure (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start = 10
+    "Upper bound of equilibrium pressure (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of functions
+  //
+protected
+  function func_p_CO2_num
+    "Function used to find root (i.e., p_adsorpt_CO2) numerically"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Real c[:,:]
+      "Coefficients of isotherm model";
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature";
+    input Modelica.Units.SI.Pressure p_adsorpt_H2O
+      "Equilibrium pressure of component 2 (i.e., H2O)";
+    input SorpLib.Units.Uptake x_adsorpt_CO2
+      "Equilibrium uptake of component 1 (i.e., CO2)";
+
+    input Modelica.Units.SI.Pressure p_threshold_min
+      "Threshold for partial pressure of all components: If a partial pressure is
+      below the threshold, its value is set to the threshold";
+  algorithm
+    y :=
+    SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals.x_CO2_pT(
+    p_i=cat(1, {u}, {p_adsorpt_H2O}),
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min) - x_adsorpt_CO2
+    "Function '0 = x(p_adsorpt_CO2, p_adsorpt_H2O, T_adsorpt, c) - x_adsorpt_CO2' 
+     used to find root (i.e., p_adsorpt) numerically";
+  end func_p_CO2_num;
+
+  //
+  // Definition of variables
+  //
+  Boolean bound_ok = false
+    "= true, if bounds are found such that func_p_CO2_num(lb) < 0 and 
+    func_p_CO2_num(ub) > 0";
+
+  Modelica.Units.SI.Pressure p_adsorpt_CO2_lb = p_adsorpt_lb_start
+    "Current best lower bound of equilibrium pressure";
+  Modelica.Units.SI.Pressure p_adsorpt_CO2_ub = p_adsorpt_ub_start
+    "Current best upper bound of equilibrium pressure";
+
+  SorpLib.Units.Uptake x_adsorpt_CO2_lb
+    "Equilibrium uptake at current best lower bound of equilibrium pressure";
+  SorpLib.Units.Uptake x_adsorpt_CO2_ub
+    "Equilibrium uptake at current best upper bound of equilibrium pressure";
+    Integer no=0;
+algorithm
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // First, calculte the equilibrium pressure of component 2 (i.e., H2O)
+  //
+  //
+  p_i[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(
+    x_adsorpt=x_adsorpt[2],
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium pressure of H2O";
+
+  p_i[2] := max(p_i[2], p_threshold_min)
+    "Limit equilibrium pressure if necessary";
+
+  //
+  // Second, find start values such that func_p_CO2_num(lb) < 0 and func_p_CO2_num(ub) > 0
+  //
+  // Reducing p_adsorpt_CO2 reduces x_adsorpt_CO2 -> func_p_CO2_num(p_adsorpt_CO2)
+  // can become < 0
+  // Increasing p_adsorpt_CO2 increases x_adsorpt_CO2 -> func_p_CO2_num(p_adsorpt_CO2)
+  // can become > 0
+  //
+  x_adsorpt_CO2_lb:=
+    SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals.x_CO2_pT(
+    p_i=cat(
+      1,
+      {p_adsorpt_CO2_lb},
+      {p_i[2]}),
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Equilibrium uptake at current best lower bound of equilibrium pressure";
+  x_adsorpt_CO2_ub:=
+    SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals.x_CO2_pT(
+    p_i=cat(
+      1,
+      {p_adsorpt_CO2_ub},
+      {p_i[2]}),
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Equilibrium uptake at current best upper bound of equilibrium pressure";
+
+  while not bound_ok loop
+    if Modelica.Math.isEqual(s1=x_adsorpt_CO2_lb, s2=x_adsorpt[1], eps=tolerance) then
+      p_i[1] := max(p_adsorpt_CO2_lb, p_threshold_min);
+      bound_ok := true;
+      return;
+
+    elseif Modelica.Math.isEqual(s1=x_adsorpt_CO2_ub, s2=x_adsorpt[1], eps=tolerance) then
+      p_i[1] := max(p_adsorpt_CO2_ub, p_threshold_min);
+      bound_ok := true;
+      return;
+
+    elseif x_adsorpt_CO2_lb-x_adsorpt[1] < 0 and x_adsorpt_CO2_ub-x_adsorpt[1] < 0 then
+      p_adsorpt_CO2_lb := p_adsorpt_CO2_ub;
+      x_adsorpt_CO2_lb := x_adsorpt_CO2_ub;
+
+      p_adsorpt_CO2_ub := p_adsorpt_CO2_ub*10;
+      x_adsorpt_CO2_ub :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals.x_CO2_pT(
+        p_i=cat(1, {p_adsorpt_CO2_ub}, {p_i[2]}),
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min);
+
+    elseif x_adsorpt_CO2_lb-x_adsorpt[1] > 0 and x_adsorpt_CO2_ub-x_adsorpt[1] > 0 then
+      p_adsorpt_CO2_ub := p_adsorpt_CO2_lb;
+      x_adsorpt_CO2_ub := x_adsorpt_CO2_lb;
+
+      p_adsorpt_CO2_lb := if p_adsorpt_CO2_lb > Modelica.Constants.small then
+        p_adsorpt_CO2_lb*0.1 else 0;
+      x_adsorpt_CO2_lb :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals.x_CO2_pT(
+        p_i=cat(1, {p_adsorpt_CO2_lb}, {p_i[2]}),
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min);
+
+    else
+      bound_ok := true;
+
+    end if;
+  end while;
+
+  //
+  // Third, find root in the interval lb <= root <= up
+  //
+  p_i[1] := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+    function func_p_CO2_num(
+      c=c,
+      T_adsorpt=T_adsorpt,
+      p_adsorpt_H2O=p_i[2],
+      x_adsorpt_CO2=x_adsorpt[1],
+      p_threshold_min=p_threshold_min),
+    p_adsorpt_CO2_lb,
+    p_adsorpt_CO2_ub,
+    tolerance)
+    "Calculation of the equilibrium pressure of the adsorpt phase";
+
+  p_i[1] := max(p_i[1], p_threshold_min)
+    "Limit equilibrium pressure if necessary";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) as function of the equilibrium uptakes <i>x_adsorpt</i> and the 
+equilibrium temperature <i>T_adsorpt</i>. Thus, this function is a inverse of the 
+function 'x_pyT.' For full details of the original function 'x_pyT,' check the 
+documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end p_i_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/package.mo
new file mode 100644
index 0000000..81afefd
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the Toth-GAB isotherm
+model. Thus, redundancy of code shall be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/package.order
new file mode 100644
index 0000000..0d4f5b9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/package.order
@@ -0,0 +1,3 @@
+p_i_xT
+x_CO2_pT
+x_H20_pT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/x_CO2_pT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/x_CO2_pT.mo
new file mode 100644
index 0000000..64ca324
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/x_CO2_pT.mo
@@ -0,0 +1,74 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals;
+function x_CO2_pT
+  "Toth-GAB isotherm model developed by Schellevis (2023): Equilibrium uptake of component 1 (i.e., CO2) as function of partial pessures and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake x_adsorpt_CO2
+    "Equilibrium uptake of component 1 (i.e., CO2)"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.Uptake x_adsorpt_CO2_dry
+    "Equilibrium uptake of component 1 (i.e., CO2) under dry conditions";
+
+algorithm
+  //
+  // Calculate equilibrium uptake
+  //
+  x_adsorpt_CO2_dry := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+    p_adsorpt=max(p_i[1], p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={c[2,1],
+       c[3,1],
+       c[4,1]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium uptake of CO2 under dry conditions";
+
+  x_adsorpt_CO2 := (1 + c[5,1] * Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+    min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1)) *
+    x_adsorpt_CO2_dry
+    "Calculate equilibrium uptake of CO2";
+
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium uptake of component 1 (i.e., CO2) 
+<i>x_adsorpt_CO2</i> as function of the partial equilibrium pressures <i>p_i</i>,
+and the equilibrium temperature <i>T_adsorpt</i>. For full details of the isotherm 
+model, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_CO2_pT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/x_H20_pT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/x_H20_pT.mo
new file mode 100644
index 0000000..188e3c8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/Internals/x_H20_pT.mo
@@ -0,0 +1,86 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals;
+function x_H20_pT
+  "Toth-GAB isotherm model developed by Schellevis (2023): Equilibrium uptake of component 2 (i.e., H2O) as function of partial pessure and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_H2O
+    "Equilibrium pressure of H2O of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake x_adsorpt_H2O
+    "Equilibrium uptake of component 2 (i.e., H2O)"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.Uptake x_adsorpt_H2O_max=
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(
+    p_adsorpt=max(c[1,2], p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Maximal equilibrium uptake of H2O achieved at relative humidity of 1 (i.e.,
+    p_adsorpt_H2O = p_sat_H2O";
+
+algorithm
+  //
+  // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+  // is required to calculate the equilibrium uptake of component 1 (i.e., CO2)
+  //
+  //
+  x_adsorpt_H2O := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(
+    p_adsorpt=max(p_H2O, p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium uptake of H2O";
+
+  x_adsorpt_H2O := min(x_adsorpt_H2O, x_adsorpt_H2O_max)
+    "Limit equilibrium uptake of H2O to its maximal equilibrium uptake";
+
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium uptake of component 2 (i.e., H2O) 
+<i>x_adsorpt_H2O</i> as function of the partial equilibrium pressure of H2O <i>p_H2O</i>
+and the equilibrium temperature <i>T_adsorpt</i>. For full details of the isotherm 
+model, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_H20_pT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/package.mo
new file mode 100644
index 0000000..c663232
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/package.mo
@@ -0,0 +1,678 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package TothGAB_Schellevis "Package containing all functions regarding the Toth-GAB isotherm developed by Schellevis (2023) for adsorption of CO2 & H2O"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponents;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "Toth-GAB isotherm model developed by Schellevis (2023): Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    //
+    // First, calculate the equilibrium uptake of component 1 (i.e., CO2)
+    //
+    x_adsorpt[1] :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals.x_CO2_pT(
+        p_i=p_i,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of CO2";
+
+    //
+    // Second, calculte the equilibrium uptake of component 2 (i.e., H2O)
+    //
+    x_adsorpt[2] :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals.x_H20_pT(
+        p_H2O=p_i[2],
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "Toth-GAB isotherm model developed by Schellevis (2023): Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    //
+    // First, calculte the equilibrium pressure of component 2 (i.e., H2O)
+    //
+    p_i[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(
+      x_adsorpt=x_adsorpt[2],
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium pressure of H2O";
+
+    p_i[2] := max(p_i[2], p_threshold_min)
+      "Limit equilibrium pressure if necessary";
+
+    //
+    // Second, calculte the equilibrium pressure of component 1 (i.e., CO2)
+    //
+    p_i[1] := y_i[1] * (p_i[2] / (1-y_i[1]))
+      "Calculate equilibrium pressure of CO2";
+
+    p_i[1] := max(p_i[1], p_threshold_min)
+      "Limit equilibrium pressure if necessary";
+
+    //
+    // Third, calculate the equilibrium pressure
+    //
+    p_adsorpt := sum(p_i)
+      "Equilibrium pressure";
+
+    //
+    // Assertions
+    //
+    assert(size(c,2)==2,
+          "This function is only valid for the two components CO2 and H2O with this order!",
+          level=AssertionLevel.error);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "Toth-GAB isotherm model developed by Schellevis (2023): Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+  algorithm
+    //
+    // First, calculte the equilibrium pressure of component 2 (i.e., H2O)
+    //
+    p_i[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(
+      x_adsorpt=x_adsorpt[2],
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium pressure of H2O";
+
+    p_i[2] := max(p_i[2], p_threshold_min)
+      "Limit equilibrium pressure if necessary";
+
+    //
+    // Second, calculte the equilibrium pressure of component 1 (i.e., CO2)
+    //
+    p_i[1] := (1 - p_i[2] / max(p_adsorpt, p_threshold_min)) * max(p_adsorpt, p_threshold_min)
+      "Calculate equilibrium pressure of CO2";
+
+    p_i[1] := max(p_i[1], p_threshold_min)
+      "Limit equilibrium pressure if necessary";
+
+    //
+    // Third, calculate the independent mole fractions (i.e., mole fraction of
+    // component 1)
+    //
+    y_i[1] := p_i[1] / max(p_adsorpt, p_threshold_min)
+      "Mole fractions of independent component in the gas or vapor phase";
+
+    //
+    // Assertions
+    //
+    assert(size(c,2)==2,
+          "This function is only valid for the two components CO2 and H2O with this order!",
+          level=AssertionLevel.error);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "Toth-GAB isotherm model developed by Schellevis (2023): Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_Schellevis.Internals.p_i_xT(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min,
+      p_adsorpt_lb_start=p_adsorpt_lb_start,
+      p_adsorpt_ub_start=p_adsorpt_ub_start,
+      tolerance=tolerance)
+      "Partial pressures";
+
+    p_adsorpt := max(sum(p_i), p_threshold_min)
+      "Equilibrium pressure";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / p_adsorpt
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "Toth-GAB isotherm model developed by Schellevis (2023): Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_CO2_dry
+      "Equilibrium uptake of component 1 (i.e., CO2) under dry conditions";
+    SorpLib.Units.DerUptakeByPressure dx_adsorpt_CO2_dry_dp_adsorpt
+      "Partial derivative of the equilibrium uptake of component 1 (i.e., CO2)
+    w.r.t. the equilibrium pressure";
+
+    Real EF_CO2(unit="1")
+      "Enhancement factor of the CO2 uptake";
+    Real dEF_CO2_dp_adsorpt_H2O(unit="1/Pa")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium pressure of component 2 (i.e., H2O)";
+    Real dEF_CO2_dx_adsorpt_CO2_dry(unit="kg/kg")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium uptake of component 1 (i.e., CO2)";
+    Real dEF_CO2_dp_adsorpt(unit="1/Pa")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium pressure";
+
+  algorithm
+    //
+    // The existing derivative function of the Toth isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // equilibrium pressure (i.e., y_i_[1]).
+    //
+    x_adsorpt_CO2_dry :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[2,1],
+         c[3,1],
+         c[4,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium uptake of CO2 under dry conditions";
+    dx_adsorpt_CO2_dry_dp_adsorpt := y_i_[1]*
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dp(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[2,1],
+         c[3,1],
+         c[4,1]})
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure";
+
+    EF_CO2 := 1 + c[5,1] * Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1)
+      "Enhancement factor of the CO2 uptake";
+    dEF_CO2_dp_adsorpt_H2O :=c[5, 1] * Modelica.Math.exp(c[6, 1] * x_adsorpt_CO2_dry) /
+      max(c[1,1], p_threshold_min)
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium pressure of component 2 (i.e., H2O)";
+    dEF_CO2_dx_adsorpt_CO2_dry :=  c[6,1] * c[5,1] *
+      Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1)
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium uptake of component 1 (i.e., CO2)";
+    dEF_CO2_dp_adsorpt :=
+      dEF_CO2_dp_adsorpt_H2O * y_i_[2] +
+      dEF_CO2_dx_adsorpt_CO2_dry * dx_adsorpt_CO2_dry_dp_adsorpt
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium pressure";
+
+    dx_adsorpt_dp_adsorpt[1] :=
+      dEF_CO2_dp_adsorpt * x_adsorpt_CO2_dry +
+      EF_CO2 * dx_adsorpt_CO2_dry_dp_adsorpt
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant mole fractions and temperature";
+
+    //
+    // The existing derivative function of the GAB isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // equilibrium pressure (i.e., y_i_[2]).
+    //
+    dx_adsorpt_dp_adsorpt[2] := y_i_[2] *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dp(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "Toth-GAB isotherm model developed by Schellevis (2023): Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_CO2_dry
+      "Equilibrium uptake of component 1 (i.e., CO2) under dry conditions";
+    SorpLib.Units.DerUptakeByMolarFraction dx_adsorpt_CO2_dry_dy_i
+      "Partial derivative of the equilibrium uptake of component 1 (i.e., CO2)
+    w.r.t. the independent mole fraction";
+
+    Real EF_CO2(unit="1")
+      "Enhancement factor of the CO2 uptake";
+    Real dEF_CO2_dp_adsorpt_H2O(unit="1/Pa")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium pressure of component 2 (i.e., H2O)";
+    Real dEF_CO2_dx_adsorpt_CO2_dry(unit="kg/kg")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium uptake of component 1 (i.e., CO2)";
+    Real dEF_CO2_dy_i(unit="mol/mol")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    independent mole fraction";
+
+  algorithm
+    //
+    // The existing derivative function of the Toth isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // independent mole fraction (i.e., p_adsorpt).
+    //
+    x_adsorpt_CO2_dry :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[2,1],
+         c[3,1],
+         c[4,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium uptake of CO2 under dry conditions";
+    dx_adsorpt_CO2_dry_dy_i := p_adsorpt*
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dp(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[2,1],
+         c[3,1],
+         c[4,1]})
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    independent mole fraction";
+
+    EF_CO2 := 1 + c[5,1] * Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1)
+      "Enhancement factor of the CO2 uptake";
+    dEF_CO2_dp_adsorpt_H2O := c[5, 1] * Modelica.Math.exp(c[6, 1] * x_adsorpt_CO2_dry) /
+      max(c[1,1], p_threshold_min)
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium pressure of component 2 (i.e., H2O)";
+    dEF_CO2_dx_adsorpt_CO2_dry :=  c[6,1] * c[5,1] *
+      Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1)
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium uptake of component 1 (i.e., CO2)";
+    dEF_CO2_dy_i :=
+      dEF_CO2_dp_adsorpt_H2O * (-p_adsorpt) +
+      dEF_CO2_dx_adsorpt_CO2_dry * dx_adsorpt_CO2_dry_dy_i
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    independent mole fraction";
+
+    dx_adsorpt_dy_i[1,1] :=
+      dEF_CO2_dy_i * x_adsorpt_CO2_dry +
+      EF_CO2 * dx_adsorpt_CO2_dry_dy_i
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    independent mole fraction at constant pressure and temperature";
+
+    //
+    // The existing derivative function of the GAB isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // independent mole fractions (i.e., -p_adsorpt)
+    //
+    dx_adsorpt_dy_i[2,1] := -p_adsorpt *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dp(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    independent mole fractions at constant pressure and temperature";
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "Toth-GAB isotherm model developed by Schellevis (2023): Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_CO2_dry
+      "Equilibrium uptake of component 1 (i.e., CO2) under dry conditions";
+    SorpLib.Units.DerUptakeByTemperature dx_adsorpt_CO2_dry_dT_adsorpt
+      "Partial derivative of the equilibrium uptake of component 1 (i.e., CO2)
+    w.r.t. the equilibrium temperature";
+
+    Real EF_CO2(unit="1")
+      "Enhancement factor of the CO2 uptake";
+    Real dEF_CO2_dc1(unit="1/Pa")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    first coefficient of the Toth isotherm model";
+    Real dEF_CO2_dc5(unit="1")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    fivth coefficient of the Toth isotherm model";
+    Real dEF_CO2_dc6(unit="kg/kg")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    sixth coefficient of the Toth isotherm model";
+    Real dEF_CO2_dx_adsorpt_CO2_dry(unit="kg/kg")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium uptake of component 1 (i.e., CO2)";
+    Real dEF_CO2_dT_adsorpt(unit="1/K")
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium temperature";
+
+  algorithm
+    //
+    // The existing derivative functions of the Toth and GAB isotherm models
+    // correspond to partial derivatives w.r.t. the equilibrium temperature. Note
+    // that for component 1, the uptake is enhanced by an enhancement factor. Thus,
+    // the correct partial derivative w.r.t. the equilibrium temperature must be
+    // calculated.
+    //
+    x_adsorpt_CO2_dry :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[2,1],
+         c[3,1],
+         c[4,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium uptake of CO2 under dry conditions";
+    dx_adsorpt_CO2_dry_dT_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[2,1],
+         c[3,1],
+         c[4,1]},
+      dc_dT_adsorpt={dc_dT_adsorpt[2,1],
+                     dc_dT_adsorpt[3,1],
+                     dc_dT_adsorpt[4,1]})
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium temperature";
+
+    EF_CO2 := 1 + c[5,1] * Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1)
+      "Enhancement factor of the CO2 uptake";
+    dEF_CO2_dc1 := -c[5,1] * Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min)^2
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    first coefficient of the Toth isotherm model";
+    dEF_CO2_dc5 := Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1)
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    fivth coefficient of the Toth isotherm model";
+    dEF_CO2_dc6 := c[5,1] * Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1) *
+      x_adsorpt_CO2_dry
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    sixth coefficient of the Toth isotherm model";
+    dEF_CO2_dx_adsorpt_CO2_dry :=  c[6,1] * c[5,1] *
+      Modelica.Math.exp(c[6,1] * x_adsorpt_CO2_dry) *
+      min(max(p_i[2], p_threshold_min) / max(c[1,1], p_threshold_min), 1)
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium uptake of component 1 (i.e., CO2)";
+    dEF_CO2_dT_adsorpt :=
+      dEF_CO2_dc1 * dc_dT_adsorpt[1,1] +
+      dEF_CO2_dc5 * dc_dT_adsorpt[5,1] +
+      dEF_CO2_dc6 * dc_dT_adsorpt[6,1] +
+      dEF_CO2_dx_adsorpt_CO2_dry * dx_adsorpt_CO2_dry_dT_adsorpt
+      "Partial derivative of the enhancement factor of the CO2 uptake w.r.t. the
+    equilibrium temperature";
+    //Modelica.Utilities.Streams.print(String(dEF_CO2_dx_adsorpt_CO2_dry));
+
+    dx_adsorpt_dT_adsorpt[1] :=
+      dEF_CO2_dT_adsorpt * x_adsorpt_CO2_dry +
+      EF_CO2 * dx_adsorpt_CO2_dry_dT_adsorpt
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant pressure and mole fractions";
+
+    dx_adsorpt_dT_adsorpt[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dT(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]},
+      dc_dT_adsorpt={dc_dT_adsorpt[1,2],
+                     dc_dT_adsorpt[2,2],
+                     dc_dT_adsorpt[3,2],
+                     dc_dT_adsorpt[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  August 5, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Toth-GAB isotherm model calculates equilibrium uptakes <i>x_adsorpt</i> of
+CO<sub>2</sub> and H<sub>2</sub>O on amine-functionalized sorbents as a function 
+of the equilibrium pressure <i>p_adsorpt</i>, mole fractions of independent 
+components in the gas or vapor phase <i>y_i</i>, and the equilibrium temperature 
+<i>T_adsorpt</i>. The model was developed by Schellevis (2023) for modeling of 
+direct air capture systems. A modified Toth isotherm model describes the uptake 
+of CO<sub>2</sub>, while a GAB isotherm model describes the uptake of H<sub>2</sub>O.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The modified Toth isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt,CO<sub>2</sub></sub> = (1 + &beta;<sub>H<sub>2</sub>O</sub> * <strong>exp</strong>(&gamma;<sub>CO<sub>2</sub></sub> * x<sub>adsorpt,CO<sub>2</sub>,dry</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)) * x<sub>adsorpt,CO<sub>2</sub>,dry</sub>;
+</pre>
+<p>
+with
+</p>
+<pre>
+    x<sub>adsorpt,CO<sub>2</sub>,dry</sub> = x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) * b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,CO<sub>2</sub></sub> / ((1 + (b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,CO<sub>2</sub></sub>) ^ t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)) ^ (1/t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)));
+</pre>
+<pre>
+    &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = p<sub>adsorpt</sub>/p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> is the saturation 
+uptake, <i>b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> is the Toth coefficient, 
+and <i>t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> is the Toth exponent. The
+coefficients <i>&beta;<sub>CO<sub>2</sub></sub></i> and <i>&gamma;<sub>H<sub>2</sub>O</sub></i>
+describe the enhancement of the CO<sub>2</sub> uptake depending on the relative humidty
+<i>&phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i>. Typical temperature 
+dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) =  x<sub>ref,CO<sub>2</sub></sub> * <strong>exp</strong>(&Chi;<sub>CO<sub>2</sub></sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,CO<sub>2</sub></sub>));
+</pre>
+<pre>
+    b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) = b<sub>ref,CO<sub>2</sub></sub> * <strong>exp</strong>(Q<sub>CO<sub>2</sub></sub>/(R * T<sub>ref,CO<sub>2</sub></sub>) * (T<sub>ref,CO<sub>2</sub></sub>/T<sub>adsorpt</sub> - 1));
+</pre>
+<pre>
+    t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) = t<sub>ref,CO<sub>2</sub></sub> + &alpha;<sub>CO<sub>2</sub></sub> * (1 - T<sub>ref,CO<sub>2</sub></sub>/T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>ref,CO<sub>2</sub></sub></i> is the saturation uptake at reference 
+temperature <i>T<sub>ref,CO<sub>2</sub></sub></i>, <i>b<sub>ref,CO<sub>2</sub></sub></i> 
+is the Toth coefficient at reference temperature, and <i>t<sub>ref,CO<sub>2</sub></sub></i> 
+is the Toth exponent at reference temperature. The parameter <i>Q<sub>CO<sub>2</sub></sub></i> 
+is a measure for the isosteric adsorption enthalpy at a fractional loading of 
+<i>x<sub>adsorpt,CO<sub>2</sub></sub>/x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) = 0.0</i>, the 
+parameter <i>&Chi;<sub>CO<sub>2</sub></sub></i> describes the change of the saturation 
+uptake with temperature, and the parameter <i>&alpha;<sub>CO<sub>2</sub></sub></i> 
+describes the change of the Toth exponent with temperature. All seven parameters 
+and the two enhancement factors <i>&gamma;<sub>CO<sub>2</sub></sub></i> and
+<i>&beta;<sub>H<sub>2</sub>O</sub></i> can be used as fitting parameters.
+<br/>
+<p>
+The GAB isotherm model has the following form:
+</p>
+</p>
+<pre>
+    x<sub>adsorpt,H<sub>2</sub>O</sub> = x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) / ((1 - k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)) * (1 + (c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) - 1) * k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+with
+</p>
+<pre>
+    &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = p<sub>adsorpt</sub>/p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> is the monolayer 
+uptake and <i>c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> and 
+<i>k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> are affinity coefficients of 
+the GAB isotherm model. These three parameters can be modeled independent of temperature. 
+When assuming these three parameters to be dependent on temperature, typical temperature 
+dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) =  x<sub>mon,ref,H<sub>2</sub>O</sub> * <strong>exp</strong>(&Chi;<sub>H<sub>2</sub>O</sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,H<sub>2</sub>O</sub>));
+</pre>
+<pre>
+    c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>1,H<sub>2</sub>O</sub> - E<sub>10+,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<pre>
+    k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>2-9,H<sub>2</sub>O</sub> - E<sub>10+,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    E<sub>1,H<sub>2</sub>O</sub> = C<sub>H<sub>2</sub>O</sub> - <strong>exp</strong>(D<sub>H<sub>2</sub>O</sub> * T<sub>adsorpt</sub>);
+</pre>
+<pre>
+    E<sub>2-9,H<sub>2</sub>O</sub> = F<sub>H<sub>2</sub>O</sub> + G<sub>H<sub>2</sub>O</sub> * T<sub>adsorpt</sub>;
+</pre>
+<pre>
+    E<sub>10+,H<sub>2</sub>O</sub> = &Delta;h<sub>vap,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>mon,ref,H<sub>2</sub>O</sub></i> is the monolayer uptake at reference 
+temperature <i>T<sub>ref,H<sub>2</sub>O</sub></i> and  <i>&Chi;<sub>H<sub>2</sub>O</sub></i> 
+describes the change of the monolayer uptake with temperature. The coefficient 
+<i>E<sub>1,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption of the first layer 
+and <i>E<sub>2-9,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption of layers 
+2-9: These enthalpies of adsorption can be modeled temperature-dependent as shown 
+in the example above, with the four fitting parameters <i>C<sub>H<sub>2</sub>O</sub></i>, 
+<i>D<sub>H<sub>2</sub>O</sub></i>, <i>E<sub>H<sub>2</sub>O</sub></i>, and <i>F<sub>H<sub>2</sub>O</sub></i>. 
+The coefficient <i>E<sub>10+,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption 
+for layer 10 or higher layers and is assumed to correspond to the temperature-dependent 
+enthalpy of vaporization <i>&Delta;h<sub>vap,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i>.
+</p>
+
+<h4>Required parameter order in function input c[:,no_components]:</h4>
+<p>
+For component 1 (i.e., CO<sub>2</sub>), the required parameter order in the function 
+input <i>c</i> is as follows:
+</p>
+<ul>
+  <li>
+  c[1,1] = p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2,1] = x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[3,1] = b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[4,1] = t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[5,1] = &beta;<sub>CO<sub>2</sub></sub> in -
+  </li>
+  <li>
+  c[6,1] = &gamma;<sub>H<sub>2</sub>O</sub> in kg/kg
+  </li>
+</ul>
+<p>
+For component 2 (i.e., H<sub>2</sub>0), the required parameter order in the function 
+input <i>c</i> is as follows:
+</p>
+<ul>
+  <li>
+  c[1,2] = p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2,2] = x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[3,2] = c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[4,2] = k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[5,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[6,2] = 0 (i.e., not required)
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Toth-GAB isotherm model for one parameter set. In 
+the upper sub-figure, the equilibrium pressure changes with time. In the centre 
+sub-figure, the independent mole fractions change with time. In the lower sub-figure, 
+the equilibrium temperature changes with time. The left side shows the uptake of 
+component 1 (i.e., CO<sub>2</sub>), and the right side shows the uptake of component 
+2 (i.e., H<sub>2</sub>0). 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_toth_gab_s.png\" alt=\"media_functions_equilibria_multi_toth_gab_s.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  <li>
+  Schellevis, H. M. (2023). CO<sub>2</sub> from air: A process engineering approach, PhD thesis. DOI: http://doi.org/10.3990/1.9789036555852.
+  </li>
+</ul>
+</html>"));
+end TothGAB_Schellevis;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_Schellevis/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/dx_CO2_dp.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/dx_CO2_dp.mo
new file mode 100644
index 0000000..e4487ac
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/dx_CO2_dp.mo
@@ -0,0 +1,63 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals;
+function dx_CO2_dp
+  "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Partial derivative of uptake w.r.t. pressure as function of pressure and temperature"
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp;
+
+  //
+  // Definition of inputs
+  //
+  input Real[:] dc_dp_adsorpt
+    "Partial derivatives of coefficients of isotherm model w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real dx_adsorpt_dc1 = c[2] * p_adsorpt /
+    ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+    "Derivative of uptake w.r.t. to first coefficient of Toth isotherm";
+  Real dx_adsorpt_dc2 = c[1] * p_adsorpt *
+    ((c[2]*p_adsorpt)^c[3] + 1) ^ (-1/c[3] - 1)
+    "Derivative of uptake w.r.t. to second coefficient of Toth isotherm";
+  Real dx_adsorpt_dc3 = c[1] * c[2] * p_adsorpt *
+    (log(1 + (c[2]*p_adsorpt)^c[3]) / c[3]^2 -
+    (c[2]*p_adsorpt)^c[3] * log(c[2]*p_adsorpt) /
+    (c[3] * (1 + (c[2]*p_adsorpt)^c[3]))) /
+    ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+    "Derivative of uptake w.r.t. to third coefficient of Toth isotherm";
+
+algorithm
+  dx_adsorpt_dp_adsorpt :=
+    c[1]*c[2] * ((c[2]*p_adsorpt)^c[3] + 1) ^ (-1/c[3] - 1) +
+    dx_adsorpt_dc1*dc_dp_adsorpt[1] +
+    dx_adsorpt_dc2*dc_dp_adsorpt[2] +
+    dx_adsorpt_dc3*dc_dp_adsorpt[3]
+    "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'x_pT' of the Toth isotherm
+model with respect to the equilibrium pressure. For full details of the original function 'x_pT,' 
+check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT\">SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT</a>.
+<br>
+In contrast to the existing function 'dx_dp' of the Toth isotherm model, this function 
+recognises that the coefficients <i>c</i> can also depend on the equilibrium pressure. 
+Therefore, this function has the partial derivatives of the coefficients w.r.t. the
+equilibrium pressure <i>dc_dp_adsorpt</i> as an additional input.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dx_CO2_dp;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/p_i_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/p_i_xT.mo
new file mode 100644
index 0000000..cf648e8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/p_i_xT.mo
@@ -0,0 +1,85 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals;
+function p_i_xT
+  "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Partial pressures as function of uptakes and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  //
+  // First, calculate the equilibrium pressure of component 1 (i.e., CO2)
+  //
+  p_i[1] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.p_xT(
+    x_adsorpt=x_adsorpt[1],
+    T_adsorpt=T_adsorpt,
+    c={c[1,1] * (1 / (1 - c[4,1]*x_adsorpt[2])),
+       c[2,1] * (1 + c[5,1]*x_adsorpt[2]),
+       c[3,1]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium pressure of CO2";
+
+  p_i[1] := max(p_i[1], p_threshold_min)
+    "Limit equilibrium pressure if necessary";
+
+  //
+  // Second, calculte the equilibrium pressure of component 2 (i.e., H2O)
+  //
+  //
+  p_i[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(
+    x_adsorpt=x_adsorpt[2],
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium pressure of H2O";
+
+  p_i[2] := max(p_i[2], p_threshold_min)
+    "Limit equilibrium pressure if necessary";
+
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) as function of the equilibrium uptakes <i>x_adsorpt</i> and the 
+equilibrium temperature <i>T_adsorpt</i>. Thus, this function is a inverse of the 
+function 'x_pyT.' For full details of the original function 'x_pyT,' check the 
+documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end p_i_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/package.mo
new file mode 100644
index 0000000..f0a67aa
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the Toth-GAB isotherm
+model. Thus, redundancy of code shall be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/package.order
new file mode 100644
index 0000000..54b2b57
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/package.order
@@ -0,0 +1,3 @@
+dx_CO2_dp
+p_i_xT
+x_H20_pT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/x_H20_pT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/x_H20_pT.mo
new file mode 100644
index 0000000..cbf5d73
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/Internals/x_H20_pT.mo
@@ -0,0 +1,86 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals;
+function x_H20_pT
+  "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Equilibrium uptake of component 2 (i.e., H2O) as function of partial pessures and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake x_adsorpt_H2O
+    "Equilibrium uptakes of component 2 (i.e., H2O)"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.Uptake x_adsorpt_H2O_max=
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(
+    p_adsorpt=max(c[1,2], p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Maximal equilibrium uptake of H2O achieved at relative humidity of 1 (i.e.,
+    p_adsorpt_H2O = p_sat_H2O";
+
+algorithm
+  //
+  // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+  // is required to calculate the equilibrium uptake of component 1 (i.e., CO2)
+  //
+  //
+  x_adsorpt_H2O := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(
+    p_adsorpt=max(p_i[2], p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium uptake of H2O";
+
+  x_adsorpt_H2O := min(x_adsorpt_H2O, x_adsorpt_H2O_max)
+    "Limit equilibrium uptake of H2O to its maximal equilibrium uptake";
+
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium uptake of component 2 (i.e., H2O) 
+<i>x_adsorpt_H2O</i> as function of the partial equilibrium pressures <i>p_i</i>
+and the equilibrium temperature <i>T_adsorpt</i>. For full details of the isotherm 
+model, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_H20_pT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/package.mo
new file mode 100644
index 0000000..dfe71ed
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/package.mo
@@ -0,0 +1,578 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package TothGAB_StampiBombelli "Package containing all functions regarding the Toth-GAB isotherm developed by Stampi-Bombelli et al. (2020) for adsorption of CO2 & H2O"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponents;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the equilibrium uptake of component 1 (i.e., CO2)
+    //
+    x_adsorpt[2] :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.x_H20_pT(
+      p_i=p_i,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate the equilibrium uptake of component 1 (i.e., CO2)
+    //
+    x_adsorpt[1] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1,1] * (1 / (1 - c[4,1]*x_adsorpt[2])),
+         c[2,1] * (1 + c[5,1]*x_adsorpt[2]),
+         c[3,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium uptake of CO2";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.p_i_xT(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min) "Partial pressures";
+
+    p_adsorpt := sum(p_i)
+      "Equilibrium pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.p_i_xT(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min) "Partial pressures";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / max(p_adsorpt, p_threshold_min)
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Pressure and mole fractions of independent gas phase components as function of uptakes and temperature"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.p_i_xT(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min) "Partial pressures";
+
+    p_adsorpt := max(sum(p_i), p_threshold_min)
+      "Equilibrium pressure";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / p_adsorpt
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real dc_1_CO2_dp_adsorpt
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    Real dc_2_CO2_dp_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    Real dc_3_CO2_dp_adsorpt
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the equilibrium pressure of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.x_H20_pT(
+      p_i=p_i,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    // The existing derivative function of the GAB isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // equilibrium pressure (i.e., y_i_[2]).
+    //
+    dx_adsorpt_dp_adsorpt[2] := y_i_[2] *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dp(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant mole fractions and temperature";
+
+    //
+    // Note that for component 1, the coefficients of the isotherm model are
+    // enhanced by the uptake of component 2. Hence, the parameters c depend also
+    // on the partial pressure of component 2 and, thus, on the equilibrium
+    // pressure. Note that all coefficients are devided by 'y_i_[1]' to compensate
+    // the multiplication by 'y_i_[1],' which is the partial derivative of the
+    // partial pressure of component 1 w.r.t. the equilibrium pressure.
+    //
+    dc_1_CO2_dp_adsorpt := c[1,1] * c[4,1] / (c[4,1] * x_adsorpt_H2O - 1) ^ 2 *
+      dx_adsorpt_dp_adsorpt[2] / y_i_[1]
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    dc_2_CO2_dp_adsorpt := c[2,1] * c[5,1] * dx_adsorpt_dp_adsorpt[2] / y_i_[1]
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    dc_3_CO2_dp_adsorpt := 0 / y_i_[1]
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+
+    dx_adsorpt_dp_adsorpt[1] := y_i_[1]*
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.dx_CO2_dp(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1, 1]*(1/(1 - c[4, 1]*x_adsorpt_H2O)),c[2, 1]*(1 + c[5, 1]*
+        x_adsorpt_H2O),c[3, 1]},
+      dc_dp_adsorpt={dc_1_CO2_dp_adsorpt,dc_2_CO2_dp_adsorpt,dc_3_CO2_dp_adsorpt})
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real dc_1_CO2_dp_adsorpt
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    Real dc_2_CO2_dp_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    Real dc_3_CO2_dp_adsorpt
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the independent mole fractions of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.x_H20_pT(
+      p_i=p_i,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    // The existing derivative function of the GAB isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // independent mole fractions (i.e., -p_adsorpt)
+    //
+    dx_adsorpt_dy_i[2,1] := -p_adsorpt *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dp(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    independent mole fractions at constant pressure and temperature";
+
+    //
+    // Note that for component 1, the coefficients of the isotherm model are
+    // enhanced by the uptake of component 2. Hence, the parameters c depend also
+    // on the partial pressure of component 2 and, thus, on the equilibrium
+    // pressure. Note that all coefficients are devided by 'p_adsorpt' to compensate
+    // the multiplication by 'p_adsorpt,' which is the partial derivative of the
+    // partial pressure of component 1 w.r.t. the equilibrium pressure.
+    //
+    dc_1_CO2_dp_adsorpt := c[1,1] * c[4,1] / (c[4,1] * x_adsorpt_H2O - 1) ^ 2 *
+      dx_adsorpt_dy_i[2,1] / p_adsorpt
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    dc_2_CO2_dp_adsorpt := c[2,1] * c[5,1] * dx_adsorpt_dy_i[2,1] / p_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+    dc_3_CO2_dp_adsorpt := 0 / p_adsorpt
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium pressure";
+
+    dx_adsorpt_dy_i[1, 1] := p_adsorpt*
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.dx_CO2_dp(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1, 1]*(1/(1 - c[4, 1]*x_adsorpt_H2O)),c[2, 1]*(1 + c[5, 1]*
+        x_adsorpt_H2O),c[3, 1]},
+      dc_dp_adsorpt={dc_1_CO2_dp_adsorpt,dc_2_CO2_dp_adsorpt,dc_3_CO2_dp_adsorpt})
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    independent mole fractions at constant pressure and temperature";
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "Toth-GAB isotherm model developed by Stampi-Bombelli et al. (2020): Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real dc_1_CO2_dT_adsorpt
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+    Real dc_2_CO2_dT_adsorpt
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+    Real dc_3_CO2_dT_adsorpt
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the equilibrium temperature of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.TothGAB_StampiBombelli.Internals.x_H20_pT(
+      p_i=p_i,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The existing derivative functions of the Toth and GAB isotherm models
+    // correspond to partial derivatives w.r.t. the equilibrium temperature. Again,
+    // the partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    dx_adsorpt_dT_adsorpt[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dT(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]},
+      dc_dT_adsorpt={dc_dT_adsorpt[1,2],
+                     dc_dT_adsorpt[2,2],
+                     dc_dT_adsorpt[3,2],
+                     dc_dT_adsorpt[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant pressure and mole fractions";
+
+    //
+    // Note that for component 1, the coefficients of the isotherm model are
+    // enhanced by the uptake of component 2. Hence, the parameter dc_dT cannot
+    // directly be passed to the existing derivative function of the Toth isotherm
+    // model. Instead, the the correct derivative must be calculated first.
+    //
+    dc_1_CO2_dT_adsorpt := dc_dT_adsorpt[1,1] * (1 / (1 - c[4,1] * x_adsorpt_H2O)) +
+      c[1,1] * (x_adsorpt_H2O / (c[4,1] * x_adsorpt_H2O - 1) ^ 2 * dc_dT_adsorpt[4,1] +
+      c[4,1] / (c[4,1] * x_adsorpt_H2O - 1) ^ 2 * dx_adsorpt_dT_adsorpt[2])
+      "Partial derivative of first coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+    dc_2_CO2_dT_adsorpt := dc_dT_adsorpt[2,1] * (1 + c[5,1] * x_adsorpt_H2O) +
+      c[2,1] * (x_adsorpt_H2O * dc_dT_adsorpt[5,1] + c[5,1] * dx_adsorpt_dT_adsorpt[2])
+      "Partial derivative of second coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+    dc_3_CO2_dT_adsorpt := dc_dT_adsorpt[3,1]
+      "Partial derivative of third coefficient of the Toth isotherm w.r.t. the
+    equilibrium temperature";
+
+    dx_adsorpt_dT_adsorpt[1] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1,1] * (1 / (1 - c[4,1] * x_adsorpt_H2O)),
+         c[2,1] * (1 + c[5,1] * x_adsorpt_H2O),
+         c[3,1]},
+      dc_dT_adsorpt={dc_1_CO2_dT_adsorpt,
+                     dc_2_CO2_dT_adsorpt,
+                     dc_3_CO2_dT_adsorpt})
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  July 31, 2024, by Mirko Engelpracht:<br/>
+  Adaptations (e.g., object-orientied approach) due to restructuring the library
+  and documentation.
+  </li>
+  <li>
+  September 1, 2021, by Patrik Postweiler:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Toth-GAB isotherm model calculates equilibrium uptakes <i>x_adsorpt</i> of
+CO<sub>2</sub> and H<sub>2</sub>O on amine-functionalized sorbents as a function 
+of the equilibrium pressure <i>p_adsorpt</i>, mole fractions of independent 
+components in the gas or vapor phase <i>y_i</i>, and the equilibrium temperature 
+<i>T_adsorpt</i>. The model was developed by Stampi-Bombelli et al. (2020) for
+modeling of direct air capture systems. A modified Toth isotherm model describes 
+the uptake of CO<sub>2</sub>, while a GAB isotherm model describes the uptake of 
+H<sub>2</sub>O.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The modified Toth isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt,CO<sub>2</sub></sub> = x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) * A<sub>CO<sub>2</sub></sub> * b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) * B<sub>CO<sub>2</sub></sub> * p<sub>adsorpt,CO<sub>2</sub></sub> / ((1 + (b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) * B<sub>CO<sub>2</sub></sub> * p<sub>adsorpt,CO<sub>2</sub></sub>) ^ t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)) ^ (1/t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+with
+</p>
+<pre>
+    A<sub>CO<sub>2</sub></sub> = (1 / (1 - &gamma;<sub>CO<sub>2</sub></sub> * x<sub>adsorpt,H<sub>2</sub>O</sub>));
+</pre>
+<pre>
+    B<sub>CO<sub>2</sub></sub> = (1 + &beta;<sub>CO<sub>2</sub></sub>x<sub>adsorpt,H<sub>2</sub>O</sub>);
+</pre>
+<p>
+Herein, <i>x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> is the saturation 
+uptake, <i>b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> is the Toth coefficient, 
+and <i>t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>)</i> is the Toth exponent. The
+coefficients <i>&gamma;<sub>CO<sub>2</sub></sub></i> and <i>&beta;<sub>H<sub>2</sub>O</sub></i>
+are enhancement factors of the saturation uptake and the Toth coeffient, respectively, both
+multiplied by the uptake of water <i>x<sub>adsorpt,H<sub>2</sub>O</sub></i>. Typical 
+temperature dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) =  x<sub>ref,CO<sub>2</sub></sub> * <strong>exp</strong>(&Chi;<sub>CO<sub>2</sub></sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,CO<sub>2</sub></sub>));
+</pre>
+<pre>
+    b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) = b<sub>ref,CO<sub>2</sub></sub> * <strong>exp</strong>(Q<sub>CO<sub>2</sub></sub>/(R * T<sub>ref,CO<sub>2</sub></sub>) * (T<sub>ref,CO<sub>2</sub></sub>/T<sub>adsorpt</sub> - 1));
+</pre>
+<pre>
+    t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) = t<sub>ref,CO<sub>2</sub></sub> + &alpha;<sub>CO<sub>2</sub></sub> * (1 - T<sub>ref,CO<sub>2</sub></sub>/T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>ref,CO<sub>2</sub></sub></i> is the saturation uptake at reference 
+temperature <i>T<sub>ref,CO<sub>2</sub></sub></i>, <i>b<sub>ref,CO<sub>2</sub></sub></i> 
+is the Toth coefficient at reference temperature, and <i>t<sub>ref,CO<sub>2</sub></sub></i> 
+is the Toth exponent at reference temperature. The parameter <i>Q<sub>CO<sub>2</sub></sub></i> 
+is a measure for the isosteric adsorption enthalpy at a fractional loading of 
+<i>x<sub>adsorpt,CO<sub>2</sub></sub>/x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) = 0.0</i>, the 
+parameter <i>&Chi;<sub>CO<sub>2</sub></sub></i> describes the change of the saturation 
+uptake with temperature, and the parameter <i>&alpha;<sub>CO<sub>2</sub></sub></i> 
+describes the change of the Toth exponent with temperature. All seven parameters 
+and the two enhancement factors <i>&gamma;<sub>CO<sub>2</sub></sub></i> and
+<i>&beta;<sub>H<sub>2</sub>O</sub></i> can be used as fitting parameters.
+<br/>
+<p>
+The GAB isotherm model has the following form:
+</p>
+</p>
+<pre>
+    x<sub>adsorpt,H<sub>2</sub>O</sub> = x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) / ((1 - k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)) * (1 + (c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) - 1) * k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+with
+</p>
+<pre>
+    &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = p<sub>adsorpt</sub>/p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> is the monolayer 
+uptake and <i>c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> and 
+<i>k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> are affinity coefficients of 
+the GAB isotherm model. These three parameters can be modeled independent of temperature. 
+When assuming these three parameters to be dependent on temperature, typical temperature 
+dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) =  x<sub>mon,ref,H<sub>2</sub>O</sub> * <strong>exp</strong>(&Chi;<sub>H<sub>2</sub>O</sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,H<sub>2</sub>O</sub>));
+</pre>
+<pre>
+    c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>1,H<sub>2</sub>O</sub> - E<sub>10+,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<pre>
+    k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>2-9,H<sub>2</sub>O</sub> - E<sub>10+,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    E<sub>1,H<sub>2</sub>O</sub> = C<sub>H<sub>2</sub>O</sub> - <strong>exp</strong>(D<sub>H<sub>2</sub>O</sub> * T<sub>adsorpt</sub>);
+</pre>
+<pre>
+    E<sub>2-9,H<sub>2</sub>O</sub> = F<sub>H<sub>2</sub>O</sub> + G<sub>H<sub>2</sub>O</sub> * T<sub>adsorpt</sub>;
+</pre>
+<pre>
+    E<sub>10+,H<sub>2</sub>O</sub> = &Delta;h<sub>vap,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>mon,ref,H<sub>2</sub>O</sub></i> is the monolayer uptake at reference 
+temperature <i>T<sub>ref,H<sub>2</sub>O</sub></i> and  <i>&Chi;<sub>H<sub>2</sub>O</sub></i> 
+describes the change of the monolayer uptake with temperature. The coefficient 
+<i>E<sub>1,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption of the first layer 
+and <i>E<sub>2-9,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption of layers 
+2-9: These enthalpies of adsorption can be modeled temperature-dependent as shown 
+in the example above, with the four fitting parameters <i>C<sub>H<sub>2</sub>O</sub></i>, 
+<i>D<sub>H<sub>2</sub>O</sub></i>, <i>E<sub>H<sub>2</sub>O</sub></i>, and <i>F<sub>H<sub>2</sub>O</sub></i>. 
+The coefficient <i>E<sub>10+,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption 
+for layer 10 or higher layers and is assumed to correspond to the temperature-dependent 
+enthalpy of vaporization <i>&Delta;h<sub>vap,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i>.
+</p>
+
+<h4>Required parameter order in function input c[:,no_components]:</h4>
+<p>
+For component 1 (i.e., CO<sub>2</sub>), the required parameter order in the function 
+input <i>c</i> is as follows:
+</p>
+<ul>
+  <li>
+  c[1,1] = x<sub>sat,CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2,1] = b<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[3,1] = t<sub>CO<sub>2</sub></sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[4,1] = &gamma;<sub>CO<sub>2</sub></sub> in kg/kg
+  </li>
+  <li>
+  c[5,1] = &beta;<sub>H<sub>2</sub>O</sub> in kg/kg
+  </li>
+</ul>
+<p>
+For component 2 (i.e., H<sub>2</sub>0), the required parameter order in the function 
+input <i>c</i> is as follows:
+</p>
+<ul>
+  <li>
+  c[1,2] = p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2,2] = x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[3,2] = c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[4,2] = k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[5,2] = 0 (i.e., not required)
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Toth-GAB isotherm model for one parameter set. In 
+the upper sub-figure, the equilibrium pressure changes with time. In the centre 
+sub-figure, the independent mole fractions change with time. In the lower sub-figure, 
+the equilibrium temperature changes with time. The left side shows the uptake of 
+component 1 (i.e., CO<sub>2</sub>), and the right side shows the uptake of component 
+2 (i.e., H<sub>2</sub>0). 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_toth_gab_sb.png\" alt=\"media_functions_equilibria_multi_toth_gab_sb.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  <li>
+  Stampi-Bombelli, V. and van der Spek, M. and Mazzotti, M. (2020). Analysis of direct capture of CO2 from ambient air via steamassisted temperature-vacuum swing adsorption, Adsorption, 26(7):1183–1197. DOI: http://doi.org/10.1007/s10450-020-00249-w.
+  </li>
+</ul>
+</html>"));
+end TothGAB_StampiBombelli;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/TothGAB_StampiBombelli/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/p_i_xT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/p_i_xT.mo
new file mode 100644
index 0000000..1330a6a
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/p_i_xT.mo
@@ -0,0 +1,205 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals;
+function p_i_xT
+  "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Partial pressures as function of uptakes and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+    "Equilibrium uptakes of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_adsorpt_lb_start = 1
+    "Lower bound of equilibrium pressure (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Modelica.Units.SI.Pressure p_adsorpt_ub_start = 10
+    "Upper bound of equilibrium pressure (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Numerical inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[size(c,2)] p_i
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of functions
+  //
+protected
+  function func_p_CO2_num
+    "Function used to find root (i.e., p_adsorpt_CO2) numerically"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Real c[:,:]
+      "Coefficients of isotherm model";
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature";
+    input SorpLib.Units.Uptake[size(c,2)] x_adsorpt
+      "Equilibrium uptake";
+
+    input Modelica.Units.SI.Pressure p_threshold_min
+      "Threshold for partial pressure of all components: If a partial pressure is
+      below the threshold, its value is set to the threshold";
+  algorithm
+    y :=
+    SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_CO2_pTx(
+    p_CO2=u,
+    x_adsorpt_H2O=x_adsorpt[2],
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min) - x_adsorpt[1]
+    "Function '0 = x(p_adsorpt_CO2, x_adsorpt_H2O, T_adsorpt, c) - x_adsorpt_CO2' 
+     used to find root (i.e., p_adsorpt) numerically";
+  end func_p_CO2_num;
+
+  //
+  // Definition of variables
+  //
+  Boolean bound_ok = false
+    "= true, if bounds are found such that func_p_CO2_num(lb) < 0 and 
+    func_p_CO2_num(ub) > 0";
+
+  Modelica.Units.SI.Pressure p_adsorpt_CO2_lb = p_adsorpt_lb_start
+    "Current best lower bound of equilibrium pressure";
+  Modelica.Units.SI.Pressure p_adsorpt_CO2_ub = p_adsorpt_ub_start
+    "Current best upper bound of equilibrium pressure";
+
+  SorpLib.Units.Uptake x_adsorpt_CO2_lb=
+    SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_CO2_pTx(
+    p_CO2=p_adsorpt_CO2_lb,
+    x_adsorpt_H2O=x_adsorpt[2],
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Equilibrium uptake at current best lower bound of equilibrium pressure";
+  SorpLib.Units.Uptake x_adsorpt_CO2_ub=
+    SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_CO2_pTx(
+    p_CO2=p_adsorpt_CO2_ub,
+    x_adsorpt_H2O=x_adsorpt[2],
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_threshold_min=p_threshold_min)
+    "Equilibrium uptake at current best upper bound of equilibrium pressure";
+
+algorithm
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // First, calculte the equilibrium pressure of component 2 (i.e., H2O)
+  //
+  //
+  p_i[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(
+    x_adsorpt=x_adsorpt[2],
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium pressure of H2O";
+
+  p_i[2] := max(p_i[2], p_threshold_min)
+    "Limit equilibrium pressure if necessary";
+
+  //
+  // Second, find start values such that func_p_CO2_num(lb) < 0 and func_p_CO2_num(ub) > 0
+  //
+  // Reducing p_adsorpt_CO2 reduces x_adsorpt_CO2 -> func_p_CO2_num(p_adsorpt_CO2)
+  // can become < 0
+  // Increasing p_adsorpt_CO2 increases x_adsorpt_CO2 -> func_p_CO2_num(p_adsorpt_CO2)
+  // can become > 0
+  //
+  while not bound_ok loop
+    if Modelica.Math.isEqual(s1=x_adsorpt_CO2_lb, s2=x_adsorpt[1], eps=tolerance) then
+      p_i[1] := max(p_adsorpt_CO2_lb, p_threshold_min);
+      bound_ok := true;
+      return;
+
+    elseif Modelica.Math.isEqual(s1=x_adsorpt_CO2_ub, s2=x_adsorpt[1], eps=tolerance) then
+      p_i[1] := max(p_adsorpt_CO2_ub, p_threshold_min);
+      bound_ok := true;
+      return;
+
+    elseif x_adsorpt_CO2_lb-x_adsorpt[1] < 0 and x_adsorpt_CO2_ub-x_adsorpt[1] < 0 then
+      p_adsorpt_CO2_lb := p_adsorpt_CO2_ub;
+      x_adsorpt_CO2_lb := x_adsorpt_CO2_ub;
+
+      p_adsorpt_CO2_ub := p_adsorpt_CO2_ub*10;
+      x_adsorpt_CO2_ub :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_CO2_pTx(
+        p_CO2=p_adsorpt_CO2_ub,
+        x_adsorpt_H2O=x_adsorpt[2],
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min);
+
+    elseif x_adsorpt_CO2_lb-x_adsorpt[1] > 0 and x_adsorpt_CO2_ub-x_adsorpt[1] > 0 then
+      p_adsorpt_CO2_ub := p_adsorpt_CO2_lb;
+      x_adsorpt_CO2_ub := x_adsorpt_CO2_lb;
+
+      p_adsorpt_CO2_lb := if p_adsorpt_CO2_lb > Modelica.Constants.small then
+        p_adsorpt_CO2_lb*0.1 else 0;
+      x_adsorpt_CO2_lb :=
+        SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_CO2_pTx(
+        p_CO2=p_adsorpt_CO2_lb,
+        x_adsorpt_H2O=x_adsorpt[2],
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_threshold_min=p_threshold_min);
+
+    else
+      bound_ok := true;
+
+    end if;
+  end while;
+
+  //
+  // Third, find root in the interval lb <= root <= up
+  //
+  p_i[1] := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+    f=function func_p_CO2_num(
+      c=c,
+      T_adsorpt=T_adsorpt,
+      x_adsorpt=x_adsorpt,
+      p_threshold_min=p_threshold_min),
+    u_min=p_adsorpt_CO2_lb,
+    u_max=p_adsorpt_CO2_ub,
+    tolerance=tolerance)
+    "Calculation of the equilibrium pressure of the adsorpt phase";
+
+  p_i[1] := max(p_i[1], p_threshold_min)
+    "Limit equilibrium pressure if necessary";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium pressures <i>p_i</i> (i.e., partial
+pressures) as function of the equilibrium uptakes <i>x_adsorpt</i> and the 
+equilibrium temperature <i>T_adsorpt</i>. Thus, this function is a inverse of the 
+function 'x_pyT.' For full details of the original function 'x_pyT,' check the 
+documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end p_i_xT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/package.mo
new file mode 100644
index 0000000..a2c6953
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB;
+package Internals "Internal functions used to avoid redundancy"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used for various functions of the weighted-
+average dual site Toth-GAB isotherm model. Thus, redundancy of code shall 
+be avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Internals;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/package.order
new file mode 100644
index 0000000..ed828e2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/package.order
@@ -0,0 +1,3 @@
+p_i_xT
+x_CO2_pTx
+x_H20_pT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/x_CO2_pTx.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/x_CO2_pTx.mo
new file mode 100644
index 0000000..26247ed
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/x_CO2_pTx.mo
@@ -0,0 +1,76 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals;
+function x_CO2_pTx
+  "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Equilibrium uptake of component 1 (i.e., CO2) as function of partial pessures and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_CO2
+    "Equilibrium pressures of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.Uptake x_adsorpt_H2O
+    "Equilibrium uptake of component 2 (i.e., H2O)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake x_adsorpt_CO2
+    "Equilibrium uptake of component 1 (i.e., CO2)"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  //
+  // Calculate equilibrium uptake
+  //
+  x_adsorpt_CO2 := (1 - Modelica.Math.exp(-c[4,1] / x_adsorpt_H2O)) *
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+    p_adsorpt=max(p_CO2, p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={c[1,1],
+       c[2,1],
+       c[3,1]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps) + Modelica.Math.exp(-c[4,1] / x_adsorpt_H2O) *
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+    p_adsorpt=max(p_CO2, p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={c[5,1],
+       c[6,1],
+       c[7,1]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium uptake of CO2";
+
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium uptake of component 1 (i.e., CO2) 
+<i>x_adsorpt_CO2</i> as function of the partial equilibrium pressure of CO2 <i>p_CO2</i>,
+the equilibrium uptake of component 2 (i.e., H2O) <i>x_adsorpt_H2O</i>, and the 
+equilibrium temperature <i>T_adsorpt</i>. For full details of the isotherm model, 
+check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_CO2_pTx;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/x_H20_pT.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/x_H20_pT.mo
new file mode 100644
index 0000000..bbeb2ab
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/Internals/x_H20_pT.mo
@@ -0,0 +1,86 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals;
+function x_H20_pT
+  "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Equilibrium uptake of component 2 (i.e., H2O) as function of partial pessures and temperature"
+  extends SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialMulti;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_H2O
+    "Equilibrium pressure of H2O of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.Uptake x_adsorpt_H2O
+    "Equilibrium uptake of component 2 (i.e., H2O)"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.Uptake x_adsorpt_H2O_max=
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(
+    p_adsorpt=max(c[1,2], p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Maximal equilibrium uptake of H2O achieved at relative humidity of 1 (i.e.,
+    p_adsorpt_H2O = p_sat_H2O";
+
+algorithm
+  //
+  // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+  // is required to calculate the equilibrium uptake of component 1 (i.e., CO2)
+  //
+  //
+  x_adsorpt_H2O := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(
+    p_adsorpt=max(p_H2O, p_threshold_min),
+    T_adsorpt=T_adsorpt,
+    c={max(c[1,2], p_threshold_min),
+       c[2,2],
+       c[3,2],
+       c[4,2]},
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Calculate equilibrium uptake of H2O";
+
+  x_adsorpt_H2O := min(x_adsorpt_H2O, x_adsorpt_H2O_max)
+    "Limit equilibrium uptake of H2O to its maximal equilibrium uptake";
+
+  //
+  // Assertions
+  //
+  assert(size(c,2)==2,
+        "This function is only valid for the two components CO2 and H2O with this order!",
+        level=AssertionLevel.error);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the equilibrium uptake of component 2 (i.e., H2O) 
+<i>x_adsorpt_H2O</i> as function of the partial equilibrium pressure of H2O <i>p_H2O</i>
+and the equilibrium temperature <i>T_adsorpt</i>. For full details of the isotherm 
+model, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.x_pyT\">SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.x_pyT</a>.
+</p>
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end x_H20_pT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/package.mo
new file mode 100644
index 0000000..04b8247
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/package.mo
@@ -0,0 +1,831 @@
+within SorpLib.Media.Functions.SorptionEquilibria.MultiComponents;
+package WeightedAverageDualSiteTothGAB "Package containing all functions regarding the weighted-average dual site Toth-GAB isotherm developed by Young et al. (2021) for adsorption of CO2 & H2O"
+  extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialMultiComponents;
+
+  //
+  // Internal package
+  //
+  redeclare final function extends x_pyT
+    "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Uptakes as function of pressure, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the equilibrium uptake of component 1 (i.e., CO2)
+    //
+    x_adsorpt[2] :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_H20_pT(
+      p_H2O=p_i[2],
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate the equilibrium uptake of component 1 (i.e., CO2)
+    //
+    x_adsorpt[1] :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_CO2_pTx(
+      p_CO2=p_i[1],
+      x_adsorpt_H2O=x_adsorpt[2],
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of CO2";
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end x_pyT;
+
+  redeclare final function extends p_xyT
+    "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Pressure as function of uptakes, mole fractions of independent gas phase components, and temperature"
+  algorithm
+    //
+    // First, calculte the equilibrium pressure of component 2 (i.e., H2O)
+    //
+    p_i[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(
+      x_adsorpt=x_adsorpt[2],
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium pressure of H2O";
+
+    p_i[2] := max(p_i[2], p_threshold_min)
+      "Limit equilibrium pressure if necessary";
+
+    //
+    // Second, calculte the equilibrium pressure of component 1 (i.e., CO2)
+    //
+    p_i[1] := y_i[1] * (p_i[2] / (1-y_i[1]))
+      "Calculate equilibrium pressure of CO2";
+
+    p_i[1] := max(p_i[1], p_threshold_min)
+      "Limit equilibrium pressure if necessary";
+
+    //
+    // Third, calculate the equilibrium pressure
+    //
+    p_adsorpt := sum(p_i)
+      "Equilibrium pressure";
+
+    //
+    // Assertions
+    //
+    assert(size(c,2)==2,
+          "This function is only valid for the two components CO2 and H2O with this order!",
+          level=AssertionLevel.error);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          y_i = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.y_pxT(p_adsorpt=p_adsorpt, x_adsorpt=x_adsorpt, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end p_xyT;
+
+  redeclare final function extends y_pxT
+    "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Mole fractions of independent gas phase components as function of uptakes, pressure, and temperature"
+  algorithm
+    //
+    // First, calculte the equilibrium pressure of component 2 (i.e., H2O)
+    //
+    p_i[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(
+      x_adsorpt=x_adsorpt[2],
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Calculate equilibrium pressure of H2O";
+
+    p_i[2] := max(p_i[2], p_threshold_min)
+      "Limit equilibrium pressure if necessary";
+
+    //
+    // Second, calculte the equilibrium pressure of component 1 (i.e., CO2)
+    //
+    p_i[1] := (1 - p_i[2] / max(p_adsorpt, p_threshold_min)) * max(p_adsorpt, p_threshold_min)
+      "Calculate equilibrium pressure of CO2";
+
+    p_i[1] := max(p_i[1], p_threshold_min)
+      "Limit equilibrium pressure if necessary";
+
+    //
+    // Third, calculate the independent mole fractions (i.e., mole fraction of
+    // component 1)
+    //
+    y_i[1] := p_i[1] / max(p_adsorpt, p_threshold_min)
+      "Mole fractions of independent component in the gas or vapor phase";
+
+    //
+    // Assertions
+    //
+    assert(size(c,2)==2,
+          "This function is only valid for the two components CO2 and H2O with this order!",
+          level=AssertionLevel.error);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.x_pyT(p_adsorpt=p_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance),
+          p_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.p_xyT(x_adsorpt=x_adsorpt, y_i=y_i, T_adsorpt=T_adsorpt, c=c, p_threshold_min=p_threshold_min, p_adsorpt_lb_start=p_adsorpt_lb_start, p_adsorpt_ub_start=p_adsorpt_ub_start, tolerance=tolerance)));
+  end y_pxT;
+
+  redeclare final function extends py_xT
+    "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Pressure and mole fractions of independent gas phase components as function of uptakes and temperature (numerical solution)"
+  algorithm
+    p_i :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.p_i_xT(
+      x_adsorpt=x_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min,
+      p_adsorpt_lb_start=p_adsorpt_lb_start,
+      p_adsorpt_ub_start=p_adsorpt_ub_start,
+      tolerance=tolerance)
+      "Partial pressures";
+
+    p_adsorpt := max(sum(p_i), p_threshold_min)
+      "Equilibrium pressure";
+
+    for ind in 1:size(c,2)-1 loop
+      y_i[ind] := p_i[ind] / p_adsorpt
+        "Mole fractions of independent components in the gas or vapor phase";
+    end for;
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true);
+  end py_xT;
+
+  redeclare final function extends dx_dp
+    "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Partial derivative of uptakes w.r.t. pressure at constant mole fractions and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real C_CO2_wet(unit="1")
+      "Contribution of saturation uptake of CO2 under wet conditions";
+    Real C_CO2_dry(unit="1")
+      "Contribution of saturation uptake of CO2 under dry conditions";
+
+    SorpLib.Units.Uptake x_adsorpt_CO2_wet
+      "Equilibrium uptakes of component 1 (i.e., CO2) under wet conditions";
+    SorpLib.Units.Uptake x_adsorpt_CO2_dry
+      "Equilibrium uptakes of component 1 (i.e., CO2) under dry conditions";
+
+    Real dC_CO2_wet_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of contribution of saturation uptake of CO2 under wet 
+    conditions w.r.t. equilibrium uptake of H2O";
+    Real dC_CO2_dry_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of contribution of saturation uptake of CO2 under dry 
+    conditions w.r.t. equilibrium uptake of H2O";
+
+    SorpLib.Units.DerUptakeByPressure dx_adsorpt_CO2_wet_dp_adsorpt
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    wet conditions w.r.t. equilibrium pressure";
+    SorpLib.Units.DerUptakeByPressure dx_adsorpt_CO2_dry_dp_adsorpt
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    dry conditions w.r.t. equilibrium pressure";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the equilibrium pressure of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_H20_pT(
+      p_H2O=p_i[2],
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    // The existing derivative function of the GAB isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // equilibrium pressure (i.e., y_i_[2]).
+    //
+    dx_adsorpt_dp_adsorpt[2] := y_i_[2] *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dp(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant mole fractions and temperature";
+
+    //
+    // The existing derivative function of the Toth isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // equilibrium pressure (i.e., y_i_[1]).
+    //
+    C_CO2_wet := Modelica.Math.exp(-c[4,1] / x_adsorpt_H2O)
+      "Contribution of saturation uptake of CO2 under wet conditions";
+    C_CO2_dry := (1 - C_CO2_wet)
+      "Contribution of saturation uptake of CO2 under dry conditions";
+
+    x_adsorpt_CO2_wet :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[5,1],
+         c[6,1],
+         c[7,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Equilibrium uptakes of component 1 (i.e., CO2) under wet conditions";
+    x_adsorpt_CO2_dry :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1,1],
+         c[2,1],
+         c[3,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Equilibrium uptakes of component 1 (i.e., CO2) under dry conditions";
+
+    dC_CO2_wet_dx_adsorpt_H2O :=
+      c[4,1] * C_CO2_wet / x_adsorpt_H2O^2
+      "Partial derivative of contribution of saturation uptake of CO2 under wet 
+    conditions w.r.t. equilibrium uptake of H2O";
+    dC_CO2_dry_dx_adsorpt_H2O :=
+      -dC_CO2_wet_dx_adsorpt_H2O
+      "Partial derivative of contribution of saturation uptake of CO2 under dry 
+    conditions w.r.t. equilibrium uptake of H2O";
+
+    dx_adsorpt_CO2_wet_dp_adsorpt := y_i_[1] *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dp(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[5,1],
+         c[6,1],
+         c[7,1]})
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    wet conditions w.r.t. equilibrium pressure";
+    dx_adsorpt_CO2_dry_dp_adsorpt := y_i_[1] *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dp(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1,1],
+         c[2,1],
+         c[3,1]})
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    dry conditions w.r.t. equilibrium pressure";
+
+    dx_adsorpt_dp_adsorpt[1] :=
+      dC_CO2_dry_dx_adsorpt_H2O * dx_adsorpt_dp_adsorpt[2] * x_adsorpt_CO2_dry +
+      C_CO2_dry * dx_adsorpt_CO2_dry_dp_adsorpt +
+      dC_CO2_wet_dx_adsorpt_H2O * dx_adsorpt_dp_adsorpt[2] * x_adsorpt_CO2_wet +
+      C_CO2_wet * dx_adsorpt_CO2_wet_dp_adsorpt
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant mole fractions and temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dy
+    "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Partial derivative of uptakes w.r.t. mole fractions of independent gas phase components at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real C_CO2_wet(unit="1")
+      "Contribution of saturation uptake of CO2 under wet conditions";
+    Real C_CO2_dry(unit="1")
+      "Contribution of saturation uptake of CO2 under dry conditions";
+
+    SorpLib.Units.Uptake x_adsorpt_CO2_wet
+      "Equilibrium uptakes of component 1 (i.e., CO2) under wet conditions";
+    SorpLib.Units.Uptake x_adsorpt_CO2_dry
+      "Equilibrium uptakes of component 1 (i.e., CO2) under dry conditions";
+
+    Real dC_CO2_wet_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of contribution of saturation uptake of CO2 under wet 
+    conditions w.r.t. equilibrium uptake of H2O";
+    Real dC_CO2_dry_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of contribution of saturation uptake of CO2 under dry 
+    conditions w.r.t. equilibrium uptake of H2O";
+
+    SorpLib.Units.DerUptakeByMolarFraction dx_adsorpt_CO2_wet_dy_i
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    wet conditions w.r.t. independent mole fractions";
+    SorpLib.Units.DerUptakeByMolarFraction dx_adsorpt_CO2_dry_dy_i
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    dry conditions w.r.t. independent mole fractions";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the independent mole fractions of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_H20_pT(
+      p_H2O=p_i[2],
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    // The existing derivative function of the GAB isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // independent mole fractions (i.e., -p_adsorpt)
+    //
+    dx_adsorpt_dy_i[2,1] := -p_adsorpt *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dp(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    independent mole fractions at contant pressure and temperature";
+
+    //
+    // The existing derivative function of the Toth isotherm model corresponds to
+    // the partial derivative w.r.t. the partial pressure. Hence, the result must
+    // be multiplied by the partial derivative of the partial pressure w.r.t. the
+    // independent mole fractions (i.e., p_adsorpt)
+    //
+    C_CO2_wet := Modelica.Math.exp(-c[4,1] / x_adsorpt_H2O)
+      "Contribution of saturation uptake of CO2 under wet conditions";
+    C_CO2_dry := (1 - C_CO2_wet)
+      "Contribution of saturation uptake of CO2 under dry conditions";
+
+    x_adsorpt_CO2_wet :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[5,1],
+         c[6,1],
+         c[7,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Equilibrium uptakes of component 1 (i.e., CO2) under wet conditions";
+    x_adsorpt_CO2_dry :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1,1],
+         c[2,1],
+         c[3,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Equilibrium uptakes of component 1 (i.e., CO2) under dry conditions";
+
+    dC_CO2_wet_dx_adsorpt_H2O :=
+      c[4,1] * C_CO2_wet / x_adsorpt_H2O^2
+      "Partial derivative of contribution of saturation uptake of CO2 under wet 
+    conditions w.r.t. equilibrium uptake of H2O";
+    dC_CO2_dry_dx_adsorpt_H2O :=
+      -dC_CO2_wet_dx_adsorpt_H2O
+      "Partial derivative of contribution of saturation uptake of CO2 under dry 
+    conditions w.r.t. equilibrium uptake of H2O";
+
+    dx_adsorpt_CO2_wet_dy_i := p_adsorpt *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dp(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[5,1],
+         c[6,1],
+         c[7,1]})
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    wet conditions w.r.t. independent mole fractions";
+    dx_adsorpt_CO2_dry_dy_i := p_adsorpt *
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dp(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1,1],
+         c[2,1],
+         c[3,1]})
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    dry conditions w.r.t. independent mole fractions";
+
+    dx_adsorpt_dy_i[1, 1] :=
+      dC_CO2_dry_dx_adsorpt_H2O * dx_adsorpt_dy_i[2,1] * x_adsorpt_CO2_dry +
+      C_CO2_dry * dx_adsorpt_CO2_dry_dy_i +
+      dC_CO2_wet_dx_adsorpt_H2O * dx_adsorpt_dy_i[2,1] * x_adsorpt_CO2_wet +
+      C_CO2_wet * dx_adsorpt_CO2_wet_dy_i
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    independent mole fractions at constant pressure and temperature";
+  end dx_dy;
+
+  redeclare final function extends dx_dT
+    "Weighted-average dual site Toth-GAB isotherm model developed by Young et al. (2021): Partial derivative of uptakes w.r.t. temperature at constant pressure and mole fractions"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.Uptake x_adsorpt_H2O
+      "Equilibrium uptakes of component 2 (i.e., H2O)";
+
+    Real C_CO2_wet(unit="1")
+      "Contribution of saturation uptake of CO2 under wet conditions";
+    Real C_CO2_dry(unit="1")
+      "Contribution of saturation uptake of CO2 under dry conditions";
+
+    SorpLib.Units.Uptake x_adsorpt_CO2_wet
+      "Equilibrium uptakes of component 1 (i.e., CO2) under wet conditions";
+    SorpLib.Units.Uptake x_adsorpt_CO2_dry
+      "Equilibrium uptakes of component 1 (i.e., CO2) under dry conditions";
+
+    Real dC_CO2_wet_dc4(unit="kg/kg")
+      "Partial derivative of contribution of saturation uptake of CO2 under wet 
+    conditions w.r.t. fourth coefficient of the weighted-average dual site Toth
+    isotherm model";
+    Real dC_CO2_dry_dc4(unit="kg/kg")
+      "Partial derivative of contribution of saturation uptake of CO2 under dry 
+    conditions w.r.t. fourth coefficient of the weighted-average dual site Toth
+    isotherm model";
+    Real dC_CO2_wet_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of contribution of saturation uptake of CO2 under wet 
+    conditions w.r.t. equilibrium uptake of H2O";
+    Real dC_CO2_dry_dx_adsorpt_H2O(unit="kg/kg")
+      "Partial derivative of contribution of saturation uptake of CO2 under dry 
+    conditions w.r.t. equilibrium uptake of H2O";
+
+    SorpLib.Units.DerUptakeByTemperature dx_adsorpt_CO2_wet_dT_adsorpt
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    wet conditions w.r.t. equilibrium temperature";
+    SorpLib.Units.DerUptakeByTemperature dx_adsorpt_CO2_dry_dT_adsorpt
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    dry conditions w.r.t. equilibrium temperature";
+
+  algorithm
+    //
+    // First, calculte the equilibrium uptake of component 2 (i.e., H2O) because it
+    // is required to calculate the partial derivative of the equilibrium uptake
+    // w.r.t. the equilibrium temperature of component 1 (i.e., CO2)
+    //
+    x_adsorpt_H2O :=
+      SorpLib.Media.Functions.SorptionEquilibria.MultiComponents.WeightedAverageDualSiteTothGAB.Internals.x_H20_pT(
+      p_H2O=p_i[2],
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_threshold_min=p_threshold_min)
+      "Calculate equilibrium uptake of H2O limited to its maximal equilibrium uptake";
+
+    //
+    // Second, calculate partial derivatives:
+    //
+    // The existing derivative functions of the Toth and GAB isotherm models
+    // correspond to partial derivatives w.r.t. the equilibrium temperature. Again,
+    // the partial derivative of component 2 (i.e., H2O) must be calculated first
+    // because it is required to calculate the partial derivative of component 1
+    // (i.e., CO2).
+    //
+    dx_adsorpt_dT_adsorpt[2] := SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.dx_dT(
+      p_adsorpt=max(p_i[2], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={max(c[1,2], p_threshold_min),
+         c[2,2],
+         c[3,2],
+         c[4,2]},
+      dc_dT_adsorpt={dc_dT_adsorpt[1,2],
+                     dc_dT_adsorpt[2,2],
+                     dc_dT_adsorpt[3,2],
+                     dc_dT_adsorpt[4,2]})
+      "Partial derivative of second component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant pressure and mole fractions";
+
+    //
+    // Note that for component 1, the coefficients of the isotherm model are
+    // enhanced by the uptake of component 2. Hence, the parameter dc_dT cannot
+    // directly be passed to the existing derivative function of the Toth isotherm
+    // model. Instead, the the correct derivative must be calculated first.
+    //
+    C_CO2_wet := Modelica.Math.exp(-c[4,1] / x_adsorpt_H2O)
+      "Contribution of saturation uptake of CO2 under wet conditions";
+    C_CO2_dry := (1 - C_CO2_wet)
+      "Contribution of saturation uptake of CO2 under dry conditions";
+
+    x_adsorpt_CO2_wet :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[5,1],
+         c[6,1],
+         c[7,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Equilibrium uptakes of component 1 (i.e., CO2) under wet conditions";
+    x_adsorpt_CO2_dry :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1,1],
+         c[2,1],
+         c[3,1]},
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+      "Equilibrium uptakes of component 1 (i.e., CO2) under dry conditions";
+
+    dC_CO2_wet_dc4 := -C_CO2_wet / x_adsorpt_H2O
+      "Partial derivative of contribution of saturation uptake of CO2 under wet 
+    conditions w.r.t. fourth coefficient of the weighted-average dual site Toth
+    isotherm model";
+    dC_CO2_dry_dc4 := -dC_CO2_wet_dc4
+      "Partial derivative of contribution of saturation uptake of CO2 under dry 
+    conditions w.r.t. fourth coefficient of the weighted-average dual site Toth
+    isotherm model";
+    dC_CO2_wet_dx_adsorpt_H2O :=
+      c[4,1] * C_CO2_wet / x_adsorpt_H2O^2
+      "Partial derivative of contribution of saturation uptake of CO2 under wet 
+    conditions w.r.t. equilibrium uptake of H2O";
+    dC_CO2_dry_dx_adsorpt_H2O :=
+      -dC_CO2_wet_dx_adsorpt_H2O
+      "Partial derivative of contribution of saturation uptake of CO2 under dry 
+    conditions w.r.t. equilibrium uptake of H2O";
+
+    dx_adsorpt_CO2_wet_dT_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[5,1],
+         c[6,1],
+         c[7,1]},
+      dc_dT_adsorpt={dc_dT_adsorpt[5,1],
+                     dc_dT_adsorpt[6,1],
+                     dc_dT_adsorpt[7,1]})
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    wet conditions w.r.t. equilibrium temperature";
+    dx_adsorpt_CO2_dry_dT_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.dx_dT(
+      p_adsorpt=max(p_i[1], p_threshold_min),
+      T_adsorpt=T_adsorpt,
+      c={c[1,1],
+         c[2,1],
+         c[3,1]},
+      dc_dT_adsorpt={dc_dT_adsorpt[1,1],
+                     dc_dT_adsorpt[2,1],
+                     dc_dT_adsorpt[3,1]})
+      "Partial derivative of equilibrium uptakes of component 1 (i.e., CO2) under 
+    dry conditions w.r.t. equilibrium temperature";
+
+    dx_adsorpt_dT_adsorpt[1] :=
+      (dC_CO2_dry_dc4 * dc_dT_adsorpt[4,1] + dC_CO2_dry_dx_adsorpt_H2O *
+      dx_adsorpt_dT_adsorpt[2]) * x_adsorpt_CO2_dry +
+      C_CO2_dry * dx_adsorpt_CO2_dry_dT_adsorpt +
+      (dC_CO2_wet_dc4 * dc_dT_adsorpt[4,1] + dC_CO2_wet_dx_adsorpt_H2O *
+      dx_adsorpt_dT_adsorpt[2]) * x_adsorpt_CO2_wet +
+      C_CO2_wet * dx_adsorpt_CO2_wet_dT_adsorpt
+      "Partial derivative of first component's equilibrium uptake w.r.t. the 
+    equilibrium pressure at constant pressure and mole fractions";
+  end dx_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  August 2, 2024, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The weighted-average dual site Toth-GAB isotherm model calculates equilibrium 
+uptakes <i>x_adsorpt</i> of CO<sub>2</sub> and H<sub>2</sub>O on amine-functionalized 
+sorbents as a function of the equilibrium pressure <i>p_adsorpt</i>, mole fractions 
+of independent components in the gas or vapor phase <i>y_i</i>, and the equilibrium 
+temperature <i>T_adsorpt</i>. The model was developed by Young et al. (2021) for 
+modeling of direct air capture systems. A weighted-average dual site Toth isotherm 
+model describes the uptake of CO<sub>2</sub>, while a GAB isotherm model describes 
+the uptake of H<sub>2</sub>O.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The weighted-average dual site Toth isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt,CO<sub>2</sub></sub> = (1 - <strong>exp</strong>(-C<sub>CO<sub>2</sub></sub> / x<sub>adsorpt,H<sub>2</sub>O</sub>)) * x<sub>adsorpt,CO<sub>2</sub>,dry</sub> + <strong>exp</strong>(-C<sub>CO<sub>2</sub></sub> / x<sub>adsorpt,H<sub>2</sub>O</sub>) * x<sub>adsorpt,CO<sub>2</sub>,wet</sub>;
+</pre>
+<p>
+with:
+</p>
+<pre>
+    x<sub>adsorpt,CO<sub>2</sub>,dry</sub> = x<sub>sat,CO<sub>2</sub>,dry</sub>(T<sub>adsorpt</sub>) * b<sub>CO<sub>2</sub>,dry</sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,CO<sub>2</sub></sub> / ((1 + (b<sub>CO<sub>2</sub>,dry</sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,CO<sub>2</sub></sub>) ^ t<sub>CO<sub>2</sub>,dry</sub>(T<sub>adsorpt</sub>)) ^ (1/t<sub>CO<sub>2</sub>,dry</sub>(T<sub>adsorpt</sub>)));
+</pre>
+<pre>
+    x<sub>adsorpt,CO<sub>2</sub>,wet</sub> = x<sub>sat,CO<sub>2</sub>,wet</sub>(T<sub>adsorpt</sub>) * b<sub>CO<sub>2</sub>,wet</sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,CO<sub>2</sub></sub> / ((1 + (b<sub>CO<sub>2</sub>,wet</sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt,CO<sub>2</sub></sub>) ^ t<sub>CO<sub>2</sub>,wet</sub>(T<sub>adsorpt</sub>)) ^ (1/t<sub>CO<sub>2</sub>,wet</sub>(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+Herein, <i>x<sub>sat,CO<sub>2</sub>,i</sub>(T<sub>adsorpt</sub>)</i> is the 
+saturation uptake, <i>b<sub>CO<sub>2</sub>,i</sub>(T<sub>adsorpt</sub></i> is 
+the Toth coefficient, and <i>t<sub>CO<sub>2</sub>,i</sub>(T<sub>adsorpt</sub>)</i>
+is the Toth exponent under dry (i.e., <i>i = dry</i>) or wet (i.e., <i>i = wet</i>). 
+conditions. The coefficient <i>C<sub>CO<sub>2</sub></sub></i> describes the 
+critical water loading to accout for the presence of H<sub>2</sub>O (i.e., 
+H<sub>2</sub>O uptake). Typical temperature dependencies may have the following 
+forms:
+</p>
+<pre>
+    x<sub>sat,i</sub>(T<sub>adsorpt</sub>) =  x<sub>ref,i</sub> * <strong>exp</strong>(&Chi;<sub>i</sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,i</sub>));
+</pre>
+<pre>
+    b<sub>i</sub>(T<sub>adsorpt</sub>) = b<sub>ref,i</sub> * <strong>exp</strong>(Q<sub>i</sub>/(R * T<sub>ref,i</sub>) * (T<sub>ref,i</sub>/T<sub>adsorpt</sub> - 1));
+</pre>
+<pre>
+    t<sub>i</sub>(T<sub>adsorpt</sub>) = t<sub>ref,i</sub> + &alpha;<sub>i</sub> * (1 - T<sub>ref,i</sub>/T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>ref,i</sub></i> is the saturation uptake at reference temperature 
+<i>T<sub>ref,i</sub></i> under dry (i.e., <i>i = dry</i>) or wet (i.e., <i>i = 
+wet</i>). conditions, <i>b<sub>ref,i</sub></i> is the Toth coefficient at reference 
+temperature, and <i>t<sub>ref,i</sub></i> is the Toth exponent at reference 
+temperature. The parameter <i>Q<sub>i</sub></i> is a measure for the isosteric 
+adsorption enthalpy, the parameter <i>&Chi;<sub>i</sub></i> describes the change 
+of the saturation uptake with temperature, and the parameter <i>&alpha;<sub>i</sub></i> 
+describes the change of the Toth exponent with temperature. All parameters can be 
+used as fitting parameters.
+<br/>
+<p>
+The GAB isotherm model has the following form:
+</p>
+</p>
+<pre>
+    x<sub>adsorpt,H<sub>2</sub>O</sub> = x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) / ((1 - k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)) * (1 + (c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) - 1) * k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) * &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+with
+</p>
+<pre>
+    &phi;<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = p<sub>adsorpt</sub>/p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> is the monolayer 
+uptake and <i>c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> and 
+<i>k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i> are affinity coefficients of 
+the GAB isotherm model. These three parameters can be modeled independent of temperature. 
+When assuming these three parameters to be dependent on temperature, typical temperature 
+dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) =  x<sub>mon,ref,H<sub>2</sub>O</sub> * <strong>exp</strong>(&Chi;<sub>H<sub>2</sub>O</sub> * (1 - T<sub>adsorpt</sub>/T<sub>ref,H<sub>2</sub>O</sub>));
+</pre>
+<pre>
+    c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>1,H<sub>2</sub>O</sub> - E<sub>10+,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<pre>
+    k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>2-9,H<sub>2</sub>O</sub> - E<sub>10+,H<sub>2</sub>O</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    E<sub>1,H<sub>2</sub>O</sub> = C<sub>H<sub>2</sub>O</sub> - <strong>exp</strong>(D<sub>H<sub>2</sub>O</sub> * T<sub>adsorpt</sub>);
+</pre>
+<pre>
+    E<sub>2-9,H<sub>2</sub>O</sub> = F<sub>H<sub>2</sub>O</sub> + G<sub>H<sub>2</sub>O</sub> * T<sub>adsorpt</sub>;
+</pre>
+<pre>
+    E<sub>10+,H<sub>2</sub>O</sub> = &Delta;h<sub>vap,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>mon,ref,H<sub>2</sub>O</sub></i> is the monolayer uptake at reference 
+temperature <i>T<sub>ref,H<sub>2</sub>O</sub></i> and  <i>&Chi;<sub>H<sub>2</sub>O</sub></i> 
+describes the change of the monolayer uptake with temperature. The coefficient 
+<i>E<sub>1,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption of the first layer 
+and <i>E<sub>2-9,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption of layers 
+2-9: These enthalpies of adsorption can be modeled temperature-dependent as shown 
+in the example above, with the four fitting parameters <i>C<sub>H<sub>2</sub>O</sub></i>, 
+<i>D<sub>H<sub>2</sub>O</sub></i>, <i>E<sub>H<sub>2</sub>O</sub></i>, and <i>F<sub>H<sub>2</sub>O</sub></i>. 
+The coefficient <i>E<sub>10+,H<sub>2</sub>O</sub></i> is the enthalpy of adsorption 
+for layer 10 or higher layers and is assumed to correspond to the temperature-dependent 
+enthalpy of vaporization <i>&Delta;h<sub>vap,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>)</i>.
+</p>
+
+<h4>Required parameter order in function input c[:,no_components]:</h4>
+<p>
+For component 1 (i.e., CO<sub>2</sub>), the required parameter order in the function 
+input <i>c</i> is as follows:
+</p>
+<ul>
+  <li>
+  c[1,1] = x<sub>sat,CO<sub>2</sub>,dry</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2,1] = b<sub>CO<sub>2</sub>,dry</sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[3,1] = t<sub>CO<sub>2</sub>,dry</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[4,1] = C<sub>CO<sub>2</sub></sub> in kg/kg
+  </li>
+  <li>
+  c[5,1] = x<sub>sat,CO<sub>2</sub>,wet</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[6,1] = b<sub>CO<sub>2</sub>,wet</sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[7,1] = t<sub>CO<sub>2</sub>,wet</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+</ul>
+<p>
+For component 2 (i.e., H<sub>2</sub>0), the required parameter order in the function 
+input <i>c</i> is as follows:
+</p>
+<ul>
+  <li>
+  c[1,2] = p<sub>sat,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2,2] = x<sub>mon,H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[3,2] = c<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[4,2] = k<sub>H<sub>2</sub>O</sub>(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[5,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[6,2] = 0 (i.e., not required)
+  </li>
+  <li>
+  c[7,2] = 0 (i.e., not required)
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the weighted-average dual site Toth-GAB isotherm model 
+for one parameter set. In the upper sub-figure, the equilibrium pressure changes 
+with time. In the centre sub-figure, the independent mole fractions change with 
+time. In the lower sub-figure, the equilibrium temperature changes with time. The 
+left side shows the uptake of component 1 (i.e., CO<sub>2</sub>), and the right 
+side shows the uptake of component 2 (i.e., H<sub>2</sub>0). 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_multi_wads_toth_gab.png\" alt=\"media_functions_equilibria_multi_wads_toth_gab.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  <li>
+  Young, J. and Garc&iacute;a-D&iacute;ez, E. and Garcia, S. and van der Spek, M. (2021). The impact of binary water–CO<sub>2</sub> isotherm models on the optimal performance of sorbent-based direct air capture processes, Energy & Environmental Science, 14:5377. DOI: http://doi.org/10.1039/d1ee01272j.
+  </li>
+</ul>
+</html>"));
+end WeightedAverageDualSiteTothGAB;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/package.order
new file mode 100644
index 0000000..6d0f8d9
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/WeightedAverageDualSiteTothGAB/package.order
@@ -0,0 +1,8 @@
+Internals
+x_pyT
+p_xyT
+y_pxT
+py_xT
+dx_dp
+dx_dy
+dx_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/package.mo
new file mode 100644
index 0000000..3694bd1
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/package.mo
@@ -0,0 +1,66 @@
+within SorpLib.Media.Functions.SorptionEquilibria;
+package MultiComponents "Functions required to calculate sorption equlibria for multicomponents"
+extends Modelica.Icons.VariantsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains isotherm models for multi-component adsorption. Each isotherm 
+model is stored as a separate package. There are also test models for each isotherm 
+model, which test all functions of the isotherm models regarding their implementation. 
+The isotherm models already implemented can be found in the package content. 
+</p>
+
+<h4>Implemented functions for each isotherm model</h4>
+<p>
+The following functions are provided for each isotherm model:
+</p>
+<ul>
+  <li>
+  Equilibrium uptakes as function of equilibrium pressure, mole fractions of independent 
+  gas phase components, and equilibrium temperature.
+  </li>
+  <li>
+  Equilibrium pressure as function of equilibrium uptakes, mole fractions of independent 
+  gas phase components, and eqiulibrium temperature.
+  </li>
+  <li>
+  Mole fractions of independent gas phase components as function of equilibrium pressure,
+  equilibrium uptakes, and eqiulibrium temperature.
+  </li>
+  <li>
+  Equilibrium pressure and mole fractions of independent gas phase components as function 
+  of equilibrium uptakes and eqiulibrium temperature.
+  </li>
+  <li>
+  Partial derivatives of equilibrium uptakes w.r.t. equilibrium pressure at constant mole 
+  fractions and temperature.
+  </li>
+  <li>
+  Partial derivatives of equilibrium uptakes w.r.t. mole fractions of independent gas phase 
+  components at constant pressure and temperature.
+  </li>
+  <li>
+  Partial derivatives of equilibrium uptakes w.r.t. equilibrium temperature at constant
+  pressure and mole fractions.
+  </li>
+</ul>
+
+<h4>How to add new isotherm models</h4>
+<p>
+To add a new isotherm model, duplicate the package of a similar isotherm model that is 
+already implemented. Then, customise all functions of the isotherm model. If new 
+functions are implemented (e.g., equilibrium temperature as function of equilibrium 
+pressure, independent mole fractions, and uptake), add these for all existing isotherm 
+models as well. Then, adapt the test models and check the functions of the new isotherm 
+model regarding their implementation. Finally, write the documentation for each function, 
+model, and package.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end MultiComponents;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/package.order b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/package.order
new file mode 100644
index 0000000..d63e983
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/MultiComponents/package.order
@@ -0,0 +1,10 @@
+Langmuir
+Sips
+Toth
+TothGAB_StampiBombelli
+TothGAB_Schellevis
+MechanisticTothGAB
+WeightedAverageDualSiteTothGAB
+IAST_N2
+IAST_N3
+Testers
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BET/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BET/package.mo
new file mode 100644
index 0000000..842549d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BET/package.mo
@@ -0,0 +1,784 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package BET "Package containing all functions regarding the BET isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  redeclare final function extends x_pT
+    "BET isotherm model: Uptake as function of pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+    Real F = c[2]*c[3] * phi / (1 - phi)
+      "Pre-factor";
+    Real A = 1 + (c[4]*c[5]/2 - c[4]) * phi ^ (c[4]-1) -
+      (c[4]*c[5] - c[4] + 1) * phi^c[4] + (c[4]*c[5]/2) * phi ^ (c[4]+1)
+      "Numerator of the fraction";
+    Real B = 1 + (c[3] - 1) * phi + (c[3]*c[5]/2 - c[3]) * phi^c[4] -
+      (c[3]*c[5]/2) * phi ^ (c[4]+1)
+      "Denominator of the fraction";
+
+  algorithm
+    x_adsorpt := F * A/B
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BET.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare function p_xT
+    "BET isotherm model: Pressure as function of uptake and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT_num(
+        redeclare final function func_x_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BET.x_pT);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BET.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "BET isotherm model: Partial derivative of uptake w.r.t. pressure at constant temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+    Real F = c[2]*c[3] * phi / (1 - phi)
+      "Pre-factor";
+    Real A = 1 + (c[4]*c[5]/2 - c[4]) * phi ^ (c[4]-1) -
+      (c[4]*c[5] - c[4] + 1) * phi^c[4] + (c[4]*c[5]/2) * phi ^ (c[4]+1)
+      "Numerator of the fraction";
+    Real B = 1 + (c[3] - 1) * phi + (c[3]*c[5]/2 - c[3]) * phi^c[4] -
+      (c[3]*c[5]/2) * phi ^ (c[4]+1)
+      "Denominator of the fraction";
+
+    Real dphi_dp_adsorpt =  1/c[1]
+      "Partial derivative of relative pressure w.r.t. to pressure";
+
+    Real dF_dphi = (c[2] * c[3]) / (phi - 1)^2
+      "Partial derivative of pre-factor w.r.t. to relative pressure";
+    Real dA_dphi = (c[4] * phi ^ (c[4]-2) * ((c[4] + 1) * c[5] * phi^2 +
+      (-2*c[4]*c[5] + 2*c[4] - 2) * phi + (c[4]-1) * c[5] - 2*c[4] + 2)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to relative pressure";
+    Real dB_dphi = -(c[3] * (c[4]+1) * c[5] * phi^c[4]) / 2 +
+      c[4] * ((c[3]*c[5])/2 - c[3]) * phi ^ (c[4]-1) + c[3] - 1
+      "Partial derivative of denominator of the fraction w.r.t. to relative pressure";
+
+    Real dF_dp_adsorpt = dF_dphi * dphi_dp_adsorpt
+      "Partial derivative of pre-factor w.r.t. pressure";
+    Real dA_dp_adsorpt = dA_dphi * dphi_dp_adsorpt
+      "Partial derivative of numerator w.r.t. pressure";
+    Real dB_dp_adsorpt = dB_dphi * dphi_dp_adsorpt
+      "Partial derivative of denominator w.r.t. pressure";
+
+  algorithm
+    dx_adsorpt_dp_adsorpt := (A/B) * dF_dp_adsorpt +
+      (F/B) * dA_dp_adsorpt +
+      (-F * A/B^2) * dB_dp_adsorpt
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dT
+    "BET isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+    Real F = c[2]*c[3] * phi / (1 - phi)
+      "Pre-factor";
+    Real A = 1 + (c[4]*c[5]/2 - c[4]) * phi ^ (c[4]-1) -
+      (c[4]*c[5] - c[4] + 1) * phi^c[4] + (c[4]*c[5]/2) * phi ^ (c[4]+1)
+      "Numerator of the fraction";
+    Real B = 1 + (c[3] - 1) * phi + (c[3]*c[5]/2 - c[3]) * phi^c[4] -
+      (c[3]*c[5]/2) * phi ^ (c[4]+1)
+      "Denominator of the fraction";
+
+    Real dphi_dT_adsorpt = -p_adsorpt/c[1]^2 * dc_dT_adsorpt[1]
+      "Partial derivative of relative pressure w.r.t. to temperature";
+
+    Real dF_dc2 = c[3] * phi / (1 - phi)
+      "Partial derivative of pre-factor w.r.t. to second coefficient of BET isotherm";
+    Real dF_dc3 = c[2] * phi / (1 - phi)
+      "Partial derivative of pre-factor w.r.t. to third coefficient of BET isotherm";
+    Real dF_dphi = (c[2] * c[3]) / (phi - 1)^2
+      "Partial derivative of pre-factor w.r.t. to relative pressure";
+
+    Real dA_dc4 = (phi ^ (c[4]-1) * ((c[5] * phi^2 + (2-2*c[5]) * phi + c[5] - 2) *
+      log(phi) * c[4] - 2*phi * log(phi) + c[5] * phi^2 + (2-2*c[5]) * phi + c[5] -
+      2)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to fourth coefficient 
+    of BET isotherm";
+    Real dA_dc5 = (c[4] * phi ^ (c[4]-1) * (phi^2 - 2*phi + 1)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to fivth coefficient 
+    of BET isotherm";
+    Real dA_dphi = (c[4] * phi ^ (c[4]-2) * ((c[4] + 1) * c[5] * phi^2 +
+      (-2*c[4]*c[5] + 2*c[4] - 2) * phi + (c[4]-1) * c[5] - 2*c[4] + 2)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to relative pressure";
+
+    Real dB_dc3 = -(phi^c[4] * (c[5]*phi - c[5] + 2) - 2*phi) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to third coefficient 
+    of BET isotherm";
+    Real dB_dc4 = -(c[3] * phi^c[4] * (c[5]*phi - c[5] + 2) * log(phi)) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to fourth coefficient 
+    of BET isotherm";
+    Real dB_dc5 = -(c[3] * (phi-1) * phi^c[4]) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to fivth coefficient 
+    of BET isotherm";
+    Real dB_dphi = -(c[3] * (c[4]+1) * c[5] * phi^c[4]) / 2 +
+      c[4] * ((c[3]*c[5])/2 - c[3]) * phi ^ (c[4]-1) + c[3] - 1
+      "Partial derivative of denominator of the fraction w.r.t. to relative pressure";
+
+    Real dF_dT_adsorpt = dF_dc2 * dc_dT_adsorpt[2] +
+      dF_dc3 * dc_dT_adsorpt[3] +
+      dF_dphi * dphi_dT_adsorpt
+      "Partial derivative of pre-factor w.r.t. temperature";
+    Real dA_dT_adsorpt = dA_dc4 * dc_dT_adsorpt[4] +
+      dA_dc5 * dc_dT_adsorpt[5] +
+      dA_dphi * dphi_dT_adsorpt
+      "Partial derivative of numerator w.r.t. temperature";
+    Real dB_dT_adsorpt = dB_dc3 * dc_dT_adsorpt[3] +
+      dB_dc4 * dc_dT_adsorpt[4] +
+      dB_dc5 * dc_dT_adsorpt[5] +
+      dB_dphi * dphi_dT_adsorpt
+      "Partial derivative of denominator w.r.t. temperature";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt := (A/B) * dF_dT_adsorpt +
+      (F/B) * dA_dT_adsorpt +
+      (-F * A/B^2) * dB_dT_adsorpt
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dp_dp
+    "BET isotherm model: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+    Real F = c[2]*c[3] * phi / (1 - phi)
+      "Pre-factor";
+    Real A = 1 + (c[4]*c[5]/2 - c[4]) * phi ^ (c[4]-1) -
+      (c[4]*c[5] - c[4] + 1) * phi^c[4] + (c[4]*c[5]/2) * phi ^ (c[4]+1)
+      "Numerator of the fraction";
+    Real B = 1 + (c[3] - 1) * phi + (c[3]*c[5]/2 - c[3]) * phi^c[4] -
+      (c[3]*c[5]/2) * phi ^ (c[4]+1)
+      "Denominator of the fraction";
+
+    Real dphi_dp_adsorpt =  1/c[1]
+      "Partial derivative of relative pressure w.r.t. to pressure";
+
+    Real dF_dphi = (c[2] * c[3]) / (phi - 1)^2
+      "Partial derivative of pre-factor w.r.t. to relative pressure";
+    Real dA_dphi = (c[4] * phi ^ (c[4]-2) * ((c[4] + 1) * c[5] * phi^2 +
+      (-2*c[4]*c[5] + 2*c[4] - 2) * phi + (c[4]-1) * c[5] - 2*c[4] + 2)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to relative pressure";
+    Real dB_dphi = -(c[3] * (c[4]+1) * c[5] * phi^c[4]) / 2 +
+      c[4] * ((c[3]*c[5])/2 - c[3]) * phi ^ (c[4]-1) + c[3] - 1
+      "Partial derivative of denominator of the fraction w.r.t. to relative pressure";
+
+    Real dF_dp_adsorpt = dF_dphi * dphi_dp_adsorpt
+      "Partial derivative of pre-factor w.r.t. pressure";
+    Real dA_dp_adsorpt = dA_dphi * dphi_dp_adsorpt
+      "Partial derivative of numerator w.r.t. pressure";
+    Real dB_dp_adsorpt = dB_dphi * dphi_dp_adsorpt
+      "Partial derivative of denominator w.r.t. pressure";
+
+    Real ddF_dphi_dp_adsorpt=
+      (-(2 * c[2] * c[3]) / (phi - 1)^3) * dphi_dp_adsorpt
+      "Second-order artial derivative of pre-factor w.r.t. to relative pressure 
+    and pressure";
+    Real ddA_dphi_dp_adsorpt=
+      ((c[4] * phi^(c[4] - 3) * (phi * (c[4] * (c[5] * ((c[4] + 1) * phi -
+      2 * c[4] + 2) + 2 * c[4] - 4) + 2) + (c[4] - 2) * (c[4] - 1) * c[5] -
+      2 * (c[4] - 2) * (c[4] - 1))) / 2) * dphi_dp_adsorpt
+      "Second-order artial derivative of numerator of the fraction w.r.t. to 
+    relative pressure and pressure";
+    Real ddB_dphi_dp_adsorpt=
+      (-(c[3] * c[4] * phi^(c[4] - 2) * (c[5] * ((c[4] + 1) * phi -
+      c[4] + 1) + 2 * c[4] - 2)) / 2) * dphi_dp_adsorpt
+      "Second-order artial derivative of denominator of the fraction w.r.t. to 
+    relative pressure and pressure";
+
+    Real ddF_dp_adsorpt_dp_adsorpt= (dphi_dp_adsorpt) * ddF_dphi_dp_adsorpt
+      "Second-order partial derivative of pre-factor w.r.t. pressure";
+    Real ddA_dp_adsorpt_dp_adsorpt= (dphi_dp_adsorpt) * ddA_dphi_dp_adsorpt
+      "Second-order partial derivative of numerator w.r.t. pressure";
+    Real ddB_dp_adsorpt_dp_adsorpt= (dphi_dp_adsorpt) * ddB_dphi_dp_adsorpt
+      "Second-order partial derivative of denominator w.r.t. pressure";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt :=
+      ((1/B * dF_dp_adsorpt) * dA_dp_adsorpt +
+       (-A/B^2 * dF_dp_adsorpt) * dB_dp_adsorpt +
+       (A/B) * ddF_dp_adsorpt_dp_adsorpt) +
+      ((1/B * dA_dp_adsorpt) * dF_dp_adsorpt +
+       (-F/B^2 * dA_dp_adsorpt) * dB_dp_adsorpt +
+       (F/B) * ddA_dp_adsorpt_dp_adsorpt) +
+       ((-A/B^2 * dB_dp_adsorpt) * dF_dp_adsorpt +
+        (-F/B^2 * dB_dp_adsorpt) * dA_dp_adsorpt +
+        (2 * F * A/B^3 * dB_dp_adsorpt) * dB_dp_adsorpt +
+        (-F * A/B^2) * ddB_dp_adsorpt_dp_adsorpt)
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+
+  redeclare final function extends ddx_dT_dT
+    "BET isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+    Real F = c[2]*c[3] * phi / (1 - phi)
+      "Pre-factor";
+    Real A = 1 + (c[4]*c[5]/2 - c[4]) * phi ^ (c[4]-1) -
+      (c[4]*c[5] - c[4] + 1) * phi^c[4] + (c[4]*c[5]/2) * phi ^ (c[4]+1)
+      "Numerator of the fraction";
+    Real B = 1 + (c[3] - 1) * phi + (c[3]*c[5]/2 - c[3]) * phi^c[4] -
+      (c[3]*c[5]/2) * phi ^ (c[4]+1)
+      "Denominator of the fraction";
+
+    Real dphi_dT_adsorpt = -p_adsorpt/c[1]^2 * dc_dT_adsorpt[1]
+      "Partial derivative of relative pressure w.r.t. to temperature";
+
+    Real dF_dc2 = c[3] * phi / (1 - phi)
+      "Partial derivative of pre-factor w.r.t. to second coefficient of BET isotherm";
+    Real dF_dc3 = c[2] * phi / (1 - phi)
+      "Partial derivative of pre-factor w.r.t. to third coefficient of BET isotherm";
+    Real dF_dphi = (c[2] * c[3]) / (phi - 1)^2
+      "Partial derivative of pre-factor w.r.t. to relative pressure";
+
+    Real dA_dc4 = (phi ^ (c[4]-1) * ((c[5] * phi^2 + (2-2*c[5]) * phi + c[5] - 2) *
+      log(phi) * c[4] - 2*phi * log(phi) + c[5] * phi^2 + (2-2*c[5]) * phi + c[5] -
+      2)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to fourth coefficient 
+    of BET isotherm";
+    Real dA_dc5 = (c[4] * phi ^ (c[4]-1) * (phi^2 - 2*phi + 1)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to fivth coefficient 
+    of BET isotherm";
+    Real dA_dphi = (c[4] * phi ^ (c[4]-2) * ((c[4] + 1) * c[5] * phi^2 +
+      (-2*c[4]*c[5] + 2*c[4] - 2) * phi + (c[4]-1) * c[5] - 2*c[4] + 2)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to relative pressure";
+
+    Real dB_dc3 = -(phi^c[4] * (c[5]*phi - c[5] + 2) - 2*phi) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to third coefficient 
+    of BET isotherm";
+    Real dB_dc4 = -(c[3] * phi^c[4] * (c[5]*phi - c[5] + 2) * log(phi)) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to fourth coefficient 
+    of BET isotherm";
+    Real dB_dc5 = -(c[3] * (phi-1) * phi^c[4]) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to fivth coefficient 
+    of BET isotherm";
+    Real dB_dphi = -(c[3] * (c[4]+1) * c[5] * phi^c[4]) / 2 +
+      c[4] * ((c[3]*c[5])/2 - c[3]) * phi ^ (c[4]-1) + c[3] - 1
+      "Partial derivative of denominator of the fraction w.r.t. to relative pressure";
+
+    Real dF_dT_adsorpt = dF_dc2 * dc_dT_adsorpt[2] +
+      dF_dc3 * dc_dT_adsorpt[3] +
+      dF_dphi * dphi_dT_adsorpt
+      "Partial derivative of pre-factor w.r.t. temperature";
+    Real dA_dT_adsorpt = dA_dc4 * dc_dT_adsorpt[4] +
+      dA_dc5 * dc_dT_adsorpt[5] +
+      dA_dphi * dphi_dT_adsorpt
+      "Partial derivative of numerator w.r.t. temperature";
+    Real dB_dT_adsorpt = dB_dc3 * dc_dT_adsorpt[3] +
+      dB_dc4 * dc_dT_adsorpt[4] +
+      dB_dc5 * dc_dT_adsorpt[5] +
+      dB_dphi * dphi_dT_adsorpt
+      "Partial derivative of denominator w.r.t. temperature";
+
+    Real ddphi_dT_adsorpt_dT_adsorpt = (2*p_adsorpt/c[1]^3 * dc_dT_adsorpt[1]^2) +
+      (-p_adsorpt/c[1]^2) * ddc_dT_adsorpt_dT_adsorpt[1]
+      "Second-order partial derivative of relative pressure w.r.t. to temperature";
+
+    Real ddF_dc2_dc3 = phi / (1 - phi)
+      "Second-order partial derivative of pre-factor w.r.t. to second and third 
+     coefficient of BET isotherm";
+    Real ddF_dc2_dphi = c[3] / (phi -1)^2
+      "Second-order partial derivative of pre-factor w.r.t. to second coefficient 
+    of BET isotherm and relative pressure";
+    Real ddF_dc3_dphi = c[2] / (phi -1)^2
+      "Second-order partial derivative of pre-factor w.r.t. to third coefficient 
+    of BET isotherm and relative pressure";
+    Real ddF_dphi_dphi = -2 * (c[2] * c[3]) / (phi - 1)^3
+      "Second-order partial derivative of pre-factor w.r.t. to relative pressure";
+
+    Real ddA_dc4_dc4 = (phi^(c[4] - 1) * log(phi) * ((c[5] * (phi - 1) + 2) *
+      (phi - 1) * log(phi) * c[4] - 2 * phi * log(phi) + 2 * c[5] * phi^2 - 4 *
+      (c[5] - 1) * phi + 2 * c[5] - 4)) / 2
+      "Second-order partial derivative of numerator w.r.t. to fourth coefficient
+    of BET isoterm";
+    Real ddA_dc4_dc5 = ((phi - 1)^2 * phi^(c[4] - 1) * (c[4] * log(phi) + 1)) / 2
+      "Second-order partial derivative of numerator w.r.t. to fourth and fivth 
+    coefficient of BET isoterm";
+    Real ddA_dc4_dphi = ((phi - 1) * phi^(c[4] - 2) * (c[4] * (c[5] * ((c[4] + 1) *
+      phi - c[4] + 1) + 2 * c[4] - 2) * log(phi) + (2 * c[4] + 1) * c[5] * phi -
+      (2 * c[4] - 1) * c[5] + 4 * c[4] - 2)) / 2
+      "Second-order partial derivative of numerator w.r.t. to fourth coefficient
+    of BET isoterm and relative pressure";
+    Real ddA_dc5_dphi = (c[4] * (phi - 1) * phi^(c[4] - 2) * (c[4] * phi + phi -
+      c[4] + 1)) / 2
+      "Second-order partial derivative of numerator w.r.t. to fivth coefficient
+    of BET isoterm and relative pressure";
+    Real ddA_dphi_dphi = (c[4] * phi^(c[4] - 3) * (phi * (c[4] * (c[5] * ((c[4] +
+      1) * phi - 2 * c[4] + 2) + 2 * c[4] - 4) + 2) + (c[4] - 2) * (c[4] - 1) *
+      c[5] - 2 * (c[4] - 2) * (c[4] - 1))) / 2
+      "Second-order partial derivative of numerator w.r.t. to relative pressure";
+
+    Real ddB_dc3_dc4 = -((c[5] * (phi - 1) + 2) * phi^c[4] * log(phi)) / 2
+      "Second-order partial derivative of denominator w.r.t. to third and fourht
+    coefficient of BET isoterm";
+    Real ddB_dc3_dc5 = -((phi - 1) * phi^c[4]) / 2
+      "Second-order partial derivative of denominator w.r.t. to third and fivth 
+    coefficient of BET isoterm";
+    Real ddB_dc3_dphi = (-c[5] * phi^c[4] - c[4] * phi^(c[4] - 1) * (c[5] * phi -
+      c[5] + 2)) / 2 + 1
+      "Second-order partial derivative of denominator w.r.t. to third coefficient
+    of BET isoterm and relative pressure";
+    Real ddB_dc4_dc4 = -(c[3] * (c[5] * (phi - 1) + 2) * phi^c[4] * log(phi)^2) / 2
+      "Second-order partial derivative of denominator w.r.t. to fourth coefficient
+    of BET isoterm";
+    Real ddB_dc4_dc5 = -(c[3] * (phi - 1) * phi^c[4] * log(phi)) / 2
+      "Second-order partial derivative of denominator w.r.t. to fourth and fivth 
+    coefficient of BET isoterm";
+    Real ddB_dc4_dphi = -(c[3] * phi^(c[4] - 1) * (((c[4] + 1) * c[5] * phi -
+      c[4] * c[5] + 2 * c[4]) * log(phi) + c[5] * phi - c[5] + 2)) / 2
+      "Second-order partial derivative of denominator w.r.t. to fourth coefficient
+    of BET isoterm and relative pressure";
+    Real ddB_dc5_dphi = -(c[3] * phi^(c[4] - 1) * (c[4] * phi + phi - c[4])) / 2
+      "Second-order partial derivative of denominator w.r.t. to fivth coefficient
+    of BET isoterm and relative pressure";
+    Real ddB_dphi_dphi = -(c[3] * c[4] * phi^(c[4] - 2) * (c[5] * ((c[4] + 1) *
+      phi - c[4] + 1) + 2 * c[4] - 2)) / 2
+      "Second-order partial derivative of denominator w.r.t. to relative pressure";
+
+    Real ddF_dc2_dT_adsorpt = ddF_dc2_dc3 * dc_dT_adsorpt[3] +
+      ddF_dc2_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of pre-factor w.r.t. to second coefficient
+    of BET isoterm and temperature";
+    Real ddF_dc3_dT_adsorpt = ddF_dc2_dc3 * dc_dT_adsorpt[2] +
+      ddF_dc3_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of pre-factor w.r.t. to third coefficient
+    of BET isoterm and temperature";
+    Real ddF_dphi_dT_adsorpt = ddF_dc2_dphi * dc_dT_adsorpt[2] +
+      ddF_dc3_dphi * dc_dT_adsorpt[3] +
+      ddF_dphi_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of pre-factor w.r.t. to relative pressure
+    and temperature";
+
+    Real ddA_dc4_dT_adsorpt = ddA_dc4_dc4 * dc_dT_adsorpt[4] +
+      ddA_dc4_dc5 * dc_dT_adsorpt[5] +
+      ddA_dc4_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of numerator w.r.t. to fourth coefficient
+    of BET isoterm and temperature";
+    Real ddA_dc5_dT_adsorpt = ddA_dc4_dc5 * dc_dT_adsorpt[4] +
+      ddA_dc5_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of numerator w.r.t. to fivth coefficient
+    of BET isoterm and temperature";
+    Real ddA_dphi_dT_adsorpt = ddA_dc4_dphi * dc_dT_adsorpt[4] +
+      ddA_dc5_dphi * dc_dT_adsorpt[5] +
+      ddA_dphi_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of numerator w.r.t. to relative pressure
+    and temperature";
+
+    Real ddB_dc3_dT_adsorpt = ddB_dc3_dc4 * dc_dT_adsorpt[4] +
+      ddB_dc3_dc5 * dc_dT_adsorpt[5] +
+      ddB_dc3_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of denominator w.r.t. to fourth coefficient
+    of BET isoterm and temperature";
+    Real ddB_dc4_dT_adsorpt = ddB_dc3_dc4 * dc_dT_adsorpt[3] +
+      ddB_dc4_dc4 * dc_dT_adsorpt[4] +
+      ddB_dc4_dc5 * dc_dT_adsorpt[5] +
+      ddB_dc4_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of denominator w.r.t. to fourth coefficient
+    of BET isoterm and temperature";
+    Real ddB_dc5_dT_adsorpt = ddB_dc3_dc5 * dc_dT_adsorpt[3] +
+      ddB_dc4_dc5 * dc_dT_adsorpt[4] +
+      ddB_dc5_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of denominator w.r.t. to fivth coefficient
+    of BET isoterm and temperature";
+    Real ddB_dphi_dT_adsorpt = ddB_dc3_dphi * dc_dT_adsorpt[3] +
+      ddB_dc4_dphi * dc_dT_adsorpt[4] +
+      ddB_dc5_dphi * dc_dT_adsorpt[5] +
+      ddB_dphi_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of denominator w.r.t. to relative pressure
+    and temperature";
+
+    Real ddF_dT_adsorpt_dT_adsorpt = ddF_dc2_dT_adsorpt * dc_dT_adsorpt[2] +
+      dF_dc2 * ddc_dT_adsorpt_dT_adsorpt[2] +
+      ddF_dc3_dT_adsorpt * dc_dT_adsorpt[3] +
+      dF_dc3 * ddc_dT_adsorpt_dT_adsorpt[3] +
+      ddF_dphi_dT_adsorpt * dphi_dT_adsorpt +
+      dF_dphi * ddphi_dT_adsorpt_dT_adsorpt
+      "Second-order partial derivative of pre-factor w.r.t. temperature";
+    Real ddA_dT_adsorpt_dT_adsorpt = ddA_dc4_dT_adsorpt * dc_dT_adsorpt[4] +
+      dA_dc4 * ddc_dT_adsorpt_dT_adsorpt[4] +
+      ddA_dc5_dT_adsorpt * dc_dT_adsorpt[5] +
+      dA_dc5 * ddc_dT_adsorpt_dT_adsorpt[5] +
+      ddA_dphi_dT_adsorpt * dphi_dT_adsorpt +
+      dA_dphi * ddphi_dT_adsorpt_dT_adsorpt
+      "Second-order partial derivative of numerator w.r.t. temperature";
+    Real ddB_dT_adsorpt_dT_adsorpt = ddB_dc3_dT_adsorpt * dc_dT_adsorpt[3] +
+      dB_dc3 * ddc_dT_adsorpt_dT_adsorpt[3] +
+      ddB_dc4_dT_adsorpt * dc_dT_adsorpt[4] +
+      dB_dc4 * ddc_dT_adsorpt_dT_adsorpt[4] +
+      ddB_dc5_dT_adsorpt * dc_dT_adsorpt[5] +
+      dB_dc5 * ddc_dT_adsorpt_dT_adsorpt[5] +
+      ddB_dphi_dT_adsorpt * dphi_dT_adsorpt +
+      dB_dphi * ddphi_dT_adsorpt_dT_adsorpt
+      "Second-order partial derivative of denominator w.r.t. temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      ((dF_dT_adsorpt/B) * dA_dT_adsorpt +
+       (-A/B^2 * dF_dT_adsorpt) * dB_dT_adsorpt +
+       (A/B) * ddF_dT_adsorpt_dT_adsorpt) +
+      ((dA_dT_adsorpt/B) * dF_dT_adsorpt +
+       (-F/B^2 * dA_dT_adsorpt) * dB_dT_adsorpt +
+       (F/B) * ddA_dT_adsorpt_dT_adsorpt) +
+      ((-A/B^2 * dB_dT_adsorpt) * dF_dT_adsorpt +
+       (-F/B^2 * dB_dT_adsorpt) * dA_dT_adsorpt +
+       (2*F * A/B^3 * dB_dT_adsorpt) * dB_dT_adsorpt +
+       (-F * A/B^2) * ddB_dT_adsorpt_dT_adsorpt)
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "BET isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+    Real F = c[2]*c[3] * phi / (1 - phi)
+      "Pre-factor";
+    Real A = 1 + (c[4]*c[5]/2 - c[4]) * phi ^ (c[4]-1) -
+      (c[4]*c[5] - c[4] + 1) * phi^c[4] + (c[4]*c[5]/2) * phi ^ (c[4]+1)
+      "Numerator of the fraction";
+    Real B = 1 + (c[3] - 1) * phi + (c[3]*c[5]/2 - c[3]) * phi^c[4] -
+      (c[3]*c[5]/2) * phi ^ (c[4]+1)
+      "Denominator of the fraction";
+
+    Real dphi_dp_adsorpt =  1/c[1]
+      "Partial derivative of relative pressure w.r.t. to pressure";
+    Real dphi_dT_adsorpt = -p_adsorpt/c[1]^2 * dc_dT_adsorpt[1]
+      "Partial derivative of relative pressure w.r.t. to temperature";
+
+    Real dF_dc2 = c[3] * phi / (1 - phi)
+      "Partial derivative of pre-factor w.r.t. to second coefficient of BET isotherm";
+    Real dF_dc3 = c[2] * phi / (1 - phi)
+      "Partial derivative of pre-factor w.r.t. to third coefficient of BET isotherm";
+    Real dF_dphi = (c[2] * c[3]) / (phi - 1)^2
+      "Partial derivative of pre-factor w.r.t. to relative pressure";
+
+    Real dA_dc4 = (phi ^ (c[4]-1) * ((c[5] * phi^2 + (2-2*c[5]) * phi + c[5] - 2) *
+      log(phi) * c[4] - 2*phi * log(phi) + c[5] * phi^2 + (2-2*c[5]) * phi + c[5] -
+      2)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to fourth coefficient 
+    of BET isotherm";
+    Real dA_dc5 = (c[4] * phi ^ (c[4]-1) * (phi^2 - 2*phi + 1)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to fivth coefficient 
+    of BET isotherm";
+    Real dA_dphi = (c[4] * phi ^ (c[4]-2) * ((c[4] + 1) * c[5] * phi^2 +
+      (-2*c[4]*c[5] + 2*c[4] - 2) * phi + (c[4]-1) * c[5] - 2*c[4] + 2)) / 2
+      "Partial derivative of numerator of the fraction w.r.t. to relative pressure";
+
+    Real dB_dc3 = -(phi^c[4] * (c[5]*phi - c[5] + 2) - 2*phi) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to third coefficient 
+    of BET isotherm";
+    Real dB_dc4 = -(c[3] * phi^c[4] * (c[5]*phi - c[5] + 2) * log(phi)) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to fourth coefficient 
+    of BET isotherm";
+    Real dB_dc5 = -(c[3] * (phi-1) * phi^c[4]) / 2
+      "Partial derivative of denominator of the fraction w.r.t. to fivth coefficient 
+    of BET isotherm";
+    Real dB_dphi = -(c[3] * (c[4]+1) * c[5] * phi^c[4]) / 2 +
+      c[4] * ((c[3]*c[5])/2 - c[3]) * phi ^ (c[4]-1) + c[3] - 1
+      "Partial derivative of denominator of the fraction w.r.t. to relative pressure";
+
+    Real ddphi_dp_adsorpt_dT_adsorpt = -1/c[1]^2 * dc_dT_adsorpt[1]
+      "Second-order partial derivative of relative pressure w.r.t. pressure and 
+    temperature";
+
+    Real ddF_dphi_dc2 =  c[3] / (phi - 1)^2
+      "Second-order partial derivative of pre-factor w.r.t. to relative pressure
+    and second coefficient of BET isotherm";
+    Real ddF_dphi_dc3 = c[2] / (phi - 1)^2
+      "Second-order partial derivative of pre-factor w.r.t. to relative pressure
+    and third coefficient of BET isotherm";
+    Real ddF_dphi_dphi = -2 * (c[2] * c[3]) / (phi - 1)^3
+      "Second-order partial derivative of pre-factor w.r.t. to relative pressure";
+
+    Real ddA_dphi_dc4 = ((phi - 1) * phi^(c[4] - 2) * (c[4] * (log(phi) * ((c[5] *
+      (phi - 1) + 2) * c[4] + c[5] * (phi + 1) - 2) + 2 * c[5] * (phi - 1) + 4) +
+      c[5] * (phi + 1) - 2)) / 2
+      "Second-order partial derivative of numerator w.r.t. to relative pressure
+    and fourth coefficient of BET isotherm";
+    Real ddA_dphi_dc5 = (c[4] * (phi - 1) * phi^(c[4] - 2) * ((c[4] + 1) * phi -
+      c[4] + 1)) / 2
+      "Second-order partial derivative of numerator w.r.t. to relative pressure
+    and fivth coefficient of BET isotherm";
+    Real ddA_dphi_dphi = (c[4] * phi^(c[4] - 3) * (phi * (c[4] * (c[5] * ((c[4] +
+      1) * phi - 2 * c[4] + 2) + 2 * c[4] - 4) + 2) + (c[4] - 2) * (c[4] - 1) *
+      c[5] - 2 * (c[4] - 2) * (c[4] - 1))) / 2
+      "Second-order partial derivative of numerator w.r.t. to relative pressure";
+
+    Real ddB_dphi_dc3 = (-(c[4] + 1) * c[5] * phi^c[4] + c[4] * (c[5] - 2) *
+      phi^(c[4] - 1) + 2) / 2
+      "Second-order partial derivative of denominator w.r.t. to relative pressure
+    and fourth coefficient of BET isotherm";
+    Real ddB_dphi_dc4 = -(c[3] * phi^(c[4] - 1) * ((c[5] * (phi - 1) + 2) *
+      log(phi) * c[4] + c[5] * phi * log(phi) + c[5] * phi - c[5] + 2)) / 2
+      "Second-order partial derivative of denominator w.r.t. to relative pressure
+    and fourth coefficient of BET isotherm";
+    Real ddB_dphi_dc5 = -(c[3] * phi^(c[4] - 1) * (c[4] * phi + phi - c[4])) / 2
+      "Second-order partial derivative of denominator w.r.t. to relative pressure
+    and fivth coefficient of BET isotherm";
+    Real ddB_dphi_dphi = -(c[3] * c[4] * phi^(c[4] - 2) * (c[5] * ((c[4] + 1) *
+      phi - c[4] + 1) + 2 * c[4] - 2)) / 2
+      "Second-order partial derivative of denominator w.r.t. to relative pressure";
+
+    Real dF_dp_adsorpt = dF_dphi * dphi_dp_adsorpt
+      "Partial derivative of pre-factor w.r.t. pressure";
+    Real dA_dp_adsorpt = dA_dphi * dphi_dp_adsorpt
+      "Partial derivative of numerator w.r.t. pressure";
+    Real dB_dp_adsorpt = dB_dphi * dphi_dp_adsorpt
+      "Partial derivative of denominator w.r.t. pressure";
+
+    Real dF_dT_adsorpt = dF_dc2 * dc_dT_adsorpt[2] +
+      dF_dc3 * dc_dT_adsorpt[3] +
+      dF_dphi * dphi_dT_adsorpt
+      "Partial derivative of pre-factor w.r.t. temperature";
+    Real dA_dT_adsorpt = dA_dc4 * dc_dT_adsorpt[4] +
+      dA_dc5 * dc_dT_adsorpt[5] +
+      dA_dphi * dphi_dT_adsorpt
+      "Partial derivative of numerator w.r.t. temperature";
+    Real dB_dT_adsorpt = dB_dc3 * dc_dT_adsorpt[3] +
+      dB_dc4 * dc_dT_adsorpt[4] +
+      dB_dc5 * dc_dT_adsorpt[5] +
+      dB_dphi * dphi_dT_adsorpt
+      "Partial derivative of denominator w.r.t. temperature";
+
+    Real ddF_dphi_dT_adsorpt = ddF_dphi_dc2 * dc_dT_adsorpt[2] +
+      ddF_dphi_dc3 * dc_dT_adsorpt[3] +
+      ddF_dphi_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of pre-factor w.r.t. relative pressure and 
+    temperature";
+    Real ddA_dphi_dT_adsorpt = ddA_dphi_dc4 * dc_dT_adsorpt[4] +
+      ddA_dphi_dc5 * dc_dT_adsorpt[5] +
+      ddA_dphi_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of numerator w.r.t. relative pressure and 
+    temperature";
+    Real ddB_dphi_dT_adsorpt = ddB_dphi_dc3 * dc_dT_adsorpt[3] +
+      ddB_dphi_dc4 * dc_dT_adsorpt[4] +
+      ddB_dphi_dc5 * dc_dT_adsorpt[5] +
+      ddB_dphi_dphi * dphi_dT_adsorpt
+      "Second-order partial derivative of denominator w.r.t. relative pressure and 
+    temperature";
+
+    Real ddF_dp_adsorpt_dT_adsorpt = ddF_dphi_dT_adsorpt * dphi_dp_adsorpt +
+      dF_dphi * ddphi_dp_adsorpt_dT_adsorpt
+      "Second-order partial derivative of pre-factor w.r.t. pressure and temperature";
+    Real ddA_dp_adsorpt_dT_adsorpt = ddA_dphi_dT_adsorpt * dphi_dp_adsorpt +
+      dA_dphi * ddphi_dp_adsorpt_dT_adsorpt
+      "Second-order partial derivative of numerator w.r.t. pressure and temperature";
+    Real ddB_dp_adsorpt_dT_adsorpt = ddB_dphi_dT_adsorpt * dphi_dp_adsorpt +
+      dB_dphi * ddphi_dp_adsorpt_dT_adsorpt
+      "Second-order partial derivative of denominator w.r.t. pressure and temperature";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      ((dF_dp_adsorpt/B) * dA_dT_adsorpt +
+       (-A/B^2 * dF_dp_adsorpt) * dB_dT_adsorpt +
+       (A/B) * ddF_dp_adsorpt_dT_adsorpt) +
+      ((dA_dp_adsorpt/B) * dF_dT_adsorpt +
+       (-F/B^2 * dA_dp_adsorpt) * dB_dT_adsorpt +
+       (F/B) * ddA_dp_adsorpt_dT_adsorpt) +
+      ((-A/B^2 * dB_dp_adsorpt) * dF_dT_adsorpt +
+       (-F/B^2 * dB_dp_adsorpt) * dA_dT_adsorpt +
+       (2*F * A/B^3 * dB_dp_adsorpt) * dB_dT_adsorpt +
+       (-F * A/B^2) * ddB_dp_adsorpt_dT_adsorpt)
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare function pi_pT
+    "BET isotherm model: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT_num(
+        redeclare final function func_x_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BET.x_pT);
+  end pi_pT;
+
+  redeclare function p_piT
+    "BET isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+        redeclare final function func_pi_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BET.pi_pT);
+  end p_piT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The BET isotherm model is a five-parameter model for calculating the  equilibrium
+uptake <i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>.
+The BET isotherm model is suitable for type I-IV isotherms according to the IUPAC 
+definition.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The BET isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = x<sub>mon</sub>(T<sub>adsorpt</sub>) * C(T<sub>adsorpt</sub>) * &phi;(T<sub>adsorpt</sub>) / (1 - &phi;(T<sub>adsorpt</sub>)) * A(T<sub>adsorpt</sub>) / B(T<sub>adsorpt</sub>);
+</pre>
+<p>
+with
+</p>
+<pre>
+    &phi;(T<sub>adsorpt</sub>) = p<sub>adsorpt</sub>/p<sub>sat</sub>(T<sub>adsorpt</sub>);
+</pre>
+<pre>
+    A(T<sub>adsorpt</sub>) = 1 + (n * g(T<sub>adsorpt</sub>)/2 - n) * &phi;(T<sub>adsorpt</sub>) ^ (n-1) - (n * g(T<sub>adsorpt</sub>) - n + 1) * &phi;(T<sub>adsorpt</sub>) ^ n + (n *g(T<sub>adsorpt</sub>)/2) * &phi;(T<sub>adsorpt</sub>) ^ (n+1);
+</pre>
+<pre>
+    B(T<sub>adsorpt</sub>) = 1 + (C(T<sub>adsorpt</sub>) - 1) * &phi;(T<sub>adsorpt</sub>) + (C(T<sub>adsorpt</sub>) * g(T<sub>adsorpt</sub>)/2 - C(T<sub>adsorpt</sub>)) * &phi;(T<sub>adsorpt</sub>) ^ n - (C(T<sub>adsorpt</sub>) * g(T<sub>adsorpt</sub>)/2) * &phi;(T<sub>adsorpt</sub>) ^ (n + 1);
+</pre>
+<p>
+and
+</p>
+<pre>
+    g(T<sub>adsorpt</sub>) = <strong>exp</strong>(Q<sub>cap</sub> / (R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+Herein, <i>x<sub>mon</sub>(T<sub>adsorpt</sub>)</i> is the monolayer uptake, 
+<i>C(T<sub>adsorpt</sub>)</i> is the BET coefficient, <i>n</i> is the number of
+layers that can be occupied, and <i>Q<sub>cap</sub> </i> is a measure for the 
+extra enthalpy added to the enthalpy of vaporization at high layers due to capillary
+forces. In the original BET equation, all parameters are independent of the temperature.
+However, sometimes the two parameters <i>x<sub>mon</sub>(T<sub>adsorpt</sub>)</i>
+and <i>C(T<sub>adsorpt</sub>)</i> are modeled as a function of the temperature,
+with typical temperature dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>mon</sub>(T<sub>adsorpt</sub>) =  x<sub>mon,ref</sub> * <strong>exp</strong>(&Chi; * (1 - T<sub>adsorpt</sub>/T<sub>ref</sub>));
+</pre>
+<pre>
+    C(T<sub>adsorpt</sub>) = C<sub>ref</sub> * <strong>exp</strong>(Q/(R * T<sub>ref</sub>) * (T<sub>ref</sub>/T<sub>adsorpt</sub> - 1));
+</pre>
+<p>
+where <i>x<sub>mon,ref</sub></i> is the monolayer uptake at reference temperature 
+<i>T<sub>ref</sub></i> and <i>C<sub>ref</sub></i> is the BET coefficient at reference 
+temperature. The parameter <i>&Chi;</i> describes the change of the monolayer uptake 
+with temperature and the parameter <i>Q</i> is a measure for some energy. These five 
+parameters and the two parameters <i>n</i> and <i>Q<sub>cap</sub></i> can be used 
+as fitting parameters.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = p<sub>sat</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2] = x<sub>mon</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[3] = C(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[4] = n in -
+  </li>
+  <li>
+  c[5] = g(T<sub>adsorpt</sub>) in -
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  All adsorption sites are energetically equivalent.
+  </li>
+  <li>
+  All adsorption sites can be occupied.
+  </li>
+  <li>
+  No interactions occur between the adsorbent molecules.
+  </li>
+  <li>
+  No limit exists for the number of layers.
+  </li>
+  <li>
+  Heat of adsorption of all layers except the first layer equals the heat of vaporization.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used for type I-V isotherms according to the IUPAC definition.
+Besides, the BET isotherm can used to calculate the surface area of the adsorbent.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the BET isotherm model for different parameter sets.
+In the upper sub-figure, the equilibrium pressure changes with time, while the 
+equilibrium temperature remains constant; in the lower sub-figure, the equilibrium 
+temperature changes with time, while the equilibrium pressure remains constant. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_bet.png\" alt=\"media_functions_equilibria_pure_bet.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>"));
+end BET;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BET/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BET/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BET/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BiLangmuir/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BiLangmuir/package.mo
new file mode 100644
index 0000000..15ee2ed
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BiLangmuir/package.mo
@@ -0,0 +1,257 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package BiLangmuir "Package containing all functions regarding the Bi-Langmuir isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  redeclare final function extends x_pT
+    "Bi-Langmuir isotherm model: Uptake as function of pressure and temperature"
+  algorithm
+    x_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.x_pT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[1:2],
+      p_adsorpt_lb_start=p_adsorpt_lb_start,
+      p_adsorpt_ub_start=p_adsorpt_ub_start,
+      tolerance=tolerance) +
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.x_pT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[3:4],
+      p_adsorpt_lb_start=p_adsorpt_lb_start,
+      p_adsorpt_ub_start=p_adsorpt_ub_start,
+      tolerance=tolerance)
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare function p_xT
+    "Bi-Langmuir isotherm model: Pressure as function of uptake and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT_num(
+        redeclare final function func_x_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir.x_pT);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "Bi-Langmuir isotherm model: Partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    dx_adsorpt_dp_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[1:2]) +
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[3:4])
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dT
+    "Bi-Langmuir isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[1:2],
+      dc_dT_adsorpt=dc_dT_adsorpt[1:2]) +
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[3:4],
+      dc_dT_adsorpt=dc_dT_adsorpt[3:4])
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dp_dp
+    "Bi-Langmuir isotherm model: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[1:2]) +
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[3:4])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+
+  redeclare final function extends ddx_dT_dT
+    "Bi-Langmuir isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[1:2],
+      dc_dT_adsorpt=dc_dT_adsorpt[1:2],
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt[1:2]) +
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[3:4],
+      dc_dT_adsorpt=dc_dT_adsorpt[3:4],
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt[3:4])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Bi-Langmuir isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[1:2],
+      dc_dT_adsorpt=dc_dT_adsorpt[1:2]) +
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[3:4],
+      dc_dT_adsorpt=dc_dT_adsorpt[3:4])
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare final function extends pi_pT
+    "Bi-Langmuir isotherm model: Pressure as function of reduced spreading pressure and temperature"
+  algorithm
+    pi :=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.pi_pT(
+      M_adsorptive=M_adsorptive,
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[1:2],
+      integral_pi_lb=integral_pi_lb,
+      tolerance=tolerance) +
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.pi_pT(
+      M_adsorptive=M_adsorptive,
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c[3:4],
+      integral_pi_lb=integral_pi_lb,
+      tolerance=tolerance)
+      "Calculation of the reduced spreading pressure";
+  end pi_pT;
+
+  redeclare function p_piT
+    "Bi-Langmuir isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+        redeclare final function func_pi_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir.pi_pT);
+  end p_piT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Bi-Langmuir isotherm model is a four-parameter model for calculating the equilibrium
+uptake <i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Bi-Langmuir isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = x<sub>sat,1</sub>(T<sub>adsorpt</sub>) * (b<sub>1</sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>) / (1 + b<sub>1</sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>) + x<sub>sat,2</sub>(T<sub>adsorpt</sub>) * (b<sub>2</sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>) / (1 + b<sub>2</sub>(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>sat,1</sub>(T<sub>adsorpt</sub>)</i> is the saturation uptake of 
+adsorption site 1, <i>x<sub>sat,2</sub>(T<sub>adsorpt</sub>)</i> is the saturation 
+uptake of adsorption site 2, <i>b<sub>1</sub>(T<sub>adsorpt</sub>)</i> is the 
+Langmuir coefficient of adsorption site 1, and <i>b<sub>2</sub>(T<sub>adsorpt</sub>)</i> 
+is the Langmuir coefficient of adsorption site 2. Typical temperature dependencies 
+may have the following forms:
+</p>
+<pre>
+    x<sub>sat,<i>i</i></sub>(T<sub>adsorpt</sub>) = a<sub>0,<i>i</i></sub> + a<sub>1,<i>i</i></sub>/T<sub>adsorpt</sub>;
+</pre>
+<pre>
+    b<sub><i>i</i></sub>(T<sub>adsorpt</sub>) = b<sub>0,<i>i</i></sub> * <strong>exp</strong>(-&Delta;H<sub>ads,<i>i</i></sub>/(R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+where <i>a<sub>0,<i>i</i></sub></i>, <i>a<sub>1,<i>i</i></sub></i>, <i>b<sub>0</sub></i>, 
+and <i>&Delta;H<sub>ads,<i>i</i></sub></i> are fiting parameters. The parameter
+<i>&Delta;H<sub>ads,<i>i</i></sub></i> is the isosteric adsorption heat, which is
+invariant with the surface uptake.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = x<sub>sat,1</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2] = b<sub>1</sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[3] = x<sub>sat,2</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[4] = b<sub>2</sub>(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  All adsorption sites can be occupied.
+  </li>
+  <li>
+  No interactions occur between the adsorbent molecules.
+  </li>
+  <li>
+  The adsorbent surface is covered monomolecularly.
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Bi-Langmuir isotherm model for different parameter sets.
+In the upper sub-figure, the equilibrium pressure changes with time, while the 
+equilibrium temperature remains constant; in the lower sub-figure, the equilibrium 
+temperature changes with time, while the equilibrium pressure remains constant. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_bi_langmuir.png\" alt=\"media_functions_equilibria_pure_bi_langmuir.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>"));
+end BiLangmuir;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BiLangmuir/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BiLangmuir/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/BiLangmuir/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininAstakhov/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininAstakhov/package.mo
new file mode 100644
index 0000000..82712ad
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininAstakhov/package.mo
@@ -0,0 +1,526 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package DubininAstakhov "Package containing all functions regarding the Dubinin-Astakhov isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin;
+
+  redeclare final function extends x_pT
+    "Dubinin-Astakhov isotherm model: Uptake as function of pressure and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Dubinin-Astakhov isotherm model: Pressure as function of uptake and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dT
+    "Dubinin-Astakhov isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    SorpLib.Units.FilledPoreVolume W=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.W_A(
+      A=A,
+      c=c)
+      "Filled pore volume";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.dW_dA(
+      A=A, c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+
+    Real dx_adsorpt_dA = c[2] * dW_dA
+      "Derivative of uptake w.r.t. to adsorption potential";
+    Real dx_adsorpt_dc2 = W
+      "Derivative of uptake w.r.t. to second coefficient of Dubinin-Astakhov isotherm";
+    Real dx_adsorpt_dc3 = c[2] * exp(-(A / c[4]) ^ c[5])
+      "Derivative of uptake w.r.t. to third coefficient of Dubinin-Astakhov isotherm";
+    Real dx_adsorpt_dc4 = c[2] * c[5] / c[4] * (A / c[4]) ^ c[5] * W
+      "Derivative of uptake w.r.t. to fourth coefficient of Dubinin-Astakhov isotherm";
+    Real dx_adsorpt_dc5 = -c[2] * log(A / c[4]) * (A / c[4]) ^ c[5] *  W
+      "Derivative of uptake w.r.t. to fivth coefficient of Dubinin-Astakhov isotherm";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      dx_adsorpt_dA*dA_dT_adsorpt +
+      dx_adsorpt_dc2*dc_dT_adsorpt[2] +
+      dx_adsorpt_dc3*dc_dT_adsorpt[3] +
+      dx_adsorpt_dc4*dc_dT_adsorpt[4] +
+      dx_adsorpt_dc5*dc_dT_adsorpt[5]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dT_dT
+    "Dubinin-Astakhov isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dT_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1],
+      ddp_sat_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt[1])
+      "Second-order partial derivative of adsorption potential w.r.t. equilibrium 
+      temperature at constant pressure";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.ddW_dA_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      A=A,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of characteristic curve w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+    Real dx_adsorpt_dA = c[2] * dW_dA
+      "Derivative of uptake w.r.t. to adsorption potential";
+    Real dx_adsorpt_dc2 = c[3] * exp(-(A / c[4]) ^ c[5])
+      "Derivative of uptake w.r.t. to second coefficient of Dubinin-Astakhov 
+    isotherm";
+    Real dx_adsorpt_dc3 = c[2] * exp(-(A / c[4]) ^ c[5])
+      "Derivative of uptake w.r.t. to third coefficient of Dubinin-Astakhov 
+    isotherm";
+    Real dx_adsorpt_dc4 = c[2] * c[5] / c[4] * (A / c[4]) ^ c[5] *
+      c[3] * exp(-(A / c[4]) ^ c[5])
+      "Derivative of uptake w.r.t. to fourth coefficient of Dubinin-Astakhov 
+    isotherm";
+    Real dx_adsorpt_dc5 = -c[2] * log(A / c[4]) * (A / c[4]) ^ c[5] *
+      c[3] * exp(-(A / c[4]) ^ c[5])
+      "Derivative of uptake w.r.t. to fivth coefficient of Dubinin-Astakhov 
+    isotherm";
+
+    Real ddx_adsorpt_dc4_dc4 = (c[2] * c[3] * c[5] * (c[5] * (A / c[4])^c[5] -
+      c[5] - 1) * (A / c[4])^c[5] * exp(-(A / c[4])^c[5])) / c[4]^2
+      "Second-order partial derivative of uptake w.r.t. to fourth coefficient of 
+    Dubinin-Astakhov isotherm";
+    Real ddx_adsorpt_dc5_dc5 = c[2] * c[3] * log(A / c[4])^2 * ((A / c[4])^c[5] -
+      1) * (A / c[4])^c[5] * exp(-(A / c[4])^c[5])
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Astakhov isotherm";
+
+    Real ddx_adsorpt_dc2_dA= -(c[3] * c[5] * (A / c[4])^c[5] *
+      exp(-(A / c[4])^c[5])) / A
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Dubinin-Astakhov isotherm and adsorption potential";
+    Real ddx_adsorpt_dc2_dc3 = exp(-(A / c[4])^c[5])
+      "Second-order partial derivative of uptake w.r.t. to second and third 
+    coefficient of Dubinin-Astakhov isotherm";
+    Real ddx_adsorpt_dc2_dc4 = (c[3] * c[5] * (A / c[4])^c[5] *
+      exp(-(A / c[4])^c[5])) / c[4]
+      "Second-order partial derivative of uptake w.r.t. to second and fourht 
+    coefficient of Dubinin-Astakhov isotherm";
+    Real ddx_adsorpt_dc2_dc5 = -c[3] * log(A / c[4]) * (A / c[4])^c[5] *
+      exp(-(A / c[4])^c[5])
+      "Second-order partial derivative of uptake w.r.t. to second and fivth 
+    coefficient of Dubinin-Astakhov isotherm";
+
+    Real ddx_adsorpt_dc3_dA = -(c[2] * c[5] * (A / c[4])^c[5] *
+      exp(-(A / c[4])^c[5])) / A
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Dubinin-Astakhov isotherm and adsorption potential";
+    Real ddx_adsorpt_dc3_dc4 = (c[2] * c[5] * (A / c[4])^c[5] *
+      exp(-(A / c[4])^c[5])) / c[4]
+      "Second-order partial derivative of uptake w.r.t. to third and fourht 
+    coefficient of Dubinin-Astakhov isotherm";
+    Real ddx_adsorpt_dc3_dc5 = -c[2] * log(A / c[4]) * (A / c[4])^c[5] *
+      exp(-(A / c[4])^c[5])
+      "Second-order partial derivative of uptake w.r.t. to third and fivth 
+    coefficient of Dubinin-Astakhov isotherm";
+
+    Real ddx_adsorpt_dc4_dA = -(c[2] * c[3] * c[5]^2 * (A / c[4])^c[5] *
+      ((A / c[4])^c[5] - 1) * exp(-(A / c[4])^c[5])) / (c[4] * A)
+      "Second-order partial derivative of uptake w.r.t. to fourth  coefficient of 
+    Dubinin-Astakhov isotherm and adsorption potential";
+    Real ddx_adsorpt_dc4_dc5 = -(c[2] * c[3] * (A / c[4])^c[5] * ((log(A / c[4]) *
+      (A / c[4])^c[5] - log(A / c[4])) * c[5] - 1) * exp(-(A / c[4])^c[5])) / c[4]
+      "Second-order partial derivative of uptake w.r.t. to fourth and fivth
+    coefficient of Dubinin-Astakhov isotherm";
+
+    Real ddx_adsorpt_dc5_dA = (c[2] * c[3] * (A / c[4])^c[5] *
+      exp(-(A / c[4])^c[5]) * ((c[5] * (A / c[4])^c[5] - c[5]) *
+      log(A / c[4]) - 1)) / A
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Astakhov isotherm and adsorption potential";
+
+    Real ddx_adsorpt_dA_dT_dT_adsorpt = dc_dT_adsorpt[2] * dW_dA +
+      c[2] * ddW_dA_dT_adsorpt
+      "Second-order partial derivative of uptake w.r.t. to adsorption potential
+    and temperature";
+    Real ddx_adsorpt_dc2_dT_dT_adsorpt = ddx_adsorpt_dc2_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc2_dc4*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc2_dc5*dc_dT_adsorpt[5]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Dubinin-Astakhov isotherm and temperature";
+    Real ddx_adsorpt_dc3_dT_dT_adsorpt = ddx_adsorpt_dc3_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc4*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc3_dc5*dc_dT_adsorpt[5]
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Dubinin-Astakhov isotherm and temperature";
+    Real ddx_adsorpt_dc4_dT_dT_adsorpt = ddx_adsorpt_dc4_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc4*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc4*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc4_dc4*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc4_dc5*dc_dT_adsorpt[5]
+      "Second-order partial derivative of uptake w.r.t. to fourth coefficient of 
+    Dubinin-Astakhov isotherm and temperature";
+    Real ddx_adsorpt_dc5_dT_dT_adsorpt = ddx_adsorpt_dc5_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc5*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc5*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc4_dc5*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc5_dc5*dc_dT_adsorpt[5]
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Astakhov isotherm and temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      (ddx_adsorpt_dA_dT_dT_adsorpt*dA_dT_adsorpt +
+       dx_adsorpt_dA*ddA_dT_adsorpt_dT_adsorpt) +
+      (ddx_adsorpt_dc2_dT_dT_adsorpt*dc_dT_adsorpt[2] +
+       dx_adsorpt_dc2*ddc_dT_adsorpt_dT_adsorpt[2]) +
+      (ddx_adsorpt_dc3_dT_dT_adsorpt*dc_dT_adsorpt[3] +
+       dx_adsorpt_dc3*ddc_dT_adsorpt_dT_adsorpt[3]) +
+      (ddx_adsorpt_dc4_dT_dT_adsorpt*dc_dT_adsorpt[4] +
+       dx_adsorpt_dc4*ddc_dT_adsorpt_dT_adsorpt[4]) +
+      (ddx_adsorpt_dc5_dT_dT_adsorpt*dc_dT_adsorpt[5] +
+       dx_adsorpt_dc5*ddc_dT_adsorpt_dT_adsorpt[5])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Dubinin-Astakhov isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt) "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of adsorption potential w.r.t. to pressure at constant
+      temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Second-order partial derivative of adsorption potential w.r.t. to pressure
+      and temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.dW_dA(
+        A=A, c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.ddW_dA_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        A=A,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of characteristic curve w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      dc_dT_adsorpt[2] * dW_dA * dA_dp_adsorpt +
+      c[2] * ddW_dA_dT_adsorpt * dA_dp_adsorpt +
+      c[2] * dW_dA * ddA_dp_adsorpt_dT_adsorpt
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare function pi_pT
+    "Dubinin-Astakhov isotherm model: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT_num(
+        integral_pi_lb = Modelica.Constants.small,
+        tolerance = 100*Modelica.Constants.eps,
+        redeclare final function func_x_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.x_pT);
+  end pi_pT;
+
+  redeclare function p_piT
+    "Dubinin-Astakhov isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+        p_adsorpt_lb_start = 1,
+        integral_pi_lb = Modelica.Constants.small,
+        tolerance_p_adsorpt = 1e-6,
+        tolerance_pi = 100*Modelica.Constants.eps,
+        redeclare final function func_pi_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.pi_pT);
+  end p_piT;
+
+  redeclare final function extends W_A
+    "Dubinin-Astakhov isotherm model: Filled pore volume as function of adsorption potential"
+  algorithm
+    W := c[3] * exp(-(max(A, 0) / c[4]) ^ c[5])
+      "Filled pore volume";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(A=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.A_W(W, c, A_lb_start, A_ub_start, tolerance)));
+  end W_A;
+
+  redeclare final function extends A_W
+    "Dubinin-Astakhov isotherm model: Adsorption potential as function of the filled pore volume"
+  algorithm
+    A := c[4] * (-log(W/c[3])) ^ (1/c[5])
+      "Adsorption potential";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(W=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov.W_A(A, c, A_lb_start, A_ub_start, tolerance)));
+  end A_W;
+
+  redeclare final function extends dW_dA
+    "Dubinin-Astakhov isotherm model: Partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+  algorithm
+    dW_dA := -c[5] / c[4] * (A / c[4]) ^ (c[5] - 1) * c[3] * exp(-(A / c[4]) ^ c[5])
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at 
+    constant pressure and temperature";
+  end dW_dA;
+
+  redeclare final function extends ddW_dA_dA
+    "Dubinin-Astakhov isotherm model: Second-order partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+  algorithm
+    ddW_dA_dA := (c[3] * c[5] * (A / c[4])^c[5] * (c[5] * ((A / c[4])^c[5] - 1) + 1) *
+      exp(-(A / c[4])^c[5])) / A^2
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential at constant pressure and temperature";
+  end ddW_dA_dA;
+
+  redeclare final function extends ddW_dA_dT
+    "Dubinin-Astakhov isotherm model: Second-order partial derivative of filled pore volume w.r.t. adsorption potential and temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt,
+        dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real ddW_dA_dA = (c[3] * c[5] * (A / c[4])^c[5] * (c[5] * (A / c[4])^c[5] -
+      c[5] + 1) * exp(-(A / c[4])^c[5])) / A^2
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential";
+    Real ddW_dA_dc3 = -((A / c[4])^c[5] * c[5] * exp(-(A / c[4])^c[5])) / A
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and third coefficient of the Dubinin-Astakhov isotherm model";
+    Real ddW_dA_dc4 = -(c[3] * c[5]^2 * ((A / c[4])^c[5] - 1) * (A / c[4])^c[5] *
+      exp(-(A / c[4])^c[5])) / (A * c[4])
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and fourth coefficient of the Dubinin-Astakhov isotherm model";
+    Real ddW_dA_dc5 = (c[3] * (A / c[4])^c[5] * ((log(A / c[4]) * (A / c[4])^c[5] -
+      log(A / c[4])) * c[5] - 1) * exp(-(A / c[4])^c[5])) / A
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and fivth coefficient of the Dubinin-Astakhov isotherm model";
+
+  algorithm
+    ddW_dA_dT := ddW_dA_dA * dA_dT_adsorpt +
+      ddW_dA_dc3 * dc_dT_adsorpt[3] +
+      ddW_dA_dc4 * dc_dT_adsorpt[4] +
+      ddW_dA_dc5 * dc_dT_adsorpt[5]
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential and temperature at constant pressure";
+  end ddW_dA_dT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Dubinin-Astakhov isotherm model is a five-parameter model for calculating the
+equilibrium uptake <i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>.
+The Dubinin-Astakhov isotherm model is suitable for type I, IV and V isotherms 
+according to the IUPAC definition.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Dubinin-Astakhov isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) * W(A(T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    W(A(T<sub>adsorpt</sub>)) = W<sub>0</sub> * <strong>exp</strong>(-(A(T<sub>adsorpt</sub>) / E) ^ n);
+</pre>
+<pre>
+    A(T<sub>adsorpt</sub>) = R * T<sub>adsorpt</sub> * <strong>ln</strong>(p<sub>sat</sub>(T<sub>adsorpt</sub>) / p<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>W(A(T<sub>adsorpt</sub>))</i> is the so-called characteristic curve and
+<i>A(T<sub>adsorpt</sub>)</i> is the adsorption potential. Within the characteristic 
+curve, the parameter <i>W<sub>0</sub></i> describes the maximum filled pore volume,
+<i>E</i> is the characteristic energy, and <i>n</i> describes the heterogeneity of the
+system. These three parameters can be used as fitting parameters.
+<br/><br/>
+Note that the exponent <i>n</i> is typically greater than unity. Furthermore, the 
+density of the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> is assumed 
+to be the saturated liquid density &rho;<sub>sat,liq</sub>(T<sub>adsorpt</sub>) without 
+any further information about the system under consideration. For super-critical
+adsorptives (i.e., <i>T<sub>adsorpt</sub> &ge; T<sub>crit</sub></i>), the density of
+the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> can be estimated by
+</p>
+<pre>
+    &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) = &rho;<sub>sat,liq</sub>(T<sub>boiling,0</sub>) * <strong>exp</strong>(-0.0025 * (T<sub>adsorpt</sub> - T<sub>boiling,0</sub>));
+</pre>
+<p>
+and a pseudo-vapour pressure <i>p<sub>sat</sub>(T<sub>adsorpt</sub>)</i> can be 
+calculated by
+</p>
+<pre>
+    p<sub>sat</sub>(T<sub>adsorpt</sub>) = p<sub>crit</sub>(T<sub>adsorpt</sub>) * (T<sub>adsorpt</sub> / T<sub>crit</sub>) ^ k;
+</pre>
+<p>
+where <i>T<sub>boiling,0</sub></i> is the normal boiling point at 1 atm and <i>k</i> is
+a fitting parameter specific to the system under consideration.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = p<sub>sat</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2] = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) in kg/m<sup>3</sup>
+  </li>
+  <li>
+  c[3] = W<sub>0</sub> in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[4] = E in J/mol
+  </li>
+  <li>
+  c[5] = n in -
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The characteristic curve <i>W(A)</i> must decrease strictly monotonically with 
+  increasing adsorption potential <i>A</i>. Otherwise, the inverses <i>A(W)</i>
+  and <i>p(x,T</i>) may not be solveable.
+  </li>
+  <li>
+  The reduced spreading pressure <i>&pi;</i> may not be calculable. Accordingly, the 
+  inverse <i>p(&pi;,T)</i> cannot be calculated either.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used for type I, IV, and V isotherms according to the IUPAC
+definition.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Dubinin-Astakhov isotherm model for different parameter 
+sets. In the upper sub-figure, the equilibrium pressure changes with time, while the 
+equilibrium temperature is constant. In the centered sub-figure, the equilibrium 
+temperature changes with time, while the equilibrium pressure is constant. In the 
+lower sub-figure, the characteristic curve is shown. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_astakhov.png\" alt=\"media_functions_equilibria_pure_dubinin_astakhov.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>"));
+end DubininAstakhov;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininAstakhov/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininAstakhov/package.order
new file mode 100644
index 0000000..44a21b8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininAstakhov/package.order
@@ -0,0 +1,12 @@
+x_pT
+p_xT
+dx_dT
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
+W_A
+A_W
+dW_dA
+ddW_dA_dA
+ddW_dA_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininChebyshevSeriesRaionalOrder33/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininChebyshevSeriesRaionalOrder33/package.mo
new file mode 100644
index 0000000..adb00bb
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininChebyshevSeriesRaionalOrder33/package.mo
@@ -0,0 +1,607 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package DubininChebyshevSeriesRaionalOrder33 "Package containing all functions regarding the Dubinin isotherm model using a 'Chebyshev series' equation type with rational order 3/3"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin;
+
+  redeclare final function extends x_pT
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Uptake as function of pressure and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Pressure as function of uptake and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dT
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real n = (A - c[10]) / c[11]
+      "Auxiliary variable";
+
+    Real num = c[3] + c[5] * n + c[7] * (2 * n^2 - 1) + c[9] * (4 * n^3 - 3 * n)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * n + c[6] * (2 * n^2 - 1) + c[8] * (4 * n^3 - 3 * n)
+      "Denominator of characteristic curve";
+
+    Real dn_dT_adsorpt = (1 / c[11]) * dA_dT_adsorpt +
+      (-1 / c[11]) * dc_dT_adsorpt[10] +
+      ((c[10] - A) / c[11]^2) * dc_dT_adsorpt[11]
+      "Partial derivative of auxiliary variable w.r.t. temprature";
+    Real dnum_dT_adsorpt = (1) * dc_dT_adsorpt[3] +
+      (n) * dc_dT_adsorpt[5] +
+      (2 * n^2 - 1) * dc_dT_adsorpt[7] +
+      (4 * n^3 - 3 * n) * dc_dT_adsorpt[9] +
+      (4 * n * (3 * c[9] * n + c[7]) - 3 * c[9] + c[5]) * dn_dT_adsorpt
+      "Partial derivative of numerator of characteristic curve w.r.t. temprature";
+    Real dden_dT_adsorpt = (n) * dc_dT_adsorpt[4] +
+      (2 * n^2 - 1) * dc_dT_adsorpt[6] +
+      (4 * n^3 - 3 * n) * dc_dT_adsorpt[8] +
+      (4 * n * (3 * c[8] * n + c[6]) - 3 * c[8] + c[4]) * dn_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+    (1 * num / den) * dc_dT_adsorpt[2] +
+    (c[2] / den) * dnum_dT_adsorpt +
+    (-c[2] * num / den^2) * dden_dT_adsorpt
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dT_dT
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dT_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1],
+      ddp_sat_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt[1])
+      "Second-order partial derivative of adsorption potential w.r.t. equilibrium 
+      temperature at constant pressure";
+
+    Real n = (A - c[10]) / c[11]
+      "Auxiliary variable";
+    Real num = c[3] + c[5] * n + c[7] * (2 * n^2 - 1) + c[9] * (4 * n^3 - 3 * n)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * n + c[6] * (2 * n^2 - 1) + c[8] * (4 * n^3 - 3 * n)
+      "Denominator of characteristic curve";
+
+    Real dn_dT_adsorpt = (1 / c[11]) * dA_dT_adsorpt +
+      (-1 / c[11]) * dc_dT_adsorpt[10] +
+      ((c[10] - A) / c[11]^2) * dc_dT_adsorpt[11]
+      "Partial derivative of auxiliary variable w.r.t. temprature";
+    Real dnum_dT_adsorpt = (1) * dc_dT_adsorpt[3] +
+      (n) * dc_dT_adsorpt[5] +
+      (2 * n^2 - 1) * dc_dT_adsorpt[7] +
+      (4 * n^3 - 3 * n) * dc_dT_adsorpt[9] +
+      (4 * n * (3 * c[9] * n + c[7]) - 3 * c[9] + c[5]) * dn_dT_adsorpt
+      "Partial derivative of numerator of characteristic curve w.r.t. temprature";
+    Real dden_dT_adsorpt = (n) * dc_dT_adsorpt[4] +
+      (2 * n^2 - 1) * dc_dT_adsorpt[6] +
+      (4 * n^3 - 3 * n) * dc_dT_adsorpt[8] +
+      (4 * n * (3 * c[8] * n + c[6]) - 3 * c[8] + c[4]) * dn_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+    Real ddn_dT_adsorpt_dT_adsorpt=
+      ((-1 / c[11]^2 * dA_dT_adsorpt) * dc_dT_adsorpt[11] +
+       (1 / c[11]) * ddA_dT_adsorpt_dT_adsorpt) +
+      ((-1 / c[11]) * ddc_dT_adsorpt_dT_adsorpt[10] +
+       (1 / c[11]^2 * dc_dT_adsorpt[10]) * dc_dT_adsorpt[11]) +
+      ((1 / c[11]^2 * dc_dT_adsorpt[11]) * dc_dT_adsorpt[10] +
+       (-2 * (c[10] - A) / c[11]^3 * dc_dT_adsorpt[11]) * dc_dT_adsorpt[11] +
+       (-1 / c[11]^2 * dc_dT_adsorpt[11]) * dA_dT_adsorpt +
+       ((c[10] - A) / c[11]^2) * ddc_dT_adsorpt_dT_adsorpt[11])
+      "Second-order partial derivative of auxiliary variable w.r.t. temprature";
+    Real ddnum_dT_adsorpt_dT_adsorpt=
+      ((1) * ddc_dT_adsorpt_dT_adsorpt[3]) +
+      ((dc_dT_adsorpt[5]) * dn_dT_adsorpt +
+       (n) * ddc_dT_adsorpt_dT_adsorpt[5]) +
+      ((4 * n * dc_dT_adsorpt[7]) * dn_dT_adsorpt +
+       (2 * n^2 - 1) * ddc_dT_adsorpt_dT_adsorpt[7]) +
+      (((12 * n^2 - 3) * dc_dT_adsorpt[9]) * dn_dT_adsorpt +
+       (4 * n^3 - 3 * n) * ddc_dT_adsorpt_dT_adsorpt[9]) +
+      ((4 * dn_dT_adsorpt * (6 * c[9] * n + c[7])) * dn_dT_adsorpt +
+       (1 * dn_dT_adsorpt) * dc_dT_adsorpt[5] +
+       (4 * n * dn_dT_adsorpt) * dc_dT_adsorpt[7] +
+       ((12 * n^2 - 3) * dn_dT_adsorpt) * dc_dT_adsorpt[9] +
+       (4 * n * (3 * c[9] * n + c[7]) - 3 * c[9] + c[5]) * ddn_dT_adsorpt_dT_adsorpt)
+      "Second-order partial derivative of numerator of characteristic curve w.r.t. 
+    temprature";
+    Real ddden_dT_adsorpt_dT_adsorpt=
+      ((dc_dT_adsorpt[4]) * dn_dT_adsorpt +
+       (n) * ddc_dT_adsorpt_dT_adsorpt[4]) +
+      ((4 * n * dc_dT_adsorpt[6]) * dn_dT_adsorpt +
+       (2 * n^2 - 1) * ddc_dT_adsorpt_dT_adsorpt[6]) +
+      (((12 * n^2 - 3) * dc_dT_adsorpt[8]) * dn_dT_adsorpt +
+       (4 * n^3 - 3 * n) * ddc_dT_adsorpt_dT_adsorpt[8]) +
+      (((4 * (6 * c[8] * n + c[6])) * dn_dT_adsorpt) * dn_dT_adsorpt +
+       (1 * dn_dT_adsorpt) * dc_dT_adsorpt[4] +
+       (4 * n * dn_dT_adsorpt) * dc_dT_adsorpt[6] +
+       ((12 * n^2 - 3) * dn_dT_adsorpt) * dc_dT_adsorpt[8] +
+       (4 * n * (3 * c[8] * n + c[6]) - 3 * c[8] + c[4]) * ddn_dT_adsorpt_dT_adsorpt)
+      "Second-order partial derivative of denominator of characteristic curve w.r.t. 
+    temprature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      ((1/den * dc_dT_adsorpt[2]) * dnum_dT_adsorpt +
+       (-num / den^2 * dc_dT_adsorpt[2]) * dden_dT_adsorpt +
+       (num / den) * ddc_dT_adsorpt_dT_adsorpt[2]) +
+      ((1/den * dnum_dT_adsorpt) * dc_dT_adsorpt[2] +
+       (-c[2] / den^2 * dnum_dT_adsorpt) * dden_dT_adsorpt +
+       (c[2] / den) * ddnum_dT_adsorpt_dT_adsorpt) +
+      ((-num / den^2 * dden_dT_adsorpt) * dc_dT_adsorpt[2] +
+       (-c[2] / den^2 * dden_dT_adsorpt) * dnum_dT_adsorpt +
+       (2 * c[2] * num / den^3 * dden_dT_adsorpt) * dden_dT_adsorpt +
+       (-c[2] * num / den^2) * ddden_dT_adsorpt_dT_adsorpt)
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+        "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of adsorption potential w.r.t. to pressure at constant
+      temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Second-order partial derivative of adsorption potential w.r.t. to pressure
+    and temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.dW_dA(
+        A=A, c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.ddW_dA_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        A=A,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of characteristic curve w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      dc_dT_adsorpt[2] * dW_dA * dA_dp_adsorpt +
+      c[2] * ddW_dA_dT_adsorpt * dA_dp_adsorpt +
+      c[2] * dW_dA * ddA_dp_adsorpt_dT_adsorpt
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare function pi_pT
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT_num(
+       integral_pi_lb = 1e-2,
+       tolerance = 1e-6,
+       redeclare final function func_x_pT =
+       SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.x_pT);
+  end pi_pT;
+
+  redeclare function p_piT
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+        p_adsorpt_lb_start = 1,
+        integral_pi_lb = 1e-2,
+        tolerance_p_adsorpt = 1e-6,
+        tolerance_pi = 1e-6,
+        redeclare final function func_pi_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.pi_pT);
+  end p_piT;
+
+  redeclare final function extends W_A
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Filled pore volume as function of adsorption potential"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real n = (A - c[10]) / c[11]
+      "Auxiliary variable";
+
+    Real num = c[3] + c[5] * n + c[7] * (2 * n^2 - 1) + c[9] * (4 * n^3 - 3 * n)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * n + c[6] * (2 * n^2 - 1) + c[8] * (4 * n^3 - 3 * n)
+      "Denominator of characteristic curve";
+
+  algorithm
+    W := num / den
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(A=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.A_W(W, c, A_lb_start, A_ub_start, tolerance)));
+  end W_A;
+
+  redeclare final function extends A_W
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Adsorption potential as function of the filled pore volume (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_A_W_num(
+        redeclare final function func_W_A =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.W_A);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(W=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33.W_A(A, c, A_lb_start, A_ub_start, tolerance)));
+  end A_W;
+
+  redeclare final function extends dW_dA
+    "Dubinin-Chebyshev-Series-3/3 isotherm model: Partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real n = (A - c[10]) / c[11]
+      "Auxiliary variable";
+
+    Real num = c[3] + c[5] * n + c[7] * (2 * n^2 - 1) + c[9] * (4 * n^3 - 3 * n)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * n + c[6] * (2 * n^2 - 1) + c[8] * (4 * n^3 - 3 * n)
+      "Denominator of characteristic curve";
+
+    Real dn_dA = 1 / c[11]
+      "Partial derivative of the auxiliary variable w.r.t. adsorption potential";
+
+    Real dnum_dn = c[9] * (12 * n^2 - 3) + 4 * c[7] * n + c[5]
+      "Partial derivative of the numerator w.r.t. auxiliary variable";
+    Real dden_dn = c[8] * (12 * n^2 - 3) + 4 * c[6] * n + c[4]
+      "Partial derivative of the numerator w.r.t. auxiliary variable";
+
+    Real dW_dn = (dnum_dn * den - num * dden_dn) / den^2
+      "Partial derivative of the equilibrium uptake w.r.t. auxiliary variable";
+
+  algorithm
+    dW_dA := dW_dn*dn_dA
+      "Partial derivative of the filled pore volume w.r.t. adsorption potential at 
+    constant pressure and temperature";
+  end dW_dA;
+
+  redeclare final function extends ddW_dA_dA
+    "Dubinin-Chebyshev-Series-3/3: Second-order partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real n = (A - c[10]) / c[11]
+      "Auxiliary variable";
+
+    Real num = c[3] + c[5] * n + c[7] * (2 * n^2 - 1) + c[9] * (4 * n^3 - 3 * n)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * n + c[6] * (2 * n^2 - 1) + c[8] * (4 * n^3 - 3 * n)
+      "Denominator of characteristic curve";
+
+    Real dn_dA = 1 / c[11]
+      "Partial derivative of the auxiliary variable w.r.t. adsorption potential";
+
+    Real dnum_dn = c[9] * (12 * n^2 - 3) + 4 * c[7] * n + c[5]
+      "Partial derivative of the numerator w.r.t. auxiliary variable";
+    Real dden_dn = c[8] * (12 * n^2 - 3) + 4 * c[6] * n + c[4]
+      "Partial derivative of the numerator w.r.t. auxiliary variable";
+
+    Real dW_dn = (dnum_dn * den - num * dden_dn) / den^2
+      "Partial derivative of the equilibrium uptake w.r.t. auxiliary variable";
+
+    Real ddnum_dn_dn = 24 * c[9] * n + 4 * c[7]
+      "Second-order partial derivative of the numerator w.r.t. auxiliary variable";
+    Real ddden_dn_dn = 24 * c[8] * n + 4 * c[6]
+      "Second-order partial derivative of the numerator w.r.t. auxiliary variable";
+
+    Real ddW_dn_dn=
+      (1 / den) * ddnum_dn_dn +
+      (-dnum_dn / den^2) * dden_dn +
+      (-dden_dn / den^2) * dnum_dn +
+      (-num / den^2) * ddden_dn_dn +
+      (2 * num * dden_dn / den^3) * dden_dn
+      "Second-order partial derivative of the equilibrium uptake w.r.t. auxiliary 
+    variable";
+
+  algorithm
+    ddW_dA_dA := (dn_dA) * (ddW_dn_dn*dn_dA)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential at constant pressure and temperature";
+  end ddW_dA_dA;
+
+  redeclare final function extends ddW_dA_dT
+    "Dubinin-Chebyshev-Series-3/3: Second-order partial derivative of filled pore volume w.r.t. adsorption potential and temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real n = (A - c[10]) / c[11]
+      "Auxiliary variable";
+
+    Real num = c[3] + c[5] * n + c[7] * (2 * n^2 - 1) + c[9] * (4 * n^3 - 3 * n)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * n + c[6] * (2 * n^2 - 1) + c[8] * (4 * n^3 - 3 * n)
+      "Denominator of characteristic curve";
+
+    Real dn_dA = 1 / c[11]
+      "Partial derivative of the auxiliary variable w.r.t. adsorption potential";
+
+    Real dnum_dn = c[9] * (12 * n^2 - 3) + 4 * c[7] * n + c[5]
+      "Partial derivative of the numerator w.r.t. auxiliary variable";
+    Real dden_dn = c[8] * (12 * n^2 - 3) + 4 * c[6] * n + c[4]
+      "Partial derivative of the numerator w.r.t. auxiliary variable";
+
+    Real dW_dn = (dnum_dn * den - num * dden_dn) / den^2
+      "Partial derivative of the equilibrium uptake w.r.t. auxiliary variable";
+
+    Real dn_dT_adsorpt = (1 / c[11]) * dA_dT_adsorpt +
+      (-1 / c[11]) * dc_dT_adsorpt[10] +
+      ((c[10] - A) / c[11]^2) * dc_dT_adsorpt[11]
+      "Partial derivative of auxiliary variable w.r.t. temprature";
+    Real dnum_dT_adsorpt = (1) * dc_dT_adsorpt[3] +
+      (n) * dc_dT_adsorpt[5] +
+      (2 * n^2 - 1) * dc_dT_adsorpt[7] +
+      (4 * n^3 - 3 * n) * dc_dT_adsorpt[9] +
+      (4 * n * (3 * c[9] * n + c[7]) - 3 * c[9] + c[5]) * dn_dT_adsorpt
+      "Partial derivative of numerator of characteristic curve w.r.t. temprature";
+    Real dden_dT_adsorpt = (n) * dc_dT_adsorpt[4] +
+      (2 * n^2 - 1) * dc_dT_adsorpt[6] +
+      (4 * n^3 - 3 * n) * dc_dT_adsorpt[8] +
+      (4 * n * (3 * c[8] * n + c[6]) - 3 * c[8] + c[4]) * dn_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+    Real ddn_dA_dT_adsorpt = (-1 / c[11]^2) * dc_dT_adsorpt[11]
+      "Second-order partial derivative of the auxiliary variable w.r.t. adsorption
+    potential and temperature at constant pressure";
+
+    Real ddnum_dn_dT_adsorpt=
+      (1) * dc_dT_adsorpt[5] +
+      (4 * n) * dc_dT_adsorpt[7] +
+      (12 * n^2 - 3) * dc_dT_adsorpt[9] +
+      (24 * c[9] * n + 4 * c[7]) * dn_dT_adsorpt
+      "Second-order partial derivative of numerator w.r.t. auxiliary variable and
+    temperature";
+    Real ddden_dn_dT_adsorpt=
+      (1) * dc_dT_adsorpt[4] +
+      (4 * n) * dc_dT_adsorpt[6] +
+      (12 * n^2 - 3) * dc_dT_adsorpt[8] +
+      (24 * c[8] * n + 4 * c[6]) * dn_dT_adsorpt
+      "Second-order partial derivative of numerator w.r.t. auxiliary variable and
+    temperature";
+
+    Real ddW_dn_dT_adsorpt=
+      ((1/den) * ddnum_dn_dT_adsorpt +
+       (-1/den^2 * dnum_dn) * dden_dT_adsorpt) +
+      ((-dden_dn/den^2) * dnum_dT_adsorpt +
+       (-num/den^2) * ddden_dn_dT_adsorpt +
+       (2 * num * dden_dn / den^3) * dden_dT_adsorpt)
+      "Second-order partial derivative of the equilibrium uptake w.r.t. auxiliary 
+    variable and temperature";
+
+  algorithm
+    ddW_dA_dT := (dn_dA) * ddW_dn_dT_adsorpt +
+      (dW_dn) * ddn_dA_dT_adsorpt
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential and temperature";
+  end ddW_dA_dT;
+  //
+  // Annotation
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Dubinin-Chebyshev-Series-3/3 isotherm model is a eleven-parameter model for calculating 
+the equilibrium uptake <i>x_adsorpt</i> as a function of the equilibrium  pressure 
+<i>p_adsorpt</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Dubinin-Chebyshev-Series-3/3 isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) * W(A(T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    W(A(T<sub>adsorpt</sub>)) = (a + c * n + e * (2 * n<sup>2</sup> - 1) + g * (4 * n<sup>3</sup> - 3 * n)) / (1 + b * n + d * (2 * n<sup>2</sup> - 1) + f * (4 * n<sup>3</sup> - 3 * n));
+</pre>
+<pre>
+    n(A(T<sub>adsorpt</sub>)) = (A - h) / i;
+</pre>
+<pre>
+    A(T<sub>adsorpt</sub>) = R * T<sub>adsorpt</sub> * <strong>ln</strong>(p<sub>sat</sub>(T<sub>adsorpt</sub>) / p<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>W(A(T<sub>adsorpt</sub>))</i> is the so-called characteristic curve and
+<i>A(T<sub>adsorpt</sub>)</i> is the adsorption potential. Within the characteristic 
+curve, the parameters <i>a</i>, <i>b</i>, <i>c</i>, <i>d</i>, <i>e</i>, <i>f</i>,
+<i>g</i>, <i>h</i>, and <i>i</i> are fitting parameters.
+<br/><br/>
+Note that the density of the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> 
+is assumed to be the saturated liquid density &rho;<sub>sat,liq</sub>(T<sub>adsorpt</sub>) 
+without any further information about the system under consideration. For super-critical
+adsorptives (i.e., <i>T<sub>adsorpt</sub> &ge; T<sub>crit</sub></i>), the density of
+the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> can be estimated by
+</p>
+<pre>
+    &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) = &rho;<sub>sat,liq</sub>(T<sub>boiling,0</sub>) * <strong>exp</strong>(-0.0025 * (T<sub>adsorpt</sub> - T<sub>boiling,0</sub>));
+</pre>
+<p>
+and a pseudo-vapour pressure <i>p<sub>sat</sub>(T<sub>adsorpt</sub>)</i> can be calculated by
+</p>
+<pre>
+    p<sub>sat</sub>(T<sub>adsorpt</sub>) = p<sub>crit</sub>(T<sub>adsorpt</sub>) * (T<sub>adsorpt</sub> / T<sub>crit</sub>) ^ k;
+</pre>
+<p>
+where <i>T<sub>boiling,0</sub></i> is the normal boiling point at 1 atm and <i>k</i> is
+a fitting parameter specific to the system under consideration.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = p<sub>sat</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2] = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) in kg/m<sup>3</sup>
+  </li>
+  <li>
+  c[3] = a in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[4] = b in -
+  </li>
+  <li>
+  c[5] = c in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[6] = d in -
+  </li>
+  <li>
+  c[7] = e in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[8] = f in -
+  </li>
+  <li>
+  c[9] = g in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[10] = h in J/mol
+  </li>
+  <li>
+  c[11] = i in J/mol
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The characteristic curve <i>W(A)</i> must decrease strictly monotonically with 
+  increasing adsorption potential <i>A</i>. Otherwise, the inverses <i>A(W)</i>
+  and <i>p(x,T</i>) may not be solveable.
+  </li>
+  <li>
+  The reduced spreading pressure <i>&pi;</i> may not be calculable. Accordingly, the 
+  inverse <i>p(&pi;,T)</i> cannot be calculated either.
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Dubinin-Chebyshev-Series-3/3 isotherm model for one 
+parameter set. In the upper sub-figure, the equilibrium pressure changes with 
+time, while the equilibrium temperature is constant. In the centered sub-figure, the 
+equilibrium temperature changes with time, while the equilibrium pressure is constant. 
+In the lower sub-figure, the characteristic curve is shown. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_chebyshev_series_3_3.png\" alt=\"media_functions_equilibria_pure_dubinin_chebyshev_series_3_3.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Schawe, D. (1999). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD Thesis, Stuttgart.
+  </li>
+</ul>
+</html>"));
+end DubininChebyshevSeriesRaionalOrder33;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininChebyshevSeriesRaionalOrder33/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininChebyshevSeriesRaionalOrder33/package.order
new file mode 100644
index 0000000..44a21b8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininChebyshevSeriesRaionalOrder33/package.order
@@ -0,0 +1,12 @@
+x_pT
+p_xT
+dx_dT
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
+W_A
+A_W
+dW_dA
+ddW_dA_dA
+ddW_dA_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical1/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical1/package.mo
new file mode 100644
index 0000000..a3dbe3d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical1/package.mo
@@ -0,0 +1,496 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package DubininEmpirical1 "Package containing all functions regarding the Dubinin-Empirical-1 isotherm model"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin;
+
+  redeclare final function extends x_pT
+    "Dubinin-Empirical-1 isotherm model: Uptake as function of pressure and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Dubinin-Empirical-1 isotherm model: Pressure as function of uptake and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dT
+    "Dubinin-Empirical-1 isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real den = (c[3] + c[4] * A^2 * log(c[5] * A) + c[6] * A^3)
+      "Denominator of characteristic curve";
+
+    Real dden_dc3 = 1
+      "Partial derivative of denominator of characteristic curve w.r.t. third
+    coefficient of isotherm";
+    Real dden_dc4 = A^2 * log(c[5] * A)
+      "Partial derivative of denominator of characteristic curve w.r.t. fourth
+    coefficient of isotherm";
+    Real dden_dc5 = c[4] * A^2 / c[5]
+      "Partial derivative of denominator of characteristic curve w.r.t. fivth
+    coefficient of isotherm";
+    Real dden_dc6 = A^3
+      "Partial derivative of denominator of characteristic curve w.r.t. sixth
+    coefficient of isotherm";
+    Real dden_dA = A * (2 * c[4] * log(c[5] * A) + 3 * c[6] * A + c[4])
+      "Partial derivative of denominator of characteristic curve w.r.t. adsorption
+    potential";
+
+    Real dden_dT_adsorpt = dden_dc3 * dc_dT_adsorpt[3] +
+      dden_dc4 * dc_dT_adsorpt[4] +
+      dden_dc5 * dc_dT_adsorpt[5] +
+      dden_dc6 * dc_dT_adsorpt[6] +
+      dden_dA * dA_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt := (1 / den) * dc_dT_adsorpt[2] +
+      (-c[2]/den^2) * dden_dT_adsorpt
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dT_dT
+    "Dubinin-Empirical-1 isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dT_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1],
+      ddp_sat_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt[1])
+      "Second-order partial derivative of adsorption potential w.r.t. equilibrium 
+      temperature at constant pressure";
+
+    Real den = (c[3] + c[4] * A^2 * log(c[5] * A) + c[6] * A^3)
+      "Denominator of characteristic curve";
+
+    Real dden_dc3 = 1
+      "Partial derivative of denominator of characteristic curve w.r.t. third
+    coefficient of isotherm";
+    Real dden_dc4 = A^2 * log(c[5] * A)
+      "Partial derivative of denominator of characteristic curve w.r.t. fourth
+    coefficient of isotherm";
+    Real dden_dc5 = c[4] * A^2 / c[5]
+      "Partial derivative of denominator of characteristic curve w.r.t. fivth
+    coefficient of isotherm";
+    Real dden_dc6 = A^3
+      "Partial derivative of denominator of characteristic curve w.r.t. sixth
+    coefficient of isotherm";
+    Real dden_dA = A * (2 * c[4] * log(c[5] * A) + 3 * c[6] * A + c[4])
+      "Partial derivative of denominator of characteristic curve w.r.t. adsorption
+    potential";
+
+    Real dden_dT_adsorpt = dden_dc3 * dc_dT_adsorpt[3] +
+      dden_dc4 * dc_dT_adsorpt[4] +
+      dden_dc5 * dc_dT_adsorpt[5] +
+      dden_dc6 * dc_dT_adsorpt[6] +
+      dden_dA * dA_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+    Real ddden_dc4_dT_adsorpt = (A^2 / c[5]) * dc_dT_adsorpt[5] +
+      (2 * A * log(c[5] * A) + A) * dA_dT_adsorpt
+      "Second-order partial darivative of denominator of characteristic curve w.r.t.
+    fourth coefficient of isotherm and temperature";
+    Real ddden_dc5_dT_adsorpt = (A^2 / c[5]) * dc_dT_adsorpt[4] +
+      (-c[4] * A^2 / c[5]^2) * dc_dT_adsorpt[5] +
+      (2 * c[4] * A / c[5]) * dA_dT_adsorpt
+      "Second-order partial darivative of denominator of characteristic curve w.r.t.
+    fivth coefficient of isotherm and temperature";
+    Real ddden_dc6_dT_adsorpt = 3 * A^2 * dA_dT_adsorpt
+      "Second-order partial darivative of denominator of characteristic curve w.r.t.
+    sixth coefficient of isotherm and temperature";
+    Real ddden_dA_dT_adsorpt = (A * (2 * log(A * c[5]) + 1)) * dc_dT_adsorpt[4] +
+      ((2 * A * c[4]) / c[5]) * dc_dT_adsorpt[5] +
+      (3 * A^2) * dc_dT_adsorpt[6] +
+      (2 * c[4] * log(c[5] * A) + 6 * c[6] * A + 3 * c[4]) * dA_dT_adsorpt
+      "Second-order partial darivative of denominator of characteristic curve w.r.t.
+    adsorption potential and temperature";
+
+    Real ddden_dT_adsorpt_dT_adsorpt=
+      ((dden_dc3) * ddc_dT_adsorpt_dT_adsorpt[3]) +
+      ((dc_dT_adsorpt[4]) * ddden_dc4_dT_adsorpt +
+       (dden_dc4) * ddc_dT_adsorpt_dT_adsorpt[4]) +
+      ((dc_dT_adsorpt[5]) * ddden_dc5_dT_adsorpt +
+       (dden_dc5) * ddc_dT_adsorpt_dT_adsorpt[5]) +
+      ((dc_dT_adsorpt[6]) * ddden_dc6_dT_adsorpt +
+       (dden_dc6) * ddc_dT_adsorpt_dT_adsorpt[6]) +
+      ((dA_dT_adsorpt) * ddden_dA_dT_adsorpt +
+       (dden_dA) * ddA_dT_adsorpt_dT_adsorpt)
+      "Second-order partial derivative of denominator of characteristic curve w.r.t. 
+    temprature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      ((-1/den^2 * dc_dT_adsorpt[2]) * dden_dT_adsorpt +
+       (1 / den) * ddc_dT_adsorpt_dT_adsorpt[2]) +
+      ((-1/den^2 * dden_dT_adsorpt) * dc_dT_adsorpt[2] +
+       (2 * c[2]/den^3 * dden_dT_adsorpt) * dden_dT_adsorpt +
+       (-c[2]/den^2) * ddden_dT_adsorpt_dT_adsorpt)
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Dubinin-Empirical-1 isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+        "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of adsorption potential w.r.t. to pressure at constant
+      temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Second-order partial derivative of adsorption potential w.r.t. to pressure
+      and temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.dW_dA(
+        A=A, c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.ddW_dA_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        A=A,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of characteristic curve w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      dc_dT_adsorpt[2] * dW_dA * dA_dp_adsorpt +
+      c[2] * ddW_dA_dT_adsorpt * dA_dp_adsorpt +
+      c[2] * dW_dA * ddA_dp_adsorpt_dT_adsorpt
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare function pi_pT
+    "Dubinin-Empirical-1 isotherm model: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT_num(
+       integral_pi_lb = 1e-12,
+       tolerance = 100*Modelica.Constants.eps,
+       redeclare final function func_x_pT =
+       SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.x_pT);
+  end pi_pT;
+
+  redeclare function p_piT
+    "Dubinin-Empirical-1 isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+       p_adsorpt_lb_start = 1,
+       integral_pi_lb = 1e-12,
+       tolerance_p_adsorpt = 1e-6,
+       tolerance_pi = 100*Modelica.Constants.eps,
+       redeclare final function func_pi_pT =
+       SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.pi_pT);
+  end p_piT;
+
+  redeclare final function extends W_A
+    "Dubinin-Empirical-1 isotherm model: Filled pore volume as function of adsorption potential"
+
+  algorithm
+    W := 1 / max((c[3] + c[4] * A^2 * log(max(c[5] * A,
+      Modelica.Constants.small)) + c[6] * A^3), Modelica.Constants.small)
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(A=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.A_W(W, c, A_lb_start, A_ub_start, tolerance)));
+  end W_A;
+
+  redeclare function A_W
+    "Dubinin-Empirical-1 isotherm model: Adsorption potential as function of the filled pore volume (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_A_W_num(
+        A_lb_start = 1,
+        redeclare final function func_W_A =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.W_A);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(W=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1.W_A(A, c, A_lb_start, A_ub_start, tolerance)));
+  end A_W;
+
+  redeclare final function extends dW_dA
+    "Dubinin-Empirical-1 isotherm model: Partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+  algorithm
+    dW_dA := -A * (2 * c[4] * log(c[5] * A) + 3 * c[6] * A + c[4]) /
+      (c[3] + c[4] * A^2 * log(c[5] * A) + c[6] * A^3)^2
+      "Partial derivative of the filled pore volume w.r.t. adsorption potential at 
+    constant pressure and temperature";
+  end dW_dA;
+
+  redeclare final function extends ddW_dA_dA
+    "Dubinin-Empirical-1: Second-order partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+  algorithm
+    ddW_dA_dA := (6 * c[4]^2 * A^2 * log(c[5] * A)^2 + c[4] * (A^2 * (16 * c[6] *
+      A + 5 * c[4]) - 2 * c[3]) * log(c[5] * A) + 12 * c[6]^2 * A^4 + 9 * c[4] *
+      c[6] * A^3 + 2 * c[4]^2 * A^2 - 6 * c[3] * c[6] * A - 3 * c[3] * c[4]) /
+      (A^2 * (c[4] * log(c[5] * A) + c[6] * A) + c[3])^3
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential at constant pressure and temperature";
+  end ddW_dA_dA;
+
+  redeclare final function extends ddW_dA_dT
+    "Dubinin-Empirical-1: Second-order partial derivative of filled pore volume w.r.t. adsorption potential and temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real num = -A * (2 * c[4] * log(c[5] * A) + 3 * c[6] * A + c[4])
+      "Numerator of characteristic curve";
+    Real den = (c[3] + c[4] * A^2 * log(c[5] * A) + c[6] * A^3)^2
+      "Denominator of characteristic curve";
+
+    Real dnum_dc4 = -A * (2 * log(A * c[5]) + 1)
+      "Partial derivative of numerator of characteristic curve w.r.t. fourth
+    coefficient of isotherm";
+    Real dnum_dc5 = -(2 * A * c[4]) / c[5]
+      "Partial derivative of numerator of characteristic curve w.r.t. fivth
+    coefficient of isotherm";
+    Real dnum_dc6 = -3 * A^2
+      "Partial derivative of numerator of characteristic curve w.r.t. sixth
+    coefficient of isotherm";
+    Real dnum_dA = -c[4] * (2 * log(c[5] * A) + 3) - 6 * c[6] * A
+      "Partial derivative of numerator of characteristic curve w.r.t. adsorption
+    potential";
+
+    Real dden_dc3 = 2 * (c[3] + A^2 * (A * c[6] + c[4] * log(A * c[5])))
+      "Partial derivative of denominator of characteristic curve w.r.t. third
+    coefficient of isotherm";
+    Real dden_dc4 = 2 * A^2 * log(A * c[5]) * (A^2 * (log(A * c[5]) * c[4] +
+      A * c[6]) + c[3])
+      "Partial derivative of denominator of characteristic curve w.r.t. fourth
+    coefficient of isotherm";
+    Real dden_dc5 = (2 * A^2 * c[4] * (A^2 * (c[4] * log(A * c[5]) + A * c[6]) +
+      c[3])) / c[5]
+      "Partial derivative of denominator of characteristic curve w.r.t. fivth
+    coefficient of isotherm";
+    Real dden_dc6 = 2 * A^3 * (A^2 * (A * c[6] + c[4] * log(A * c[5])) + c[3])
+      "Partial derivative of denominator of characteristic curve w.r.t. sixth
+    coefficient of isotherm";
+    Real dden_dA = 2 * A * (2 * c[4] * log(c[5] * A) + 3 * c[6] * A + c[4]) *
+      (A^2 * (c[4] * log(c[5] * A) + c[6] * A) + c[3])
+      "Partial derivative of denominator of characteristic curve w.r.t. adsorption
+    potential";
+
+    Real dnum_dT_adsorpt = dnum_dc4 * dc_dT_adsorpt[4] +
+      dnum_dc5 * dc_dT_adsorpt[5] +
+      dnum_dc6 * dc_dT_adsorpt[6] +
+      dnum_dA * dA_dT_adsorpt
+      "Partial derivative of numerator of characteristic curve w.r.t. temprature";
+    Real dden_dT_adsorpt = dden_dc3 * dc_dT_adsorpt[3] +
+      dden_dc4 * dc_dT_adsorpt[4] +
+      dden_dc5 * dc_dT_adsorpt[5] +
+      dden_dc6 * dc_dT_adsorpt[6] +
+      dden_dA * dA_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+  algorithm
+    ddW_dA_dT := (1/den) * dnum_dT_adsorpt +
+      (-num/den^2) * dden_dT_adsorpt
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential and temperature at constant pressure";
+  end ddW_dA_dT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 3, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Dubinin-Empirical-1 isotherm model is a four-parameter model for calculating 
+the equilibrium uptake <i>x_adsorpt</i> as a function of the equilibrium  pressure 
+<i>p_adsorpt</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Dubinin-Empirical-1 isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) * W(A(T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    W(A(T<sub>adsorpt</sub>)) = 1 / (a + b * A<sup>2</sup> * <strong>ln</strong>(c * A) + d * A<sup>3</sup>);
+</pre>
+<pre>
+    A(T<sub>adsorpt</sub>) = R * T<sub>adsorpt</sub> * <strong>ln</strong>(p<sub>sat</sub>(T<sub>adsorpt</sub>) / p<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>W(A(T<sub>adsorpt</sub>))</i> is the so-called characteristic curve and
+<i>A(T<sub>adsorpt</sub>)</i> is the adsorption potential. Within the characteristic 
+curve, the parameters <i>a</i>, <i>b</i>, and <i>c</i> are fitting parameters.
+<br/><br/>
+Note that the density of the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> 
+is assumed to be the saturated liquid density &rho;<sub>sat,liq</sub>(T<sub>adsorpt</sub>) 
+without any further information about the system under consideration. For super-critical
+adsorptives (i.e., <i>T<sub>adsorpt</sub> &ge; T<sub>crit</sub></i>), the density of
+the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> can be estimated by
+</p>
+<pre>
+    &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) = &rho;<sub>sat,liq</sub>(T<sub>boiling,0</sub>) * <strong>exp</strong>(-0.0025 * (T<sub>adsorpt</sub> - T<sub>boiling,0</sub>));
+</pre>
+<p>
+and a pseudo-vapour pressure <i>p<sub>sat</sub>(T<sub>adsorpt</sub>)</i> can be calculated by
+</p>
+<pre>
+    p<sub>sat</sub>(T<sub>adsorpt</sub>) = p<sub>crit</sub>(T<sub>adsorpt</sub>) * (T<sub>adsorpt</sub> / T<sub>crit</sub>) ^ k;
+</pre>
+<p>
+where <i>T<sub>boiling,0</sub></i> is the normal boiling point at 1 atm and <i>k</i> is
+a fitting parameter specific to the system under consideration.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = p<sub>sat</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2] = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) in kg/m<sup>3</sup>
+  </li>
+  <li>
+  c[3] = a in kg/m<sup>3</sup>
+  </li>
+  <li>
+  c[4] = b in kg.mol<sup>2</sup>/(m<sup>3</sup>.J<sup>2</sup>)
+  </li>
+  <li>
+  c[5] = c in mol/J
+  </li>
+  <li>
+  c[6] = d in kg.mol<sup>3</sup>/(m<sup>3</sup>.J<sup>3</sup>)
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The characteristic curve <i>W(A)</i> must decrease strictly monotonically with 
+  increasing adsorption potential <i>A</i>. Otherwise, the inverses <i>A(W)</i>
+  and <i>p(x,T</i>) may not be solveable.
+  </li>
+  <li>
+  The reduced spreading pressure <i>&pi;</i> may not be calculable. Accordingly, the 
+  inverse <i>p(&pi;,T)</i> cannot be calculated either.
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Dubinin-Empirical-1 isotherm model for one 
+parameter set. In the upper sub-figure, the equilibrium pressure changes with 
+time, while the equilibrium temperature is constant. In the centered sub-figure, the 
+equilibrium temperature changes with time, while the equilibrium pressure is constant. 
+In the lower sub-figure, the characteristic curve is shown. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_empirical_1.png\" alt=\"media_functions_equilibria_pure_dubinin_empirical_1.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Schawe, D. (1999). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD Thesis, Stuttgart.
+  </li>
+</ul>
+</html>"));
+end DubininEmpirical1;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical1/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical1/package.order
new file mode 100644
index 0000000..44a21b8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical1/package.order
@@ -0,0 +1,12 @@
+x_pT
+p_xT
+dx_dT
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
+W_A
+A_W
+dW_dA
+ddW_dA_dA
+ddW_dA_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical2/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical2/package.mo
new file mode 100644
index 0000000..261393d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical2/package.mo
@@ -0,0 +1,645 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package DubininEmpirical2 "Package containing all functions regarding the Dubinin-Empirical-2 isotherm model"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin;
+
+  redeclare final function extends x_pT
+    "Dubinin-Empirical-2 isotherm model: Uptake as function of pressure and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Dubinin-Empirical-2 isotherm model: Pressure as function of uptake and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dT
+    "Dubinin-Empirical-2 isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real num = c[3] + c[5] * sqrt(A) + c[7] * A + c[9] * A * sqrt(A)
+      "Numerator of characteristic curve";
+    Real den = 1    + c[4] * sqrt(A) + c[6] * A + c[8] * A * sqrt(A)
+      "Denominator of characteristic curve";
+
+    Real dnum_dc3 = 1
+      "Partial derivative of numerator of characteristic curve w.r.t. third
+    coefficient of isotherm";
+    Real dnum_dc5 = sqrt(A)
+      "Partial derivative of numerator of characteristic curve w.r.t. fivth
+    coefficient of isotherm";
+    Real dnum_dc7 = A
+      "Partial derivative of numerator of characteristic curve w.r.t. seventh
+    coefficient of isotherm";
+    Real dnum_dc9 = A ^ (3 / 2)
+      "Partial derivative of numerator of characteristic curve w.r.t. ninth
+    coefficient of isotherm";
+    Real dnum_dA = (3 * c[9] * sqrt(A)) / 2 + c[5] / (2 * sqrt(A)) + c[7]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+
+    Real dden_dc4 = sqrt(A)
+      "Partial derivative of denominator of characteristic curve w.r.t. fourth
+    coefficient of isotherm";
+    Real dden_dc6 = A
+      "Partial derivative of denominator of characteristic curve w.r.t. sixth
+    coefficient of isotherm";
+    Real dden_dc8 = A * sqrt(A)
+      "Partial derivative of denominator of characteristic curve w.r.t. eigth
+    coefficient of isotherm";
+    Real dden_dA = (3 * c[8] * sqrt(A)) / 2 + c[4] / (2 * sqrt(A)) + c[6]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+
+    Real dnum_dT_adsorpt = dnum_dc3 * dc_dT_adsorpt[3] +
+      dnum_dc5 * dc_dT_adsorpt[5] +
+      dnum_dc7 * dc_dT_adsorpt[7] +
+      dnum_dc9 * dc_dT_adsorpt[9] +
+      dnum_dA * dA_dT_adsorpt
+      "Partial derivative of numerator of characteristic curve w.r.t. temprature";
+    Real dden_dT_adsorpt = dden_dc4 * dc_dT_adsorpt[4] +
+      dden_dc6 * dc_dT_adsorpt[6] +
+      dden_dc8 * dc_dT_adsorpt[8] +
+      dden_dA * dA_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt := (num / den) * dc_dT_adsorpt[2] +
+      (c[2] / den) * dnum_dT_adsorpt +
+      (-c[2] * num / den^2) * dden_dT_adsorpt
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dT_dT
+    "Dubinin-Empirical-1 isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dT_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1],
+      ddp_sat_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt[1])
+      "Second-order partial derivative of adsorption potential w.r.t. equilibrium 
+      temperature at constant pressure";
+
+    Real num = c[3] + c[5] * sqrt(A) + c[7] * A + c[9] * A * sqrt(A)
+      "Numerator of characteristic curve";
+    Real den = 1    + c[4] * sqrt(A) + c[6] * A + c[8] * A * sqrt(A)
+      "Denominator of characteristic curve";
+
+    Real dnum_dc3 = 1
+      "Partial derivative of numerator of characteristic curve w.r.t. third
+    coefficient of isotherm";
+    Real dnum_dc5 = sqrt(A)
+      "Partial derivative of numerator of characteristic curve w.r.t. fivth
+    coefficient of isotherm";
+    Real dnum_dc7 = A
+      "Partial derivative of numerator of characteristic curve w.r.t. seventh
+    coefficient of isotherm";
+    Real dnum_dc9 = A ^ (3 / 2)
+      "Partial derivative of numerator of characteristic curve w.r.t. ninth
+    coefficient of isotherm";
+    Real dnum_dA = (3 * c[9] * sqrt(A)) / 2 + c[5] / (2 * sqrt(A)) + c[7]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+
+    Real dden_dc4 = sqrt(A)
+      "Partial derivative of denominator of characteristic curve w.r.t. fourth
+    coefficient of isotherm";
+    Real dden_dc6 = A
+      "Partial derivative of denominator of characteristic curve w.r.t. sixth
+    coefficient of isotherm";
+    Real dden_dc8 = A * sqrt(A)
+      "Partial derivative of denominator of characteristic curve w.r.t. eigth
+    coefficient of isotherm";
+    Real dden_dA = (3 * c[8] * sqrt(A)) / 2 + c[4] / (2 * sqrt(A)) + c[6]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+
+    Real dnum_dT_adsorpt=
+      dnum_dc3 * dc_dT_adsorpt[3] +
+      dnum_dc5 * dc_dT_adsorpt[5] +
+      dnum_dc7 * dc_dT_adsorpt[7] +
+      dnum_dc9 * dc_dT_adsorpt[9] +
+      dnum_dA * dA_dT_adsorpt
+      "Partial derivative of numerator of characteristic curve w.r.t. temprature";
+    Real dden_dT_adsorpt=
+      dden_dc4 * dc_dT_adsorpt[4] +
+      dden_dc6 * dc_dT_adsorpt[6] +
+      dden_dc8 * dc_dT_adsorpt[8] +
+      dden_dA * dA_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+    Real ddnum_dc5_dT_adsorpt = (1 / (2 * sqrt(A))) * dA_dT_adsorpt
+      "Second-order partial derivative of numerator of characteristic curve w.r.t. 
+    fivth coefficient of isotherm and temperature";
+    Real ddnum_dc7_dT_adsorpt = (1) * dA_dT_adsorpt
+      "Partial derivative of numerator of characteristic curve w.r.t. seventh
+    coefficient of isotherm and temperature";
+    Real ddnum_dc9_dT_adsorpt = ((3 * sqrt(A)) / 2) * dA_dT_adsorpt
+      "Second-order partial derivative of numerator of characteristic curve w.r.t. ninth
+    coefficient of isotherm";
+    Real ddnum_dA_dT_adsorpt = (1 / (2 * sqrt(A))) * dc_dT_adsorpt[5] +
+      (1) * dc_dT_adsorpt[7] +
+      ((3 * sqrt(A)) / 2) * dc_dT_adsorpt[9] +
+      ((3 * c[9] * A - c[5]) / (4 * A^(3 / 2))) * dA_dT_adsorpt
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential
+    and temperature";
+
+    Real ddden_dc4_dT_adsorpt = (1 / (2 * sqrt(A))) * dA_dT_adsorpt
+      "Second-order partial derivative of denominator of characteristic curve w.r.t.
+    fourth coefficient of isotherm and temperature";
+    Real ddden_dc6_dT_adsorpt = (1) * dA_dT_adsorpt
+      "Second-order partial derivative of denominator of characteristic curve w.r.t. 
+    sixth coefficient of isotherm and temperature";
+    Real ddden_dc8_dT_adsorpt = ((3 * sqrt(A)) / 2) * dA_dT_adsorpt
+      "Second-order partial derivative of denominator of characteristic curve w.r.t. 
+    eigth coefficient of isotherm and temperature";
+    Real ddden_dA_dT_adsorpt = (1 / (2 * sqrt(A))) * dc_dT_adsorpt[4] +
+      (1) * dc_dT_adsorpt[6] +
+      ((3 * sqrt(A)) / 2) * dc_dT_adsorpt[8] +
+      ((3 * c[8] * A - c[4]) / (4 * A^(3 / 2))) * dA_dT_adsorpt
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential
+    and temperature";
+
+    Real ddnum_dT_adsorpt_dT_adsorpt=
+      ((dnum_dc3) * ddc_dT_adsorpt_dT_adsorpt[3]) +
+      ((dc_dT_adsorpt[5]) * ddnum_dc5_dT_adsorpt +
+       (dnum_dc5) * ddc_dT_adsorpt_dT_adsorpt[5]) +
+      ((dc_dT_adsorpt[7]) * ddnum_dc7_dT_adsorpt +
+       (dnum_dc7) * ddc_dT_adsorpt_dT_adsorpt[7]) +
+      ((dc_dT_adsorpt[9]) * ddnum_dc9_dT_adsorpt +
+       (dnum_dc9) * ddc_dT_adsorpt_dT_adsorpt[9]) +
+      ((dA_dT_adsorpt) * ddnum_dA_dT_adsorpt +
+       (dnum_dA) * ddA_dT_adsorpt_dT_adsorpt)
+      "Second-order partial derivative of numerator of characteristic curve w.r.t. 
+    temprature";
+    Real ddden_dT_adsorpt_dT_adsorpt=
+      ((dc_dT_adsorpt[4]) * ddden_dc4_dT_adsorpt +
+       (dden_dc4) * ddc_dT_adsorpt_dT_adsorpt[4]) +
+      ((dc_dT_adsorpt[6]) * ddden_dc6_dT_adsorpt +
+       (dden_dc6) * ddc_dT_adsorpt_dT_adsorpt[6]) +
+      ((dc_dT_adsorpt[8]) * ddden_dc8_dT_adsorpt +
+       (dden_dc8) * ddc_dT_adsorpt_dT_adsorpt[8]) +
+      ((dA_dT_adsorpt) * ddden_dA_dT_adsorpt +
+       (dden_dA) * ddA_dT_adsorpt_dT_adsorpt)
+      "Second-order partial derivative of denominator of characteristic curve w.r.t. 
+    temprature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      ((1/den * dc_dT_adsorpt[2]) * dnum_dT_adsorpt +
+       (-num / den^2 * dc_dT_adsorpt[2]) * dden_dT_adsorpt +
+       (num / den) * ddc_dT_adsorpt_dT_adsorpt[2]) +
+      ((1/den * dnum_dT_adsorpt) * dc_dT_adsorpt[2] +
+       (-c[2] / den^2 * dnum_dT_adsorpt) * dden_dT_adsorpt +
+       (c[2] / den) * ddnum_dT_adsorpt_dT_adsorpt) +
+      ((-num / den^2 * dden_dT_adsorpt) * dc_dT_adsorpt[2] +
+       (-c[2] / den^2 * dden_dT_adsorpt) * dnum_dT_adsorpt +
+       (2 * c[2] * num / den^3 * dden_dT_adsorpt) * dden_dT_adsorpt +
+       (-c[2] * num / den^2) * ddden_dT_adsorpt_dT_adsorpt)
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Dubinin-Empirical-2 isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+        "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of adsorption potential w.r.t. to pressure at constant
+      temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Second-order partial derivative of adsorption potential w.r.t. to pressure
+      and temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.dW_dA(
+        A=A, c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.ddW_dA_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        A=A,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of characteristic curve w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      dc_dT_adsorpt[2] * dW_dA * dA_dp_adsorpt +
+      c[2] * ddW_dA_dT_adsorpt * dA_dp_adsorpt +
+      c[2] * dW_dA * ddA_dp_adsorpt_dT_adsorpt
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare function pi_pT
+    "Dubinin-Empirical-2 isotherm model: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT_num(
+       integral_pi_lb = 1e-2,
+       tolerance = 1e-4,
+       redeclare final function func_x_pT =
+       SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.x_pT);
+  end pi_pT;
+
+  redeclare function p_piT
+    "Dubinin-Empirical-2 isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+       p_adsorpt_lb_start = 1,
+       integral_pi_lb = 1e-2,
+       tolerance_p_adsorpt = 1e-6,
+       tolerance_pi = 1e-4,
+       redeclare final function func_pi_pT =
+       SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.pi_pT);
+  end p_piT;
+
+  redeclare final function extends W_A
+    "Dubinin-Empirical-2 isotherm model: Filled pore volume as function of adsorption potential"
+  algorithm
+    W := (c[3] + c[5] * sqrt(max(A, Modelica.Constants.small)) +
+      c[7] * A + c[9] * A * sqrt(max(A, Modelica.Constants.small))) /
+      (1 + c[4] * sqrt(max(A, Modelica.Constants.small)) +
+      c[6] * A + c[8] * A * sqrt(max(A, Modelica.Constants.small)))
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(A=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.A_W(W, c, A_lb_start, A_ub_start, tolerance)));
+  end W_A;
+
+  redeclare function A_W
+    "Dubinin-Empirical-2 isotherm model: Adsorption potential as function of the filled pore volume (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_A_W_num(
+        redeclare final function func_W_A =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.W_A);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(W=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2.W_A(A, c, A_lb_start, A_ub_start, tolerance)));
+  end A_W;
+
+  redeclare final function extends dW_dA
+    "Dubinin-Empirical-2 isotherm model: Partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real num = c[3] + c[5] * sqrt(A) + c[7] * A + c[9] * A * sqrt(A)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * sqrt(A) + c[6] * A + c[8] * A * sqrt(A)
+      "Denominator of characteristic curve";
+
+    Real dnum_dA = (3 * c[9] * sqrt(A)) / 2 + c[5] / (2 * sqrt(A)) + c[7]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+    Real dden_dA = (3 * c[8] * sqrt(A)) / 2 + c[4] / (2 * sqrt(A)) + c[6]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+
+  algorithm
+    dW_dA := (dnum_dA * den - num * dden_dA) / den^2
+      "Partial derivative of the filled pore volume w.r.t. adsorption potential at 
+    constant pressure and temperature";
+  end dW_dA;
+
+  redeclare final function extends ddW_dA_dA
+    "Dubinin-Empirical-1: Second-order partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real num = c[3] + c[5] * sqrt(A) + c[7] * A + c[9] * A * sqrt(A)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * sqrt(A) + c[6] * A + c[8] * A * sqrt(A)
+      "Denominator of characteristic curve";
+
+    Real dnum_dA = (3 * c[9] * sqrt(A)) / 2 + c[5] / (2 * sqrt(A)) + c[7]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+    Real dden_dA = (3 * c[8] * sqrt(A)) / 2 + c[4] / (2 * sqrt(A)) + c[6]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+
+    Real ddnum_dA_dA = (3 * c[9] * A - c[5]) / (4 * A^(3 / 2))
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential";
+    Real ddden_dA_dA = (3 * c[8] * A - c[4]) / (4 * A^(3 / 2))
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential";
+
+  algorithm
+    ddW_dA_dA :=
+      (1 / den) * ddnum_dA_dA +
+      (-dnum_dA / den^2) * dden_dA +
+      (-dden_dA / den^2) * dnum_dA +
+      (-num / den^2) * ddden_dA_dA +
+      (2 * num * dden_dA / den^3) * dden_dA
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential at constant pressure and temperature";
+  end ddW_dA_dA;
+
+  redeclare final function extends ddW_dA_dT
+    "Dubinin-Empirical-1: Second-order partial derivative of filled pore volume w.r.t. adsorption potential and temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real num = c[3] + c[5] * sqrt(A) + c[7] * A + c[9] * A * sqrt(A)
+      "Numerator of characteristic curve";
+    Real den = 1 + c[4] * sqrt(A) + c[6] * A + c[8] * A * sqrt(A)
+      "Denominator of characteristic curve";
+
+    Real dnum_dc3 = 1
+      "Partial derivative of numerator of characteristic curve w.r.t. third
+    coefficient of isotherm";
+    Real dnum_dc5 = sqrt(A)
+      "Partial derivative of numerator of characteristic curve w.r.t. fivth
+    coefficient of isotherm";
+    Real dnum_dc7 = A
+      "Partial derivative of numerator of characteristic curve w.r.t. seventh
+    coefficient of isotherm";
+    Real dnum_dc9 = A * sqrt(A)
+      "Partial derivative of numerator of characteristic curve w.r.t. ninth
+    coefficient of isotherm";
+    Real dnum_dA = (3 * c[9] * sqrt(A)) / 2 + c[5] / (2 * sqrt(A)) + c[7]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+
+    Real dden_dc4 = sqrt(A)
+      "Partial derivative of denominator of characteristic curve w.r.t. fourth
+    coefficient of isotherm";
+    Real dden_dc6 = A
+      "Partial derivative of denominator of characteristic curve w.r.t. sixth
+    coefficient of isotherm";
+    Real dden_dc8 = A * sqrt(A)
+      "Partial derivative of denominator of characteristic curve w.r.t. eigth
+    coefficient of isotherm";
+    Real dden_dA = (3 * c[8] * sqrt(A)) / 2 + c[4] / (2 * sqrt(A)) + c[6]
+      "Partial derivative of the numerator w.r.t. adsorption potential";
+
+    Real dnum_dT_adsorpt = dnum_dc3 * dc_dT_adsorpt[3] +
+      dnum_dc5 * dc_dT_adsorpt[5] +
+      dnum_dc7 * dc_dT_adsorpt[7] +
+      dnum_dc9 * dc_dT_adsorpt[9] +
+      dnum_dA * dA_dT_adsorpt
+      "Partial derivative of numerator of characteristic curve w.r.t. temprature";
+    Real dden_dT_adsorpt = dden_dc4 * dc_dT_adsorpt[4] +
+      dden_dc6 * dc_dT_adsorpt[6] +
+      dden_dc8 * dc_dT_adsorpt[8] +
+      dden_dA * dA_dT_adsorpt
+      "Partial derivative of denominator of characteristic curve w.r.t. temprature";
+
+    Real ddnum_dA_dc5 = 1 / (2 * sqrt(A))
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential
+    fivth coefficient of isotherm";
+    Real ddnum_dA_dc7 = 1
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential
+    seventh coefficient of isotherm";
+    Real ddnum_dA_dc9 = (3 * sqrt(A)) / 2
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential
+    ninth coefficient of isotherm";
+    Real ddnum_dA_dA = (3 * c[9] * A - c[5]) / (4 * A^(3 / 2))
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential";
+
+    Real ddden_dA_dc4 = 1 / (2 * sqrt(A))
+      "Second-order partial derivative of the denominator w.r.t. adsorption potential
+    fourth coefficient of isotherm";
+    Real ddden_dA_dc6 = 1
+      "Second-order partial derivative of the denominator w.r.t. adsorption potential
+    sixth coefficient of isotherm";
+    Real ddden_dA_dc8 = (3 * sqrt(A)) / 2
+      "Second-order partial derivative of the denominator w.r.t. adsorption potential
+    eigth coefficient of isotherm";
+    Real ddden_dA_dA = (3 * c[8] * A - c[4]) / (4 * A^(3 / 2))
+      "Second-order partial derivative of the denominator w.r.t. adsorption potential";
+
+    Real ddnum_dA_dT_adsorpt = ddnum_dA_dc5 * dc_dT_adsorpt[5] +
+      ddnum_dA_dc7 * dc_dT_adsorpt[7] +
+      ddnum_dA_dc9 * dc_dT_adsorpt[9] +
+      ddnum_dA_dA * dA_dT_adsorpt
+      "Second-order partial derivative of the numerator w.r.t. adsorption potential
+    and temperature";
+
+    Real ddden_dA_dT_adsorpt = ddden_dA_dc4 * dc_dT_adsorpt[4] +
+      ddden_dA_dc6 * dc_dT_adsorpt[6] +
+      ddden_dA_dc8 * dc_dT_adsorpt[8] +
+      ddden_dA_dA * dA_dT_adsorpt
+      "Second-order partial derivative of the denominator w.r.t. adsorption potential
+    and temperature";
+
+  algorithm
+    ddW_dA_dT := (1 / den) * ddnum_dA_dT_adsorpt +
+      (-dnum_dA / den^2) * dden_dT_adsorpt +
+      (-dden_dA / den^2) * dnum_dT_adsorpt +
+      (-num / den^2) * ddden_dA_dT_adsorpt +
+      (2 * num * dden_dA / den^3) * dden_dT_adsorpt
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential and temperature at constant pressure";
+  end ddW_dA_dT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Dubinin-Empirical-2 isotherm model is a nine-parameter model for calculating 
+the equilibrium uptake <i>x_adsorpt</i> as a function of the equilibrium  pressure 
+<i>p_adsorpt</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Dubinin-Empirical-2 isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) * W(A(T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    W(A(T<sub>adsorpt</sub>)) = (a + c * <strong>sqrt</strong>(A) + e * A + g * A * <strong>sqrt</strong>(A)) / (1 + b * <strong>sqrt</strong>(A) + d * A + f * A * <strong>sqrt</strong>(A));
+</pre>
+<pre>
+    A(T<sub>adsorpt</sub>) = R * T<sub>adsorpt</sub> * <strong>ln</strong>(p<sub>sat</sub>(T<sub>adsorpt</sub>) / p<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>W(A(T<sub>adsorpt</sub>))</i> is the so-called characteristic curve and
+<i>A(T<sub>adsorpt</sub>)</i> is the adsorption potential. Within the characteristic 
+curve, the parameters <i>a</i>, <i>b</i>, and <i>c</i> are fitting parameters.
+<br/><br/>
+Note that the density of the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> 
+is assumed to be the saturated liquid density &rho;<sub>sat,liq</sub>(T<sub>adsorpt</sub>) 
+without any further information about the system under consideration. For super-critical
+adsorptives (i.e., <i>T<sub>adsorpt</sub> &ge; T<sub>crit</sub></i>), the density of
+the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> can be estimated by
+</p>
+<pre>
+    &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) = &rho;<sub>sat,liq</sub>(T<sub>boiling,0</sub>) * <strong>exp</strong>(-0.0025 * (T<sub>adsorpt</sub> - T<sub>boiling,0</sub>));
+</pre>
+<p>
+and a pseudo-vapour pressure <i>p<sub>sat</sub>(T<sub>adsorpt</sub>)</i> can be calculated by
+</p>
+<pre>
+    p<sub>sat</sub>(T<sub>adsorpt</sub>) = p<sub>crit</sub>(T<sub>adsorpt</sub>) * (T<sub>adsorpt</sub> / T<sub>crit</sub>) ^ k;
+</pre>
+<p>
+where <i>T<sub>boiling,0</sub></i> is the normal boiling point at 1 atm and <i>k</i> is
+a fitting parameter specific to the system under consideration.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = p<sub>sat</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2] = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) in kg/m<sup>3</sup>
+  </li>
+  <li>
+  c[3] = a in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[4] = b in -
+  </li>
+  <li>
+  c[5] = c in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[6] = d in mol<sup>3</sup>/J
+  </li>
+  <li>
+  c[7] = e in m<sup>3</sup>.mol/(kg.J)
+  </li>
+  <li>
+  c[8] = f in mol<sup>3</sup>/J
+  </li>
+  <li>
+  c[9] = g in m<sup>3</sup>.mol/(kg.J)
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The characteristic curve <i>W(A)</i> must decrease strictly monotonically with 
+  increasing adsorption potential <i>A</i>. Otherwise, the inverses <i>A(W)</i>
+  and <i>p(x,T</i>) may not be solveable.
+  </li>
+  <li>
+  The reduced spreading pressure <i>&pi;</i> may not be calculable. Accordingly, the 
+  inverse <i>p(&pi;,T)</i> cannot be calculated either.
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Dubinin-Empirical-2 isotherm model for one 
+parameter set. In the upper sub-figure, the equilibrium pressure changes with 
+time, while the equilibrium temperature is constant. In the centered sub-figure, the 
+equilibrium temperature changes with time, while the equilibrium pressure is constant. 
+In the lower sub-figure, the characteristic curve is shown. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_empirical_2.png\" alt=\"media_functions_equilibria_pure_dubinin_empirical_2.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Schawe, D. (1999). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD Thesis, Stuttgart.
+  </li>
+</ul>
+</html>"));
+end DubininEmpirical2;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical2/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical2/package.order
new file mode 100644
index 0000000..44a21b8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininEmpirical2/package.order
@@ -0,0 +1,12 @@
+x_pT
+p_xT
+dx_dT
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
+W_A
+A_W
+dW_dA
+ddW_dA_dA
+ddW_dA_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininLorentzianCumulative/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininLorentzianCumulative/package.mo
new file mode 100644
index 0000000..10f579e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininLorentzianCumulative/package.mo
@@ -0,0 +1,558 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package DubininLorentzianCumulative "Package containing all functions regarding the Dubinin isotherm model using a 'Lorentzian Cumulative' equation type (i.e., arctan-function)"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin;
+
+  redeclare final function extends x_pT
+    "Dubinin-Lorentzian-Cumulative isotherm model: Uptake as function of pressure and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Dubinin-Lorentzian-Cumulative isotherm model: Pressure as function of uptake and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dT
+    "Dubinin-Lorentzian-Cumulative isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt) "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt,
+        dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature";
+
+    SorpLib.Units.FilledPoreVolume W=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.W_A(
+      A=A, c=c)
+      "Filled pore volume";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+        A=A, c=c)
+      "Partial derivative of characteristic curve w.r.t. adsorption potential";
+
+    Real dx_adsorpt_dA = c[2] * dW_dA
+      "Derivative of uptake w.r.t. to adsorption potential";
+    Real dx_adsorpt_dc2 = W
+      "Derivative of uptake w.r.t. to second coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+    Real dx_adsorpt_dc3 = c[2] / Modelica.Constants.pi *
+      (Modelica.Math.atan((A - c[4]) / c[5]) + Modelica.Constants.pi / 2)
+      "Derivative of uptake w.r.t. to third coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+    Real dx_adsorpt_dc4 = -c[2] * c[3] /
+      (Modelica.Constants.pi * c[5] * ((A - c[4])^2 / c[5]^2 + 1))
+      "Derivative of uptake w.r.t. to fourth coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+    Real dx_adsorpt_dc5 = -c[2] * c[3] * (A - c[4]) /
+      (Modelica.Constants.pi * c[5]^2 * ((A - c[4])^2 / c[5]^2 + 1))
+      "Derivative of uptake w.r.t. to fivth coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+    Real dx_adsorpt_dc6 = c[2]
+      "Derivative of uptake w.r.t. to sixth coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      dx_adsorpt_dA*dA_dT_adsorpt +
+      dx_adsorpt_dc2*dc_dT_adsorpt[2] +
+      dx_adsorpt_dc3*dc_dT_adsorpt[3] +
+      dx_adsorpt_dc4*dc_dT_adsorpt[4] +
+      dx_adsorpt_dc5*dc_dT_adsorpt[5] +
+      dx_adsorpt_dc6*dc_dT_adsorpt[6]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dT_dT
+    "Dubinin-Lorentzian-Cumulative isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dT_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1],
+      ddp_sat_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt[1])
+      "Second-order partial derivative of adsorption potential w.r.t. equilibrium 
+      temperature at constant pressure";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      A=A,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+    Real dx_adsorpt_dA = c[2] * dW_dA
+      "Derivative of uptake w.r.t. to adsorption potential";
+    Real dx_adsorpt_dc2 = c[3] / Modelica.Constants.pi *
+      (Modelica.Math.atan((A - c[4]) / c[5]) + Modelica.Constants.pi / 2) + c[6]
+      "Derivative of uptake w.r.t. to second coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+    Real dx_adsorpt_dc3 = c[2] / Modelica.Constants.pi *
+      (Modelica.Math.atan((A - c[4]) / c[5]) + Modelica.Constants.pi / 2)
+      "Derivative of uptake w.r.t. to third coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+    Real dx_adsorpt_dc4 = -c[2] * c[3] /
+      (Modelica.Constants.pi * c[5] * ((A - c[4])^2 / c[5]^2 + 1))
+      "Derivative of uptake w.r.t. to fourth coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+    Real dx_adsorpt_dc5 = -c[2] * c[3] * (A - c[4]) /
+      (Modelica.Constants.pi * c[5]^2 * ((A - c[4])^2 / c[5]^2 + 1))
+      "Derivative of uptake w.r.t. to fivth coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+    Real dx_adsorpt_dc6 = c[2]
+      "Derivative of uptake w.r.t. to sixth coefficient of Dubinin-Lorentzian-Cumulative 
+    isotherm";
+
+    Real ddx_adsorpt_dc4_dc4 = -(2 * c[2] * c[3] * (A - c[4])) /
+      (Modelica.Constants.pi * c[5]^3 * ((A - c[4])^2 / c[5]^2 + 1)^2)
+      "Second-order partial derivative of uptake w.r.t. to fourth coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm";
+    Real ddx_adsorpt_dc5_dc5 = -(2 * c[2] * c[3] * (c[4] - A) * c[5]) /
+      (Modelica.Constants.pi * (c[5]^2 + c[4]^2 - 2 * A * c[4] + A^2)^2)
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm";
+
+    Real ddx_adsorpt_dc2_dA= c[3] / (Modelica.Constants.pi * c[5] *
+      ((A - c[4])^2 / c[5]^2 + 1))
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and adsorption potential";
+    Real ddx_adsorpt_dc2_dc3 = (Modelica.Math.atan((A - c[4]) / c[5]) +
+      Modelica.Constants.pi / 2) / Modelica.Constants.pi
+      "Second-order partial derivative of uptake w.r.t. to second and third 
+    coefficient of Dubinin-Lorentzian-Cumulative isotherm";
+    Real ddx_adsorpt_dc2_dc4 = -c[3] / (Modelica.Constants.pi * c[5] *
+      ((A - c[4])^2 / c[5]^2 + 1))
+      "Second-order partial derivative of uptake w.r.t. to second and fourht 
+    coefficient of Dubinin-Lorentzian-Cumulative isotherm";
+    Real ddx_adsorpt_dc2_dc5 = -(c[3] * (A - c[4])) / (Modelica.Constants.pi *
+      ((A - c[4])^2 / c[5]^2 + 1) * c[5]^2)
+      "Second-order partial derivative of uptake w.r.t. to second and fivth 
+    coefficient of Dubinin-Lorentzian-Cumulative isotherm";
+    Real ddx_adsorpt_dc2_dc6 = 1
+      "Second-order partial derivative of uptake w.r.t. to second and sixth 
+    coefficient of Dubinin-Lorentzian-Cumulative isotherm";
+
+    Real ddx_adsorpt_dc3_dA = c[2] / (Modelica.Constants.pi * c[5] *
+      ((A - c[4])^2 / c[5]^2 + 1))
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and adsorption potential";
+    Real ddx_adsorpt_dc3_dc4 = -c[2] / (Modelica.Constants.pi * c[5] *
+      ((A - c[4])^2 / c[5]^2 + 1))
+      "Second-order partial derivative of uptake w.r.t. to third and fourht 
+    coefficient of Dubinin-Lorentzian-Cumulative isotherm";
+    Real ddx_adsorpt_dc3_dc5 = -(c[2] * (A - c[4])) / (Modelica.Constants.pi *
+      ((A - c[4])^2 / c[5]^2 + 1) * c[5]^2)
+      "Second-order partial derivative of uptake w.r.t. to third and fivth 
+    coefficient of Dubinin-Lorentzian-Cumulative isotherm";
+
+    Real ddx_adsorpt_dc4_dA = (2 * c[2] * c[3] * (A - c[4])) /
+      (Modelica.Constants.pi * c[5]^3 * ((A - c[4])^2 / c[5]^2 + 1)^2)
+      "Second-order partial derivative of uptake w.r.t. to fourth  coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and adsorption potential";
+    Real ddx_adsorpt_dc4_dc5 = (c[2] * c[3] * (c[5]^2 - c[4]^2 + 2 * A * c[4] -
+      A^2)) / (Modelica.Constants.pi * (c[5]^2 + c[4]^2 - 2 * A * c[4] + A^2)^2)
+      "Second-order partial derivative of uptake w.r.t. to fourth and fivth
+    coefficient of Dubinin-Lorentzian-Cumulative isotherm";
+
+    Real ddx_adsorpt_dc5_dA = (2 * c[2] * c[3] * (A - c[4])^2) /
+      (Modelica.Constants.pi * c[5]^4 * ((A - c[4])^2 / c[5]^2 + 1)^2) - (c[2] *
+      c[3]) / (Modelica.Constants.pi * c[5]^2 * ((A - c[4])^2 / c[5]^2 + 1))
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and adsorption potential";
+
+    Real ddx_adsorpt_dA_dT_dT_adsorpt = dc_dT_adsorpt[2] * dW_dA +
+      c[2] * ddW_dA_dT_adsorpt
+      "Second-order partial derivative of uptake w.r.t. to adsorption potential
+    and temperature";
+    Real ddx_adsorpt_dc2_dT_dT_adsorpt = ddx_adsorpt_dc2_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc2_dc4*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc2_dc5*dc_dT_adsorpt[5] +
+      ddx_adsorpt_dc2_dc6*dc_dT_adsorpt[6]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and temperature";
+    Real ddx_adsorpt_dc3_dT_dT_adsorpt = ddx_adsorpt_dc3_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc4*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc3_dc5*dc_dT_adsorpt[5]
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and temperature";
+    Real ddx_adsorpt_dc4_dT_dT_adsorpt = ddx_adsorpt_dc4_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc4*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc4*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc4_dc4*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc4_dc5*dc_dT_adsorpt[5]
+      "Second-order partial derivative of uptake w.r.t. to fourth coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and temperature";
+    Real ddx_adsorpt_dc5_dT_dT_adsorpt = ddx_adsorpt_dc5_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc5*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc5*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc4_dc5*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc5_dc5*dc_dT_adsorpt[5]
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and temperature";
+    Real ddx_adsorpt_dc6_dT_dT_adsorpt = ddx_adsorpt_dc2_dc6*dc_dT_adsorpt[2]
+      "Second-order partial derivative of uptake w.r.t. to sixth coefficient of 
+    Dubinin-Lorentzian-Cumulative isotherm and temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      (ddx_adsorpt_dA_dT_dT_adsorpt*dA_dT_adsorpt +
+       dx_adsorpt_dA*ddA_dT_adsorpt_dT_adsorpt) +
+      (ddx_adsorpt_dc2_dT_dT_adsorpt*dc_dT_adsorpt[2] +
+       dx_adsorpt_dc2*ddc_dT_adsorpt_dT_adsorpt[2]) +
+      (ddx_adsorpt_dc3_dT_dT_adsorpt*dc_dT_adsorpt[3] +
+       dx_adsorpt_dc3*ddc_dT_adsorpt_dT_adsorpt[3]) +
+      (ddx_adsorpt_dc4_dT_dT_adsorpt*dc_dT_adsorpt[4] +
+       dx_adsorpt_dc4*ddc_dT_adsorpt_dT_adsorpt[4]) +
+      (ddx_adsorpt_dc5_dT_dT_adsorpt*dc_dT_adsorpt[5] +
+       dx_adsorpt_dc5*ddc_dT_adsorpt_dT_adsorpt[5]) +
+      (ddx_adsorpt_dc6_dT_dT_adsorpt*dc_dT_adsorpt[6] +
+       dx_adsorpt_dc6*ddc_dT_adsorpt_dT_adsorpt[6])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Dubinin-Lorentzian-Cumulative isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+        "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of adsorption potential w.r.t. to pressure at constant
+      temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Second-order partial derivative of adsorption potential w.r.t. to pressure
+      and temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+        A=A, c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        A=A,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      dc_dT_adsorpt[2] * dW_dA * dA_dp_adsorpt +
+      c[2] * ddW_dA_dT_adsorpt * dA_dp_adsorpt +
+      c[2] * dW_dA * ddA_dp_adsorpt_dT_adsorpt
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare function pi_pT
+    "Dubinin-Lorentzian-Cumulative isotherm model: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT_num(
+        integral_pi_lb = 1e-12,
+        tolerance = 100*Modelica.Constants.eps,
+        redeclare final function func_x_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT);
+  end pi_pT;
+
+  redeclare function p_piT
+    "Dubinin-Lorentzian-Cumulative isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+        p_adsorpt_lb_start = 1,
+        integral_pi_lb = 1e-12,
+        tolerance_p_adsorpt = 1e-6,
+        tolerance_pi = 100*Modelica.Constants.eps,
+        redeclare final function func_pi_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.pi_pT);
+  end p_piT;
+
+  redeclare final function extends W_A
+    "Dubinin-Lorentzian-Cumulative isotherm model: Filled pore volume as function of adsorption potential"
+  algorithm
+    W := c[3] / Modelica.Constants.pi *
+      (Modelica.Math.atan((A - c[4]) / c[5]) + Modelica.Constants.pi / 2) + c[6]
+      "Filled pore volume";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(A=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.A_W(W, c, A_lb_start, A_ub_start, tolerance)));
+  end W_A;
+
+  redeclare final function extends A_W
+    "Dubinin-Lorentzian-Cumulative isotherm model: Adsorption potential as function of the filled pore volume"
+  algorithm
+    A := c[5] * Modelica.Math.tan((W - c[6]) / c[3] * Modelica.Constants.pi -
+       Modelica.Constants.pi / 2) + c[4]
+      "Adsorption potential";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(W=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.W_A(A, c, A_lb_start, A_ub_start, tolerance)));
+  end A_W;
+
+  redeclare final function extends dW_dA
+    "Dubinin-Lorentzian-Cumulative isotherm model: Partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+  algorithm
+    dW_dA := c[3] / (Modelica.Constants.pi * c[5] * ((A - c[4])^2 / c[5]^2 + 1))
+      "Partial derivative of the filled pore volume w.r.t. adsorption potential at 
+    constant pressure and temperature";
+  end dW_dA;
+
+  redeclare final function extends ddW_dA_dA
+    "Dubinin-Lorentzian-Cumulative: Second-order partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+  algorithm
+    ddW_dA_dA := -(2 * c[3] * c[5] * (A - c[4])) / (Modelica.Constants.pi *
+      ((A - c[4])^2 + c[5]^2)^2)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential at constant pressure and temperature";
+  end ddW_dA_dA;
+
+  redeclare final function extends ddW_dA_dT
+    "Dubinin-Lorentzian-Cumulative: Second-order partial derivative of filled pore volume w.r.t. adsorption potential and temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt,
+        dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real ddW_dA_dA = -(2 * c[3] * (A - c[4])) / (Modelica.Constants.pi *
+      c[5]^3 * ((A - c[4])^2 / c[5]^2 + 1)^2)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential";
+    Real ddW_dA_dc3 = 1 / (Modelica.Constants.pi * ((A - c[4])^2 / c[5]^2 + 1) *
+      c[5])
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and third coefficient of the Dubinin-Lorentzian-Cumulative 
+    isotherm model";
+    Real ddW_dA_dc4 = (2 * c[3] * (A - c[4])) / (Modelica.Constants.pi * c[5]^3 *
+      ((A - c[4])^2 / c[5]^2 + 1)^2)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and fourth coefficient of the Dubinin-Lorentzian-Cumulative 
+    isotherm model";
+    Real ddW_dA_dc5 = -(c[3] * (c[5]^2 - c[4]^2 + 2 * A * c[4] - A^2)) /
+      (Modelica.Constants.pi * (c[5]^2 + c[4]^2 - 2 * A * c[4] + A^2)^2)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and fivth coefficient of the Dubinin-Lorentzian-Cumulative 
+    isotherm model";
+
+  algorithm
+    ddW_dA_dT := ddW_dA_dA * dA_dT_adsorpt +
+      ddW_dA_dc3 * dc_dT_adsorpt[3] +
+      ddW_dA_dc4 * dc_dT_adsorpt[4] +
+      ddW_dA_dc5 * dc_dT_adsorpt[5]
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential and temperature at constant pressure";
+  end ddW_dA_dT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Dubinin-Lorentzian-Cumulative isotherm model is a six-parameter model for 
+calculating the equilibrium uptake <i>x_adsorpt</i> as a function of the 
+equilibrium  pressure <i>p_adsorpt</i>. The Dubinin-Lorentzian-Cumulative 
+isotherm model is suitable for type IV and V isotherms according to the IUPAC 
+definition.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Dubinin-Lorentzian-Cumulative isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) * W(A(T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    W(A(T<sub>adsorpt</sub>)) = a/&pi; *(<strong>arctan</strong>((A - b) / c) + &pi;/2) + d;
+</pre>
+<pre>
+    A(T<sub>adsorpt</sub>) = R * T<sub>adsorpt</sub> * <strong>ln</strong>(p<sub>sat</sub>(T<sub>adsorpt</sub>) / p<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>W(A(T<sub>adsorpt</sub>))</i> is the so-called characteristic curve and
+<i>A(T<sub>adsorpt</sub>)</i> is the adsorption potential. Within the characteristic 
+curve, the parameters <i>a</i>, <i>b</i>, <i>c</i>, and <i>d</i> are fitting parameters.
+<br/><br/>
+Note that the density of the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> 
+is assumed to be the saturated liquid density &rho;<sub>sat,liq</sub>(T<sub>adsorpt</sub>) 
+without any further information about the system under consideration. For super-critical
+adsorptives (i.e., <i>T<sub>adsorpt</sub> &ge; T<sub>crit</sub></i>), the density of
+the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> can be estimated by
+</p>
+<pre>
+    &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) = &rho;<sub>sat,liq</sub>(T<sub>boiling,0</sub>) * <strong>exp</strong>(-0.0025 * (T<sub>adsorpt</sub> - T<sub>boiling,0</sub>));
+</pre>
+<p>
+and a pseudo-vapour pressure <i>p<sub>sat</sub>(T<sub>adsorpt</sub>)</i> can be calculated by
+</p>
+<pre>
+    p<sub>sat</sub>(T<sub>adsorpt</sub>) = p<sub>crit</sub>(T<sub>adsorpt</sub>) * (T<sub>adsorpt</sub> / T<sub>crit</sub>) ^ k;
+</pre>
+<p>
+where <i>T<sub>boiling,0</sub></i> is the normal boiling point at 1 atm and <i>k</i> is
+a fitting parameter specific to the system under consideration.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = p<sub>sat</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2] = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) in kg/m<sup>3</sup>
+  </li>
+  <li>
+  c[3] = a in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[4] = b in J/mol
+  </li>
+  <li>
+  c[5] = c in J/mol
+  </li>
+  <li>
+  c[6] = d in m<sup>3</sup>/kg
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The characteristic curve <i>W(A)</i> must decrease strictly monotonically with 
+  increasing adsorption potential <i>A</i>. Otherwise, the inverses <i>A(W)</i>
+  and <i>p(x,T</i>) may not be solveable.
+  </li>
+  <li>
+  The reduced spreading pressure <i>&pi;</i> may not be calculable. Accordingly, the 
+  inverse <i>p(&pi;,T)</i> cannot be calculated either.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used for type IV and V isotherms according to the IUPAC
+definition.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Dubinin-Lorentzian-Cumulativ isotherm model for different 
+parameter sets. In the upper sub-figure, the equilibrium pressure changes with 
+time, while the equilibrium temperature is constant. In the centered sub-figure, the 
+equilibrium temperature changes with time, while the equilibrium pressure is constant. 
+In the lower sub-figure, the characteristic curve is shown. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_cumulativ.png\" alt=\"media_functions_equilibria_pure_dubinin_lorentzian_cumulativ.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Schawe, D. (1999). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD Thesis, Stuttgart.
+  </li>
+</ul>
+</html>"));
+end DubininLorentzianCumulative;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininLorentzianCumulative/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininLorentzianCumulative/package.order
new file mode 100644
index 0000000..44a21b8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininLorentzianCumulative/package.order
@@ -0,0 +1,12 @@
+x_pT
+p_xT
+dx_dT
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
+W_A
+A_W
+dW_dA
+ddW_dA_dA
+ddW_dA_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininPearsonIV/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininPearsonIV/package.mo
new file mode 100644
index 0000000..d37d8bf
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininPearsonIV/package.mo
@@ -0,0 +1,1170 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package DubininPearsonIV "Package containing all functions regarding the Dubinin isotherm model using a 'Pearson IV' equation type"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin;
+
+  redeclare final function extends x_pT
+    "Dubinin-Pearson-IV isotherm model: Uptake as function of pressure and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Dubinin-Pearson-IV isotherm model: Pressure as function of uptake and temperature"
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dT
+    "Dubinin-Pearson-IV isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt) "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt,
+        dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    SorpLib.Units.FilledPoreVolume W=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.W_A(
+      A=A, c=c)
+      "Filled pore volume";
+
+    Real n = (A - c[6]/2 * c[8]/c[7] - c[5]) / c[6]
+      "Auxiliary variable";
+    Real dn_dA = 1 / c[6]
+      "Partial derivative of the auxiliary variable w.r.t. adsorption potential";
+    Real dn_dc5 = -1 / c[6]
+      "Derivative of auxiliary variable w.r.t. fifth coefficient of 
+    Dubinin-Pearson-IV isotherm";
+    Real dn_dc6 = (c[5] - A) / c[6]^2
+      "Derivative of auxiliary variable w.r.t. sixth coefficient of 
+    Dubinin-Pearson-IV isotherm";
+    Real dn_dc7 = c[8] / (2*c[7]^2)
+      "Derivative of auxiliary variable w.r.t. seventh coefficient of 
+    Dubinin-Pearson-IV isotherm";
+    Real dn_dc8 = -1 / (2*c[7])
+      "Derivative of auxiliary variable w.r.t. eigth coefficient of 
+    Dubinin-Pearson-IV isotherm";
+
+    Real dW_dn = -c[4] * (1 + c[8]^2 / 4 / c[7]^2) ^ c[7] *
+      (2*c[7] * n + c[8]) * (n^2 + 1) ^ (-c[7] - 1) *
+      exp(-c[8] * (Modelica.Math.atan(n) + Modelica.Math.atan(c[8] / (2 * c[7]))))
+      "Partial derivative of the equilibrium uptake w.r.t. auxiliary variable";
+
+    Real dx_adsorpt_dA = c[2] * dW_dn * dn_dA
+      "Derivative of uptake w.r.t. to adsorption potential";
+    Real dx_adsorpt_dc2 = W
+      "Derivative of uptake w.r.t. to second coefficient of Dubinin-Pearson-IV
+    isotherm";
+    Real dx_adsorpt_dc3 = c[2]
+      "Derivative of uptake w.r.t. to third coefficient of Dubinin-Pearson-IV
+    isotherm";
+    Real dx_adsorpt_dc4 = c[2] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      exp(-c[8] * (Modelica.Math.atan(n) + Modelica.Math.atan(c[8] / (2 * c[7])))) /
+      (n^2 + 1)^c[7]
+      "Derivative of uptake w.r.t. to fourth coefficient of Dubinin-Pearson-IV
+    isotherm";
+    Real dx_adsorpt_dc5 = c[2] * dW_dn*dn_dc5
+      "Derivative of uptake w.r.t. to fivth coefficient of Dubinin-Pearson-IV
+    isotherm";
+    Real dx_adsorpt_dc6 = c[2] * dW_dn*dn_dc6
+      "Derivative of uptake w.r.t. to sixth coefficient of Dubinin-Pearson-IV
+    isotherm";
+    Real dx_adsorpt_dc7 = c[2] * ((c[4] * (log(c[8]^2 / (4 * c[7]^2) + 1) -
+      log(n^2 + 1)) * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      exp(-c[8] * (Modelica.Math.atan(c[8] / (2 * c[7])) +
+      Modelica.Math.atan(n)))) / (n^2 + 1)^c[7] +
+      dW_dn*dn_dc7)
+      "Derivative of uptake w.r.t. to seventh coefficient of Dubinin-Pearson-IV
+    isotherm";
+    Real dx_adsorpt_dc8 = c[2] * (-(c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      exp(-c[8] * (Modelica.Math.atan(c[8] / (2 * c[7])) + Modelica.Math.atan(n))) *
+      (Modelica.Math.atan(c[8] / (2 * c[7])) + Modelica.Math.atan(n))) /
+      (n^2 + 1)^c[7] +
+      dW_dn*dn_dc8)
+      "Derivative of uptake w.r.t. to eigth coefficient of Dubinin-Pearson-IV
+    isotherm";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      dx_adsorpt_dA*dA_dT_adsorpt +
+      dx_adsorpt_dc2*dc_dT_adsorpt[2] +
+      dx_adsorpt_dc3*dc_dT_adsorpt[3] +
+      dx_adsorpt_dc4*dc_dT_adsorpt[4] +
+      dx_adsorpt_dc5*dc_dT_adsorpt[5] +
+      dx_adsorpt_dc6*dc_dT_adsorpt[6] +
+      dx_adsorpt_dc7*dc_dT_adsorpt[7] +
+      dx_adsorpt_dc8*dc_dT_adsorpt[8]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dT_dT
+    "Dubinin-Pearson-IV isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dT_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT_adsorpt[1],
+      ddp_sat_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt[1])
+      "Second-order partial derivative of adsorption potential w.r.t. equilibrium 
+      temperature at constant pressure";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.ddW_dA_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      A=A,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of characteristic curve w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+    Real dx_adsorpt_dA = c[2] * dW_dA
+      "Derivative of uptake w.r.t. to adsorption potential";
+    Real dx_adsorpt_dc2 = (c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) / ((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)^c[7] + c[3]
+      "Derivative of uptake w.r.t. to second coefficient of Dubinin-Pearson-IV 
+    isotherm";
+    Real dx_adsorpt_dc3 = c[2]
+      "Derivative of uptake w.r.t. to third coefficient of Dubinin-Pearson-IV 
+    isotherm";
+    Real dx_adsorpt_dc4 = (c[2] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) / ((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)^c[7]
+      "Derivative of uptake w.r.t. to fourth coefficient of Dubinin-Pearson-IV 
+    isotherm";
+    Real dx_adsorpt_dc5 = -(8 * c[2] * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * (c[5] - A) * exp(-c[8] * (Modelica.Math.atan((-c[5] - (c[6] *
+      c[8]) / (2 * c[7]) + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      (((-c[5] - (c[6] * c[8]) / (2 * c[7]) + A)^2 / c[6]^2 + 1)^c[7] * (4 *
+      c[7]^2 * c[5]^2 + (4 * c[6] * c[7] * c[8] - 8 * A * c[7]^2) * c[5] +
+      c[6]^2 * c[8]^2 - 4 * A * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * A^2) *
+      c[7]^2))
+      "Derivative of uptake w.r.t. to fivth coefficient of Dubinin-Pearson-IV 
+    isotherm";
+    Real dx_adsorpt_dc6 = (8 * c[2] * c[4] * (c[5] - A)^2 * c[7]^3 * (c[8]^2 /
+      (4 * c[7]^2) + 1)^c[7] * exp(-c[8] * (Modelica.Math.atan((-(c[8] * c[6]) /
+      (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      (c[6] * ((c[8]^2 + 4 * c[7]^2) * c[6]^2 + (4 * c[5] - 4 * A) * c[7] *
+      c[8] * c[6] + (4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[8] *
+      c[6]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Derivative of uptake w.r.t. to sixth coefficient of Dubinin-Pearson-IV 
+    isotherm";
+    Real dx_adsorpt_dc7 = (c[2] * c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      (((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * log(c[8]^2 / (4 *
+      c[7]^2) + 1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) *
+      log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * c[7]^2 +
+      ((4 * c[5] - 4 * A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 *
+      A - 4 * c[5]) * c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1) + (4 * c[5] - 4 * A) * c[6] * c[8]) * c[7] + c[6]^2 *
+      c[8]^2 * log(c[8]^2 / (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) / (((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)^c[7] * ((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] +
+      4 * A^2) * c[7]^2 + (4 * c[5] - 4 * A) * c[6] * c[8] * c[7] + c[6]^2 *
+      c[8]^2))
+      "Derivative of uptake w.r.t. to seventh coefficient of Dubinin-Pearson-IV 
+    isotherm";
+    Real dx_adsorpt_dc8 = -(c[2] * c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) /
+      c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) * ((c[6]^2 * c[8]^2 + (4 *
+      c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A *
+      c[5] + 4 * A^2) * c[7]^2) * Modelica.Math.atan((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A) / c[6]) + (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] *
+      c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      Modelica.Math.atan(c[8] / (2 * c[7])) + (4 * c[5] - 4 * A) * c[6] *
+      c[7]^2)) / ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Derivative of uptake w.r.t. to eigth coefficient of Dubinin-Pearson-IV 
+    isotherm";
+
+    Real ddx_adsorpt_dc5_dc5 = (8 * c[2] * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * ((8 * c[7]^3 + 4 * c[7]^2) * c[5]^2 + (-16 * A * c[7]^3 - 8 * A *
+      c[7]^2) * c[5] - c[6]^2 * c[8]^2 + 8 * A^2 * c[7]^3 + (4 * A^2 - 4 * c[6]^2) *
+      c[7]^2) * exp(-c[8] * (Modelica.Math.atan((-c[5] - (c[6] * c[8]) / (2 * c[7]) +
+      A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) / (((-c[5] - (c[6] *
+      c[8]) / (2 * c[7]) + A)^2 / c[6]^2 + 1)^c[7] * (4 * c[7]^2 * c[5]^2 + (4 *
+      c[6] * c[7] * c[8] - 8 * A * c[7]^2) * c[5] + c[6]^2 * c[8]^2 - 4 * A * c[6] *
+      c[7] * c[8] + (4 * c[6]^2 + 4 * A^2) * c[7]^2)^2)
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc6_dc6 = -(8 * c[2] * c[4] * (c[5] - A)^2 * c[7]^3 *
+      (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * ((3 * c[8]^2 + 12 * c[7]^2) * c[6]^2 +
+      (8 * c[5] - 8 * A) * c[7] * c[8] * c[6] + (-8 * c[5]^2 + 16 * A * c[5] - 8 *
+      A^2) * c[7]^3 + (4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * exp(-c[8] *
+      (Modelica.Math.atan((-(c[8] * c[6]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) / (c[6]^2 * ((c[8]^2 + 4 * c[7]^2) *
+      c[6]^2 + (4 * c[5] - 4 * A) * c[7] * c[8] * c[6] + (4 * c[5]^2 - 8 * A *
+      c[5] + 4 * A^2) * c[7]^2)^2 * ((-(c[8] * c[6]) / (2 * c[7]) - c[5] + A)^2 /
+      c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to sixth coefficient of 
+    Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc7_dc7 = ((c[2] * c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      ((((-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) * c[8] * (-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)) / (c[6] * ((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1) * c[7]^2) - ((4 * c[6]^2 + 4 * c[5]^2 - 8 * A *
+      c[5] + 4 * A^2) * c[8]^2) / (2 * (c[8]^2 / (4 * c[7]^2) + 1) * c[7]^3)) *
+      c[7]^2 + (((4 * A - 4 * c[5]) * c[8]^2 * (-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)) / (((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) *
+      c[7]^2) - ((4 * c[5] - 4 * A) * c[6] * c[8]^3) / (2 * (c[8]^2 / (4 * c[7]^2) +
+      1) * c[7]^3)) * c[7] + 2 * ((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * log(c[8]^2 / (4 * c[7]^2) + 1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A *
+      c[5] - 4 * A^2) * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 +
+      1)) * c[7] - (c[6] * c[8]^3 * (-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)) /
+      (((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) * c[7]^2) -
+      (c[6]^2 * c[8]^4) / (2 * (c[8]^2 / (4 * c[7]^2) + 1) * c[7]^3) + (4 * c[5] -
+      4 * A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 * A - 4 * c[5]) *
+      c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) +
+      (4 * c[5] - 4 * A) * c[6] * c[8]) * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7])))) + c[2] * c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * (log(c[8]^2 /
+      (4 * c[7]^2) + 1) - c[8]^2 / (2 * (c[8]^2 / (4 * c[7]^2) + 1) * c[7]^2)) *
+      (((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * log(c[8]^2 / (4 *
+      c[7]^2) + 1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) *
+      log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * c[7]^2 +
+      ((4 * c[5] - 4 * A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 *
+      A - 4 * c[5]) * c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1) + (4 * c[5] - 4 * A) * c[6] * c[8]) * c[7] + c[6]^2 *
+      c[8]^2 * log(c[8]^2 / (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7])))) - c[2] * c[4] * c[8] * (c[8]^2 /
+      (4 * c[7]^2) + 1)^c[7] * (c[8] / (2 * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1) * c[7]^2) - c[8] / (2 * (c[8]^2 / (4 * c[7]^2) + 1) *
+      c[7]^2)) * (((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * log(c[8]^2 /
+      (4 * c[7]^2) + 1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) *
+      log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * c[7]^2 +
+      ((4 * c[5] - 4 * A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 *
+      A - 4 * c[5]) * c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 /
+      c[6]^2 + 1) + (4 * c[5] - 4 * A) * c[6] * c[8]) * c[7] + c[6]^2 * c[8]^2 *
+      log(c[8]^2 / (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7]))))) * (((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7] *
+      ((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (4 * c[5] - 4 *
+      A) * c[6] * c[8] * c[7] + c[6]^2 * c[8]^2)) - (c[2] * c[4] * (c[8]^2 / (4 *
+      c[7]^2) + 1)^c[7] * (((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) *
+      log(c[8]^2 / (4 * c[7]^2) + 1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] -
+      4 * A^2) * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) *
+      c[7]^2 + ((4 * c[5] - 4 * A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) + 1) +
+      (4 * A - 4 * c[5]) * c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1) + (4 * c[5] - 4 * A) * c[6] * c[8]) * c[7] + c[6]^2 *
+      c[8]^2 * log(c[8]^2 / (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) * (((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)^c[7] * ((c[8] * (-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)) / (c[6] * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 +
+      1) * c[7]) + log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) *
+      ((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (4 * c[5] -
+      4 * A) * c[6] * c[8] * c[7] + c[6]^2 * c[8]^2) + ((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7] * (2 * (4 * c[6]^2 + 4 * c[5]^2 - 8 *
+      A * c[5] + 4 * A^2) * c[7] + (4 * c[5] - 4 * A) * c[6] * c[8]))) / (((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7] * ((4 * c[6]^2 + 4 * c[5]^2 -
+      8 * A * c[5] + 4 * A^2) * c[7]^2 + (4 * c[5] - 4 * A) * c[6] * c[8] * c[7] +
+      c[6]^2 * c[8]^2))^2
+      "Second-order partial derivative of uptake w.r.t. to seventh coefficient of 
+    Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc8_dc8 = -(c[2] * c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) /
+      c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) * (-Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) - Modelica.Math.atan(c[8] / (2 * c[7])) -
+      c[8] * (1 / (2 * c[7] * (c[8]^2 / (4 * c[7]^2) + 1)) - 1 / (2 * c[7] * ((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)))) * ((c[6]^2 * c[8]^2 + (4 *
+      c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A *
+      c[5] + 4 * A^2) * c[7]^2) * Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A) / c[6]) + (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] *
+      c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      Modelica.Math.atan(c[8] / (2 * c[7])) + (4 * c[5] - 4 * A) * c[6] * c[7]^2)) /
+      ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)^c[7]) + (c[2] * c[4] * (2 * c[6]^2 * c[8] + (4 *
+      c[5] - 4 * A) * c[6] * c[7]) * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7])))) * ((c[6]^2 * c[8]^2 + (4 * c[5] -
+      4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * c[7]^2) * Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A) / c[6]) + (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      Modelica.Math.atan(c[8] / (2 * c[7])) + (4 * c[5] - 4 * A) * c[6] * c[7]^2)) /
+      ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2)^2 * ((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7]) - (c[2] * c[4] * c[8] * (c[8]^2 /
+      (4 * c[7]^2) + 1)^(c[7] - 1) * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7])))) * ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * Modelica.Math.atan(c[8] /
+      (2 * c[7])) + (4 * c[5] - 4 * A) * c[6] * c[7]^2)) / (2 * c[7] * (c[6]^2 *
+      c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 -
+      8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1)^c[7]) - (c[2] * c[4] * (-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A) * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1)^(-c[7] - 1) * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7])))) * ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 *
+      c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + (c[6]^2 *
+      c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 -
+      8 * A * c[5] + 4 * A^2) * c[7]^2) * Modelica.Math.atan(c[8] / (2 * c[7])) +
+      (4 * c[5] - 4 * A) * c[6] * c[7]^2)) / (c[6] * (c[6]^2 * c[8]^2 + (4 * c[5] -
+      4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * c[7]^2)) - (c[2] * c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7])))) * ((2 * c[6]^2 * c[8] + (4 * c[5] -
+      4 * A) * c[6] * c[7]) * Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A) / c[6]) + (2 * c[6]^2 * c[8] + (4 * c[5] - 4 * A) * c[6] * c[7]) *
+      Modelica.Math.atan(c[8] / (2 * c[7])) - (c[6]^2 * c[8]^2 + (4 * c[5] - 4 *
+      A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) *
+      c[7]^2) / (2 * c[7] * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 +
+      1)) + (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 *
+      c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) / (2 * c[7] *
+      (c[8]^2 / (4 * c[7]^2) + 1)))) / ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) *
+      c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) *
+      c[7]^2) * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to eigth coefficient of 
+    Dubinin-Pearson-IV isotherm";
+
+    Real ddx_adsorpt_dc2_dA= -(8 * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * (A - c[5]) * exp(-c[8] * (Modelica.Math.atan((A - (c[6] * c[8]) /
+      (2 * c[7]) - c[5]) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) / ((4 *
+      c[7]^2 * A^2 + (-4 * c[6] * c[7] * c[8] - 8 * c[5] * c[7]^2) * A + c[6]^2 *
+      c[8]^2 + 4 * c[5] * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2) * c[7]^2) *
+      ((A - (c[6] * c[8]) / (2 * c[7]) - c[5])^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Dubinin-Pearson-IV isotherm and adsorption potential";
+    Real ddx_adsorpt_dc2_dc3 = 1
+      "Second-order partial derivative of uptake w.r.t. to second and third 
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc2_dc4 = ((c[8]^2 / (4 * c[7]^2) + 1)^c[7] * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) / ((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)^c[7]
+      "Second-order partial derivative of uptake w.r.t. to second and fourht 
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc2_dc5 = -(8 * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * (c[5] - A) * exp(-c[8] * (Modelica.Math.atan((-c[5] - (c[6] *
+      c[8]) / (2 * c[7]) + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      (((-c[5] - (c[6] * c[8]) / (2 * c[7]) + A)^2 / c[6]^2 + 1)^c[7] * (4 * c[7]^2 *
+      c[5]^2 + (4 * c[6] * c[7] * c[8] - 8 * A * c[7]^2) * c[5] + c[6]^2 * c[8]^2 -
+      4 * A * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * A^2) * c[7]^2))
+      "Second-order partial derivative of uptake w.r.t. to second and fivth 
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc2_dc6 = (8 * c[4] * (c[5] - A)^2 * c[7]^3 * (c[8]^2 / (4 *
+      c[7]^2) + 1)^c[7] * exp(-c[8] * (Modelica.Math.atan((-(c[8] * c[6]) / (2 *
+      c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      (c[6] * ((c[8]^2 + 4 * c[7]^2) * c[6]^2 + (4 * c[5] - 4 * A) * c[7] * c[8] *
+      c[6] + (4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[8] * c[6]) /
+      (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to second and sixth 
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc2_dc7 = (c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * (((4 *
+      c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * log(c[8]^2 / (4 * c[7]^2) +
+      1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * c[7]^2 + ((4 * c[5] - 4 *
+      A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 * A - 4 * c[5]) *
+      c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) +
+      (4 * c[5] - 4 * A) * c[6] * c[8]) * c[7] + c[6]^2 * c[8]^2 * log(c[8]^2 /
+      (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)) * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7]))))) / (((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7] *
+      ((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (4 * c[5] -
+      4 * A) * c[6] * c[8] * c[7] + c[6]^2 * c[8]^2))
+      "Second-order partial derivative of uptake w.r.t. to second and seventh 
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc2_dc8 = -(c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) /
+      c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) * ((c[6]^2 * c[8]^2 + (4 *
+      c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A *
+      c[5] + 4 * A^2) * c[7]^2) * Modelica.Math.atan((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A) / c[6]) + (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] *
+      c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      Modelica.Math.atan(c[8] / (2 * c[7])) + (4 * c[5] - 4 * A) * c[6] * c[7]^2)) /
+      ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to second and eigth 
+    coefficient of Dubinin-Pearson-IV isotherm";
+
+    Real ddx_adsorpt_dc4_dA = -(8 * c[2] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * (A - c[5]) * exp(-c[8] * (Modelica.Math.atan((A - (c[6] * c[8]) /
+      (2 * c[7]) - c[5]) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      ((4 * c[7]^2 * A^2 + (-4 * c[6] * c[7] * c[8] - 8 * c[5] * c[7]^2) * A +
+      c[6]^2 * c[8]^2 + 4 * c[5] * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 *
+      c[5]^2) * c[7]^2) * ((A - (c[6] * c[8]) / (2 * c[7]) - c[5])^2 / c[6]^2 +
+      1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to fourth  coefficient of 
+    Dubinin-Pearson-IV isotherm and adsorption potential";
+    Real ddx_adsorpt_dc4_dc5 = -(8 * c[2] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * (c[5] - A) * exp(-c[8] * (Modelica.Math.atan((-c[5] - (c[6] *
+      c[8]) / (2 * c[7]) + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      (((-c[5] - (c[6] * c[8]) / (2 * c[7]) + A)^2 / c[6]^2 + 1)^c[7] * (4 *
+      c[7]^2 * c[5]^2 + (4 * c[6] * c[7] * c[8] - 8 * A * c[7]^2) * c[5] +
+      c[6]^2 * c[8]^2 - 4 * A * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * A^2) *
+      c[7]^2))
+      "Second-order partial derivative of uptake w.r.t. to fourth and fivth
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc4_dc6 = (8 * c[2] * (c[5] - A)^2 * c[7]^3 * (c[8]^2 / (4 *
+      c[7]^2) + 1)^c[7] * exp(-c[8] * (Modelica.Math.atan((-(c[8] * c[6]) / (2 *
+      c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      (c[6] * ((c[8]^2 + 4 * c[7]^2) * c[6]^2 + (4 * c[5] - 4 * A) * c[7] * c[8] *
+      c[6] + (4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[8] * c[6]) /
+      (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to fourth and sixth
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc4_dc7 = (c[2] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * (((4 *
+      c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * log(c[8]^2 / (4 * c[7]^2) +
+      1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)) * c[7]^2 + ((4 * c[5] - 4 *
+      A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 * A - 4 * c[5]) *
+      c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) +
+      (4 * c[5] - 4 * A) * c[6] * c[8]) * c[7] + c[6]^2 * c[8]^2 * log(c[8]^2 /
+      (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)) * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7]))))) / (((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7] *
+      ((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (4 * c[5] -
+      4 * A) * c[6] * c[8] * c[7] + c[6]^2 * c[8]^2))
+      "Second-order partial derivative of uptake w.r.t. to fourth and seventh
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc4_dc8 = -(c[2] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7])))) * ((c[6]^2 * c[8]^2 + (4 * c[5] -
+      4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * c[7]^2) * Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A) / c[6]) + (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      Modelica.Math.atan(c[8] / (2 * c[7])) + (4 * c[5] - 4 * A) * c[6] *
+      c[7]^2)) / ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to fourth and eigth
+    coefficient of Dubinin-Pearson-IV isotherm";
+
+    Real ddx_adsorpt_dc5_dA = -(8 * c[2] * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * ((8 * c[7]^3 + 4 * c[7]^2) * A^2 + (-16 * c[5] * c[7]^3 - 8 *
+      c[5] * c[7]^2) * A - c[6]^2 * c[8]^2 + 8 * c[5]^2 * c[7]^3 + (4 * c[5]^2 -
+      4 * c[6]^2) * c[7]^2) * exp(-c[8] * (Modelica.Math.atan((A - (c[6] * c[8]) /
+      (2 * c[7]) - c[5]) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      ((4 * c[7]^2 * A^2 + (-4 * c[6] * c[7] * c[8] - 8 * c[5] * c[7]^2) * A +
+      c[6]^2 * c[8]^2 + 4 * c[5] * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2) *
+      c[7]^2)^2 * ((A - (c[6] * c[8]) / (2 * c[7]) - c[5])^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Pearson-IV isotherm and adsorption potential";
+    Real ddx_adsorpt_dc5_dc6 = (16 * c[2] * c[4] * (c[5] - A) * c[7]^3 * (c[8]^2 /
+      (4 * c[7]^2) + 1)^c[7] * ((c[8]^2 + 4 * c[7]^2) * c[6]^2 + (2 * c[5] - 2 *
+      A) * c[7] * c[8] * c[6] + (-4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) * c[7]^3) *
+      exp(-c[8] * (Modelica.Math.atan((-(c[8] * c[6]) / (2 * c[7]) - c[5] + A) /
+      c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) / (c[6] * ((c[8]^2 + 4 *
+      c[7]^2) * c[6]^2 + (4 * c[5] - 4 * A) * c[7] * c[8] * c[6] + (4 * c[5]^2 -
+      8 * A * c[5] + 4 * A^2) * c[7]^2)^2 * ((-(c[8] * c[6]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to fivth and sixth
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc5_dc7 = -(8 * c[2] * c[4] * (c[5] - A) * (c[8]^2 / (4 *
+      c[7]^2) + 1)^c[7] * c[7]^2 * (((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * log(c[8]^2 / (4 * c[7]^2) + 1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A *
+      c[5] - 4 * A^2) * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 +
+      1)) * c[7]^3 + ((4 * c[5] - 4 * A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) +
+      1) + (4 * A - 4 * c[5]) * c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1) + (4 * c[5] - 4 * A) * c[6] * c[8] + 4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (c[6]^2 * c[8]^2 * log(c[8]^2 /
+      (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1) + (8 * c[5] - 8 * A) * c[6] * c[8]) * c[7] + 3 *
+      c[6]^2 * c[8]^2) * exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      (((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7] * ((4 *
+      c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (4 * c[5] - 4 * A) *
+      c[6] * c[8] * c[7] + c[6]^2 * c[8]^2)^2)
+      "Second-order partial derivative of uptake w.r.t. to fivth and seventh
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc5_dc8 = (8 * c[2] * c[4] * (c[5] - A) * c[7]^3 * (c[8]^2 /
+      (4 * c[7]^2) + 1)^c[7] * exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) /
+      (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) *
+      ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + (c[6]^2 * c[8]^2 + (4 * c[5] - 4 *
+      A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) *
+      c[7]^2) * Modelica.Math.atan(c[8] / (2 * c[7])) + 2 * c[6]^2 * c[8] + (4 *
+      c[5] - 4 * A) * c[6] * c[7]^2 + (4 * c[5] - 4 * A) * c[6] * c[7])) /
+      ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2)^2 * ((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to fivth and eigth
+    coefficient of Dubinin-Pearson-IV isotherm";
+
+    Real ddx_adsorpt_dc6_dA = -(16 * c[2] * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * (A - c[5]) * (4 * c[7]^3 * A^2 + (2 * c[6] * c[7] * c[8] - 8 *
+      c[5] * c[7]^3) * A - c[6]^2 * c[8]^2 - 2 * c[5] * c[6] * c[7] * c[8] + 4 *
+      c[5]^2 * c[7]^3 - 4 * c[6]^2 * c[7]^2) * exp(-c[8] * (Modelica.Math.atan((A -
+      (c[6] * c[8]) / (2 * c[7]) - c[5]) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7]))))) / (c[6] * (4 * c[7]^2 * A^2 + (-4 * c[6] * c[7] * c[8] - 8 * c[5] *
+      c[7]^2) * A + c[6]^2 * c[8]^2 + 4 * c[5] * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2) * c[7]^2)^2 * ((A - (c[6] * c[8]) / (2 * c[7]) - c[5])^2 /
+      c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to sixth coefficient of 
+    Dubinin-Pearson-IV isotherm and adsorption potential";
+    Real ddx_adsorpt_dc6_dc7 = (8 * c[2] * c[4] * (c[5] - A)^2 * (c[8]^2 / (4 *
+      c[7]^2) + 1)^c[7] * c[7]^2 * (((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * log(c[8]^2 / (4 * c[7]^2) + 1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A *
+      c[5] - 4 * A^2) * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 +
+      1)) * c[7]^3 + ((4 * c[5] - 4 * A) * c[6] * c[8] * log(c[8]^2 / (4 * c[7]^2) +
+      1) + (4 * A - 4 * c[5]) * c[6] * c[8] * log((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1) + (4 * c[5] - 4 * A) * c[6] * c[8] + 4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (c[6]^2 * c[8]^2 * log(c[8]^2 /
+      (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1) + (8 * c[5] - 8 * A) * c[6] * c[8]) * c[7] + 3 *
+      c[6]^2 * c[8]^2) * exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) / (c[6] *
+      ((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7] * ((4 *
+      c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (4 * c[5] - 4 * A) *
+      c[6] * c[8] * c[7] + c[6]^2 * c[8]^2)^2)
+      "Second-order partial derivative of uptake w.r.t. to sixth and seventh
+    coefficient of Dubinin-Pearson-IV isotherm";
+    Real ddx_adsorpt_dc6_dc8 = -(8 * c[2] * c[4] * (c[5] - A)^2 * c[7]^3 *
+      (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7])))) * ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * Modelica.Math.atan(c[8] /
+      (2 * c[7])) + 2 * c[6]^2 * c[8] + (4 * c[5] - 4 * A) * c[6] * c[7]^2 + (4 *
+      c[5] - 4 * A) * c[6] * c[7])) / (c[6] * (c[6]^2 * c[8]^2 + (4 * c[5] - 4 *
+      A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * c[7]^2)^2 * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 +
+      1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to sixth and eigth
+    coefficient of Dubinin-Pearson-IV isotherm";
+
+    Real ddx_adsorpt_dc7_dA = (8 * c[2] * c[4] * c[7]^2 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * (A - c[5]) * exp(-c[8] * (Modelica.Math.atan((A - (c[6] * c[8]) /
+      (2 * c[7]) - c[5]) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) * ((4 *
+      c[7]^3 * A^2 + (-4 * c[6] * c[7]^2 * c[8] - 8 * c[5] * c[7]^3) * A + c[6]^2 *
+      c[7] * c[8]^2 + 4 * c[5] * c[6] * c[7]^2 * c[8] + (4 * c[6]^2 + 4 * c[5]^2) *
+      c[7]^3) * log((A - (c[6] * c[8]) / (2 * c[7]) - c[5])^2 / c[6]^2 + 1) + (-4 *
+      c[7]^3 * log(c[8]^2 / (4 * c[7]^2) + 1) - 4 * c[7]^2) * A^2 + ((4 * c[6] *
+      c[7]^2 * c[8] + 8 * c[5] * c[7]^3) * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 *
+      c[6] * c[7]^2 + 8 * c[6] * c[7]) * c[8] + 8 * c[5] * c[7]^2) * A + (-c[6]^2 *
+      c[7] * c[8]^2 - 4 * c[5] * c[6] * c[7]^2 * c[8] + (-4 * c[6]^2 - 4 * c[5]^2) *
+      c[7]^3) * log(c[8]^2 / (4 * c[7]^2) + 1) - 3 * c[6]^2 * c[8]^2 + (-4 * c[5] *
+      c[6] * c[7]^2 - 8 * c[5] * c[6] * c[7]) * c[8] + (-4 * c[6]^2 - 4 * c[5]^2) *
+      c[7]^2)) / ((4 * c[7]^2 * A^2 + (-4 * c[6] * c[7] * c[8] - 8 * c[5] * c[7]^2) *
+      A + c[6]^2 * c[8]^2 + 4 * c[5] * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2) *
+      c[7]^2)^2 * ((A - (c[6] * c[8]) / (2 * c[7]) - c[5])^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to seventh coefficient of 
+    Dubinin-Pearson-IV isotherm and adsorption potential";
+    Real ddx_adsorpt_dc7_dc8 = (-c[2] * c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) /
+      c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) *
+      (-Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) -
+      Modelica.Math.atan(c[8] / (2 * c[7])) - c[8] * (1 / (2 * c[7] * (c[8]^2 /
+      (4 * c[7]^2) + 1)) - 1 / (2 * c[7] * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1)))) * ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] *
+      c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) *
+      log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) + (-c[6]^2 *
+      c[8]^2 + (4 * A - 4 * c[5]) * c[6] * c[7] * c[8] + (-4 * c[6]^2 - 4 *
+      c[5]^2 + 8 * A * c[5] - 4 * A^2) * c[7]^2) * log(c[8]^2 / (4 * c[7]^2) +
+      1) + (4 * A - 4 * c[5]) * c[6] * c[7] * c[8]) - c[2] * c[4] * (c[8]^2 /
+      (4 * c[7]^2) + 1)^c[7] * exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) /
+      (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) *
+      ((2 * c[6]^2 * c[8] + (4 * c[5] - 4 * A) * c[6] * c[7]) * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) + ((4 * A - 4 * c[5]) *
+      c[6] * c[7] - 2 * c[6]^2 * c[8]) * log(c[8]^2 / (4 * c[7]^2) + 1) -
+      ((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) * (c[6]^2 * c[8]^2 + (4 * c[5] -
+      4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] +
+      4 * A^2) * c[7]^2)) / (c[6] * c[7] * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1)) + (c[8] * (-c[6]^2 * c[8]^2 + (4 * A - 4 * c[5]) *
+      c[6] * c[7] * c[8] + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) *
+      c[7]^2)) / (2 * c[7]^2 * (c[8]^2 / (4 * c[7]^2) + 1)) + (4 * A - 4 * c[5]) *
+      c[6] * c[7])) / ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * ((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7]) + (c[2] * c[4] * (2 *
+      c[6]^2 * c[8] + (4 * c[5] - 4 * A) * c[6] * c[7]) * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) * ((c[6]^2 *
+      c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 -
+      8 * A * c[5] + 4 * A^2) * c[7]^2) * log((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1) + (-c[6]^2 * c[8]^2 + (4 * A - 4 * c[5]) * c[6] *
+      c[7] * c[8] + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) * c[7]^2) *
+      log(c[8]^2 / (4 * c[7]^2) + 1) + (4 * A - 4 * c[5]) * c[6] * c[7] * c[8])) /
+      ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2)^2 * ((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7]) - (c[2] * c[4] * c[8] * (c[8]^2 /
+      (4 * c[7]^2) + 1)^(c[7] - 1) * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7])))) * ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) + (-c[6]^2 * c[8]^2 + (4 *
+      A - 4 * c[5]) * c[6] * c[7] * c[8] + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A *
+      c[5] - 4 * A^2) * c[7]^2) * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 * A - 4 *
+      c[5]) * c[6] * c[7] * c[8])) / (2 * c[7] * (c[6]^2 * c[8]^2 + (4 * c[5] -
+      4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * c[7]^2) * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 +
+      1)^c[7]) - (c[2] * c[4] * (-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) *
+      (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * ((-(c[6] * c[8]) / (2 * c[7]) - c[5] +
+      A)^2 / c[6]^2 + 1)^(-c[7] - 1) * exp(-c[8] * (Modelica.Math.atan((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 *
+      c[7])))) * ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] +
+      (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2) * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) + (-c[6]^2 * c[8]^2 + (4 *
+      A - 4 * c[5]) * c[6] * c[7] * c[8] + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A *
+      c[5] - 4 * A^2) * c[7]^2) * log(c[8]^2 / (4 * c[7]^2) + 1) + (4 * A - 4 *
+      c[5]) * c[6] * c[7] * c[8])) / (c[6] * (c[6]^2 * c[8]^2 + (4 * c[5] - 4 *
+      A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 *
+      A^2) * c[7]^2))
+      "Second-order partial derivative of uptake w.r.t. to seventh and eigth
+    coefficient of Dubinin-Pearson-IV isotherm";
+
+    Real ddx_adsorpt_dc8_dA = (8 * c[2] * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * (A - c[5]) * exp(-c[8] * (Modelica.Math.atan((A - (c[6] * c[8]) /
+      (2 * c[7]) - c[5]) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) * ((4 *
+      c[7]^2 * A^2 + (-4 * c[6] * c[7] * c[8] - 8 * c[5] * c[7]^2) * A + c[6]^2 *
+      c[8]^2 + 4 * c[5] * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2) * c[7]^2) *
+      Modelica.Math.atan((A - (c[6] * c[8]) / (2 * c[7]) - c[5]) / c[6]) + 4 *
+      c[7]^2 * Modelica.Math.atan(c[8] / (2 * c[7])) * A^2 + ((-4 * c[6] * c[7] *
+      c[8] - 8 * c[5] * c[7]^2) * Modelica.Math.atan(c[8] / (2 * c[7])) - 4 *
+      c[6] * c[7]^2 - 4 * c[6] * c[7]) * A + (c[6]^2 * c[8]^2 + 4 * c[5] * c[6] *
+      c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2) * c[7]^2) * Modelica.Math.atan(c[8] /
+      (2 * c[7])) + 2 * c[6]^2 * c[8] + 4 * c[5] * c[6] * c[7]^2 + 4 * c[5] *
+      c[6] * c[7])) / ((4 * c[7]^2 * A^2 + (-4 * c[6] * c[7] * c[8] - 8 * c[5] *
+      c[7]^2) * A + c[6]^2 * c[8]^2 + 4 * c[5] * c[6] * c[7] * c[8] + (4 *
+      c[6]^2 + 4 * c[5]^2) * c[7]^2)^2 * ((A - (c[6] * c[8]) / (2 * c[7]) -
+      c[5])^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of uptake w.r.t. to eigth coefficient of 
+    Dubinin-Pearson-IV isotherm and adsorption potential";
+
+    Real ddx_adsorpt_dA_dT_dT_adsorpt = dc_dT_adsorpt[2] * dW_dA +
+      c[2] * ddW_dA_dT_adsorpt
+      "Second-order partial derivative of uptake w.r.t. to adsorption potential
+    and temperature";
+    Real ddx_adsorpt_dc2_dT_dT_adsorpt = ddx_adsorpt_dc2_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc2_dc4*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc2_dc5*dc_dT_adsorpt[5] +
+      ddx_adsorpt_dc2_dc6*dc_dT_adsorpt[6] +
+      ddx_adsorpt_dc2_dc7*dc_dT_adsorpt[7] +
+      ddx_adsorpt_dc2_dc8*dc_dT_adsorpt[8]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Dubinin-Pearson-IV isotherm and temperature";
+    Real ddx_adsorpt_dc3_dT_dT_adsorpt = ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[2]
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Dubinin-Pearson-IV isotherm and temperature";
+    Real ddx_adsorpt_dc4_dT_dT_adsorpt = ddx_adsorpt_dc4_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc4*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc4_dc5*dc_dT_adsorpt[5] +
+      ddx_adsorpt_dc4_dc6*dc_dT_adsorpt[6] +
+      ddx_adsorpt_dc4_dc7*dc_dT_adsorpt[7] +
+      ddx_adsorpt_dc4_dc8*dc_dT_adsorpt[8]
+      "Second-order partial derivative of uptake w.r.t. to fourth coefficient of 
+    Dubinin-Pearson-IV isotherm and temperature";
+    Real ddx_adsorpt_dc5_dT_dT_adsorpt = ddx_adsorpt_dc5_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc5*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc4_dc5*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc5_dc5*dc_dT_adsorpt[5] +
+      ddx_adsorpt_dc5_dc6*dc_dT_adsorpt[6] +
+      ddx_adsorpt_dc5_dc7*dc_dT_adsorpt[7] +
+      ddx_adsorpt_dc5_dc8*dc_dT_adsorpt[8]
+      "Second-order partial derivative of uptake w.r.t. to fivth coefficient of 
+    Dubinin-Pearson-IV isotherm and temperature";
+    Real ddx_adsorpt_dc6_dT_dT_adsorpt = ddx_adsorpt_dc6_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc6*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc4_dc6*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc5_dc6*dc_dT_adsorpt[5] +
+      ddx_adsorpt_dc6_dc6*dc_dT_adsorpt[6] +
+      ddx_adsorpt_dc6_dc7*dc_dT_adsorpt[7] +
+      ddx_adsorpt_dc6_dc8*dc_dT_adsorpt[8]
+      "Second-order partial derivative of uptake w.r.t. to sixth coefficient of 
+    Dubinin-Pearson-IV isotherm and temperature";
+    Real ddx_adsorpt_dc7_dT_dT_adsorpt = ddx_adsorpt_dc7_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc7*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc4_dc7*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc5_dc7*dc_dT_adsorpt[5] +
+      ddx_adsorpt_dc6_dc7*dc_dT_adsorpt[6] +
+      ddx_adsorpt_dc7_dc7*dc_dT_adsorpt[7] +
+      ddx_adsorpt_dc7_dc8*dc_dT_adsorpt[8]
+      "Second-order partial derivative of uptake w.r.t. to seventh coefficient of 
+    Dubinin-Pearson-IV isotherm and temperature";
+    Real ddx_adsorpt_dc8_dT_dT_adsorpt = ddx_adsorpt_dc8_dA*dA_dT_adsorpt +
+      ddx_adsorpt_dc2_dc8*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc4_dc8*dc_dT_adsorpt[4] +
+      ddx_adsorpt_dc5_dc8*dc_dT_adsorpt[5] +
+      ddx_adsorpt_dc6_dc8*dc_dT_adsorpt[6] +
+      ddx_adsorpt_dc7_dc8*dc_dT_adsorpt[7] +
+      ddx_adsorpt_dc8_dc8*dc_dT_adsorpt[8]
+      "Second-order partial derivative of uptake w.r.t. to eigth coefficient of 
+    Dubinin-Pearson-IV isotherm and temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      (ddx_adsorpt_dA_dT_dT_adsorpt*dA_dT_adsorpt +
+       dx_adsorpt_dA*ddA_dT_adsorpt_dT_adsorpt) +
+      (ddx_adsorpt_dc2_dT_dT_adsorpt*dc_dT_adsorpt[2] +
+       dx_adsorpt_dc2*ddc_dT_adsorpt_dT_adsorpt[2]) +
+      (ddx_adsorpt_dc3_dT_dT_adsorpt*dc_dT_adsorpt[3] +
+       dx_adsorpt_dc3*ddc_dT_adsorpt_dT_adsorpt[3]) +
+      (ddx_adsorpt_dc4_dT_dT_adsorpt*dc_dT_adsorpt[4] +
+       dx_adsorpt_dc4*ddc_dT_adsorpt_dT_adsorpt[4]) +
+      (ddx_adsorpt_dc5_dT_dT_adsorpt*dc_dT_adsorpt[5] +
+       dx_adsorpt_dc5*ddc_dT_adsorpt_dT_adsorpt[5]) +
+      (ddx_adsorpt_dc6_dT_dT_adsorpt*dc_dT_adsorpt[6] +
+       dx_adsorpt_dc6*ddc_dT_adsorpt_dT_adsorpt[6]) +
+      (ddx_adsorpt_dc7_dT_dT_adsorpt*dc_dT_adsorpt[7] +
+       dx_adsorpt_dc7*ddc_dT_adsorpt_dT_adsorpt[7]) +
+      (ddx_adsorpt_dc8_dT_dT_adsorpt*dc_dT_adsorpt[8] +
+       dx_adsorpt_dc8*ddc_dT_adsorpt_dT_adsorpt[8])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Dubinin-Pearson-IV isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+        "Adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of adsorption potential w.r.t. to pressure at constant
+      temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Second-order partial derivative of adsorption potential w.r.t. to pressure
+    and temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.dW_dA(
+        A=A, c=c)
+      "Partial derivative of filled pore volume w.r.t. adsorption potential at
+      constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.ddW_dA_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        A=A,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of characteristic curve w.r.t. adsorption 
+      potential and temperature at constant pressure";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      dc_dT_adsorpt[2] * dW_dA * dA_dp_adsorpt +
+      c[2] * ddW_dA_dT_adsorpt * dA_dp_adsorpt +
+      c[2] * dW_dA * ddA_dp_adsorpt_dT_adsorpt
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare function pi_pT
+    "Dubinin-Pearson-IV isotherm model: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT_num(
+        integral_pi_lb = 1e-2,
+        tolerance = 100*Modelica.Constants.eps,
+        redeclare final function func_x_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.x_pT);
+  end pi_pT;
+
+  redeclare function p_piT
+    "Dubinin-Pearson-IV isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+        p_adsorpt_lb_start = 1,
+        integral_pi_lb = 1e-2,
+        tolerance_p_adsorpt = 1e-6,
+        tolerance_pi = 100*Modelica.Constants.eps,
+        redeclare final function func_pi_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.pi_pT);
+  end p_piT;
+
+  redeclare final function extends W_A
+    "Dubinin-Pearson-IV isotherm model: Filled pore volume as function of adsorption potential"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real n = (A - c[6]/2 * c[8]/c[7] - c[5]) / c[6]
+      "Auxiliary variable";
+
+  algorithm
+    W := c[3] + (c[4] * (1 + n^2) ^ (-c[7]) * exp(-c[8] * (Modelica.Math.atan(n) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      (1 + c[8]^2 / 4 / c[7]^2) ^ (-c[7])
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(A=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.A_W(W, c, A_lb_start, A_ub_start, tolerance)));
+  end W_A;
+
+  redeclare function A_W
+    "Dubinin-Pearson-IV isotherm model: Adsorption potential as function of the filled pore volume (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_A_W_num(
+        redeclare final function func_W_A =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.W_A);
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(W=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV.W_A(A, c, A_lb_start, A_ub_start, tolerance)));
+  end A_W;
+
+  redeclare final function extends dW_dA
+    "Dubinin-Pearson-IV isotherm model: Partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real n = (A - c[6]/2 * c[8]/c[7] - c[5]) / c[6]
+      "Auxiliary variable";
+
+    Real dW_dn = -c[4] * (1 + c[8]^2 / 4 / c[7]^2) ^ c[7] *
+      (2*c[7] * n + c[8]) * (n^2 + 1) ^ (-c[7] - 1) *
+      exp(-c[8] * (Modelica.Math.atan(n) + Modelica.Math.atan(c[8] / (2 * c[7]))))
+      "Partial derivative of the equilibrium uptake w.r.t. auxiliary variable";
+    Real dn_dA = 1 / c[6]
+      "Partial derivative of the auxiliary variable w.r.t. adsorption potential";
+
+  algorithm
+    dW_dA := dW_dn*dn_dA
+      "Partial derivative of the filled pore volume w.r.t. adsorption potential at 
+    constant pressure and temperature";
+  end dW_dA;
+
+  redeclare final function extends ddW_dA_dA
+    "Dubinin-Pearson-IV: Second-order partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real n = (A - c[6]/2 * c[8]/c[7] - c[5]) / c[6]
+      "Auxiliary variable";
+
+    Real dW_dn = -c[4] * (1 + c[8]^2 / 4 / c[7]^2) ^ c[7] *
+      (2*c[7] * n + c[8]) * (n^2 + 1) ^ (-c[7] - 1) *
+      exp(-c[8] * (Modelica.Math.atan(n) + Modelica.Math.atan(c[8] / (2 * c[7]))))
+      "Partial derivative of the equilibrium uptake w.r.t. auxiliary variable";
+    Real dn_dA = 1 / c[6]
+      "Partial derivative of the auxiliary variable w.r.t. adsorption potential";
+
+    Real ddW_dn_dn = c[4] * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * (n^2 + 1)^(-c[7] - 2) *
+      ((4 * c[7]^2 + 2 * c[7]) * n^2 + (4 * c[7] + 2) * c[8] * n + c[8]^2 - 2 * c[7]) *
+      exp(-c[8] * (Modelica.Math.atan(n) + Modelica.Math.atan(c[8] / (2 * c[7]))))
+      "Second-order partial derivative of the equilibrium uptake w.r.t. auxiliary 
+    variable";
+
+  algorithm
+    ddW_dA_dA := (dn_dA) * (ddW_dn_dn * dn_dA)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential at constant pressure and temperature";
+  end ddW_dA_dA;
+
+  redeclare final function extends ddW_dA_dT
+    "Dubinin-Pearson-IV: Second-order partial derivative of filled pore volume w.r.t. adsorption potential and temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt=
+        SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt,
+        dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of adsorption potential w.r.t. equilibrium temperature
+      at constant pressure";
+
+    Real ddW_dA_dA = (8 * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      ((8 * c[7]^3 + 4 * c[7]^2) * A^2 + (-16 * c[5] * c[7]^3 - 8 * c[5] *
+      c[7]^2) * A - c[6]^2 * c[8]^2 + 8 * c[5]^2 * c[7]^3 + (4 * c[5]^2 - 4 *
+      c[6]^2) * c[7]^2) * exp(-c[8] * (Modelica.Math.atan((A - (c[6] * c[8]) /
+      (2 * c[7]) - c[5]) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) /
+      ((4 * c[7]^2 * A^2 + (-4 * c[6] * c[7] * c[8] - 8 * c[5] * c[7]^2) * A +
+      c[6]^2 * c[8]^2 + 4 * c[5] * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 *
+      c[5]^2) * c[7]^2)^2 * ((A - (c[6] * c[8]) / (2 * c[7]) - c[5])^2 /
+      c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential";
+    Real ddW_dA_dc4 = -(((2 * c[7] * (-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)) /
+      c[6] + c[8]) * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] * ((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A)^2 / c[6]^2 + 1)^(-c[7] - 1) * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) / c[6]
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and fourth coefficient of the Dubinin-Pearson-IV 
+    isotherm model";
+    Real ddW_dA_dc5 = -(8 * c[4] * c[7]^3 * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      ((8 * c[7]^3 + 4 * c[7]^2) * c[5]^2 + (-16 * A * c[7]^3 - 8 * A * c[7]^2) *
+      c[5] - c[6]^2 * c[8]^2 + 8 * A^2 * c[7]^3 + (4 * A^2 - 4 * c[6]^2) *
+      c[7]^2) * exp(-c[8] * (Modelica.Math.atan((-c[5] - (c[6] * c[8]) / (2 *
+      c[7]) + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) / (((-c[5] -
+      (c[6] * c[8]) / (2 * c[7]) + A)^2 / c[6]^2 + 1)^c[7] * (4 * c[7]^2 *
+      c[5]^2 + (4 * c[6] * c[7] * c[8] - 8 * A * c[7]^2) * c[5] + c[6]^2 *
+      c[8]^2 - 4 * A * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * A^2) * c[7]^2)^2)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and fivth coefficient of the Dubinin-Pearson-IV 
+    isotherm model";
+    Real ddW_dA_dc6 = -(16 * c[4] * (c[5] - A) * c[7]^3 * (c[8]^2 / (4 *
+      c[7]^2) + 1)^c[7] * ((c[8]^2 + 4 * c[7]^2) * c[6]^2 + (2 * c[5] - 2 * A) *
+      c[7] * c[8] * c[6] + (-4 * c[5]^2 + 8 * A * c[5] - 4 * A^2) * c[7]^3) *
+      exp(-c[8] * (Modelica.Math.atan((-(c[8] * c[6]) / (2 * c[7]) - c[5] + A) /
+      c[6]) + Modelica.Math.atan(c[8] / (2 * c[7]))))) / (c[6] * ((c[8]^2 + 4 *
+      c[7]^2) * c[6]^2 + (4 * c[5] - 4 * A) * c[7] * c[8] * c[6] + (4 * c[5]^2 -
+      8 * A * c[5] + 4 * A^2) * c[7]^2)^2 * ((-(c[8] * c[6]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and sixth coefficient of the Dubinin-Pearson-IV 
+    isotherm model";
+    Real ddW_dA_dc7 = (8 * c[4] * (c[5] - A) * (c[8]^2 / (4 * c[7]^2) + 1)^c[7] *
+      c[7]^2 * (((4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) *
+      log(c[8]^2 / (4 * c[7]^2) + 1) + (-4 * c[6]^2 - 4 * c[5]^2 + 8 * A *
+      c[5] - 4 * A^2) * log((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 +
+      1)) * c[7]^3 + ((4 * c[5] - 4 * A) * c[6] * c[8] * log(c[8]^2 / (4 *
+      c[7]^2) + 1) + (4 * A - 4 * c[5]) * c[6] * c[8] * log((-(c[6] * c[8]) /
+      (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) + (4 * c[5] - 4 * A) * c[6] * c[8] +
+      4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2 + (c[6]^2 *
+      c[8]^2 * log(c[8]^2 / (4 * c[7]^2) + 1) - c[6]^2 * c[8]^2 * log((-(c[6] *
+      c[8]) / (2 * c[7]) - c[5] + A)^2 / c[6]^2 + 1) + (8 * c[5] - 8 * A) *
+      c[6] * c[8]) * c[7] + 3 * c[6]^2 * c[8]^2) * exp(-c[8] *
+      (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) - c[5] + A) / c[6]) +
+      Modelica.Math.atan(c[8] / (2 * c[7]))))) / (((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A)^2 / c[6]^2 + 1)^c[7] * ((4 * c[6]^2 + 4 * c[5]^2 - 8 * A *
+      c[5] + 4 * A^2) * c[7]^2 + (4 * c[5] - 4 * A) * c[6] * c[8] * c[7] +
+      c[6]^2 * c[8]^2)^2)
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and seventh coefficient of the Dubinin-Pearson-IV 
+    isotherm model";
+    Real ddW_dA_dc8 = -(8 * c[4] * (c[5] - A) * c[7]^3 * (c[8]^2 / (4 * c[7]^2) +
+      1)^c[7] * exp(-c[8] * (Modelica.Math.atan((-(c[6] * c[8]) / (2 * c[7]) -
+      c[5] + A) / c[6]) + Modelica.Math.atan(c[8] / (2 * c[7])))) * ((c[6]^2 *
+      c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 -
+      8 * A * c[5] + 4 * A^2) * c[7]^2) * Modelica.Math.atan((-(c[6] * c[8]) /
+      (2 * c[7]) - c[5] + A) / c[6]) + (c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) *
+      c[6] * c[7] * c[8] + (4 * c[6]^2 + 4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) *
+      c[7]^2) * Modelica.Math.atan(c[8] / (2 * c[7])) + 2 * c[6]^2 * c[8] + (4 *
+      c[5] - 4 * A) * c[6] * c[7]^2 + (4 * c[5] - 4 * A) * c[6] * c[7])) /
+      ((c[6]^2 * c[8]^2 + (4 * c[5] - 4 * A) * c[6] * c[7] * c[8] + (4 * c[6]^2 +
+      4 * c[5]^2 - 8 * A * c[5] + 4 * A^2) * c[7]^2)^2 * ((-(c[6] * c[8]) / (2 *
+      c[7]) - c[5] + A)^2 / c[6]^2 + 1)^c[7])
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption
+    potential and eigth coefficient of the Dubinin-Pearson-IV 
+    isotherm model";
+
+  algorithm
+    ddW_dA_dT := ddW_dA_dA * dA_dT_adsorpt +
+      ddW_dA_dc4 * dc_dT_adsorpt[4] +
+      ddW_dA_dc5 * dc_dT_adsorpt[5] +
+      ddW_dA_dc6 * dc_dT_adsorpt[6] +
+      ddW_dA_dc7 * dc_dT_adsorpt[7] +
+      ddW_dA_dc8 * dc_dT_adsorpt[8]
+      "Second-order partial derivative of filled pore volume w.r.t. adsorption 
+    potential and temperature at constant pressure";
+  end ddW_dA_dT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Dubinin-Pearson-IV isotherm model is a eight-parameter model for calculating 
+the equilibrium uptake <i>x_adsorpt</i> as a function of the equilibrium  pressure 
+<i>p_adsorpt</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Dubinin-Pearson-IV isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) * W(A(T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    W(A(T<sub>adsorpt</sub>)) = a + (b * (1 + n<sup>2</sup>) ^(-e) * <strong>exp</strong>(-f * (<strong>arctan</strong>(n) + <strong>arctan</strong>(f / (2 * e))))) / (1 + f<sup>2</sup> / (4 * e<sup>2</sup>)) ^(-e);
+</pre>
+<pre>
+    n(A(T<sub>adsorpt</sub>)) = (A - d/2 * f/e - c) / d;
+</pre>
+<pre>
+    A(T<sub>adsorpt</sub>) = R * T<sub>adsorpt</sub> * <strong>ln</strong>(p<sub>sat</sub>(T<sub>adsorpt</sub>) / p<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>W(A(T<sub>adsorpt</sub>))</i> is the so-called characteristic curve and
+<i>A(T<sub>adsorpt</sub>)</i> is the adsorption potential. Within the characteristic 
+curve, the parameters <i>a</i>, <i>b</i>, <i>c</i>, <i>d</i>, <i>e</i>, and <i>f</i>
+are fitting parameters.
+<br/><br/>
+Note that the density of the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> 
+is assumed to be the saturated liquid density &rho;<sub>sat,liq</sub>(T<sub>adsorpt</sub>) 
+without any further information about the system under consideration. For super-critical
+adsorptives (i.e., <i>T<sub>adsorpt</sub> &ge; T<sub>crit</sub></i>), the density of
+the adsorpt <i>&rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>)</i> can be estimated by
+</p>
+<pre>
+    &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) = &rho;<sub>sat,liq</sub>(T<sub>boiling,0</sub>) * <strong>exp</strong>(-0.0025 * (T<sub>adsorpt</sub> - T<sub>boiling,0</sub>));
+</pre>
+<p>
+and a pseudo-vapour pressure <i>p<sub>sat</sub>(T<sub>adsorpt</sub>)</i> can be calculated by
+</p>
+<pre>
+    p<sub>sat</sub>(T<sub>adsorpt</sub>) = p<sub>crit</sub>(T<sub>adsorpt</sub>) * (T<sub>adsorpt</sub> / T<sub>crit</sub>) ^ k;
+</pre>
+<p>
+where <i>T<sub>boiling,0</sub></i> is the normal boiling point at 1 atm and <i>k</i> is
+a fitting parameter specific to the system under consideration.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = p<sub>sat</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2] = &rho;<sub>adsorpt</sub>(T<sub>adsorpt</sub>) in kg/m<sup>3</sup>
+  </li>
+  <li>
+  c[3] = a in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[4] = b in m<sup>3</sup>/kg
+  </li>
+  <li>
+  c[5] = c in J/mol
+  </li>
+  <li>
+  c[6] = d in J/mol
+  </li>
+  <li>
+  c[7] = e in -
+  </li>
+  <li>
+  c[8] = f in -
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The characteristic curve <i>W(A)</i> must decrease strictly monotonically with 
+  increasing adsorption potential <i>A</i>. Otherwise, the inverses <i>A(W)</i>
+  and <i>p(x,T</i>) may not be solveable.
+  </li>
+  <li>
+  The reduced spreading pressure <i>&pi;</i> may not be calculable. Accordingly, the 
+  inverse <i>p(&pi;,T)</i> cannot be calculated either.
+  </li>
+</ul>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Dubinin-Pearson-IV isotherm model for one 
+parameter set. In the upper sub-figure, the equilibrium pressure changes with 
+time, while the equilibrium temperature is constant. In the centered sub-figure, the 
+equilibrium temperature changes with time, while the equilibrium pressure is constant. 
+In the lower sub-figure, the characteristic curve is shown. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_pearson_iv.png\" alt=\"media_functions_equilibria_pure_dubinin_pearson_iv.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+  <li>
+  Schawe, D. (1999). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD Thesis, Stuttgart.
+  </li>
+</ul>
+</html>"));
+end DubininPearsonIV;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininPearsonIV/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininPearsonIV/package.order
new file mode 100644
index 0000000..44a21b8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/DubininPearsonIV/package.order
@@ -0,0 +1,12 @@
+x_pT
+p_xT
+dx_dT
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
+W_A
+A_W
+dW_dA
+ddW_dA_dA
+ddW_dA_dT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Freundlich/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Freundlich/package.mo
new file mode 100644
index 0000000..bb11cd3
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Freundlich/package.mo
@@ -0,0 +1,242 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package Freundlich "Package containing all functions regarding the Freundlich isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  redeclare final function extends x_pT
+    "Freundlich isotherm model: Uptake as function of pressure and temperature"
+  algorithm
+    x_adsorpt := c[1] * p_adsorpt^(1/c[2])
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Freundlich.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Freundlich isotherm model: Pressure as function of uptake and temperature"
+  algorithm
+    p_adsorpt := (x_adsorpt/c[1])^c[2]
+      "Calculation of the equilibrium pressure of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Freundlich.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "Freundlich isotherm model: Partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    dx_adsorpt_dp_adsorpt := c[1]/c[2] * p_adsorpt^(1/c[2] - 1)
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dT
+    "Freundlich isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = p_adsorpt ^ (1/c[2])
+      "Derivative of uptake w.r.t. to first coefficient of Freundlich isotherm";
+    Real dx_adsorpt_dc2 = -c[1] / c[2]^2 * p_adsorpt ^ (1/c[2]) * log(p_adsorpt)
+      "Derivative of uptake w.r.t. to second coefficient of Freundlich isotherm";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      dx_adsorpt_dc1*dc_dT_adsorpt[1] +
+      dx_adsorpt_dc2*dc_dT_adsorpt[2]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dp_dp
+    "Freundlich isotherm model: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt := (c[1] * (1 / c[2] - 1) *
+      p_adsorpt^(1 / c[2] - 2)) / c[2]
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+
+  redeclare final function extends ddx_dT_dT
+    "Freundlich isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = p_adsorpt ^ (1/c[2])
+      "Derivative of uptake w.r.t. to first coefficient of Freundlich isotherm";
+    Real dx_adsorpt_dc2 = -c[1] / c[2]^2 * p_adsorpt ^ (1/c[2]) * log(p_adsorpt)
+      "Derivative of uptake w.r.t. to second coefficient of Freundlich isotherm";
+
+    Real ddx_adsorpt_dc1_dc2 = -1 / c[2]^2 * p_adsorpt ^ (1/c[2]) * log(p_adsorpt)
+      "Second-order partial derivative of uptake w.r.t. to first and second 
+    coefficient of Freundlich isotherm";
+
+    Real ddx_adsorpt_dc2_dc2 = c[1] / c[2]^4 * p_adsorpt ^ (1/c[2]) *
+      log(p_adsorpt) * (2*c[2] + log(p_adsorpt))
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Freundlich isotherm";
+
+    Real ddx_adsorpt_dc1_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[2]
+      "Second-order partial derivative of uptake w.r.t. to first coefficient of 
+    Freundlich isotherm and temperature";
+    Real ddx_adsorpt_dc2_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc2*dc_dT_adsorpt[2]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Freundlich isotherm and temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      (ddx_adsorpt_dc1_dT_adsorpt*dc_dT_adsorpt[1] +
+       dx_adsorpt_dc1*ddc_dT_adsorpt_dT_adsorpt[1]) +
+      (ddx_adsorpt_dc2_dT_adsorpt*dc_dT_adsorpt[2] +
+       dx_adsorpt_dc2*ddc_dT_adsorpt_dT_adsorpt[2])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Freundlich isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real ddx_adsorpt_dp_adsorpt_dc1 = 1 / c[2] * p_adsorpt ^ (1/c[2] - 1)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    first coefficient of Freundlich isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc2 = -c[1] / c[2]^3 * p_adsorpt ^ (1/c[2] - 1) *
+      (log(p_adsorpt) + c[2])
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    second coefficient of Freundlich isotherm";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      ddx_adsorpt_dp_adsorpt_dc1*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dp_adsorpt_dc2*dc_dT_adsorpt[2]
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare final function extends pi_pT
+    "Freundlich isotherm model: Reduced spreading pressure as function of pressure and temperature"
+  algorithm
+    pi := 1/M_adsorptive * (c[1]*c[2] * p_adsorpt^(1/c[2]))
+      "Calculation of the reduced spreading pressure";
+  end pi_pT;
+
+  redeclare final function extends p_piT
+    "Freundlich isotherm model: Pressure as function of reduced spreading pressure and temperature"
+  algorithm
+    p_adsorpt := (M_adsorptive * pi / (c[1]*c[2])) ^ c[2]
+      "Calculation of the equilibrium pressure";
+  end p_piT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Freundlich isotherm model is a two-parameter model for calculating the  equilibrium
+uptake <i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>.
+The Freundlich isotherm model is suitable for type III isotherms according to the 
+IUPAC definition.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Freundlich isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = K(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub> ^ (1/n(T<sub>adsorpt</sub>));
+</pre>
+<p>
+where <i>K(T<sub>adsorpt</sub>)</i> is the Freundlich coefficient and 
+<i>n(T<sub>adsorpt</sub>)</i> is the Freundlich exponent. Typical temperature
+dependencies may have the following forms:
+</p>
+</p>
+<pre>
+    K(T<sub>adsorpt</sub>) = a<sub>0</sub> * <strong>exp</strong>(-a<sub>1</sub> * T<sub>adsorpt</sub>));
+</pre>
+<pre>
+    n(T<sub>adsorpt</sub>) = b<sub>0</sub> + b<sub>1</sub>/T<sub>adsorpt</sub>;
+</pre>
+<p>
+where <i>a<sub>0</sub></i>, <i>a<sub>1</sub></i>, <i>b<sub>0</sub></i>, and 
+<i>b<sub>1</sub></i> are fiiting parameters.
+<br/><br/>
+Note that the Freundlich exponent <i>n(T<sub>adsorpt</sub>)</i> is typically 
+greater than unity.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = K(T<sub>adsorpt</sub>) in 1/Pa^(1/n(T<sub>adsorpt</sub>))
+  </li>
+  <li>
+  c[2] = n(T<sub>adsorpt</sub>) in -
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  No proper Henry law behavior.
+  </li>
+  <li>
+  No finite limit when pressure is sufficiently high.
+  </li>
+</ul>
+<p>
+Hence, the Freundlich isotherm is generally valid narrow the range of adsorption
+data used for fitting.
+</p>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used for type III isotherms according to the IUPAC definition.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Freundlich isotherm model for different parameter sets.
+In the upper sub-figure, the equilibrium pressure changes with time, while the 
+equilibrium temperature remains constant; in the lower sub-figure, the equilibrium 
+temperature changes with time, while the equilibrium pressure remains constant. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_freundlich.png\" alt=\"media_functions_equilibria_pure_freundlich.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>"));
+end Freundlich;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Freundlich/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Freundlich/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Freundlich/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/GAB/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/GAB/package.mo
new file mode 100644
index 0000000..53016cb
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/GAB/package.mo
@@ -0,0 +1,416 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package GAB "Package containing all functions regarding the GAB isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  redeclare final function extends x_pT
+    "GAB isotherm model: Uptake as function of pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+  algorithm
+    x_adsorpt := c[2]*c[3]*c[4] * phi /
+      ((1 - c[4] * phi) * (1 + (c[3] - 1) * c[4] * phi))
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "GAB isotherm model: Pressure as function of uptake and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+  algorithm
+    p_adsorpt := (c[3]*x_adsorpt - c[3]*c[2] - 2*x_adsorpt + sqrt(c[3] *
+      (c[3]*x_adsorpt^2 - 2*c[3]*c[2]*x_adsorpt + c[3]*c[2]^2 + 4*c[2]*x_adsorpt))) /
+      (2*c[4]*x_adsorpt * (c[3] - 1)) * c[1]
+      "Calculation of the equilibrium pressure of the adsorpt phase: Solve 
+    quadratic equation and discard negative solution";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "GAB isotherm model: Partial derivative of uptake w.r.t. pressure at constant temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+    Real dphi_dp_adsorpt =  1/c[1]
+      "Partial derivative of relative pressure w.r.t. to pressure";
+
+  algorithm
+    dx_adsorpt_dp_adsorpt := c[2]*c[3]*c[4] * ((c[3] - 1) * c[4]^2 * phi^2 + 1) /
+      ((c[4] * phi - 1)^2 * (1 + (c[3] - 1) * c[4] * phi)^2) * dphi_dp_adsorpt
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dT
+    "GAB isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+    Real dphi_dc1 = -p_adsorpt/c[1]^2
+      "Partial derivative of relative pressure w.r.t. to saturation pressure";
+
+    Real dx_adsorpt_dphi =  c[2]*c[3]*c[4] * ((c[3] - 1) * c[4]^2 * phi^2 + 1) /
+      ((c[4] * phi - 1)^2 * (1 + (c[3] - 1) * c[4] * phi)^2)
+      "Partial derivative of uptake w.r.t. to relative pressure";
+
+    Real dx_adsorpt_dc1 = dx_adsorpt_dphi*dphi_dc1
+      "Derivative of uptake w.r.t. to first coefficient of GAB isotherm";
+    Real dx_adsorpt_dc2 = c[3]*c[4] * phi /
+      ((1 - c[4] * phi) * (1 + (c[3] - 1) * c[4] * phi))
+      "Derivative of uptake w.r.t. to second coefficient of GAB isotherm";
+    Real dx_adsorpt_dc3 = c[2]*c[4] * phi / (c[3]*c[4] * phi - c[4] * phi + 1)^2
+      "Derivative of uptake w.r.t. to third coefficient of GAB isotherm";
+    Real dx_adsorpt_dc4 = c[2]*c[3] * phi * ((c[3] - 1) * c[4]^2 * phi^2 + 1) /
+      ((c[4] * phi - 1)^2 * (1 + (c[3] - 1) * c[4] * phi)^2)
+      "Derivative of uptake w.r.t. to fourtg coefficient of GAB isotherm";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      dx_adsorpt_dc1*dc_dT_adsorpt[1] +
+      dx_adsorpt_dc2*dc_dT_adsorpt[2] +
+      dx_adsorpt_dc3*dc_dT_adsorpt[3] +
+      dx_adsorpt_dc4*dc_dT_adsorpt[4]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dp_dp
+    "GAB isotherm model: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+    Real dphi_dp_adsorpt =  1/c[1]
+      "Partial derivative of relative pressure w.r.t. to pressure";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt :=
+      (-(2 * c[2] * c[3] * c[4]^2 * ((c[3] - 1) * c[4] * phi *
+      ((c[3] - 1) * c[4]^2 * phi^2 + 3) - c[3] + 2)) /
+      ((c[4] * phi - 1)^3 * ((c[3] - 1) * c[4] * phi + 1)^3)) * dphi_dp_adsorpt^2
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+
+  redeclare final function extends ddx_dT_dT
+    "GAB isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = -(c[2] * c[3] * c[4] * p_adsorpt * (c[1]^2 + (c[3] - 1) *
+      c[4]^2 * p_adsorpt^2)) / ((c[1] - c[4] * p_adsorpt)^2 * (c[1] + (c[3] - 1) *
+      c[4] * p_adsorpt)^2)
+      "Derivative of uptake w.r.t. to first coefficient of GAB isotherm";
+    Real dx_adsorpt_dc2 = -(c[1] * c[3] * c[4] * p_adsorpt) / ((c[4] * p_adsorpt -
+      c[1]) * ((c[3] - 1) * c[4] * p_adsorpt + c[1]))
+      "Derivative of uptake w.r.t. to second coefficient of GAB isotherm";
+    Real dx_adsorpt_dc3 = (c[1] * c[2] * c[4] * p_adsorpt) / (c[4] * p_adsorpt *
+      c[3] - c[4] * p_adsorpt + c[1])^2
+      "Derivative of uptake w.r.t. to third coefficient of GAB isotherm";
+    Real dx_adsorpt_dc4 = (c[1] * c[2] * c[3] * p_adsorpt * ((c[3] - 1) * p_adsorpt^2 *
+      c[4]^2 + c[1]^2)) / ((p_adsorpt * c[4] - c[1])^2 * ((c[3] - 1) * p_adsorpt *
+      c[4] + c[1])^2)
+      "Derivative of uptake w.r.t. to fourtg coefficient of GAB isotherm";
+
+    Real ddx_adsorpt_dc1_dc1 = (2 * c[2] * c[3] * c[4] * p_adsorpt * (c[1]^3 + (3 *
+      c[3] - 3) * c[4]^2 * p_adsorpt^2 * c[1] + (c[3]^2 - 3 * c[3] + 2) * c[4]^3 *
+      p_adsorpt^3)) / ((c[1] - c[4] * p_adsorpt)^3 * (c[1] + (c[3] - 1) * c[4] *
+      p_adsorpt)^3)
+      "Second-order partial derivative of uptake w.r.t. to first coefficient of 
+    GAB isotherm";
+    Real ddx_adsorpt_dc3_dc3 = -(2 * c[1] * c[2] * c[4]^2 * p_adsorpt^2) / (c[4] *
+      p_adsorpt * c[3] - c[4] * p_adsorpt + c[1])^3
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    GAB isotherm";
+    Real ddx_adsorpt_dc4_dc4 = -(2 * c[1] * c[2] * c[3] * p_adsorpt^2 * ((c[3]^2 -
+      2 * c[3] + 1) * p_adsorpt^3 * c[4]^3 + (3 * c[1]^2 * c[3] - 3 * c[1]^2) *
+      p_adsorpt * c[4] - c[1]^3 * c[3] + 2 * c[1]^3)) / ((p_adsorpt * c[4] - c[1])^3 *
+      ((c[3] - 1) * p_adsorpt * c[4] + c[1])^3)
+      "Second-order partial derivative of uptake w.r.t. to fourth coefficient of 
+    GAB isotherm";
+
+    Real ddx_adsorpt_dc1_dc2= -(c[3] * c[4] * p_adsorpt * ((c[3] - 1) * c[4]^2 *
+      p_adsorpt^2 + c[1]^2)) / ((c[1] - c[4] * p_adsorpt)^2 * ((c[3] - 1) * c[4] *
+      p_adsorpt + c[1])^2)
+      "Second-order partial derivative of uptake w.r.t. to first and second 
+    coefficient of GAB isotherm";
+    Real ddx_adsorpt_dc1_dc3 = (c[2] * c[4] * p_adsorpt * (c[4] * p_adsorpt * c[3] -
+      c[4] * p_adsorpt - c[1])) / (c[4] * p_adsorpt * c[3] - c[4] * p_adsorpt +
+      c[1])^3
+      "Second-order partial derivative of uptake w.r.t. to first and third 
+    coefficient of GAB isotherm";
+    Real ddx_adsorpt_dc1_dc4 = (c[2] * c[3] * p_adsorpt * ((c[3]^2 - 2 * c[3] + 1) *
+      p_adsorpt^4 * c[4]^4 + (c[1] * c[3]^2 - 3 * c[1] * c[3] + 2 * c[1]) * p_adsorpt^3 *
+      c[4]^3 + (6 * c[1]^2 * c[3] - 6 * c[1]^2) * p_adsorpt^2 * c[4]^2 + (2 * c[1]^3 -
+      c[1]^3 * c[3]) * p_adsorpt * c[4] + c[1]^4)) / ((p_adsorpt * c[4] - c[1])^3 *
+      ((c[3] - 1) * p_adsorpt * c[4] + c[1])^3)
+      "Second-order partial derivative of uptake w.r.t. to first and fourth 
+    coefficient of GAB isotherm";
+
+    Real ddx_adsorpt_dc2_dc3 = (c[1] * c[4] * p_adsorpt) / (c[4] * p_adsorpt * c[3] -
+      c[4] * p_adsorpt + c[1])^2
+      "Second-order partial derivative of uptake w.r.t. to second and third 
+    coefficient of GAB isotherm";
+    Real ddx_adsorpt_dc2_dc4 = (c[1] * c[3] * p_adsorpt * ((c[3] - 1) * p_adsorpt^2 *
+      c[4]^2 + c[1]^2)) / ((p_adsorpt * c[4] - c[1])^2 * ((c[3] - 1) * p_adsorpt *
+      c[4] + c[1])^2)
+      "Second-order partial derivative of uptake w.r.t. to second and fourht 
+    coefficient of GAB isotherm";
+
+    Real ddx_adsorpt_dc3_dc4 = -(c[1] * c[2] * p_adsorpt * ((c[3] - 1) * p_adsorpt *
+      c[4] - c[1])) / ((c[3] - 1) * p_adsorpt * c[4] + c[1])^3
+      "Second-order partial derivative of uptake w.r.t. to third and fourht 
+    coefficient of GAB isotherm";
+
+    Real ddx_adsorpt_dc1_dT_dT_adsorpt = ddx_adsorpt_dc1_dc1*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc1_dc3*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc1_dc4*dc_dT_adsorpt[4]
+      "Second-order partial derivative of uptake w.r.t. to first coefficient of 
+    GAB isotherm and temperature";
+    Real ddx_adsorpt_dc2_dT_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc2_dc4*dc_dT_adsorpt[4]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    GAB isotherm and temperature";
+    Real ddx_adsorpt_dc3_dT_dT_adsorpt = ddx_adsorpt_dc1_dc3*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc3*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc3_dc4*dc_dT_adsorpt[4]
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    GAB isotherm and temperature";
+    Real ddx_adsorpt_dc4_dT_dT_adsorpt = ddx_adsorpt_dc1_dc4*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc4*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc4*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dc4_dc4*dc_dT_adsorpt[4]
+      "Second-order partial derivative of uptake w.r.t. to fourth coefficient of 
+    GAB isotherm and temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      (ddx_adsorpt_dc1_dT_dT_adsorpt*dc_dT_adsorpt[1] +
+       dx_adsorpt_dc1*ddc_dT_adsorpt_dT_adsorpt[1]) +
+      (ddx_adsorpt_dc2_dT_dT_adsorpt*dc_dT_adsorpt[2] +
+       dx_adsorpt_dc2*ddc_dT_adsorpt_dT_adsorpt[2]) +
+      (ddx_adsorpt_dc3_dT_dT_adsorpt*dc_dT_adsorpt[3] +
+       dx_adsorpt_dc3*ddc_dT_adsorpt_dT_adsorpt[3]) +
+      (ddx_adsorpt_dc4_dT_dT_adsorpt*dc_dT_adsorpt[4] +
+       dx_adsorpt_dc4*ddc_dT_adsorpt_dT_adsorpt[4])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "GAB isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real ddx_adsorpt_dp_adsorpt_dc1 = (c[2] * c[3] * c[4] * ((c[3]^2 - 2 * c[3] + 1) *
+      c[4]^4 * p_adsorpt^4 + (c[1] * c[3]^2 - 3 * c[1] * c[3] + 2 * c[1]) * c[4]^3 *
+      p_adsorpt^3 + (6 * c[1]^2 * c[3] - 6 * c[1]^2) * c[4]^2 * p_adsorpt^2 + (2 *
+      c[1]^3 - c[1]^3 * c[3]) * c[4] * p_adsorpt + c[1]^4)) / ((c[4] * p_adsorpt -
+      c[1])^3 * ((c[3] - 1) * c[4] * p_adsorpt + c[1])^3)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    first coefficient of GAB isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc2 = (c[1] * c[3] * c[4] * ((c[3] - 1) * c[4]^2 *
+      p_adsorpt^2 + c[1]^2)) / ((c[4] * p_adsorpt - c[1])^2 * ((c[3] - 1) * c[4] *
+      p_adsorpt + c[1])^2)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    second coefficient of GAB isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc3 = -(c[1] * c[2] * c[4] * ((c[3] - 1) * c[4] *
+      p_adsorpt - c[1])) / ((c[3] - 1) * c[4] * p_adsorpt + c[1])^3
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    third coefficient of GAB isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc4 = -(c[1] * c[2] * c[3] * ((c[3]^2 - 2 * c[3] + 1) *
+      c[4]^4 * p_adsorpt^4 + (c[1] * c[3]^2 - 3 * c[1] * c[3] + 2 * c[1]) * c[4]^3 *
+      p_adsorpt^3 + (6 * c[1]^2 * c[3] - 6 * c[1]^2) * c[4]^2 * p_adsorpt^2 + (2 *
+      c[1]^3 - c[1]^3 * c[3]) * c[4] * p_adsorpt + c[1]^4)) / ((c[4] * p_adsorpt -
+      c[1])^3 * ((c[3] - 1) * c[4] * p_adsorpt + c[1])^3)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    fourth coefficient of GAB isotherm";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      ddx_adsorpt_dp_adsorpt_dc1*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dp_adsorpt_dc2*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dp_adsorpt_dc3*dc_dT_adsorpt[3] +
+      ddx_adsorpt_dp_adsorpt_dc4*dc_dT_adsorpt[4]
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare final function extends pi_pT
+    "GAB isotherm model: Reduced spreading pressure as function of pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real phi = p_adsorpt/c[1]
+      "Relative pressure";
+
+  algorithm
+    pi := 1/M_adsorptive *
+      (c[2] * log((1 - c[4] * phi + c[3]*c[4] * phi) / (1 - c[4] * phi)))
+      "Calculation of the reduced spreading pressure";
+  end pi_pT;
+
+  redeclare final function extends p_piT
+    "GAB isotherm model: Pressure as function of reduced spreading pressure and temperature"
+  algorithm
+    p_adsorpt := c[1] * (1 - exp(pi * M_adsorptive / c[2])) /
+      (-exp(pi * M_adsorptive / c[2]) * c[4] + c[4] - c[3] * c[4])
+      "Calculation of the equilibrium pressure";
+  end p_piT;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The GAB isotherm model is a four-parameter model for calculating the  equilibrium
+uptake <i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>.
+The GAB isotherm model is suitable for type III isotherms according to the IUPAC 
+definition.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The GAB isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = x<sub>mon</sub>(T<sub>adsorpt</sub>) * c(T<sub>adsorpt</sub>) * k(T<sub>adsorpt</sub>) * &phi;(T<sub>adsorpt</sub>) / ((1 - k(T<sub>adsorpt</sub>) * &phi;(T<sub>adsorpt</sub>)) * (1 + (c(T<sub>adsorpt</sub>) - 1) * k(T<sub>adsorpt</sub>) * &phi;(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+with
+</p>
+<pre>
+    &phi;(T<sub>adsorpt</sub>) = p<sub>adsorpt</sub>/p<sub>sat</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+Herein, <i>x<sub>mon</sub>(T<sub>adsorpt</sub>)</i> is the monolayer uptake and 
+<i>c(T<sub>adsorpt</sub>)</i> and <i>k(T<sub>adsorpt</sub>)</i> are affinity
+coefficients of the GAB isotherm model. These three parameters can be modeled
+independent of temperature. When assuming these three parameters to be dependent
+on temperature, typical temperature dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>mon</sub>(T<sub>adsorpt</sub>) =  x<sub>mon,ref</sub> * <strong>exp</strong>(&Chi; * (1 - T<sub>adsorpt</sub>/T<sub>ref</sub>));
+</pre>
+<pre>
+    c(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>1</sub> - E<sub>10+</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<pre>
+    k(T<sub>adsorpt</sub>) = <strong>exp</strong>((E<sub>2-9</sub> - E<sub>10+</sub>) / (R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+with
+</p>
+<pre>
+    E<sub>1</sub> = C - <strong>exp</strong>(D * T<sub>adsorpt</sub>);
+</pre>
+<pre>
+    E<sub>2-9</sub> = F + G * T<sub>adsorpt</sub>;
+</pre>
+<pre>
+    E<sub>10+</sub> = &Delta;h<sub>vap</sub>(T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>mon,ref</sub></i> is the monolayer uptake at reference temperature 
+<i>T<sub>ref</sub></i> and  <i>&Chi;</i> describes the change of the monolayer uptake 
+with temperature. The coefficient <i>E<sub>1</sub></i> is the enthalpy of adsorption 
+of the first layer and <i>E<sub>2-9</sub></i> is the enthalpy of adsorption of layers 
+2-9: These enthalpies of adsorption can be modeled temperature-dependent as shown 
+in the example above, with the four fitting parameters <i>C</i>, <i>D</i>, <i>E</i>, 
+and <i>F</i>. The coefficient <i>E<sub>10+</sub></i> is the enthalpy of adsorptions 
+for layer 10 or higher layers and is assumed to correspond to the temperature-dependent 
+enthalpy of vaporization <i>&Delta;h<sub>vap</sub>(T<sub>adsorpt</sub>)</i>.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = p<sub>sat</sub>(T<sub>adsorpt</sub>) in Pa
+  </li>
+  <li>
+  c[2] = x<sub>mon</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[3] = c(T<sub>adsorpt</sub>) in -
+  </li>
+  <li>
+  c[4] = k(T<sub>adsorpt</sub>) in -
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used for type III isotherms according to the IUPAC definition.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the GAB isotherm model for different parameter sets.
+In the upper sub-figure, the equilibrium pressure changes with time, while the 
+equilibrium temperature remains constant; in the lower sub-figure, the equilibrium 
+temperature changes with time, while the equilibrium pressure remains constant. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_gab.png\" alt=\"media_functions_equilibria_pure_gab.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Young et al. (2021). The impact of binary water – CO<sub>2</sub> isotherm models on the optimal performance of sorbent-based direct air capture processes, Energy Environ. Sci. 14: 5377. DOI: 10.1039/d1ee01272j.
+  </li>
+</ul>
+</html>"));
+end GAB;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/GAB/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/GAB/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/GAB/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Henry/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Henry/package.mo
new file mode 100644
index 0000000..b5fa299
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Henry/package.mo
@@ -0,0 +1,172 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package Henry "Package containing all functions regarding the Henry isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  redeclare final function extends x_pT
+    "Henry isotherm model: Uptake as function of pressure and temperature"
+  algorithm
+    x_adsorpt := c[1]*p_adsorpt
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true,
+                inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Henry isotherm model: Pressure as function of uptake and temperature"
+  algorithm
+    p_adsorpt := x_adsorpt/c[1]
+      "Calculation of the equilibrium pressure of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+                InlineAfterIndexReduction=false,
+                LateInline=true,
+                inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "Henry isotherm model: Partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    dx_adsorpt_dp_adsorpt := c[1]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dT
+    "Henry isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+  algorithm
+    dx_adsorpt_dT_adsorpt := p_adsorpt*dc_dT_adsorpt[1]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dp_dp
+    "Henry isotherm model: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt := 0
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+
+  redeclare final function extends ddx_dT_dT
+    "Henry isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt := p_adsorpt*ddc_dT_adsorpt_dT_adsorpt[1]
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Henry isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt := dc_dT_adsorpt[1]
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare final function extends pi_pT
+    "Henry isotherm model: Reduced spreading pressure as function of pressure and temperature"
+  algorithm
+    pi := 1/M_adsorptive * (c[1]*p_adsorpt)
+      "Calculation of the reduced spreading pressure";
+  end pi_pT;
+
+  redeclare final function extends p_piT
+    "Henry isotherm model: Pressure as function of reduced spreading pressure and temperature"
+  algorithm
+    p_adsorpt := M_adsorptive * pi / c[1]
+      "Calculation of the equilibrium pressure";
+  end p_piT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Henry isotherm model calculates the equilibrium uptake <i>x_adsorpt</i> in 
+linear relation to the equilibrium pressure <i>p_adsorpt</i>. The proportionality 
+coefficient is the so-called Henry coefficient <i>H</i>, which may depend on the 
+equilibrium temperature <i>T_adsorpt</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Henry isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = H(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>;
+</pre>
+<p>
+where <i>H</i> is the temperature-dependent Henry coefficient. A typical temperature
+dependency may have the following form:
+</p>
+<pre>
+    H(T<sub>adsorpt</sub>) = H<sub>ref</sub> * <strong>exp</strong>(C<sub>exp</sub> * (1/T<sub>adsorpt</sub> - 1/T<sub>ref</sub>));
+</pre>
+<p>
+where <i>H<sub>ref</sub></i> is the Henry coefficient at reference temperature 
+<i>T<sub>ref</sub></i> and <i>C<sub>exp</sub></i> describes the change of the Henry
+coefficient with the temperature. All three parameters can be used as fitting
+parameters.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = H(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  All adsorption sites are energetically equivalent.
+  </li>
+  <li>
+  All adsorption sites can be occupied.
+  </li>
+  <li>
+  No interactions occur between the adsorbent molecules.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used to calculate the equilibrium uptake <i>x_adsorpt</i> 
+at very low equilibrium pressures <i>p_adsorpt</i>.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Henry isotherm model for different reference 
+values of the Henry coefficient <i>H_ref</i>. In the upper sub-figure, the 
+equilibrium pressure changes with time, while the equilibrium temperature
+remains constant; in the lower sub-figure, the equilibrium temperature 
+changes with time, while the equilibrium pressure remains constant. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_henry.png\" alt=\"media_functions_equilibria_pure_henry.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+</ul>
+</html>"));
+end Henry;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Henry/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Henry/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Henry/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Langmuir/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Langmuir/package.mo
new file mode 100644
index 0000000..422b37c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Langmuir/package.mo
@@ -0,0 +1,243 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package Langmuir "Package containing all functions regarding the Langmuir isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  redeclare final function extends x_pT
+    "Langmuir isotherm model: Uptake as function of pressure and temperature"
+  algorithm
+    x_adsorpt := c[1]*c[2]*p_adsorpt / (1 + c[2]*p_adsorpt)
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Langmuir isotherm model: Pressure as function of uptake and temperature"
+  algorithm
+    p_adsorpt := x_adsorpt / (c[2] * (c[1]-x_adsorpt))
+      "Calculation of the equilibrium pressure of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "Langmuir isotherm model: Partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    dx_adsorpt_dp_adsorpt := c[1]*c[2] / (1 + c[2]*p_adsorpt) -
+      c[1]*c[2]^2*p_adsorpt / (1 + c[2]*p_adsorpt)^2
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dT
+    "Langmuir isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = c[2]*p_adsorpt / (1 + c[2]*p_adsorpt)
+      "Derivative of uptake w.r.t. to first coefficient of Langmuir isotherm";
+    Real dx_adsorpt_dc2 = c[1]*p_adsorpt / (1 + c[2]*p_adsorpt)^2
+      "Derivative of uptake w.r.t. to second coefficient of Langmuir isotherm";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      dx_adsorpt_dc1*dc_dT_adsorpt[1] +
+      dx_adsorpt_dc2*dc_dT_adsorpt[2]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dp_dp
+    "Langmuir isotherm model: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt :=
+      -(2 * c[1] * c[2]^2) / (c[2] * p_adsorpt + 1)^3
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+
+  redeclare final function extends ddx_dT_dT
+    "Langmuir isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = c[2]*p_adsorpt / (1 + c[2]*p_adsorpt)
+      "Partial derivative of uptake w.r.t. to first coefficient of Langmuir isotherm";
+    Real dx_adsorpt_dc2 = c[1]*p_adsorpt / (1 + c[2]*p_adsorpt)^2
+      "Partial derivative of uptake w.r.t. to second coefficient of Langmuir isotherm";
+
+    Real ddx_adsorpt_dc1_dc2 = p_adsorpt / (1 + c[2]*p_adsorpt)^2
+      "Second-order partial derivative of uptake w.r.t. to first and second 
+    coefficient of Langmuir isotherm";
+
+    Real ddx_adsorpt_dc2_dc2 = -2 * c[1] * p_adsorpt^2 / (1 + c[2]*p_adsorpt)^3
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Langmuir isotherm";
+
+    Real ddx_adsorpt_dc1_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[2]
+      "Second-order partial derivative of uptake w.r.t. to first coefficient of 
+    Langmuir isotherm and temperature";
+    Real ddx_adsorpt_dc2_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc2*dc_dT_adsorpt[2]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Langmuir isotherm and temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      (ddx_adsorpt_dc1_dT_adsorpt*dc_dT_adsorpt[1] +
+       dx_adsorpt_dc1*ddc_dT_adsorpt_dT_adsorpt[1]) +
+      (ddx_adsorpt_dc2_dT_adsorpt*dc_dT_adsorpt[2] +
+       dx_adsorpt_dc2*ddc_dT_adsorpt_dT_adsorpt[2])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Langmuir isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real ddx_adsorpt_dp_adsorpt_dc1 = c[2] / (1 + c[2]*p_adsorpt)^2
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    first coefficient of Langmuir isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc2 = -c[1] * (c[2]*p_adsorpt - 1) /
+      (1 + c[2]*p_adsorpt)^3
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    second coefficient of Langmuir isotherm";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      ddx_adsorpt_dp_adsorpt_dc1*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dp_adsorpt_dc2*dc_dT_adsorpt[2]
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare final function extends pi_pT
+    "Langmuir isotherm model: Pressure as function of reduced spreading pressure and temperature"
+  algorithm
+    pi := 1/M_adsorptive * (c[1]*log(1 + c[2]*p_adsorpt))
+      "Calculation of the reduced spreading pressure";
+  end pi_pT;
+
+  redeclare final function extends p_piT
+    "Langmuir isotherm model: Pressure as function of reduced spreading pressure and temperature"
+  algorithm
+    p_adsorpt := (exp(M_adsorptive * pi / c[1]) - 1) / c[2]
+      "Calculation of the equilibrium pressure";
+  end p_piT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Langmuir isotherm model is a two-parameter model for calculating the  equilibrium
+uptake <i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>.
+The Langmuir isotherm model is suitable for type I isotherms according to the 
+IUPAC definition.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Langmuir isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = x<sub>sat</sub>(T<sub>adsorpt</sub>) * (b(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>) / (1 + b(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>sat</sub>(T<sub>adsorpt</sub>)</i> is the saturation uptake and 
+<i>b(T<sub>adsorpt</sub>)</i> is the Langmuir coefficient. Typical temperature
+dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>sat</sub>(T<sub>adsorpt</sub>) = a<sub>0</sub> + a<sub>1</sub>/T<sub>adsorpt</sub>;
+</pre>
+<pre>
+    b(T<sub>adsorpt</sub>) = b<sub>0</sub> * <strong>exp</strong>(-&Delta;H<sub>ads</sub>/(R * T<sub>adsorpt</sub>));
+</pre>
+<p>
+where <i>a<sub>0</sub></i>, <i>a<sub>1</sub></i>, <i>b<sub>0</sub></i>, and 
+<i>&Delta;H<sub>ads</sub></i> are fitting parameters. The parameter
+<i>&Delta;H<sub>ads</sub></i> is the isosteric adsorption heat, which is
+invariant with the surface uptake. Note that the Langmuir isotherm model only 
+consists of thermodynamic consistency if the saturation uptake <i>x<sub>sat</sub></i> 
+is constant.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = x<sub>sat</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2] = b(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  All adsorption sites are energetically equivalent.
+  </li>
+  <li>
+  All adsorption sites can be occupied.
+  </li>
+  <li>
+  No interactions occur between the adsorbent molecules.
+  </li>
+  <li>
+  The adsorbent surface is covered monomolecularly.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used for type I isotherms according to the IUPAC definition.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Langmuir isotherm model for different parameter sets.
+In the upper sub-figure, the equilibrium pressure changes with time, while the 
+equilibrium temperature remains constant; in the lower sub-figure, the equilibrium 
+temperature changes with time, while the equilibrium pressure remains constant. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_langmuir.png\" alt=\"media_functions_equilibria_pure_langmuir.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>"));
+end Langmuir;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Langmuir/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Langmuir/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Langmuir/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Sips/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Sips/package.mo
new file mode 100644
index 0000000..937644f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Sips/package.mo
@@ -0,0 +1,296 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package Sips "Package containing all functions regarding the Sips isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  redeclare final function extends x_pT
+    "Sips isotherm model: Uptake as function of pressure and temperature"
+  algorithm
+    x_adsorpt := c[1] * (c[2]*p_adsorpt)^(1/c[3]) / (1 + (c[2]*p_adsorpt)^(1/c[3]))
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Sips.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Sips isotherm model: Pressure as function of uptake and temperature"
+  algorithm
+    p_adsorpt := 1/c[2] * (x_adsorpt / (c[1] - x_adsorpt)) ^ c[3]
+      "Calculation of the equilibrium pressure of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Sips.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "Sips isotherm model: Partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    dx_adsorpt_dp_adsorpt := c[1] * (c[2]*p_adsorpt)^(1/c[3]) /
+      (c[3] * p_adsorpt * (1 + (c[2]*p_adsorpt)^(1/c[3]))^2)
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dT
+    "Sips isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = (c[2]*p_adsorpt)^(1/c[3]) /
+      (1 + (c[2]*p_adsorpt)^(1/c[3]))
+      "Derivative of uptake w.r.t. to first coefficient of Sips isotherm";
+    Real dx_adsorpt_dc2 = c[1] * (c[2]*p_adsorpt)^(1/c[3]) /
+      (c[2] * c[3] * (1 + (c[2]*p_adsorpt)^(1/c[3]))^2)
+      "Derivative of uptake w.r.t. to second coefficient of Sips isotherm";
+    Real dx_adsorpt_dc3 = -c[1] * (c[2]*p_adsorpt)^(1/c[3]) * log(c[2]*p_adsorpt)/
+      (c[3]^2 * (1 + (c[2]*p_adsorpt)^(1/c[3]))^2)
+      "Derivative of uptake w.r.t. to third coefficient of Sips isotherm";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      dx_adsorpt_dc1*dc_dT_adsorpt[1] +
+      dx_adsorpt_dc2*dc_dT_adsorpt[2] +
+      dx_adsorpt_dc3*dc_dT_adsorpt[3]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dp_dp
+    "Sips isotherm model: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt := -(c[1] * (c[2] * p_adsorpt)^(1 / c[3]) *
+      ((c[3] + 1) * (c[2] * p_adsorpt)^(1 / c[3]) + c[3] - 1)) /
+      (c[3]^2 * p_adsorpt^2 * ((c[2] * p_adsorpt)^(1 / c[3]) + 1)^3)
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+
+  redeclare final function extends ddx_dT_dT
+    "Sips isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = (c[2]*p_adsorpt)^(1/c[3]) /
+      (1 + (c[2]*p_adsorpt)^(1/c[3]))
+      "Derivative of uptake w.r.t. to first coefficient of Sips isotherm";
+    Real dx_adsorpt_dc2 = c[1] * (c[2]*p_adsorpt)^(1/c[3]) /
+      (c[2] * c[3] * (1 + (c[2]*p_adsorpt)^(1/c[3]))^2)
+      "Derivative of uptake w.r.t. to second coefficient of Sips isotherm";
+    Real dx_adsorpt_dc3 = -c[1] * (c[2]*p_adsorpt)^(1/c[3]) * log(c[2]*p_adsorpt)/
+      (c[3]^2 * (1 + (c[2]*p_adsorpt)^(1/c[3]))^2)
+      "Derivative of uptake w.r.t. to third coefficient of Sips isotherm";
+
+    Real ddx_adsorpt_dc1_dc2 = (c[2]*p_adsorpt)^(1/c[3]) /
+      (c[3] * c[2] * (1 + (c[2]*p_adsorpt)^(1/c[3]))^2)
+      "Second-order partial derivative of uptake w.r.t. to first and second 
+    coefficient of Sips isotherm";
+    Real ddx_adsorpt_dc1_dc3 = -(c[2]*p_adsorpt)^(1/c[3]) * log(c[2]*p_adsorpt) /
+      ((1 + (c[2]*p_adsorpt)^(1/c[3]))^2 * c[3]^2)
+      "Second-order partial derivative of uptake w.r.t. to first and third 
+    coefficient of Sips isotherm";
+
+    Real ddx_adsorpt_dc2_dc2 = -c[1] * (c[2]*p_adsorpt)^(1/c[3]) * ((c[3] + 1) *
+      (c[2]*p_adsorpt)^(1/c[3]) + c[3] - 1) /
+      (c[2]^2 * c[3]^2 * (1 + (c[2]*p_adsorpt)^(1/c[3]))^3)
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Sips isotherm";
+    Real ddx_adsorpt_dc2_dc3 = -(c[1] * (c[2] * p_adsorpt)^(1 / c[3]) *
+      (((c[2] * p_adsorpt)^(1 / c[3]) + 1) * c[3] - (c[2] * p_adsorpt)^(1 / c[3]) *
+      log(c[2] * p_adsorpt) + log(c[2] * p_adsorpt))) /
+      (c[2] * ((c[2] * p_adsorpt)^(1 / c[3]) + 1)^3 * c[3]^3)
+      "Second-order partial derivative of uptake w.r.t. to second and third 
+    coefficient of Sips isotherm";
+
+    Real ddx_adsorpt_dc3_dc3 = (c[1] * (c[2] * p_adsorpt)^(1 / c[3]) * log(c[2] *
+      p_adsorpt) * ((2 * (c[2] * p_adsorpt)^(1 / c[3]) + 2) *
+      c[3] - (c[2] * p_adsorpt)^(1 / c[3]) * log(c[2] * p_adsorpt) +
+      log(c[2] * p_adsorpt))) / (((c[2] * p_adsorpt)^(1 / c[3]) + 1)^3 * c[3]^4)
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Sips isotherm";
+
+    Real ddx_adsorpt_dc1_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc1_dc3*dc_dT_adsorpt[3]
+      "Second-order partial derivative of uptake w.r.t. to first coefficient of 
+    Sips isotherm and temperature";
+    Real ddx_adsorpt_dc2_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc2*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[3]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Sips isotherm and temperature";
+    Real ddx_adsorpt_dc3_dT_adsorpt = ddx_adsorpt_dc1_dc3*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc3*dc_dT_adsorpt[3]
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Sips isotherm and temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      (ddx_adsorpt_dc1_dT_adsorpt*dc_dT_adsorpt[1] +
+       dx_adsorpt_dc1*ddc_dT_adsorpt_dT_adsorpt[1]) +
+      (ddx_adsorpt_dc2_dT_adsorpt*dc_dT_adsorpt[2] +
+       dx_adsorpt_dc2*ddc_dT_adsorpt_dT_adsorpt[2]) +
+      (ddx_adsorpt_dc3_dT_adsorpt*dc_dT_adsorpt[3] +
+       dx_adsorpt_dc3*ddc_dT_adsorpt_dT_adsorpt[3])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Sips isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real ddx_adsorpt_dp_adsorpt_dc1 = (c[2]*p_adsorpt)^(1/c[3]) /
+      ((1 + (c[2]*p_adsorpt)^(1/c[3]))^2 * c[3] * p_adsorpt)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    first coefficient of Sips isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc2 = -c[1] * (c[2]*p_adsorpt)^(1/c[3]) *
+      ((c[2]*p_adsorpt)^(1/c[3]) - 1) /
+      (c[2] * c[3]^2 * p_adsorpt * (1 + (c[2]*p_adsorpt)^(1/c[3]))^3)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    second coefficient of Sips isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc3 = c[1] * (c[2]*p_adsorpt)^(1/c[3]) *
+      (((c[2]*p_adsorpt)^(1/c[3]) - 1) * log(c[2]*p_adsorpt) - c[3] *
+      (c[2]*p_adsorpt)^(1/c[3]) - c[3]) /
+      (c[3]^3 * p_adsorpt * (1 + (c[2]*p_adsorpt)^(1/c[3]))^3)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    third coefficient of Sips isotherm";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      ddx_adsorpt_dp_adsorpt_dc1*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dp_adsorpt_dc2*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dp_adsorpt_dc3*dc_dT_adsorpt[3]
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare final function extends pi_pT
+    "Sips isotherm model: Reduced spreading pressure as function of pressure and temperature"
+  algorithm
+    pi := 1/M_adsorptive * (c[1]*c[3] * log(1 + (c[2]*p_adsorpt)^(1/c[3])))
+      "Calculation of the reduced spreading pressure";
+  end pi_pT;
+
+  redeclare final function extends p_piT
+    "Sips isotherm model: Pressure as function of reduced spreading pressure and temperature"
+  algorithm
+    p_adsorpt := (exp(M_adsorptive * pi / (c[1]*c[3])) - 1) ^ c[3] / c[2]
+      "Calculation of the equilibrium pressure";
+  end p_piT;
+  //
+  // Annotations
+  //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Sips isotherm model is a three-parameter model for calculating the  equilibrium
+uptake <i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>.
+The Sips isotherm model is suitable for type I and II isotherms according to the 
+IUPAC definition.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Sips isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = x<sub>sat</sub>(T<sub>adsorpt</sub>) * (b(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>) ^ (1/n(T<sub>adsorpt</sub>)) / (1 + (b(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>) ^ (1/n(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+where <i>x<sub>sat</sub>(T<sub>adsorpt</sub>)</i> is the saturation uptake, 
+<i>b(T<sub>adsorpt</sub>)</i> is the Sips coefficient, and <i>n(T<sub>adsorpt</sub>)</i>
+is the Sips exponent. Typical temperature dependencies may have the following forms:
+</p>
+</p>
+<pre>
+    x<sub>sat</sub>(T<sub>adsorpt</sub>) =  x<sub>ref</sub> * <strong>exp</strong>(&Chi; * (1 - T<sub>adsorpt</sub>/T<sub>ref</sub>));
+</pre>
+<pre>
+    b(T<sub>adsorpt</sub>) = b<sub>ref</sub> * <strong>exp</strong>(Q/(R * T<sub>ref</sub>) * (T<sub>ref</sub>/T<sub>adsorpt</sub> - 1));
+</pre>
+<pre>
+    n(T<sub>adsorpt</sub>) = (1/n<sub>ref</sub> + &alpha; * (1 - T<sub>ref</sub>/T<sub>adsorpt</sub>)) ^ (-1);
+</pre>
+<p>
+where <i>x<sub>ref</sub></i> is the saturation uptake at reference temperature 
+<i>T<sub>ref</sub></i>, <i>b<sub>ref</sub></i> is the Sips coefficient at reference 
+temperature, and <i>n<sub>ref</sub></i> is the Sips exponent at reference temperature. 
+The parameter <i>Q</i> is a measure for the isosteric adsorption enthalpy at a fractional
+loading of <i>x<sub>adsorpt</sub>/x<sub>sat</sub>(T<sub>adsorpt</sub>) = 0.5</i>, the 
+parameter <i>&Chi;</i> describes the change of the saturation uptake with temperature, 
+and the parameter <i>&alpha;</i> describes the change of the Sips exponent with 
+temperature. All seven parameters can be used as fitting parameters.
+<br/><br/>
+Note that the Sips exponent <i>n(T<sub>adsorpt</sub>)</i> is typically greater than
+unity. For <i>n(T<sub>adsorpt</sub>) = 1</i>, the Sips isotherm becomes the
+Langmuir isotherm. Hence, the Sips exponent <i>n(T<sub>adsorpt</sub>)</i> can be 
+interpreted as a parameter describing the heterogeneity of the adsorption system. 
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = x<sub>sat</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2] = b(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[3] = n(T<sub>adsorpt</sub>) in -
+  </li>
+</ul>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  No proper Henry law behavior.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used for type I an II isotherms according to the IUPAC definition.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Sips isotherm model for different parameter sets.
+In the upper sub-figure, the equilibrium pressure changes with time, while the 
+equilibrium temperature remains constant; in the lower sub-figure, the equilibrium 
+temperature changes with time, while the equilibrium pressure remains constant. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_sips.png\" alt=\"media_functions_equilibria_pure_sips.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>"));
+end Sips;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Sips/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Sips/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Sips/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_pressure.mo
new file mode 100644
index 0000000..0c0bf45
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_pressure.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.BET;
+model Test_changing_pressure
+  "Tester for all functions of the BET isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_mon_ref = 0.15
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.25
+    "Parameter describing the change of the monolayer uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_ref(unit="1/Pa") = 50
+    "BET coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 35e3
+    "Parameter describing the change of the BET coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_cap(unit="J/mol") = 1.5e3
+    "Parameter describing extra enthalpy added due to capillary forces at high layers"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Integer n = 10
+    "Number of layers that can be occupied"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 30,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BET,
+    final tolerance_p_inv = 1e-6,
+    final tolerance_p_pi = 1e-6,
+    final tolerance_pi = 1e-6,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = x_mon_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[4] = n+0.1/273.15*T_adsorpt;
+  c[5] = exp(Q_cap/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = -chi/T_ref * c[2];
+  dc_dT[3] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[3];
+  dc_dT[4] = 0.1/273.15;
+  dc_dT[5] = -Q_cap/(Modelica.Constants.R*T_adsorpt^2)*c[5];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = -chi/T_ref * dc_dT[2];
+  ddc_dT_dT[3] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt+Q) * dc_dT[3];
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = -1/(Modelica.Constants.R*T_adsorpt^2) *
+    (2*Modelica.Constants.R*T_adsorpt+Q_cap) * dc_dT[5];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[4] = n+0.1/273.15*(T_adsorpt+dT);
+  c_pdT[5] = exp(Q_cap/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[4] = n+0.1/273.15*(T_adsorpt-dT);
+  c_mdT[5] = exp(Q_cap/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the BET isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..b755b89
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_pressureTemperature.mo
@@ -0,0 +1,120 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.BET;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the BET isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_mon_ref = 0.35
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.25
+    "Parameter describing the change of the monolayer uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_ref(unit="1/Pa") = 100
+    "BET coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 35e3
+    "Parameter describing the change of the BET coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_cap(unit="J/mol") = 12.420e3
+    "Parameter describing extra enthalpy added due to capillary forces at high layers"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Integer n = 10
+    "Number of layers that can be occupied"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 300,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BET,
+    final tolerance_p_inv = 1e-6,
+    final tolerance_p_pi = 1e-6,
+    final tolerance_pi = 1e-6,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = x_mon_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[4] = n+0.1/273.15*T_adsorpt;
+  c[5] = exp(Q_cap/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = -chi/T_ref * c[2];
+  dc_dT[3] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[3];
+  dc_dT[4] = 0.1/273.15;
+  dc_dT[5] = -Q_cap/(Modelica.Constants.R*T_adsorpt^2)*c[5];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = -chi/T_ref * dc_dT[2];
+  ddc_dT_dT[3] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt+Q) * dc_dT[3];
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = -1/(Modelica.Constants.R*T_adsorpt^2) *
+    (2*Modelica.Constants.R*T_adsorpt+Q_cap) * dc_dT[5];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[4] = n+0.1/273.15*(T_adsorpt+dT);
+  c_pdT[5] = exp(Q_cap/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[4] = n+0.1/273.15*(T_adsorpt-dT);
+  c_mdT[5] = exp(Q_cap/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the BET isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_temperature.mo
new file mode 100644
index 0000000..b1c18b1
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/Test_changing_temperature.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.BET;
+model Test_changing_temperature
+  "Tester for all functions of the BET isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_mon_ref = 0.15
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.25
+    "Parameter describing the change of the monolayer uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C_ref(unit="1/Pa") = 50
+    "BET coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 35e3
+    "Parameter describing the change of the BET coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q_cap(unit="J/mol") = 1.5e3
+    "Parameter describing extra enthalpy added due to capillary forces at high layers"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Integer n = 10
+    "Number of layers that can be occupied"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 3000,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BET,
+    final tolerance_p_inv = 1e-6,
+    final tolerance_p_pi = 1e-6,
+    final tolerance_pi = 1e-6,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = x_mon_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[4] = n+0.1/273.15*T_adsorpt;
+  c[5] = exp(Q_cap/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = -chi/T_ref * c[2];
+  dc_dT[3] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[3];
+  dc_dT[4] = 0.1/273.15;
+  dc_dT[5] = -Q_cap/(Modelica.Constants.R*T_adsorpt^2)*c[5];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = -chi/T_ref * dc_dT[2];
+  ddc_dT_dT[3] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt+Q) * dc_dT[3];
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = -1/(Modelica.Constants.R*T_adsorpt^2) *
+    (2*Modelica.Constants.R*T_adsorpt+Q_cap) * dc_dT[5];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[4] = n+0.1/273.15*(T_adsorpt+dT);
+  c_pdT[5] = exp(Q_cap/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[3] = C_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[4] = n+0.1/273.15*(T_adsorpt-dT);
+  c_mdT[5] = exp(Q_cap/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the BET isotherm models.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/package.mo
new file mode 100644
index 0000000..104892d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package BET "Models to test and varify functions of the BET isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the BET isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BET;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BET/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_pressure.mo
new file mode 100644
index 0000000..6cbbb76
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_pressure.mo
@@ -0,0 +1,112 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.BiLangmuir;
+model Test_changing_pressure
+  "Tester for all functions of the Bi-Langmuir isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake a0_1 = 0.35
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake a0_2 = 0.45
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1_1(unit="kg.K/kg") = 1e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1_2(unit="kg.K/kg") = 2e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0_1(unit="1/Pa") = 5e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0_2(unit="1/Pa") = 6e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads_1(unit="J/mol") = -2e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads_2(unit="J/mol") = -2.5e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 1000,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 0,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 4,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0_1 + a1_1/T_adsorpt;
+  c[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*T_adsorpt));
+  c[3] = a0_2 + a1_2/T_adsorpt;
+  c[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1_1/T_adsorpt^2;
+  dc_dT[2] = Delta_H_ads_1/(Modelica.Constants.R*T_adsorpt^2) * c[2];
+  dc_dT[3] = -a1_2/T_adsorpt^2;
+  dc_dT[4] = Delta_H_ads_2/(Modelica.Constants.R*T_adsorpt^2) * c[4];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -2*dc_dT[1]/T_adsorpt;
+  ddc_dT_dT[2] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads_1) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[2];
+  ddc_dT_dT[3] = -2*dc_dT[3]/T_adsorpt;
+  ddc_dT_dT[4] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads_2) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[4];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0_1 + a1_1/(T_adsorpt+dT);
+  c_pdT[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*(T_adsorpt+dT)));
+  c_pdT[3] = a0_2 + a1_2/(T_adsorpt+dT);
+  c_pdT[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0_1 + a1_1/(T_adsorpt-dT);
+  c_mdT[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*(T_adsorpt-dT)));
+  c_mdT[3] = a0_2 + a1_2/(T_adsorpt-dT);
+  c_mdT[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Bi-Langmuir isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..dd2c9a3
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_pressureTemperature.mo
@@ -0,0 +1,113 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.BiLangmuir;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Bi-Langmuir isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake a0_1 = 0.35
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake a0_2 = 0.45
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1_1(unit="kg.K/kg") = 1e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1_2(unit="kg.K/kg") = 2e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0_1(unit="1/Pa") = 5e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0_2(unit="1/Pa") = 6e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads_1(unit="J/mol") = -2e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads_2(unit="J/mol") = -2.5e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 1000,
+    final T_adsorpt_der = 1.5,
+    final p_adsorpt_start = 0,
+    final T_adsorpt_start = 273.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 4,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0_1 + a1_1/T_adsorpt;
+  c[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*T_adsorpt));
+  c[3] = a0_2 + a1_2/T_adsorpt;
+  c[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1_1/T_adsorpt^2;
+  dc_dT[2] = Delta_H_ads_1/(Modelica.Constants.R*T_adsorpt^2) * c[2];
+  dc_dT[3] = -a1_2/T_adsorpt^2;
+  dc_dT[4] = Delta_H_ads_2/(Modelica.Constants.R*T_adsorpt^2) * c[4];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -2*dc_dT[1]/T_adsorpt;
+  ddc_dT_dT[2] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads_1) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[2];
+  ddc_dT_dT[3] = -2*dc_dT[3]/T_adsorpt;
+  ddc_dT_dT[4] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads_2) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[4];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0_1 + a1_1/(T_adsorpt+dT);
+  c_pdT[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*(T_adsorpt+dT)));
+  c_pdT[3] = a0_2 + a1_2/(T_adsorpt+dT);
+  c_pdT[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0_1 + a1_1/(T_adsorpt-dT);
+  c_mdT[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*(T_adsorpt-dT)));
+  c_mdT[3] = a0_2 + a1_2/(T_adsorpt-dT);
+  c_mdT[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Bi-Langmuir isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_temperature.mo
new file mode 100644
index 0000000..2c4fbfb
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/Test_changing_temperature.mo
@@ -0,0 +1,112 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.BiLangmuir;
+model Test_changing_temperature
+  "Tester for all functions of the Bi-Langmuir isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake a0_1 = 0.35
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.Uptake a0_2 = 0.45
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1_1(unit="kg.K/kg") = 1e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1_2(unit="kg.K/kg") = 2e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0_1(unit="1/Pa") = 5e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0_2(unit="1/Pa") = 6e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads_1(unit="J/mol") = -2e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads_2(unit="J/mol") = -2.5e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 1000,
+    final T_adsorpt_start = 273.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 4,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.BiLangmuir,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0_1 + a1_1/T_adsorpt;
+  c[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*T_adsorpt));
+  c[3] = a0_2 + a1_2/T_adsorpt;
+  c[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1_1/T_adsorpt^2;
+  dc_dT[2] = Delta_H_ads_1/(Modelica.Constants.R*T_adsorpt^2) * c[2];
+  dc_dT[3] = -a1_2/T_adsorpt^2;
+  dc_dT[4] = Delta_H_ads_2/(Modelica.Constants.R*T_adsorpt^2) * c[4];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -2*dc_dT[1]/T_adsorpt;
+  ddc_dT_dT[2] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads_1) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[2];
+  ddc_dT_dT[3] = -2*dc_dT[3]/T_adsorpt;
+  ddc_dT_dT[4] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads_2) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[4];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0_1 + a1_1/(T_adsorpt+dT);
+  c_pdT[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*(T_adsorpt+dT)));
+  c_pdT[3] = a0_2 + a1_2/(T_adsorpt+dT);
+  c_pdT[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0_1 + a1_1/(T_adsorpt-dT);
+  c_mdT[2] = b0_1*exp(-Delta_H_ads_1/(Modelica.Constants.R*(T_adsorpt-dT)));
+  c_mdT[3] = a0_2 + a1_2/(T_adsorpt-dT);
+  c_mdT[4] = b0_2*exp(-Delta_H_ads_2/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Bi-Langmuir isotherm model.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/package.mo
new file mode 100644
index 0000000..653d630
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package BiLangmuir "Models to test and varify functions of the Bi-Langmuir isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Bi-Langmuir isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BiLangmuir;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/BiLangmuir/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_pressure.mo
new file mode 100644
index 0000000..7b3ad39
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_pressure.mo
@@ -0,0 +1,110 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininAstakhov;
+model Test_changing_pressure
+  "Tester for all functions of the Dubinin-Astakhov isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume W_0 = 4.32e-4
+    "Maximum filled pore volume"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real E(unit="J/mol") = 2.364e3
+    "Characteristic energy"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n(unit="1") = 2.283
+    "Parameter describing the heterogenity of the system"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 25,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 400,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov,
+    final p_lb_pi=Modelica.Constants.small,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = W_0+T_adsorpt/273.15*1e-4;
+  c[4] = E+1*T_adsorpt;
+  c[5] = n+T_adsorpt/273.15;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = 1e-4/273.15;
+  dc_dT[4] = 1;
+  dc_dT[5] = 1/273.15;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = W_0+(T_adsorpt+dT)/273.15*1e-4;
+  c_pdT[4] = E+1*(T_adsorpt+dT);
+  c_pdT[5] = n+(T_adsorpt+dT)/273.15;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = W_0+(T_adsorpt-dT)/273.15*1e-4;
+  c_mdT[4] = E+1*(T_adsorpt-dT);
+  c_mdT[5] = n+(T_adsorpt-dT)/273.15;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Astakhov isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..91235d2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_pressureTemperature.mo
@@ -0,0 +1,111 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininAstakhov;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Dubinin-Astakhov isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume W_0 = 4.32e-4
+    "Maximum filled pore volume"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real E(unit="J/mol") = 2.364e3
+    "Characteristic energy"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n(unit="1") = 2.283
+    "Parameter describing the heterogenity of the system"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 300,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 400,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov,
+    final p_lb_pi=Modelica.Constants.small,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = W_0+T_adsorpt/273.15*1e-4;
+  c[4] = E+1*T_adsorpt;
+  c[5] = n+T_adsorpt/273.15;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = 1e-4/273.15;
+  dc_dT[4] = 1;
+  dc_dT[5] = 1/273.15;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = W_0+(T_adsorpt+dT)/273.15*1e-4;
+  c_pdT[4] = E+1*(T_adsorpt+dT);
+  c_pdT[5] = n+(T_adsorpt+dT)/273.15;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = W_0+(T_adsorpt-dT)/273.15*1e-4;
+  c_mdT[4] = E+1*(T_adsorpt-dT);
+  c_mdT[5] = n+(T_adsorpt-dT)/273.15;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Astakhov isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_temperature.mo
new file mode 100644
index 0000000..1851b0d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/Test_changing_temperature.mo
@@ -0,0 +1,110 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininAstakhov;
+model Test_changing_temperature
+  "Tester for all functions of the Dubinin-Astakhov isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume W_0 = 4.32e-4
+    "Maximum filled pore volume"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real E(unit="J/mol") = 2.364e3
+    "Characteristic energy"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n(unit="1") = 2.283
+    "Parameter describing the heterogenity of the system"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1000,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 5,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininAstakhov,
+    final p_lb_pi=Modelica.Constants.small,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = W_0+T_adsorpt/273.15*1e-4;
+  c[4] = E+1*T_adsorpt;
+  c[5] = n+T_adsorpt/273.15;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = 1e-4/273.15;
+  dc_dT[4] = 1;
+  dc_dT[5] = 1/273.15;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = W_0+(T_adsorpt+dT)/273.15*1e-4;
+  c_pdT[4] = E+1*(T_adsorpt+dT);
+  c_pdT[5] = n+(T_adsorpt+dT)/273.15;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = W_0+(T_adsorpt-dT)/273.15*1e-4;
+  c_mdT[4] = E+1*(T_adsorpt-dT);
+  c_mdT[5] = n+(T_adsorpt-dT)/273.15;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Astakhov isotherm models.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/package.mo
new file mode 100644
index 0000000..b82ab65
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package DubininAstakhov "Models to test and varify functions of the Dubinin-Astakhov isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Dubinin-Astakhov isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end DubininAstakhov;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininAstakhov/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_pressure.mo
new file mode 100644
index 0000000..ddbcb24
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_pressure.mo
@@ -0,0 +1,162 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininChebyshevSeriesRaionalOrder33;
+model Test_changing_pressure
+  "Tester for all functions of the Dubinin-Chebyshev-Series-3/3 isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.472616e-2 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = 1.322831
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_c = 9.401171e-3 / 1000
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 5.760414e-1
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_e = 1.350676e-3 / 1000
+    "Fivth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_f = 1.313913e-1
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_g(min=-1) = -1.926730e-4 / 1000
+    "Seventh fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.MolarAdsorptionPotential char_curve_h = 1061.930 * 1000 * 0.018
+    "Ninth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.MolarAdsorptionPotential char_curve_i = 1065.595 * 1000 * 0.018
+    "Tenth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 30,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1e-2,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 11,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33,
+    final p_lb_pi=1e-2,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=1e-6,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-10*T_adsorpt^2;
+  c[4] = char_curve_b-1e-10*T_adsorpt^2;
+  c[5] = char_curve_c-1e-10*T_adsorpt^2;
+  c[6] = char_curve_d-1e-10*T_adsorpt^2;
+  c[7] = char_curve_e-1e-10*T_adsorpt^2;
+  c[8] = char_curve_f-1e-10*T_adsorpt^2;
+  c[9] = char_curve_g-1e-10*T_adsorpt^2;
+  c[10] = char_curve_h-1e-10*T_adsorpt^2;
+  c[11] = char_curve_i-1e-10*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-10*T_adsorpt;
+  dc_dT[4] = -2*1e-10*T_adsorpt;
+  dc_dT[5] = -2*1e-10*T_adsorpt;
+  dc_dT[6] = -2*1e-10*T_adsorpt;
+  dc_dT[7] = -2*1e-10*T_adsorpt;
+  dc_dT[8] = -2*1e-10*T_adsorpt;
+  dc_dT[9] = -2*1e-10*T_adsorpt;
+  dc_dT[10] = -2*1e-10*T_adsorpt;
+  dc_dT[11] = -2*1e-10*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-10;
+  ddc_dT_dT[4] = -2*1e-10;
+  ddc_dT_dT[5] = -2*1e-10;
+  ddc_dT_dT[6] = -2*1e-10;
+  ddc_dT_dT[7] = -2*1e-10;
+  ddc_dT_dT[8] = -2*1e-10;
+  ddc_dT_dT[9] = -2*1e-10;
+  ddc_dT_dT[10] = -2*1e-10;
+  ddc_dT_dT[11] = -2*1e-10;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[9] = char_curve_g-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[10] = char_curve_h-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[11] = char_curve_i-1e-10*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[9] = char_curve_g-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[10] = char_curve_h-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[11] = char_curve_i-1e-10*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Interval=0.01,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Chebyshev-Series-3/3
+isotherm models. 
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).    
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..64ebdca
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_pressureTemperature.mo
@@ -0,0 +1,163 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininChebyshevSeriesRaionalOrder33;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Dubinin-Chebyshev-Series-3/3 isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.472616e-2 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = 1.322831
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_c = 9.401171e-3 / 1000
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 5.760414e-1
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_e = 1.350676e-3 / 1000
+    "Fivth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_f = 1.313913e-1
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_g(min=-1) = -1.926730e-4 / 1000
+    "Seventh fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.MolarAdsorptionPotential char_curve_h = 1061.930 * 1000 * 0.018
+    "Ninth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.MolarAdsorptionPotential char_curve_i = 1065.595 * 1000 * 0.018
+    "Tenth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 300,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1e-2,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 11,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33,
+    final p_lb_pi=1e-2,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=1e-6,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-10*T_adsorpt^2;
+  c[4] = char_curve_b-1e-10*T_adsorpt^2;
+  c[5] = char_curve_c-1e-10*T_adsorpt^2;
+  c[6] = char_curve_d-1e-10*T_adsorpt^2;
+  c[7] = char_curve_e-1e-10*T_adsorpt^2;
+  c[8] = char_curve_f-1e-10*T_adsorpt^2;
+  c[9] = char_curve_g-1e-10*T_adsorpt^2;
+  c[10] = char_curve_h-1e-10*T_adsorpt^2;
+  c[11] = char_curve_i-1e-10*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-10*T_adsorpt;
+  dc_dT[4] = -2*1e-10*T_adsorpt;
+  dc_dT[5] = -2*1e-10*T_adsorpt;
+  dc_dT[6] = -2*1e-10*T_adsorpt;
+  dc_dT[7] = -2*1e-10*T_adsorpt;
+  dc_dT[8] = -2*1e-10*T_adsorpt;
+  dc_dT[9] = -2*1e-10*T_adsorpt;
+  dc_dT[10] = -2*1e-10*T_adsorpt;
+  dc_dT[11] = -2*1e-10*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-10;
+  ddc_dT_dT[4] = -2*1e-10;
+  ddc_dT_dT[5] = -2*1e-10;
+  ddc_dT_dT[6] = -2*1e-10;
+  ddc_dT_dT[7] = -2*1e-10;
+  ddc_dT_dT[8] = -2*1e-10;
+  ddc_dT_dT[9] = -2*1e-10;
+  ddc_dT_dT[10] = -2*1e-10;
+  ddc_dT_dT[11] = -2*1e-10;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[9] = char_curve_g-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[10] = char_curve_h-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[11] = char_curve_i-1e-10*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[9] = char_curve_g-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[10] = char_curve_h-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[11] = char_curve_i-1e-10*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Interval=0.01,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Chebyshev-Series-3/3
+isotherm models. 
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_temperature.mo
new file mode 100644
index 0000000..eaf37ad
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/Test_changing_temperature.mo
@@ -0,0 +1,162 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininChebyshevSeriesRaionalOrder33;
+model Test_changing_temperature
+  "Tester for all functions of the Dubinin-Chebyshev-Series-3/3 isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.472616e-2 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = 1.322831
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_c = 9.401171e-3 / 1000
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 5.760414e-1
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_e = 1.350676e-3 / 1000
+    "Fivth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_f = 1.313913e-1
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_g(min=-1) = -1.926730e-4 / 1000
+    "Seventh fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.MolarAdsorptionPotential char_curve_h = 1061.930 * 1000 * 0.018
+    "Ninth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.MolarAdsorptionPotential char_curve_i = 1065.595 * 1000 * 0.018
+    "Tenth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 40/100,
+    final p_adsorpt_start = 10000,
+    final T_adsorpt_start = 323.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 11,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininChebyshevSeriesRaionalOrder33,
+    final p_lb_pi=1e-2,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=1e-6,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-10*T_adsorpt^2;
+  c[4] = char_curve_b-1e-10*T_adsorpt^2;
+  c[5] = char_curve_c-1e-10*T_adsorpt^2;
+  c[6] = char_curve_d-1e-10*T_adsorpt^2;
+  c[7] = char_curve_e-1e-10*T_adsorpt^2;
+  c[8] = char_curve_f-1e-10*T_adsorpt^2;
+  c[9] = char_curve_g-1e-10*T_adsorpt^2;
+  c[10] = char_curve_h-1e-10*T_adsorpt^2;
+  c[11] = char_curve_i-1e-10*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-10*T_adsorpt;
+  dc_dT[4] = -2*1e-10*T_adsorpt;
+  dc_dT[5] = -2*1e-10*T_adsorpt;
+  dc_dT[6] = -2*1e-10*T_adsorpt;
+  dc_dT[7] = -2*1e-10*T_adsorpt;
+  dc_dT[8] = -2*1e-10*T_adsorpt;
+  dc_dT[9] = -2*1e-10*T_adsorpt;
+  dc_dT[10] = -2*1e-10*T_adsorpt;
+  dc_dT[11] = -2*1e-10*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-10;
+  ddc_dT_dT[4] = -2*1e-10;
+  ddc_dT_dT[5] = -2*1e-10;
+  ddc_dT_dT[6] = -2*1e-10;
+  ddc_dT_dT[7] = -2*1e-10;
+  ddc_dT_dT[8] = -2*1e-10;
+  ddc_dT_dT[9] = -2*1e-10;
+  ddc_dT_dT[10] = -2*1e-10;
+  ddc_dT_dT[11] = -2*1e-10;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[9] = char_curve_g-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[10] = char_curve_h-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[11] = char_curve_i-1e-10*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[9] = char_curve_g-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[10] = char_curve_h-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[11] = char_curve_i-1e-10*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Interval=0.01,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Chebyshev-Series-3/3
+isotherm models. 
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/package.mo
new file mode 100644
index 0000000..8d8f8a0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package DubininChebyshevSeriesRaionalOrder33 "Models to test and varify functions of the Dubinin-Chebyshev-Series-3/3 isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Dubinin-Chebyshev series 3/3 isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end DubininChebyshevSeriesRaionalOrder33;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininChebyshevSeriesRaionalOrder33/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_pressure.mo
new file mode 100644
index 0000000..817b6bb
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_pressure.mo
@@ -0,0 +1,121 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininEmpirical1;
+model Test_changing_pressure
+  "Tester for all functions of the Dubinin-Empirical-1 isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.570644 * 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = 8.569149e-6 * 1000 * (1 / 1000 / 0.018)^2
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c = 1 / 1000 / 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 9.597209e-8 * 1000 * (1 / 1000 / 0.018)^3
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 30,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1e-2,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-14*T_adsorpt^2;
+  c[4] = char_curve_b-1e-14*T_adsorpt^2;
+  c[5] = char_curve_c-1e-14*T_adsorpt^2;
+  c[6] = char_curve_d-1e-14*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-14*T_adsorpt;
+  dc_dT[4] = -2*1e-14*T_adsorpt;
+  dc_dT[5] = -2*1e-14*T_adsorpt;
+  dc_dT[6] = -2*1e-14*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-14;
+  ddc_dT_dT[4] = -2*1e-14;
+  ddc_dT_dT[5] = -2*1e-14;
+  ddc_dT_dT[6] = -2*1e-14;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-14*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-14*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 3, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Empirical-1
+isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).  
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..7f7c774
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_pressureTemperature.mo
@@ -0,0 +1,122 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininEmpirical1;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Dubinin-Empirical-1 isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.570644 * 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = 8.569149e-6 * 1000 * (1 / 1000 / 0.018)^2
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c = 1 / 1000 / 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 9.597209e-8 * 1000 * (1 / 1000 / 0.018)^3
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 300,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1e-2,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-14*T_adsorpt^2;
+  c[4] = char_curve_b-1e-14*T_adsorpt^2;
+  c[5] = char_curve_c-1e-14*T_adsorpt^2;
+  c[6] = char_curve_d-1e-14*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-14*T_adsorpt;
+  dc_dT[4] = -2*1e-14*T_adsorpt;
+  dc_dT[5] = -2*1e-14*T_adsorpt;
+  dc_dT[6] = -2*1e-14*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-14;
+  ddc_dT_dT[4] = -2*1e-14;
+  ddc_dT_dT[5] = -2*1e-14;
+  ddc_dT_dT[6] = -2*1e-14;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-14*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-14*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 3, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Empirical-1
+isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_temperature.mo
new file mode 100644
index 0000000..a157915
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/Test_changing_temperature.mo
@@ -0,0 +1,121 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininEmpirical1;
+model Test_changing_temperature
+  "Tester for all functions of the Dubinin-Empirical-1 isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.570644 * 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = 8.569149e-6 * 1000 * (1 / 1000 / 0.018)^2
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c = 1 / 1000 / 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 9.597209e-8 * 1000 * (1 / 1000 / 0.018)^3
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1000,
+    final T_adsorpt_start = 293.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-14*T_adsorpt^2;
+  c[4] = char_curve_b-1e-14*T_adsorpt^2;
+  c[5] = char_curve_c-1e-14*T_adsorpt^2;
+  c[6] = char_curve_d-1e-14*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-14*T_adsorpt;
+  dc_dT[4] = -2*1e-14*T_adsorpt;
+  dc_dT[5] = -2*1e-14*T_adsorpt;
+  dc_dT[6] = -2*1e-14*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-14;
+  ddc_dT_dT[4] = -2*1e-14;
+  ddc_dT_dT[5] = -2*1e-14;
+  ddc_dT_dT[6] = -2*1e-14;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-14*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-14*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 3, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Empirical-1
+isotherm model.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/package.mo
new file mode 100644
index 0000000..b8ecc0b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package DubininEmpirical1 "Models to test and varify functions of the Dubinin-Empirical-1 isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Dubinin-Empirical-1 
+isotherm model. The test models check the implementation of the functions and enable 
+verification of the function behavior. Three test models are implemented, in which 
+the pressure and temperature change over time. In addition, the test models demonstrate 
+the functions' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end DubininEmpirical1;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical1/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_pressure.mo
new file mode 100644
index 0000000..9202860
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_pressure.mo
@@ -0,0 +1,145 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininEmpirical2;
+model Test_changing_pressure
+  "Tester for all functions of the Dubinin-Empirical-2 isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.083531e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = -5.415506e-2 * sqrt(1 / 1000 / 0.018)
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c = -1.969937e-2 / 1000 * sqrt(1 / 1000 / 0.018)
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 8.174501e-4 / 1000 / 0.018
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_e = 4.362905e-4 / 1000 / 1000 / 0.018
+    "Fifth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_f = 2.339058e-6 / 1000 / 0.018 * sqrt(1 / 1000 / 0.018)
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_g = -3.199002e-6 / 1000 / 1000 / 0.018 * sqrt(1 / 1000 / 0.018)
+    "Seventh fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 30,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1e-2,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 9,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-14*T_adsorpt^2;
+  c[4] = char_curve_b+1e-14*T_adsorpt^2;
+  c[5] = char_curve_c-1e-14*T_adsorpt^2;
+  c[6] = char_curve_d+1e-14*T_adsorpt^2;
+  c[7] = char_curve_e-1e-18*T_adsorpt^2;
+  c[8] = char_curve_f+1e-14*T_adsorpt^2;
+  c[9] = char_curve_g-1e-18*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-14*T_adsorpt;
+  dc_dT[4] = +2*1e-14*T_adsorpt;
+  dc_dT[5] = -2*1e-14*T_adsorpt;
+  dc_dT[6] = +2*1e-14*T_adsorpt;
+  dc_dT[7] = -2*1e-18*T_adsorpt;
+  dc_dT[8] = +2*1e-14*T_adsorpt;
+  dc_dT[9] = -2*1e-18*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-14;
+  ddc_dT_dT[4] = +2*1e-14;
+  ddc_dT_dT[5] = -2*1e-14;
+  ddc_dT_dT[6] = +2*1e-14;
+  ddc_dT_dT[7] = -2*1e-18;
+  ddc_dT_dT[8] = +2*1e-14;
+  ddc_dT_dT[9] = -2*1e-18;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-18*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[9] = char_curve_g-1e-18*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-18*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[9] = char_curve_g-1e-18*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 6, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Empirical-2
+isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).    
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..8c770b7
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_pressureTemperature.mo
@@ -0,0 +1,146 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininEmpirical2;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Dubinin-Empirical-2 isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.083531e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = -5.415506e-2 * sqrt(1 / 1000 / 0.018)
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c = -1.969937e-2 / 1000 * sqrt(1 / 1000 / 0.018)
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 8.174501e-4 / 1000 / 0.018
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_e = 4.362905e-4 / 1000 / 1000 / 0.018
+    "Fifth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_f = 2.339058e-6 / 1000 / 0.018 * sqrt(1 / 1000 / 0.018)
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_g = -3.199002e-6 / 1000 / 1000 / 0.018 * sqrt(1 / 1000 / 0.018)
+    "Seventh fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 300,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1e-2,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 9,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-14*T_adsorpt^2;
+  c[4] = char_curve_b+1e-14*T_adsorpt^2;
+  c[5] = char_curve_c-1e-14*T_adsorpt^2;
+  c[6] = char_curve_d+1e-14*T_adsorpt^2;
+  c[7] = char_curve_e-1e-18*T_adsorpt^2;
+  c[8] = char_curve_f+1e-14*T_adsorpt^2;
+  c[9] = char_curve_g-1e-18*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-14*T_adsorpt;
+  dc_dT[4] = +2*1e-14*T_adsorpt;
+  dc_dT[5] = -2*1e-14*T_adsorpt;
+  dc_dT[6] = +2*1e-14*T_adsorpt;
+  dc_dT[7] = -2*1e-18*T_adsorpt;
+  dc_dT[8] = +2*1e-14*T_adsorpt;
+  dc_dT[9] = -2*1e-18*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-14;
+  ddc_dT_dT[4] = +2*1e-14;
+  ddc_dT_dT[5] = -2*1e-14;
+  ddc_dT_dT[6] = +2*1e-14;
+  ddc_dT_dT[7] = -2*1e-18;
+  ddc_dT_dT[8] = +2*1e-14;
+  ddc_dT_dT[9] = -2*1e-18;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-18*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[9] = char_curve_g-1e-18*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-18*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[9] = char_curve_g-1e-18*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 6, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Empirical-2
+isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_temperature.mo
new file mode 100644
index 0000000..b646714
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/Test_changing_temperature.mo
@@ -0,0 +1,145 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininEmpirical2;
+model Test_changing_temperature
+  "Tester for all functions of the Dubinin-Empirical-2 isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 3.083531e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b = -5.415506e-2 * sqrt(1 / 1000 / 0.018)
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c = -1.969937e-2 / 1000 * sqrt(1 / 1000 / 0.018)
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_d = 8.174501e-4 / 1000 / 0.018
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_e = 4.362905e-4 / 1000 / 1000 / 0.018
+    "Fifth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_f = 2.339058e-6 / 1000 / 0.018 * sqrt(1 / 1000 / 0.018)
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_g = -3.199002e-6 / 1000 / 1000 / 0.018 * sqrt(1 / 1000 / 0.018)
+    "Seventh fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1000,
+    final T_adsorpt_start = 293.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 9,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-14*T_adsorpt^2;
+  c[4] = char_curve_b+1e-14*T_adsorpt^2;
+  c[5] = char_curve_c-1e-14*T_adsorpt^2;
+  c[6] = char_curve_d+1e-14*T_adsorpt^2;
+  c[7] = char_curve_e-1e-18*T_adsorpt^2;
+  c[8] = char_curve_f+1e-14*T_adsorpt^2;
+  c[9] = char_curve_g-1e-18*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-14*T_adsorpt;
+  dc_dT[4] = +2*1e-14*T_adsorpt;
+  dc_dT[5] = -2*1e-14*T_adsorpt;
+  dc_dT[6] = +2*1e-14*T_adsorpt;
+  dc_dT[7] = -2*1e-18*T_adsorpt;
+  dc_dT[8] = +2*1e-14*T_adsorpt;
+  dc_dT[9] = -2*1e-18*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-14;
+  ddc_dT_dT[4] = +2*1e-14;
+  ddc_dT_dT[5] = -2*1e-14;
+  ddc_dT_dT[6] = +2*1e-14;
+  ddc_dT_dT[7] = -2*1e-18;
+  ddc_dT_dT[8] = +2*1e-14;
+  ddc_dT_dT[9] = -2*1e-18;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-14*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-18*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f+1e-14*(T_adsorpt+dT)^2;
+  c_pdT[9] = char_curve_g-1e-18*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-14*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-18*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f+1e-14*(T_adsorpt-dT)^2;
+  c_mdT[9] = char_curve_g-1e-18*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 6, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Empirical-2
+isotherm model.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).    
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/package.mo
new file mode 100644
index 0000000..9ac858b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package DubininEmpirical2 "Models to test and varify functions of the Dubinin-Empirical-2 isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Dubinin-Empirical-2
+isotherm model. The test models check the implementation of the functions and enable 
+verification of the function behavior. Three test models are implemented, in which 
+the pressure and temperature change over time. In addition, the test models demonstrate 
+the functions' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end DubininEmpirical2;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininEmpirical2/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_pressure.mo
new file mode 100644
index 0000000..a89a9f0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_pressure.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininLorentzianCumulative;
+model Test_changing_pressure
+  "Tester for all functions of the Dubinin-Lorentzian-Cumulative isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 5.072313e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b(unit="J/mol") = 1.305531e2 * 1000 * 0.018
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c(unit="J/mol") = -8.492403e1 * 1000 * 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_d = 4.128962e-3 / 1000
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 30,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a+1e-6*T_adsorpt;
+  c[4] = char_curve_b+1e-4*T_adsorpt^2;
+  c[5] = char_curve_c-1e-4*T_adsorpt^2;
+  c[6] = char_curve_d-1e-8*T_adsorpt;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = 1e-6;
+  dc_dT[4] = 2*1e-4*T_adsorpt;
+  dc_dT[5] = -2*1e-4*T_adsorpt;
+  dc_dT[6] = -1e-8;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 2*1e-4;
+  ddc_dT_dT[5] = -2*1e-4;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a+1e-6*(T_adsorpt+dT);
+  c_pdT[4] = char_curve_b+1e-4*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-4*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-8*(T_adsorpt+dT);
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a+1e-6*(T_adsorpt-dT);
+  c_mdT[4] = char_curve_b+1e-4*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-4*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-8*(T_adsorpt-dT);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Lorentzian-Cumulative
+isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..bf74b2a
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_pressureTemperature.mo
@@ -0,0 +1,120 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininLorentzianCumulative;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Dubinin-Lorentzian-Cumulative model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 5.072313e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b(unit="J/mol") = 1.305531e2 * 1000 * 0.018
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c(unit="J/mol") = -8.492403e1 * 1000 * 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_d = 4.128962e-3 / 1000
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 300,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a+1e-6*T_adsorpt;
+  c[4] = char_curve_b+1e-4*T_adsorpt^2;
+  c[5] = char_curve_c-1e-4*T_adsorpt^2;
+  c[6] = char_curve_d-1e-8*T_adsorpt;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = 1e-6;
+  dc_dT[4] = 2*1e-4*T_adsorpt;
+  dc_dT[5] = -2*1e-4*T_adsorpt;
+  dc_dT[6] = -1e-8;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 2*1e-4;
+  ddc_dT_dT[5] = -2*1e-4;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a+1e-6*(T_adsorpt+dT);
+  c_pdT[4] = char_curve_b+1e-4*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-4*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-8*(T_adsorpt+dT);
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a+1e-6*(T_adsorpt-dT);
+  c_mdT[4] = char_curve_b+1e-4*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-4*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-8*(T_adsorpt-dT);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Lorentzian-Cumulative
+isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_temperature.mo
new file mode 100644
index 0000000..6b994ee
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/Test_changing_temperature.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininLorentzianCumulative;
+model Test_changing_temperature
+  "Tester for all functions of the Dubinin-Lorentzian-Cumulative isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a = 5.072313e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b(unit="J/mol") = 1.305531e2 * 1000 * 0.018
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c(unit="J/mol") = -8.492403e1 * 1000 * 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_d = 4.128962e-3 / 1000
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1000,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    final p_lb_pi=1e-12,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a+1e-6*T_adsorpt;
+  c[4] = char_curve_b+1e-4*T_adsorpt^2;
+  c[5] = char_curve_c-1e-4*T_adsorpt^2;
+  c[6] = char_curve_d-1e-8*T_adsorpt;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = 1e-6;
+  dc_dT[4] = 2*1e-4*T_adsorpt;
+  dc_dT[5] = -2*1e-4*T_adsorpt;
+  dc_dT[6] = -1e-8;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 2*1e-4;
+  ddc_dT_dT[5] = -2*1e-4;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a+1e-6*(T_adsorpt+dT);
+  c_pdT[4] = char_curve_b+1e-4*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-4*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-8*(T_adsorpt+dT);
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a+1e-6*(T_adsorpt-dT);
+  c_mdT[4] = char_curve_b+1e-4*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-4*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-8*(T_adsorpt-dT);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Lorentzian-Cumulative
+isotherm models.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/package.mo
new file mode 100644
index 0000000..3aa9ccf
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package DubininLorentzianCumulative "Models to test and varify functions of the Dubinin-Lorentzian-Cumulative isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Dubinin-Lorentzian-Cumulative
+isotherm model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end DubininLorentzianCumulative;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininLorentzianCumulative/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_pressure.mo
new file mode 100644
index 0000000..41288b2
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_pressure.mo
@@ -0,0 +1,135 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininPearsonIV;
+model Test_changing_pressure
+  "Tester for all functions of the Dubinin-Pearson-IV isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = -7.689279e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b(unit="J/mol") = 1.176831 / 1000
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c(unit="J/mol") = 1.485965e1 * 1000 * 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_d = 4.244922e1 * 1000 * 0.018
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_e = 2.207797e-2
+    "Fivth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_f = 1.146067e-1
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 24,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 100,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 8,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV,
+    final p_lb_pi=1e-2,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-10*T_adsorpt^2;
+  c[4] = char_curve_b-1e-10*T_adsorpt^2;
+  c[5] = char_curve_c-1e-10*T_adsorpt^2;
+  c[6] = char_curve_d-1e-10*T_adsorpt^2;
+  c[7] = char_curve_e-1e-10*T_adsorpt^2;
+  c[8] = char_curve_f-1e-10*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-10*T_adsorpt;
+  dc_dT[4] = -2*1e-10*T_adsorpt;
+  dc_dT[5] = -2*1e-10*T_adsorpt;
+  dc_dT[6] = -2*1e-10*T_adsorpt;
+  dc_dT[7] = -2*1e-10*T_adsorpt;
+  dc_dT[8] = -2*1e-10*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-10;
+  ddc_dT_dT[4] = -2*1e-10;
+  ddc_dT_dT[5] = -2*1e-10;
+  ddc_dT_dT[6] = -2*1e-10;
+  ddc_dT_dT[7] = -2*1e-10;
+  ddc_dT_dT[8] = -2*1e-10;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f-1e-10*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f-1e-10*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Pearson-IV
+isotherm models. 
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..8b634ed
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_pressureTemperature.mo
@@ -0,0 +1,137 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininPearsonIV;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Dubinin-Pearson-IV isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = -7.689279e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b(unit="J/mol") = 1.176831 / 1000
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c(unit="J/mol") = 1.485965e1 * 1000 * 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_d = 4.244922e1 * 1000 * 0.018
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_e = 2.207797e-2
+    "Fivth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_f = 1.146067e-1
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 300,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 8,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV,
+    final p_lb_pi=1e-2,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3,
+    check_func_p_piT=false);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-10*T_adsorpt^2;
+  c[4] = char_curve_b-1e-10*T_adsorpt^2;
+  c[5] = char_curve_c-1e-10*T_adsorpt^2;
+  c[6] = char_curve_d-1e-10*T_adsorpt^2;
+  c[7] = char_curve_e-1e-10*T_adsorpt^2;
+  c[8] = char_curve_f-1e-10*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-10*T_adsorpt;
+  dc_dT[4] = -2*1e-10*T_adsorpt;
+  dc_dT[5] = -2*1e-10*T_adsorpt;
+  dc_dT[6] = -2*1e-10*T_adsorpt;
+  dc_dT[7] = -2*1e-10*T_adsorpt;
+  dc_dT[8] = -2*1e-10*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-10;
+  ddc_dT_dT[4] = -2*1e-10;
+  ddc_dT_dT[5] = -2*1e-10;
+  ddc_dT_dT[6] = -2*1e-10;
+  ddc_dT_dT[7] = -2*1e-10;
+  ddc_dT_dT[8] = -2*1e-10;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f-1e-10*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f-1e-10*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Pearson-IV
+isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_temperature.mo
new file mode 100644
index 0000000..88cf670
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/Test_changing_temperature.mo
@@ -0,0 +1,136 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.DubininPearsonIV;
+model Test_changing_temperature
+  "Tester for all functions of the Dubinin-Pearson-IV isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = -7.689279e-1 / 1000
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_b(unit="J/mol") = 1.176831 / 1000
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real char_curve_c(unit="J/mol") = 1.485965e1 * 1000 * 0.018
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_d = 4.244922e1 * 1000 * 0.018
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_e = 2.207797e-2
+    "Fivth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter SorpLib.Units.FilledPoreVolume char_curve_f = 1.146067e-1
+    "Sixth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPureDubinin(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1000,
+    final T_adsorpt_start = 293.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 8,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV,
+    final p_lb_pi=1e-2,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3,
+    final dA=1e-3,
+    check_func_p_piT=false);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt);
+  c[3] = char_curve_a-1e-10*T_adsorpt^2;
+  c[4] = char_curve_b-1e-10*T_adsorpt^2;
+  c[5] = char_curve_c-1e-10*T_adsorpt^2;
+  c[6] = char_curve_d-1e-10*T_adsorpt^2;
+  c[7] = char_curve_e-1e-10*T_adsorpt^2;
+  c[8] = char_curve_f-1e-10*T_adsorpt^2;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c[1]) *
+    dc_dT[1];
+  dc_dT[3] = -2*1e-10*T_adsorpt;
+  dc_dT[4] = -2*1e-10*T_adsorpt;
+  dc_dT[5] = -2*1e-10*T_adsorpt;
+  dc_dT[6] = -2*1e-10*T_adsorpt;
+  dc_dT[7] = -2*1e-10*T_adsorpt;
+  dc_dT[8] = -2*1e-10*T_adsorpt;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_pdT[1]) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT) *
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhol_dp(p=c_mdT[1])) / (2*dT);
+  ddc_dT_dT[3] = -2*1e-10;
+  ddc_dT_dT[4] = -2*1e-10;
+  ddc_dT_dT[5] = -2*1e-10;
+  ddc_dT_dT[6] = -2*1e-10;
+  ddc_dT_dT[7] = -2*1e-10;
+  ddc_dT_dT[8] = -2*1e-10;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt+dT);
+  c_pdT[3] = char_curve_a-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[4] = char_curve_b-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[5] = char_curve_c-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[6] = char_curve_d-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[7] = char_curve_e-1e-10*(T_adsorpt+dT)^2;
+  c_pdT[8] = char_curve_f-1e-10*(T_adsorpt+dT)^2;
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.rhol_T(T=T_adsorpt-dT);
+  c_mdT[3] = char_curve_a-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[4] = char_curve_b-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[5] = char_curve_c-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[6] = char_curve_d-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[7] = char_curve_e-1e-10*(T_adsorpt-dT)^2;
+  c_mdT[8] = char_curve_f-1e-10*(T_adsorpt-dT)^2;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Dubinin-Pearson-IV
+isotherm models. 
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/package.mo
new file mode 100644
index 0000000..609c3fa
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package DubininPearsonIV "Models to test and varify functions of the Dubinin-Pearson-IV isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Dubinin-Pearson-IV isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end DubininPearsonIV;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/DubininPearsonIV/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_pressure.mo
new file mode 100644
index 0000000..c9f15ff
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_pressure.mo
@@ -0,0 +1,88 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Freundlich;
+model Test_changing_pressure
+  "Tester for all functions of the Freundlich isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter Real a0 = 0.01
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1(unit="1/K") = 1/273.15
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0(unit="1") = 2
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b1(unit="K") = 50
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 100,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Freundlich,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0*exp(-a1*T_adsorpt);
+  c[2] = b0 + b1/T_adsorpt;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1 * c[1];
+  dc_dT[2] = -b1/T_adsorpt^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -a1 * dc_dT[1];
+  ddc_dT_dT[2] = -2 / T_adsorpt * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0*exp(-a1*(T_adsorpt+dT));
+  c_pdT[2] = b0 + b1/(T_adsorpt+dT);
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0*exp(-a1*(T_adsorpt-dT));
+  c_mdT[2] = b0 + b1/(T_adsorpt-dT);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Freundlich isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..bec086b
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_pressureTemperature.mo
@@ -0,0 +1,89 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Freundlich;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Freundlich isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter Real a0 = 0.01
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1(unit="1/K") = 1/273.15
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0(unit="1") = 2
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b1(unit="K") = 50
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 100,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 273.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Freundlich,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0*exp(-a1*T_adsorpt);
+  c[2] = b0 + b1/T_adsorpt;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1 * c[1];
+  dc_dT[2] = -b1/T_adsorpt^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -a1 * dc_dT[1];
+  ddc_dT_dT[2] = -2 / T_adsorpt * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0*exp(-a1*(T_adsorpt+dT));
+  c_pdT[2] = b0 + b1/(T_adsorpt+dT);
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0*exp(-a1*(T_adsorpt-dT));
+  c_mdT[2] = b0 + b1/(T_adsorpt-dT);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Freundlich isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_temperature.mo
new file mode 100644
index 0000000..bf665dd
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/Test_changing_temperature.mo
@@ -0,0 +1,88 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Freundlich;
+model Test_changing_temperature
+  "Tester for all functions of the Freundlich isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter Real a0 = 0.01
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1(unit="1/K") = 1/273.15
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0(unit="1") = 2
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b1(unit="K") = 50
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 5000,
+    final T_adsorpt_start = 273.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Freundlich,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0*exp(-a1*T_adsorpt);
+  c[2] = b0 + b1/T_adsorpt;
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1 * c[1];
+  dc_dT[2] = -b1/T_adsorpt^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -a1 * dc_dT[1];
+  ddc_dT_dT[2] = -2 / T_adsorpt * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0*exp(-a1*(T_adsorpt+dT));
+  c_pdT[2] = b0 + b1/(T_adsorpt+dT);
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0*exp(-a1*(T_adsorpt-dT));
+  c_mdT[2] = b0 + b1/(T_adsorpt-dT);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Freundlich isotherm models.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/package.mo
new file mode 100644
index 0000000..2c99dce
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package Freundlich "Models to test and varify functions of the Freundlich isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Freundlich isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Freundlich;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Freundlich/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_pressure.mo
new file mode 100644
index 0000000..feaf22f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_pressure.mo
@@ -0,0 +1,129 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.GAB;
+model Test_changing_pressure
+  "Tester for all functions of the GAB isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_mon_ref = 0.06534
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0
+    "Parameter describing the change of the monolayer uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C(unit="J/mol") = 47110
+    "Adsorption enthalpy of first layer: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D(unit="1/K") = 0.023744
+    "Adsorption enthalpy of first layer: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F(unit="J/mol") = 57706
+    "Adsorption enthalpy of layers 2-9: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G(unit="J/(mol.K)") = -47.814
+    "Adsorption enthalpy of layers 2-9: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real H(unit="J/mol") = 57220
+    "Adsorption enthalpy of layer 10 or higher layers: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I(unit="J/(mol.K)") = -44.38
+    "Adsorption enthalpy of layer 10 or higher layers: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 30,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 4,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = x_mon_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[3] = exp(((C - exp(D*T_adsorpt)) - (H + I*T_adsorpt)) /
+    (Modelica.Constants.R*T_adsorpt));
+  c[4] = exp(((F + G*T_adsorpt) - (H + I*T_adsorpt)) /
+    (Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = -chi/T_ref * c[2];
+  dc_dT[3] = -((D*T_adsorpt - 1) * exp(D*T_adsorpt) - H + C) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3];
+  dc_dT[4] = (H - F) / (Modelica.Constants.R*T_adsorpt^2) * c[4];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = -chi/T_ref * dc_dT[2];
+  ddc_dT_dT[3] = (((D^2 * T_adsorpt^2 - 2 * D * T_adsorpt + 1) *
+    exp(2 * D * T_adsorpt) + (-D^2 * Modelica.Constants.R * T_adsorpt^3 +
+    2 * D * Modelica.Constants.R * T_adsorpt^2 + (-2 * Modelica.Constants.R -
+    2 * D * H + 2 * C * D) * T_adsorpt + 2 * H - 2 * C) * exp(D * T_adsorpt) +
+    (2 * C - 2 * H) * Modelica.Constants.R * T_adsorpt + H^2 - 2 * C * H + C^2) *
+    exp((-exp(D * T_adsorpt) - I * T_adsorpt - H + C) / (Modelica.Constants.R *
+    T_adsorpt))) / (Modelica.Constants.R^2 * T_adsorpt^4);
+  ddc_dT_dT[4] = -1 / (Modelica.Constants.R*T_adsorpt^2) *
+    (2*Modelica.Constants.R*T_adsorpt - H + F) * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[3] = exp(((C - exp(D*(T_adsorpt+dT))) - (H + I*(T_adsorpt+dT))) /
+    (Modelica.Constants.R*(T_adsorpt+dT)));
+  c_pdT[4] = exp(((F + G*(T_adsorpt+dT)) - (H + I*(T_adsorpt+dT))) /
+    (Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[3] = exp(((C - exp(D*(T_adsorpt-dT))) - (H + I*(T_adsorpt-dT))) /
+    (Modelica.Constants.R*(T_adsorpt-dT)));
+  c_mdT[4] = exp(((F + G*(T_adsorpt-dT)) - (H + I*(T_adsorpt-dT))) /
+    (Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the GAB isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..08d10aa
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_pressureTemperature.mo
@@ -0,0 +1,130 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.GAB;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the GAB isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_mon_ref = 0.06534
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0
+    "Parameter describing the change of the monolayer uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C(unit="J/mol") = 47110
+    "Adsorption enthalpy of first layer: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D(unit="1/K") = 0.023744
+    "Adsorption enthalpy of first layer: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F(unit="J/mol") = 57706
+    "Adsorption enthalpy of layers 2-9: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G(unit="J/(mol.K)") = -47.814
+    "Adsorption enthalpy of layers 2-9: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real H(unit="J/mol") = 57220
+    "Adsorption enthalpy of layer 10 or higher layers: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I(unit="J/(mol.K)") = -44.38
+    "Adsorption enthalpy of layer 10 or higher layers: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 300,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 4,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = x_mon_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[3] = exp(((C - exp(D*T_adsorpt)) - (H + I*T_adsorpt)) /
+    (Modelica.Constants.R*T_adsorpt));
+  c[4] = exp(((F + G*T_adsorpt) - (H + I*T_adsorpt)) /
+    (Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = -chi/T_ref * c[2];
+  dc_dT[3] = -((D*T_adsorpt - 1) * exp(D*T_adsorpt) - H + C) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3];
+  dc_dT[4] = (H - F) / (Modelica.Constants.R*T_adsorpt^2) * c[4];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = -chi/T_ref * dc_dT[2];
+  ddc_dT_dT[3] = (((D^2 * T_adsorpt^2 - 2 * D * T_adsorpt + 1) *
+    exp(2 * D * T_adsorpt) + (-D^2 * Modelica.Constants.R * T_adsorpt^3 +
+    2 * D * Modelica.Constants.R * T_adsorpt^2 + (-2 * Modelica.Constants.R -
+    2 * D * H + 2 * C * D) * T_adsorpt + 2 * H - 2 * C) * exp(D * T_adsorpt) +
+    (2 * C - 2 * H) * Modelica.Constants.R * T_adsorpt + H^2 - 2 * C * H + C^2) *
+    exp((-exp(D * T_adsorpt) - I * T_adsorpt - H + C) / (Modelica.Constants.R *
+    T_adsorpt))) / (Modelica.Constants.R^2 * T_adsorpt^4);
+  ddc_dT_dT[4] = -1 / (Modelica.Constants.R*T_adsorpt^2) *
+    (2*Modelica.Constants.R*T_adsorpt - H + F) * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[3] = exp(((C - exp(D*(T_adsorpt+dT))) - (H + I*(T_adsorpt+dT))) /
+    (Modelica.Constants.R*(T_adsorpt+dT)));
+  c_pdT[4] = exp(((F + G*(T_adsorpt+dT)) - (H + I*(T_adsorpt+dT))) /
+    (Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[3] = exp(((C - exp(D*(T_adsorpt-dT))) - (H + I*(T_adsorpt-dT))) /
+    (Modelica.Constants.R*(T_adsorpt-dT)));
+  c_mdT[4] = exp(((F + G*(T_adsorpt-dT)) - (H + I*(T_adsorpt-dT))) /
+    (Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the GAB isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_temperature.mo
new file mode 100644
index 0000000..5531c52
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/Test_changing_temperature.mo
@@ -0,0 +1,129 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.GAB;
+model Test_changing_temperature
+  "Tester for all functions of the BET isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_mon_ref = 0.06534
+    "Monolayer uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0
+    "Parameter describing the change of the monolayer uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real C(unit="J/mol") = 47110
+    "Adsorption enthalpy of first layer: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real D(unit="1/K") = 0.023744
+    "Adsorption enthalpy of first layer: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real F(unit="J/mol") = 57706
+    "Adsorption enthalpy of layers 2-9: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real G(unit="J/(mol.K)") = -47.814
+    "Adsorption enthalpy of layers 2-9: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real H(unit="J/mol") = 57220
+    "Adsorption enthalpy of layer 10 or higher layers: First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real I(unit="J/(mol.K)") = -44.38
+    "Adsorption enthalpy of layer 10 or higher layers: Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 80/100,
+    final p_adsorpt_start = 3000,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 4,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.GAB,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt);
+  c[2] = x_mon_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[3] = exp(((C - exp(D*T_adsorpt)) - (H + I*T_adsorpt)) /
+    (Modelica.Constants.R*T_adsorpt));
+  c[4] = exp(((F + G*T_adsorpt) - (H + I*T_adsorpt)) /
+    (Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt);
+  dc_dT[2] = -chi/T_ref * c[2];
+  dc_dT[3] = -((D*T_adsorpt - 1) * exp(D*T_adsorpt) - H + C) /
+    (Modelica.Constants.R*T_adsorpt^2) * c[3];
+  dc_dT[4] = (H - F) / (Modelica.Constants.R*T_adsorpt^2) * c[4];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)) /
+    (2*dT);
+  ddc_dT_dT[2] = -chi/T_ref * dc_dT[2];
+  ddc_dT_dT[3] = (((D^2 * T_adsorpt^2 - 2 * D * T_adsorpt + 1) *
+    exp(2 * D * T_adsorpt) + (-D^2 * Modelica.Constants.R * T_adsorpt^3 +
+    2 * D * Modelica.Constants.R * T_adsorpt^2 + (-2 * Modelica.Constants.R -
+    2 * D * H + 2 * C * D) * T_adsorpt + 2 * H - 2 * C) * exp(D * T_adsorpt) +
+    (2 * C - 2 * H) * Modelica.Constants.R * T_adsorpt + H^2 - 2 * C * H + C^2) *
+    exp((-exp(D * T_adsorpt) - I * T_adsorpt - H + C) / (Modelica.Constants.R *
+    T_adsorpt))) / (Modelica.Constants.R^2 * T_adsorpt^4);
+  ddc_dT_dT[4] = -1 / (Modelica.Constants.R*T_adsorpt^2) *
+    (2*Modelica.Constants.R*T_adsorpt - H + F) * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT);
+  c_pdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[3] = exp(((C - exp(D*(T_adsorpt+dT))) - (H + I*(T_adsorpt+dT))) /
+    (Modelica.Constants.R*(T_adsorpt+dT)));
+  c_pdT[4] = exp(((F + G*(T_adsorpt+dT)) - (H + I*(T_adsorpt+dT))) /
+    (Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT);
+  c_mdT[2] = x_mon_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[3] = exp(((C - exp(D*(T_adsorpt-dT))) - (H + I*(T_adsorpt-dT))) /
+    (Modelica.Constants.R*(T_adsorpt-dT)));
+  c_mdT[4] = exp(((F + G*(T_adsorpt-dT)) - (H + I*(T_adsorpt-dT))) /
+    (Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the BET isotherm models.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/package.mo
new file mode 100644
index 0000000..fd2d0d8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package GAB "Models to test and varify functions of the GAB isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the GAB isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end GAB;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/GAB/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_pressure.mo
new file mode 100644
index 0000000..aaaebfa
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_pressure.mo
@@ -0,0 +1,80 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Henry;
+model Test_changing_pressure
+  "Tester for all functions of the Henry isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter Real H_ref(unit="kg/(kg.Pa)") = 0.01
+    "Henry constant at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  final parameter Real C_exp(unit="K") = 2400
+    "Exponent describing change of Henry constant with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  final parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature for Henry constant"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 1,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 0,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 1,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = H_ref * exp(C_exp * (1/T_adsorpt - 1 / T_ref));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -C_exp * c[1] / (T_adsorpt^2);
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -dc_dT[1] * (2 * T_adsorpt + C_exp) / (T_adsorpt^2);
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = H_ref * exp(C_exp * (1/(T_adsorpt + dT) - 1 / T_ref));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = H_ref * exp(C_exp * (1/(T_adsorpt - dT) - 1 / T_ref));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Henry isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..f27800a
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_pressureTemperature.mo
@@ -0,0 +1,81 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Henry;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Henry isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter Real H_ref(unit="kg/(kg.Pa)") = 0.01
+    "Henry constant at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  final parameter Real C_exp(unit="K") = 2400
+    "Exponent describing change of Henry constant with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  final parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature for Henry constant"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 1,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 0,
+    final T_adsorpt_start = 273.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 1,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = H_ref * exp(C_exp * (1/T_adsorpt - 1 / T_ref));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -C_exp * c[1] / (T_adsorpt^2);
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -dc_dT[1] * (2 * T_adsorpt + C_exp) / (T_adsorpt^2);
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = H_ref * exp(C_exp * (1/(T_adsorpt + dT) - 1 / T_ref));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = H_ref * exp(C_exp * (1/(T_adsorpt - dT) - 1 / T_ref));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Henry isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_temperature.mo
new file mode 100644
index 0000000..ccdb66d
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/Test_changing_temperature.mo
@@ -0,0 +1,80 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Henry;
+model Test_changing_temperature
+  "Tester for all functions of the Henry isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter Real H_ref(unit="kg/(kg.Pa)") = 0.01
+    "Henry constant at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  final parameter Real C_exp(unit="K") = 2400
+    "Exponent describing change of Henry constant with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  final parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature for Henry constant"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 100,
+    final T_adsorpt_start = 273.15,
+    final M_adsorptive = 0.018,
+    final no_coefficients = 1,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Henry,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = H_ref * exp(C_exp * (1/T_adsorpt - 1 / T_ref));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -C_exp * c[1] / (T_adsorpt^2);
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -dc_dT[1] * (2 * T_adsorpt + C_exp) / (T_adsorpt^2);
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = H_ref * exp(C_exp * (1/(T_adsorpt + dT) - 1 / T_ref));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = H_ref * exp(C_exp * (1/(T_adsorpt - dT) - 1 / T_ref));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Henry isotherm model.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/package.mo
new file mode 100644
index 0000000..63f5f0c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package Henry "Models to test and varify functions of the Henry isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Henry isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Henry;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Henry/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_pressure.mo
new file mode 100644
index 0000000..e595e6f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_pressure.mo
@@ -0,0 +1,92 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Langmuir;
+model Test_changing_pressure
+  "Tester for all functions of the Langmuir isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake a0 = 0.35
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1(unit="kg.K/kg") = 1e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0(unit="1/Pa") = 5e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads(unit="J/mol") = -2e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 100,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 0,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0 + a1/T_adsorpt;
+  c[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1/T_adsorpt^2;
+  dc_dT[2] = Delta_H_ads/(Modelica.Constants.R*T_adsorpt^2) * c[2];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -2*dc_dT[1]/T_adsorpt;
+  ddc_dT_dT[2] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0 + a1/(T_adsorpt+dT);
+  c_pdT[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0 + a1/(T_adsorpt-dT);
+  c_mdT[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=100,
+      Tolerance=1e-06,
+      __Dymola_Algorithm="Dassl"),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Langmuir isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..5708515
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_pressureTemperature.mo
@@ -0,0 +1,90 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Langmuir;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Langmuir isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake a0 = 0.35
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1(unit="kg.K/kg") = 1e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0(unit="1/Pa") = 5e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads(unit="J/mol") = -2e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 100,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 0,
+    final T_adsorpt_start = 273.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0 + a1/T_adsorpt;
+  c[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1/T_adsorpt^2;
+  dc_dT[2] = Delta_H_ads/(Modelica.Constants.R*T_adsorpt^2) * c[2];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -2*dc_dT[1]/T_adsorpt;
+  ddc_dT_dT[2] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0 + a1/(T_adsorpt+dT);
+  c_pdT[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0 + a1/(T_adsorpt-dT);
+  c_mdT[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Langmuir isotherm model.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_temperature.mo
new file mode 100644
index 0000000..fcd12ca
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/Test_changing_temperature.mo
@@ -0,0 +1,89 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Langmuir;
+model Test_changing_temperature
+  "Tester for all functions of the Langmuir isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake a0 = 0.35
+    "First fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real a1(unit="kg.K/kg") = 1e-4
+    "Second fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b0(unit="1/Pa") = 5e-8
+    "Third fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Delta_H_ads(unit="J/mol") = -2e4
+    "Fourth fitting parameter"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 100,
+    final T_adsorpt_start = 273.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = a0 + a1/T_adsorpt;
+  c[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -a1/T_adsorpt^2;
+  dc_dT[2] = Delta_H_ads/(Modelica.Constants.R*T_adsorpt^2) * c[2];
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -2*dc_dT[1]/T_adsorpt;
+  ddc_dT_dT[2] = -(2*Modelica.Constants.R*T_adsorpt - Delta_H_ads) /
+    (Modelica.Constants.R*T_adsorpt^2) * dc_dT[2];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = a0 + a1/(T_adsorpt+dT);
+  c_pdT[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = a0 + a1/(T_adsorpt-dT);
+  c_mdT[2] = b0*exp(-Delta_H_ads/(Modelica.Constants.R*(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Langmuir isotherm model.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/package.mo
new file mode 100644
index 0000000..92bbd1e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package Langmuir "Models to test and varify functions of the Langmuir isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Langmuir isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Langmuir;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Langmuir/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_pressure.mo
new file mode 100644
index 0000000..5842516
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_pressure.mo
@@ -0,0 +1,104 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Sips;
+model Test_changing_pressure
+  "Tester for all functions of the Sips isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_ref = 0.32
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.01
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref(unit="1/Pa") = 1.075e-4
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 28.752e3
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n_ref(unit="1") = 2.312
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha(unit="1") = 0.5559
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 283
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 1400,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Sips,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = x_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[3] = 1 / (1/n_ref + alpha * (1 - T_ref/T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -chi/T_ref * c[1];
+  dc_dT[2] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[2];
+  dc_dT[3] = -T_ref*alpha/T_adsorpt^2 / (1/n_ref + alpha * (1 - T_ref/T_adsorpt))^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -chi/T_ref * dc_dT[1];
+  ddc_dT_dT[2] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt + Q) * dc_dT[2];
+  ddc_dT_dT[3] = 2 * T_ref * n_ref^2 * alpha * (n_ref * alpha + 1) /
+    ((n_ref * alpha + 1) * T_adsorpt - T_ref * n_ref * alpha)^3;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = x_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[3] = 1 / (1/n_ref + alpha * (1 - T_ref/(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = x_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[3] = 1 / (1/n_ref + alpha * (1 - T_ref/(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Sips isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..28ef8fe
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_pressureTemperature.mo
@@ -0,0 +1,105 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Sips;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Sips isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_ref = 0.32
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.01
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref(unit="1/Pa") = 1.075e-4
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 28.752e3
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n_ref(unit="1") = 2.312
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha(unit="1") = 0.5559
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 283
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 1400,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Sips,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = x_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[3] = 1 / (1/n_ref + alpha * (1 - T_ref/T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -chi/T_ref * c[1];
+  dc_dT[2] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[2];
+  dc_dT[3] = -T_ref*alpha/T_adsorpt^2 / (1/n_ref + alpha * (1 - T_ref/T_adsorpt))^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -chi/T_ref * dc_dT[1];
+  ddc_dT_dT[2] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt + Q) * dc_dT[2];
+  ddc_dT_dT[3] = 2 * T_ref * n_ref^2 * alpha * (n_ref * alpha + 1) /
+    ((n_ref * alpha + 1) * T_adsorpt - T_ref * n_ref * alpha)^3;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = x_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[3] = 1 / (1/n_ref + alpha * (1 - T_ref/(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = x_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[3] = 1 / (1/n_ref + alpha * (1 - T_ref/(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Sips isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_temperature.mo
new file mode 100644
index 0000000..e90de12
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/Test_changing_temperature.mo
@@ -0,0 +1,104 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Sips;
+model Test_changing_temperature
+  "Tester for all functions of the Sips isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_ref = 0.32
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.01
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref(unit="1/Pa") = 1.075e-4
+    "Sips coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 28.752e3
+    "Parameter describing the change of the Sips coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real n_ref(unit="1") = 2.312
+    "Sips exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha(unit="1") = 0.5559
+    "Parameter describing the change of the Sips exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 283
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 50000,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Sips,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = x_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[3] = 1 / (1/n_ref + alpha * (1 - T_ref/T_adsorpt));
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -chi/T_ref * c[1];
+  dc_dT[2] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[2];
+  dc_dT[3] = -T_ref*alpha/T_adsorpt^2 / (1/n_ref + alpha * (1 - T_ref/T_adsorpt))^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -chi/T_ref * dc_dT[1];
+  ddc_dT_dT[2] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt + Q) * dc_dT[2];
+  ddc_dT_dT[3] = 2 * T_ref * n_ref^2 * alpha * (n_ref * alpha + 1) /
+    ((n_ref * alpha + 1) * T_adsorpt - T_ref * n_ref * alpha)^3;
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = x_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[3] = 1 / (1/n_ref + alpha * (1 - T_ref/(T_adsorpt+dT)));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = x_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[3] = 1 / (1/n_ref + alpha * (1 - T_ref/(T_adsorpt-dT)));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Sips isotherm models.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/package.mo
new file mode 100644
index 0000000..e3f036c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package Sips "Models to test and varify functions of the Sips isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Sips isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Sips;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Sips/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_pressure.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_pressure.mo
new file mode 100644
index 0000000..917a734
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_pressure.mo
@@ -0,0 +1,105 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Toth;
+model Test_changing_pressure
+  "Tester for all functions of the Toth isotherm model: Changing pressure"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_ref = 0.38
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.01
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref(unit="1/Pa") = 10.54e-3
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 46.093e3
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref(unit="1") = 0.2842
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha(unit="1") = 0.284
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 283
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 1400,
+    final T_adsorpt_der = 0,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = x_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[3] = t_ref + alpha * (1 - T_ref/T_adsorpt);
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -chi/T_ref * c[1];
+  dc_dT[2] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[2];
+  dc_dT[3] = T_ref*alpha/T_adsorpt^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -chi/T_ref * dc_dT[1];
+  ddc_dT_dT[2] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt + Q) * dc_dT[2];
+  ddc_dT_dT[3] = -2/T_adsorpt * dc_dT[3];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = x_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[3] = t_ref + alpha * (1 - T_ref/(T_adsorpt+dT));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = x_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[3] = t_ref + alpha * (1 - T_ref/(T_adsorpt-dT));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s). 
+</p>
+</html>"));
+end Test_changing_pressure;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_pressureTemperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_pressureTemperature.mo
new file mode 100644
index 0000000..c1f1a38
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_pressureTemperature.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Toth;
+model Test_changing_pressureTemperature
+  "Tester for all functions of the Toth isotherm model: Changing pressure and temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_ref = 0.38
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.01
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref(unit="1/Pa") = 10.54e-3
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 46.093e3
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref(unit="1") = 0.2842
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha(unit="1") = 0.284
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 283
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 1400,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 1,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=1e-4,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = x_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[3] = t_ref + alpha * (1 - T_ref/T_adsorpt);
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -chi/T_ref * c[1];
+  dc_dT[2] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[2];
+  dc_dT[3] = T_ref*alpha/T_adsorpt^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -chi/T_ref * dc_dT[1];
+  ddc_dT_dT[2] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt + Q) * dc_dT[2];
+  ddc_dT_dT[3] = -2/T_adsorpt * dc_dT[3];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = x_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[3] = t_ref + alpha * (1 - T_ref/(T_adsorpt+dT));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = x_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[3] = t_ref + alpha * (1 - T_ref/(T_adsorpt-dT));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth isotherm models.
+<br/><br/>
+As an example, this tester increases the pressure and temperature with time. To 
+see the behavior of all functions, plot the variables <i>x_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, and <i>red_spreading_pressure</i> over 
+the variable <i>p_adsorpt</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_pressureTemperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_temperature.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_temperature.mo
new file mode 100644
index 0000000..7e56e39
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/Test_changing_temperature.mo
@@ -0,0 +1,105 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers.Toth;
+model Test_changing_temperature
+  "Tester for all functions of the Toth isotherm model: Changing temperature"
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Units.Uptake x_ref = 0.38
+    "Saturation uptake at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real chi(unit="1") = 0.01
+    "Parameter describing the change of the saturation uptake with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real b_ref(unit="1/Pa") = 10.54e-3
+    "Toth coefficient at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real Q(unit="J/mol") = 46.093e3
+    "Parameter describing the change of the Toth coefficient with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real t_ref(unit="1") = 0.2842
+    "Toth exponent at reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real alpha(unit="1") = 0.284
+    "Parameter describing the change of the Toth exponent with temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Modelica.Units.SI.Temperature T_ref = 283
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialTestPure(
+    final p_adsorpt_der = 0,
+    final T_adsorpt_der = 1,
+    final p_adsorpt_start = 50000,
+    final T_adsorpt_start = 298.15,
+    final M_adsorptive = 0.044,
+    final no_coefficients = 3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    final tolerance_p_pi=1e-6,
+    final tolerance_pi=100*Modelica.Constants.eps,
+    final dp=1e-3,
+    final dT=1e-3);
+
+equation
+  //
+  // Coefficients of the isotherm model
+  //
+  c[1] = x_ref * exp(chi * (1 - T_adsorpt/T_ref));
+  c[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/T_adsorpt - 1));
+  c[3] = t_ref + alpha * (1 - T_ref/T_adsorpt);
+
+  //
+  // Partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  dc_dT[1] = -chi/T_ref * c[1];
+  dc_dT[2] = -Q/Modelica.Constants.R/T_adsorpt^2 * c[2];
+  dc_dT[3] = T_ref*alpha/T_adsorpt^2;
+
+  //
+  // Second-oder partial derivative of coefficients of isotherm model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = -chi/T_ref * dc_dT[1];
+  ddc_dT_dT[2] = -1/Modelica.Constants.R/T_adsorpt^2 *
+    (2*Modelica.Constants.R*T_adsorpt + Q) * dc_dT[2];
+  ddc_dT_dT[3] = -2/T_adsorpt * dc_dT[3];
+
+  //
+  // Coefficients of isotherm model: T + dT K
+  //
+  c_pdT[1] = x_ref * exp(chi * (1 - (T_adsorpt+dT)/T_ref));
+  c_pdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt+dT) - 1));
+  c_pdT[3] = t_ref + alpha * (1 - T_ref/(T_adsorpt+dT));
+
+  //
+  // Coefficients of isotherm model: T - dT K
+  //
+  c_mdT[1] = x_ref * exp(chi * (1 - (T_adsorpt-dT)/T_ref));
+  c_mdT[2] = b_ref * exp(Q/Modelica.Constants.R/T_ref * (T_ref/(T_adsorpt-dT) - 1));
+  c_mdT[3] = t_ref + alpha * (1 - T_ref/(T_adsorpt-dT));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=100, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of all functions of the Toth isotherm models.
+<br/><br/>
+As an example, this tester increases the temperature with time. To see the behavior of
+all functions, plot the variables <i>x_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt</i>, 
+<i>dx_adsorpt_dT_adsorpt</i>, <i>dx_adsorpt_dp_adsorpt_dT_adsorpt</i>, 
+<i>dx_adsorpt_dp_adsorpt_dp_adsorpt</i>, <i>dx_adsorpt_dT_adsorpt_dT_adsorpt</i>, 
+and <i>red_spreading_pressure</i> over the variable <i>p_adsorpt</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 100 s).
+</p>
+</html>"));
+end Test_changing_temperature;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/package.mo
new file mode 100644
index 0000000..fb61ae8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/package.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Testers;
+package Toth "Models to test and varify functions of the Toth isotherm"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the Toth isotherm
+model. The test models check the implementation of the functions and enable verification 
+of the function behavior. Three test models are implemented, in which the pressure and 
+temperature change over time. In addition, the test models demonstrate the functions' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Toth;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/package.order
new file mode 100644
index 0000000..bdb9f26
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/Toth/package.order
@@ -0,0 +1,3 @@
+Test_changing_pressure
+Test_changing_temperature
+Test_changing_pressureTemperature
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/package.mo
new file mode 100644
index 0000000..424b1d7
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package Testers "This package contains test models to check and varify pure component isotherm models"
+extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented isotherm models. Each
+isotherm model has its test models saved in a separate package.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/package.order
new file mode 100644
index 0000000..db10ed0
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Testers/package.order
@@ -0,0 +1,14 @@
+Henry
+Langmuir
+BiLangmuir
+Freundlich
+Sips
+Toth
+BET
+GAB
+DubininAstakhov
+DubininLorentzianCumulative
+DubininPearsonIV
+DubininChebyshevSeriesRaionalOrder33
+DubininEmpirical1
+DubininEmpirical2
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Toth/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Toth/package.mo
new file mode 100644
index 0000000..7e34794
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Toth/package.mo
@@ -0,0 +1,304 @@
+within SorpLib.Media.Functions.SorptionEquilibria.PureComponents;
+package Toth "Package containing all functions regarding the Toth isotherm"
+extends
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents;
+
+  redeclare final function extends x_pT
+    "Toth isotherm model: Uptake as function of pressure and temperature"
+  algorithm
+    x_adsorpt := c[1] * (c[2]*p_adsorpt) / ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+      "Calculation of the equilibrium uptake of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(p_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.p_xT(x_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end x_pT;
+
+  redeclare final function extends p_xT
+    "Toth isotherm model: Pressure as function of uptake and temperature"
+  algorithm
+    p_adsorpt := x_adsorpt/c[2] * 1 / (c[1]^c[3] - x_adsorpt^c[3]) ^ (1/c[3])
+      "Calculation of the equilibrium pressure of the adsorpt phase";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+  InlineAfterIndexReduction=false,
+  LateInline=true,
+  inverse(x_adsorpt=SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT(p_adsorpt, T_adsorpt, c, p_adsorpt_lb_start, p_adsorpt_ub_start, tolerance)));
+  end p_xT;
+
+  redeclare final function extends dx_dp
+    "Toth isotherm model: Partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    dx_adsorpt_dp_adsorpt := c[1]*c[2] * ((c[2]*p_adsorpt)^c[3] + 1) ^
+      (-1/c[3] - 1)
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium pressure at constant temperature";
+  end dx_dp;
+
+  redeclare final function extends dx_dT
+    "Toth isotherm model: Partial derivative of uptake w.r.t. temperature at constant pressure"
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = c[2] * p_adsorpt /
+      ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+      "Derivative of uptake w.r.t. to first coefficient of Toth isotherm";
+    Real dx_adsorpt_dc2 = c[1] * p_adsorpt *
+      ((c[2]*p_adsorpt)^c[3] + 1) ^ (-1/c[3] - 1)
+      "Derivative of uptake w.r.t. to second coefficient of Toth isotherm";
+    Real dx_adsorpt_dc3 = c[1] * c[2] * p_adsorpt *
+      (log(1 + (c[2]*p_adsorpt)^c[3]) / c[3]^2 -
+      (c[2]*p_adsorpt)^c[3] * log(c[2]*p_adsorpt) /
+      (c[3] * (1 + (c[2]*p_adsorpt)^c[3]))) /
+      ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+      "Derivative of uptake w.r.t. to third coefficient of Toth isotherm";
+
+  algorithm
+    dx_adsorpt_dT_adsorpt :=
+      dx_adsorpt_dc1*dc_dT_adsorpt[1] +
+      dx_adsorpt_dc2*dc_dT_adsorpt[2] +
+      dx_adsorpt_dc3*dc_dT_adsorpt[3]
+      "Calculation of the partial derivative of the equilibrium uptake w.r.t. the
+     equilibrium temperature at constant pressure";
+  end dx_dT;
+
+  redeclare final function extends ddx_dp_dp
+    "Toth isotherm model: Second-order partial derivative of uptake w.r.t. pressure at constant temperature"
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dp_adsorpt := -(c[1] * c[2] * (c[3] + 1) *
+      (c[2] * p_adsorpt)^c[3]) /
+      (p_adsorpt * ((c[2] * p_adsorpt)^c[3] + 1)^((2 * c[3] + 1) / c[3]))
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium pressure at constant temperature";
+  end ddx_dp_dp;
+
+  redeclare final function extends ddx_dT_dT
+    "Toth isotherm model: Second-order partial derivative of uptake w.r.t. temperature at constant pressure"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real dx_adsorpt_dc1 = c[2] * p_adsorpt /
+      ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+      "Derivative of uptake w.r.t. to first coefficient of Toth isotherm";
+    Real dx_adsorpt_dc2 = c[1] * p_adsorpt *
+      ((c[2]*p_adsorpt)^c[3] + 1) ^ (-1/c[3] - 1)
+      "Derivative of uptake w.r.t. to second coefficient of Toth isotherm";
+    Real dx_adsorpt_dc3 = c[1] * c[2] * p_adsorpt *
+      (log(1 + (c[2]*p_adsorpt)^c[3]) / c[3]^2 -
+      (c[2]*p_adsorpt)^c[3] * log(c[2]*p_adsorpt) /
+      (c[3] * (1 + (c[2]*p_adsorpt)^c[3]))) /
+      ((1 + (c[2]*p_adsorpt)^c[3])^(1/c[3]))
+      "Derivative of uptake w.r.t. to third coefficient of Toth isotherm";
+
+    Real ddx_adsorpt_dc1_dc2 = p_adsorpt * ((p_adsorpt * c[2])^c[3] + 1) ^
+      (-1 / c[3] - 1)
+      "Second-order partial derivative of uptake w.r.t. to first and second 
+    coefficient of Toth isotherm";
+    Real ddx_adsorpt_dc1_dc3 = (c[2] * p_adsorpt * (log((c[2] * p_adsorpt)^c[3] + 1) /
+      c[3]^2 - ((c[2] * p_adsorpt)^c[3] * log(c[2] * p_adsorpt)) /
+      (((c[2] * p_adsorpt)^c[3] + 1) * c[3]))) /
+      ((c[2] * p_adsorpt)^c[3] + 1)^(1 / c[3])
+      "Second-order partial derivative of uptake w.r.t. to first and third 
+    coefficient of Toth isotherm";
+
+    Real ddx_adsorpt_dc2_dc2 = -(c[1] * (c[3] + 1) * p_adsorpt *
+      (p_adsorpt * c[2])^c[3] * ((p_adsorpt * c[2])^c[3] + 1)^(-1 / c[3] - 2)) / c[2]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Toth isotherm";
+    Real ddx_adsorpt_dc2_dc3 = c[1] * p_adsorpt * ((c[2] * p_adsorpt)^c[3] + 1) ^
+      (-1 / c[3] - 1) * (((c[2] * p_adsorpt)^c[3] * log(c[2] * p_adsorpt) *
+      (-1 / c[3] - 1)) / ((c[2] * p_adsorpt)^c[3] + 1) +
+      log((c[2] * p_adsorpt)^c[3] + 1) / c[3]^2)
+      "Second-order partial derivative of uptake w.r.t. to second and third 
+    coefficient of Toth isotherm";
+
+    Real ddx_adsorpt_dc3_dc3 = (c[1] * c[2] * p_adsorpt * (-((c[2] * p_adsorpt)^c[3] *
+      log(c[2] * p_adsorpt)^2) / (((c[2] * p_adsorpt)^c[3] + 1) * c[3]) +
+      ((c[2] * p_adsorpt)^(2 * c[3]) * log(c[2] * p_adsorpt)^2) /
+      (((c[2] * p_adsorpt)^c[3] + 1)^2 * c[3]) + (2 * (c[2] * p_adsorpt)^c[3] *
+      log(c[2] * p_adsorpt)) / (((c[2] * p_adsorpt)^c[3] + 1) * c[3]^2) -
+      (2 * log((c[2] * p_adsorpt)^c[3] + 1)) / c[3]^3)) /
+      ((c[2] * p_adsorpt)^c[3] + 1)^(1 / c[3]) + (c[1] * c[2] * p_adsorpt *
+      (log((c[2] * p_adsorpt)^c[3] + 1) / c[3]^2 - ((c[2] * p_adsorpt)^c[3] *
+      log(c[2] * p_adsorpt)) / (((c[2] * p_adsorpt)^c[3] + 1) * c[3]))^2) /
+      ((c[2] * p_adsorpt)^c[3] + 1)^(1 / c[3])
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Toth isotherm";
+
+    Real ddx_adsorpt_dc1_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc1_dc3*dc_dT_adsorpt[3]
+      "Second-order partial derivative of uptake w.r.t. to first coefficient of 
+    Toth isotherm and temperature";
+    Real ddx_adsorpt_dc2_dT_adsorpt = ddx_adsorpt_dc1_dc2*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc2*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[3]
+      "Second-order partial derivative of uptake w.r.t. to second coefficient of 
+    Toth isotherm and temperature";
+    Real ddx_adsorpt_dc3_dT_adsorpt = ddx_adsorpt_dc1_dc3*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dc2_dc3*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dc3_dc3*dc_dT_adsorpt[3]
+      "Second-order partial derivative of uptake w.r.t. to third coefficient of 
+    Toth isotherm and temperature";
+
+  algorithm
+    ddx_adsorpt_dT_adsorpt_dT_adsorpt :=
+      (ddx_adsorpt_dc1_dT_adsorpt*dc_dT_adsorpt[1] +
+       dx_adsorpt_dc1*ddc_dT_adsorpt_dT_adsorpt[1]) +
+      (ddx_adsorpt_dc2_dT_adsorpt*dc_dT_adsorpt[2] +
+       dx_adsorpt_dc2*ddc_dT_adsorpt_dT_adsorpt[2]) +
+      (ddx_adsorpt_dc3_dT_adsorpt*dc_dT_adsorpt[3] +
+       dx_adsorpt_dc3*ddc_dT_adsorpt_dT_adsorpt[3])
+      "Calculation of the second-order partial derivative of the equilibrium uptake 
+    w.r.t. the equilibrium temperature at constant pressure";
+  end ddx_dT_dT;
+
+  redeclare final function extends ddx_dp_dT
+    "Toth isotherm model: Second-order partial derivative of uptake w.r.t. pressure and temperature"
+
+    //
+    // Definition of variables
+    //
+protected
+    Real ddx_adsorpt_dp_adsorpt_dc1 = c[2] * ((c[2] * p_adsorpt)^c[3] + 1) ^
+      (-1 / c[3] - 1)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    first coefficient of Toth isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc2 = -c[1] * ((c[2] * p_adsorpt)^c[3] + 1) ^
+      (-1 / c[3] - 2) * (c[3] * (c[2] * p_adsorpt)^c[3] - 1)
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    second coefficient of Toth isotherm";
+    Real ddx_adsorpt_dp_adsorpt_dc3 = (c[1] * c[2] * ((c[2] * p_adsorpt)^c[3] + 1) ^
+      (-1 / c[3] - 2) * (((c[2] * p_adsorpt)^c[3] + 1) *
+      log((c[2] * p_adsorpt)^c[3] + 1) + (-c[3]^2 - c[3]) * (c[2] * p_adsorpt)^c[3] *
+      log(c[2] * p_adsorpt))) / c[3]^2
+      "Second-order partial derivative of uptake w.r.t. to equilibrium pressure and
+    third coefficient of Toth isotherm";
+
+  algorithm
+    ddx_adsorpt_dp_adsorpt_dT_adsorpt :=
+      ddx_adsorpt_dp_adsorpt_dc1*dc_dT_adsorpt[1] +
+      ddx_adsorpt_dp_adsorpt_dc2*dc_dT_adsorpt[2] +
+      ddx_adsorpt_dp_adsorpt_dc3*dc_dT_adsorpt[3]
+      "Calculation of the second-oder partial derivative of the equilibrium uptake 
+     w.r.t. the equilibrium pressure and temperature";
+  end ddx_dp_dT;
+
+  redeclare function pi_pT
+    "Toth isotherm model: Reduced spreading pressure as function of pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_pi_pT_num(
+        redeclare final function func_x_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.x_pT);
+  end pi_pT;
+
+  redeclare function p_piT
+    "Toth isotherm model: Pressure as function of reduced spreading pressure and temperature (numerical solution)"
+    extends
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_piT_num(
+        redeclare final function func_pi_pT =
+        SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth.pi_pT);
+  end p_piT;
+    //
+    // Annotations
+    //
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 1, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+The Toth isotherm model is a three-parameter model for calculating the  equilibrium
+uptake <i>x_adsorpt</i> as a function of the equilibrium pressure <i>p_adsorpt</i>.
+The Toth isotherm model is suitable for type I-III isotherms according to the 
+IUPAC definition.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The Toth isotherm model has the following form:
+</p>
+<pre>
+    x<sub>adsorpt</sub> = x<sub>sat</sub>(T<sub>adsorpt</sub>) * b(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub> / ((1 + (b(T<sub>adsorpt</sub>) * p<sub>adsorpt</sub>) ^ t(T<sub>adsorpt</sub>)) ^ (1/t(T<sub>adsorpt</sub>)));
+</pre>
+<p>
+where <i>x<sub>sat</sub>(T<sub>adsorpt</sub>)</i> is the saturation uptake, 
+<i>b(T<sub>adsorpt</sub>)</i> is the Toth coefficient, and <i>t(T<sub>adsorpt</sub>)</i>
+is the Toth exponent. Typical temperature dependencies may have the following forms:
+</p>
+<pre>
+    x<sub>sat</sub>(T<sub>adsorpt</sub>) =  x<sub>ref</sub> * <strong>exp</strong>(&Chi; * (1 - T<sub>adsorpt</sub>/T<sub>ref</sub>));
+</pre>
+<pre>
+    b(T<sub>adsorpt</sub>) = b<sub>ref</sub> * <strong>exp</strong>(Q/(R * T<sub>ref</sub>) * (T<sub>ref</sub>/T<sub>adsorpt</sub> - 1));
+</pre>
+<pre>
+    t(T<sub>adsorpt</sub>) = t<sub>ref</sub> + &alpha; * (1 - T<sub>ref</sub>/T<sub>adsorpt</sub>);
+</pre>
+<p>
+where <i>x<sub>ref</sub></i> is the saturation uptake at reference temperature 
+<i>T<sub>ref</sub></i>, <i>b<sub>ref</sub></i> is the Toth coefficient at reference 
+temperature, and <i>t<sub>ref</sub></i> is the Toth exponent at reference temperature. 
+The parameter <i>Q</i> is a measure for the isosteric adsorption enthalpy at a fractional
+loading of <i>x<sub>adsorpt</sub>/x<sub>sat</sub>(T<sub>adsorpt</sub>) = 0.0</i>, the 
+parameter <i>&Chi;</i> describes the change of the saturation uptake with temperature, 
+and the parameter <i>&alpha;</i> describes the change of the Toth exponent with 
+temperature. All seven parameters can be used as fitting parameters.
+<br/><br/>
+Note that the Toth exponent <i>t(T<sub>adsorpt</sub>)</i> is typically lower than
+unity. For <i>t(T<sub>adsorpt</sub>) = 1</i>, the Toth isotherm becomes the
+Langmuir isotherm. Hence, the Toth exponent <i>t(T<sub>adsorpt</sub>)</i> can be
+interpreted as a parameter describing the heterogeneity of the adsorption system.
+</p>
+
+<h4>Required parameter order in function input c[:]:</h4>
+<ul>
+  <li>
+  c[1] = x<sub>sat</sub>(T<sub>adsorpt</sub>) in kg/kg
+  </li>
+  <li>
+  c[2] = b(T<sub>adsorpt</sub>) in 1/Pa
+  </li>
+  <li>
+  c[3] = t(T<sub>adsorpt</sub>) in -
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+The isotherm model is used for type I-III isotherms according to the IUPAC definition.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the Toth isotherm model for different parameter sets.
+In the upper sub-figure, the equilibrium pressure changes with time, while the 
+equilibrium temperature remains constant; in the lower sub-figure, the equilibrium 
+temperature changes with time, while the equilibrium pressure remains constant. 
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/media_functions_equilibria_pure_toth.png\" alt=\"media_functions_equilibria_pure_toth.png\">
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>"));
+end Toth;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Toth/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Toth/package.order
new file mode 100644
index 0000000..5b33869
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/Toth/package.order
@@ -0,0 +1,9 @@
+x_pT
+p_xT
+dx_dp
+dx_dT
+ddx_dp_dp
+ddx_dT_dT
+ddx_dp_dT
+pi_pT
+p_piT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/package.mo
new file mode 100644
index 0000000..932ae38
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/package.mo
@@ -0,0 +1,95 @@
+within SorpLib.Media.Functions.SorptionEquilibria;
+package PureComponents "Functions required to calculate sorption equlibria for pure components"
+extends Modelica.Icons.VariantsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains isotherm models for pure component adsorption. Each isotherm 
+model is stored as a separate package. There are also test models for each isotherm 
+model, which test all functions of the isotherm models regarding their implementation. 
+The isotherm models already implemented can be found in the package content. 
+</p>
+
+<h4>Implemented functions for each isotherm model</h4>
+<p>
+The following functions are provided for each isotherm model:
+</p>
+<ul>
+  <li>
+  Equilibrium uptake as function of equilibrium pressure and eqiulibrium temperature.
+  </li>
+  <li>
+  Equilibrium pressure as function of equilibrium uptake and eqiulibrium temperature.
+  </li>
+  <li>
+  Partial derivative of equilibrium uptake w.r.t. equilibrium pressure at constant
+  pressure.
+  </li>
+  <li>
+  Partial derivative of equilibrium uptake w.r.t. equilibrium temperature at constant
+  pressure.
+  </li>
+  <li>
+  Second-order partial derivative of equilibrium uptake w.r.t. equilibrium pressure at
+  constant temperature.
+  </li>
+  <li>
+  Second-order partial derivative of equilibrium uptake w.r.t. equilibrium temperature
+  at constant pressure.
+  </li>
+  <li>
+  Second-order partial derivative of equilibrium uptake w.r.t. equilibrium pressure and
+  temperature.
+  </li>
+  <li>
+  Reduced spreading pressure as function of equilibrium pressure and eqiulibrium 
+  temperature.
+  </li>
+  <li>
+  Equilibrium pressure as function of reduced spreading pressure and eqiulibrium 
+  temperature.
+  </li>
+</ul>
+<p>
+The following additional functions are provided for isotherm models based on the model
+of Dubinin:
+</p>
+<ul>
+  <li>
+  Filled pore volume as function of adsorption potential.
+  </li>
+  <li>
+  Adsorption potential as function of filled pore volume.
+  </li>
+  <li>
+  Partial derivative of filled pore volume w.r.t. adsorption potential at constant pressure
+  and temperature.
+  </li>
+  <li>
+  Second-order partial derivative of filled pore volume w.r.t. adsorption potential at
+  constant pressure and temperature.
+  </li>
+  <li>
+  Second-order partial derivative of filled pore volume w.r.t. adsorption potential and
+  temperature at constant pressure.
+  </li>
+</ul>
+
+<h4>How to add new isotherm models</h4>
+<p>
+To add a new isotherm model, duplicate the package of a similar isotherm model that is 
+already implemented. Then, customise all functions of the isotherm model. If new 
+functions are implemented (e.g., equilibrium temperature as function of equilibrium 
+pressure and uptake), add these for all existing isotherm models as well. Then, adapt 
+the test models and check the functions of the new isotherm model regarding their 
+implementation. Finally, write the documentation for each function, model, and package.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end PureComponents;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/package.order b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/package.order
new file mode 100644
index 0000000..e772968
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/PureComponents/package.order
@@ -0,0 +1,15 @@
+Henry
+Langmuir
+BiLangmuir
+Freundlich
+Sips
+Toth
+BET
+GAB
+DubininAstakhov
+DubininLorentzianCumulative
+DubininPearsonIV
+DubininChebyshevSeriesRaionalOrder33
+DubininEmpirical1
+DubininEmpirical2
+Testers
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Records/NumericsIAST.mo b/SorpLib/Media/Functions/SorptionEquilibria/Records/NumericsIAST.mo
new file mode 100644
index 0000000..40c8468
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Records/NumericsIAST.mo
@@ -0,0 +1,72 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Records;
+record NumericsIAST
+  "This record contains entries defining the numerics of IAST algorithms"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of paramters
+  //
+  parameter SorpLib.Choices.IASTAlgorithm IASTAlgorithm=SorpLib.Choices.IASTAlgorithm.NewtonRaphson
+    "Algorithm used to solve the IAST"
+    annotation (Dialog(tab="General", group="Basic setup"));
+
+  parameter Integer no_max = 250
+    "Maximal number of iterations"
+    annotation (Dialog(tab="General", group="Newton-Raphson and Fast IAST",
+                enable=IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST
+           or IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson));
+  parameter Real tolerance = 1e-10
+    "Tolereance for loop"
+    annotation (Dialog(tab="General", group="Newton-Raphson and Fast IAST",
+                enable=IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST
+           or IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NewtonRaphson));
+
+  parameter Integer no_max_inner = 25
+    "Maximal number of iterations for inner loop"
+    annotation (Dialog(tab="General", group="Nested Loop - Inner loop",
+                enable=IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop));
+  parameter Real tolerance_inner = 1e-10
+    "Tolerance for inner loop"
+    annotation (Dialog(tab="General", group="Nested Loop - Inner loop",
+                enable=IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop));
+
+  parameter Integer no_max_outer = 25
+    "Maximal number of iterations for outer loop"
+    annotation (Dialog(tab="General", group="Nested Loop - Outer loop",
+                enable=IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop));
+  parameter Real tolerance_outer = 1e-10
+    "Tolerance for outer loop"
+    annotation (Dialog(tab="General", group="Nested Loop - Outer loop",
+                enable=IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.NestedLoop));
+
+  parameter Integer no_max_inv = 250
+    "Maximal number of iterations"
+    annotation (Dialog(tab="General", group="Inverses of IAST"));
+  parameter Real tolerance_inv = 1e-10
+    "Tolereance for loop"
+    annotation (Dialog(tab="General", group="Inverses of IAST"));
+
+  parameter Modelica.Units.SI.Pressure p_K_0 = 1e-6
+    "Pressure used to estimated Henry constants"
+    annotation (Dialog(tab="General", group="Initial values"));
+  parameter Modelica.Units.SI.Pressure p_sat_0 = 1e15
+    "Pressure used to estimated saturation uptake"
+    annotation (Dialog(tab="General", group="Initial values",
+                enable=IASTAlgorithm == SorpLib.Choices.IASTAlgorithm.FastIAST));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains entries defining the numerics of IAST algorithms.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end NumericsIAST;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Records/NumericsIAST_PureComponents.mo b/SorpLib/Media/Functions/SorptionEquilibria/Records/NumericsIAST_PureComponents.mo
new file mode 100644
index 0000000..424a9a7
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Records/NumericsIAST_PureComponents.mo
@@ -0,0 +1,47 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Records;
+record NumericsIAST_PureComponents
+  "This record contains entries defining the numerics of pure component isotherm models used within IAST algorithms"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of paramters
+  //
+  parameter Modelica.Units.SI.Pressure p_adsorpt_lb_start = 1
+    "Lower bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Equilibrium pressure"));
+  parameter Modelica.Units.SI.Pressure p_adsorpt_ub_start = 10
+    "Upper bound of equilibrium pressure (required if pressure is calculated 
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Equilibrium pressure"));
+  parameter Real tolerance_p_adsorpt = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (required if pressure is calculated
+    numerically (i.e., root finding))"
+    annotation (Dialog(tab="General", group="Equilibrium pressure"));
+
+  parameter Modelica.Units.SI.Pressure integral_pi_lb = 0
+    "Lower limit of integral when calculating the reduced spreading pressure
+    numerically (should be 0)"
+    annotation (Dialog(tab="General", group="Reduced spreading pressure"));
+  parameter Real tolerance_pi = 100*Modelica.Constants.eps
+    "Tolerance for numerical calculation (required if reduced spreading pressure
+    is calculated numerically (i.e., integral))"
+    annotation (Dialog(tab="General", group="Reduced spreading pressure"));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains entries defining the numerics of pure component isotherm 
+models used within IAST algorithms.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 10, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end NumericsIAST_PureComponents;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Records/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/Records/package.mo
new file mode 100644
index 0000000..c5cab90
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Records/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions.SorptionEquilibria;
+package Records "Package containing records used as function inputs"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records that are used as function inputs. 
+Using records reduces the number of function inputs. In addition, the functions 
+are easier to expand if the function prototype needs to remain unchanged, as only 
+more entries need to be added to the data set if necessary.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Records/package.order b/SorpLib/Media/Functions/SorptionEquilibria/Records/package.order
new file mode 100644
index 0000000..6f3376e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Records/package.order
@@ -0,0 +1,2 @@
+NumericsIAST
+NumericsIAST_PureComponents
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/A_ppsT.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/A_ppsT.mo
new file mode 100644
index 0000000..06040b4
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/A_ppsT.mo
@@ -0,0 +1,73 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities;
+function A_ppsT "Calculates the molar adsorption potential"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure at the equilibrium temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.MolarAdsorptionPotential A "Molar adsorption potential"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+algorithm
+  A := Modelica.Constants.R * T_adsorpt * log(p_sat/p_adsorpt)
+    "Molar adsorption potential";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+inverse(p_adsorpt=p_ApsT(A,p_sat,T_adsorpt)),
+Documentation(info="<html>
+<p>
+This function calculates the molar adsorption potential <i>A</i>. The molar adsorption
+potential <i>A</i> is an important quantity for isotherm models following the model
+of Dubinin.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption potential <i>A</i> is defined as follows:
+</p>
+<pre>
+    A(T<sub>adsorpt</sub>) = R * T<sub>adsorpt</sub> * <strong>ln</strong>(p<sub>sat</sub>(T<sub>adsorpt</sub>) / p<sub>adsorpt</sub>);
+</pre>
+
+<h4>Typical use</h4>
+<p>
+The molar adsorption potential <i>A</i> is used to calculate the characteristic
+curve of isotherm models following the model of Dubinin.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end A_ppsT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/Test_A_ppsT.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/Test_A_ppsT.mo
new file mode 100644
index 0000000..b0ab14f
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/Test_A_ppsT.mo
@@ -0,0 +1,308 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities.Testers;
+model Test_A_ppsT
+  "Tester for the function 'calc_A_ppsT' and all corresponding functions"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="General", group="Numerical parameters"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="General", group="Numerical parameters"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt(start=100, fixed=true)
+    "Equilibrium pressure";
+  Modelica.Units.SI.Temperature T_adsorpt(start=278.15, fixed=true)
+    "Equilibrium temperature";
+
+  Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure at equilibrium temperature";
+  Modelica.Units.SI.DerPressureByTemperature dp_sat_dT
+    "Partial derivative of saturation pressure w.r.t. equilibrium temperature";
+  Real ddp_sat_dT_dT(unit="Pa/K2")
+    "Second-order partial derivative of saturation pressure w.r.t. equilibrium 
+    temperature";
+
+  SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential";
+
+  Modelica.Units.SI.Pressure p_adsorpt_inv
+   "Equilibrium pressure calculated via inverse function of the molar adsorption 
+    potential";
+
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt
+    "Partial derivative of the molar adsorption potential w.r.t. pressure at 
+    constant temperature";
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt_num
+    "Partial derivative of the molar adsorption potential w.r.t. pressure at 
+    constant temperature calculated numerically";
+
+  SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt
+    "Partial derivative of the molar adsorption potential w.r.t. temperature at 
+    constant pressure";
+  SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt_num
+    "Partial derivative of the molar adsorption potential w.r.t. temperature at 
+    constant pressure calculated numerically";
+
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressurePressure ddA_dp_adsorpt_dp_adsorpt
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure at constant temperature";
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressurePressure ddA_dp_adsorpt_dp_adsorpt_num
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure at constant temperature calculated numerically";
+
+  SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    temperature at constant pressure";
+  SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt_num
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    temperature at constant pressure calculated numerically";
+
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure and temperature";
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt_num
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure and temperature calculated numerically";
+
+protected
+  Modelica.Units.SI.Pressure p_sat_pdT
+    "Saturation pressure at equilibrium temperature: T + 1e-6 K";
+  Modelica.Units.SI.Pressure p_sat_mdT
+    "Saturation pressure at equilibrium temperature: T - 1e-6 K";
+
+  Modelica.Units.SI.DerPressureByTemperature dp_sat_dT_pdT
+    "Partial derivative of saturation pressure w.r.t. equilibrium temperature: 
+    T + 1e-6 K";
+  Modelica.Units.SI.DerPressureByTemperature dp_sat_dT_mdT
+    "Partial derivative of saturation pressure w.r.t. equilibrium temperature: 
+    T - 1e-6 K";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 500
+    "Predecsriped slope of p_adsorpt";
+  der(T_adsorpt) = 95/20
+    "Predecsriped slope of T_adsorpt";
+
+  //
+  // Calculation of properties
+  //
+  p_sat= Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt)
+    "Saturation pressure at equilibrium temperature";
+  dp_sat_dT= Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt)
+    "Partial derivative of saturation pressure w.r.t. equilibrium temperature";
+  ddp_sat_dT_dT=
+    (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt + dT) -
+    Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt - dT)) /
+    (2*dT)
+    "Second-order partial derivative of saturation pressure w.r.t. equilibrium 
+    temperature";
+
+  p_adsorpt_inv= SorpLib.Media.Functions.SorptionEquilibria.Utilities.p_ApsT(
+    A=A,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt)
+    "Equilibrium pressure calculated via inverse function of the molar adsorption 
+    potential";
+
+  A= SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt)
+    "Molar adsorption potential";
+
+  //
+  // Calculation of derivatives
+  //
+  dA_dp_adsorpt=
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt)
+    "Partial derivative of the molar adsorption potential w.r.t. pressure at 
+    constant temperature";
+
+  dA_dT_adsorpt=
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt,
+    dp_sat_dT_adsorpt=dp_sat_dT)
+    "Partial derivative of the molar adsorption potential w.r.t. temperature at 
+    constant pressure";
+
+  ddA_dp_adsorpt_dp_adsorpt=
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dp(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt)
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure at constant temperature";
+  ddA_dT_adsorpt_dT_adsorpt=
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dT_dT(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt,
+    dp_sat_dT_adsorpt=dp_sat_dT,
+    ddp_sat_dT_adsorpt_dT_adsorpt=ddp_sat_dT_dT)
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    temperature at constant pressure";
+  ddA_dp_adsorpt_dT_adsorpt=
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.ddA_dp_dT(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt)
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure and temperature";
+
+  //
+  // Calculation of numerical derivatives
+  //
+  p_sat_pdT= Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt+dT)
+    "Saturation pressure at equilibrium temperature: T + 1e-6 K";
+  p_sat_mdT= Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T=T_adsorpt-dT)
+    "Saturation pressure at equilibrium temperature: T - 1e-6 K";
+
+  dp_sat_dT_pdT= Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt+dT)
+    "Partial derivative of saturation pressure w.r.t. equilibrium temperature: 
+    T + 1e-6 K";
+  dp_sat_dT_mdT= Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T=T_adsorpt-dT)
+    "Partial derivative of saturation pressure w.r.t. equilibrium temperature: 
+    T - 1e-6 K";
+
+  dA_dp_adsorpt_num=(
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt + dp,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt) -
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt - dp,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt))/(2*dp)
+    "Partial derivative of the molar adsorption potential w.r.t. pressure at 
+    constant temperature calculated numerically";
+  dA_dT_adsorpt_num=(
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat_pdT,
+    T_adsorpt=T_adsorpt + dT) -
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat_mdT,
+    T_adsorpt=T_adsorpt - dT))/(2*dT)
+    "Partial derivative of the molar adsorption potential w.r.t. temperature at 
+    constant pressure calculated numerically";
+
+  ddA_dp_adsorpt_dp_adsorpt_num=(
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+    p_adsorpt=p_adsorpt + dp,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt) -
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+    p_adsorpt=p_adsorpt - dp,
+    p_sat=p_sat,
+    T_adsorpt=T_adsorpt))/(2*dp)
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure at constant temperature calculated numerically";
+  ddA_dT_adsorpt_dT_adsorpt_num=(
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat_pdT,
+    T_adsorpt=T_adsorpt + dT,
+    dp_sat_dT_adsorpt=dp_sat_dT_pdT) -
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat_mdT,
+    T_adsorpt=T_adsorpt - dT,
+    dp_sat_dT_adsorpt=dp_sat_dT_mdT))/(2*dT)
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    temperature at constant pressure calculated numerically";
+  ddA_dp_adsorpt_dT_adsorpt_num=(
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat_pdT,
+    T_adsorpt=T_adsorpt + dT) -
+    SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+    p_adsorpt=p_adsorpt,
+    p_sat=p_sat_mdT,
+    T_adsorpt=T_adsorpt - dT))/(2*dT)
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure and temperature calculated numerically";
+
+  //
+  // Definition of assertions: Check numerical implementation of isotherm model
+  //
+  assert(abs(p_adsorpt-p_adsorpt_inv) < 1e-6,
+    "Inverse function of molar adsorption potential is not valid: Deviation (|" +
+    String(abs(p_adsorpt-p_adsorpt_inv)) +
+    "|) is greater than 1e-6 Pa!",
+    level = AssertionLevel.warning);
+  assert(abs(dA_dp_adsorpt-dA_dp_adsorpt_num) < 1e-6,
+    "Partial derivative of molar adsorption potential w.r.t. pressure at " +
+    "constant temperature is not valid: Deviation (|" +
+    String(abs(dA_dp_adsorpt-dA_dp_adsorpt_num)) +
+    "|) is greater than 1e-6 J/mol/Pa!",
+    level = AssertionLevel.warning);
+  assert(abs(dA_dT_adsorpt-dA_dT_adsorpt_num) < 1e-6,
+    "Partial derivative of molar adsorption potential w.r.t. temperature at " +
+    "constant pressure is not valid: Deviation (|" +
+    String(abs(dA_dT_adsorpt-dA_dT_adsorpt_num)) +
+    "|) is greater than 1e-6 J/mol/K!",
+    level = AssertionLevel.warning);
+  assert(abs(ddA_dp_adsorpt_dp_adsorpt-ddA_dp_adsorpt_dp_adsorpt_num) < 1e-6,
+    "Second-order partial derivative of molar adsorption potential w.r.t. " +
+    "pressure at constant temperature is not valid: Deviation (|" +
+    String(abs(ddA_dp_adsorpt_dp_adsorpt-ddA_dp_adsorpt_dp_adsorpt_num)) +
+    "|) is greater than 1e-6 J/mol/Pa!",
+    level = AssertionLevel.warning);
+  assert(abs(ddA_dT_adsorpt_dT_adsorpt-ddA_dT_adsorpt_dT_adsorpt_num) < 1e-6,
+    "Second-order partial derivative of molar adsorption potential w.r.t. " +
+    "temperature at constant pressure is not valid: Deviation (|" +
+    String(abs(ddA_dT_adsorpt_dT_adsorpt-ddA_dT_adsorpt_dT_adsorpt_num)) +
+    "|) is greater than 1e-6 J/mol/K2!",
+    level = AssertionLevel.warning);
+  assert(abs(ddA_dp_adsorpt_dT_adsorpt-ddA_dp_adsorpt_dT_adsorpt_num) < 1e-6,
+    "Second-order partial derivative of molar adsorption potential w.r.t. " +
+    "pressure and temperature is not valid: Deviation (|" +
+    String(abs(ddA_dp_adsorpt_dT_adsorpt-ddA_dp_adsorpt_dT_adsorpt_num)) +
+    "|) is greater than 1e-6 J/mol/Pa/K!",
+    level = AssertionLevel.warning);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-08),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'calc_A_ppsT' function and its corresponding
+functions, such as inverse functions of partial derivatives.
+<br/><br/>
+To see the function behavior, plot the variable <i>A</i>, <i>dA_dp_adsorpt</i>, 
+<i>dA_dT_adsorpt</i>, <i>ddA_dp_adsorpt_dp_adsorpt</i>, <i>ddA_dT_adsorpt_dT_adsorpt</i>, 
+and <i>ddA_dp_adsorpt_dT_adsorpt</i> over the time. The simulation time is correctly 
+preset (Start: 0 s, Stop = 20 s).  
+</p>
+</html>"));
+end Test_A_ppsT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/package.mo
new file mode 100644
index 0000000..34d508e
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities;
+package Testers "Models to test and/or varify utility functions or models"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions and models of the
+'Utilities' package. The test models check the implementation of the functions and
+models and enable verification of their behavior. In addition, the test models 
+demonstrate the functions' and models' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/package.order b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/package.order
new file mode 100644
index 0000000..c528107
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/Testers/package.order
@@ -0,0 +1 @@
+Test_A_ppsT
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/dA_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/dA_dT.mo
new file mode 100644
index 0000000..4d82458
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/dA_dT.mo
@@ -0,0 +1,61 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities;
+function dA_dT
+  "Calculates the partial derivative of molar adsorption potential w.r.t. equilibrium temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure at the equilibrium temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dp_sat_dT_adsorpt(unit="Pa/K")
+    "Partial derivative of saturation pressure at the equilibrium temperature 
+    w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT_adsorpt
+    "Partial derivative of the molar adsorption potential w.r.t. equilibrium 
+    temperature at constant pressure"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+algorithm
+  dA_dT_adsorpt := Modelica.Constants.R * (
+    log(p_sat / p_adsorpt) +
+    T_adsorpt / p_sat * dp_sat_dT_adsorpt)
+    "Partial derivative of the molar adsorption potential w.r.t. equilibrium 
+    temperature at constant pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the molar adsorption potential 
+with respect to the equilibrium temperature <i>dA_dT_adsorpt</i> at constant pressure.
+For more information about the molar adsorption potential <i>A</i>, check the 
+documentation of the function
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT\">SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end dA_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/dA_dp.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/dA_dp.mo
new file mode 100644
index 0000000..1e322f1
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/dA_dp.mo
@@ -0,0 +1,55 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities;
+function dA_dp
+  "Calculates the partial derivative of molar adsorption potential w.r.t. equilibrium pressure at constant temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure at the equilibrium temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp_adsorpt
+    "Partial derivative of the molar adsorption potential w.r.t. equilibrium 
+    pressure at constant temperature"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+algorithm
+  dA_dp_adsorpt := -Modelica.Constants.R * T_adsorpt / p_adsorpt
+    "Partial derivative of the molar adsorption potential w.r.t. equilibrium 
+    pressure at constant temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the molar adsorption potential 
+with respect to the equilibrium pressure <i>dA_dp_adsorpt</i> at constant temperature.
+For more information about the molar adsorption potential <i>A</i>, check the 
+documentation of the function
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT\">SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end dA_dp;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dT_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dT_dT.mo
new file mode 100644
index 0000000..93a16d8
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dT_dT.mo
@@ -0,0 +1,67 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities;
+function ddA_dT_dT
+  "Calculates the second-order partial derivative of molar adsorption potential w.r.t. equilibrium temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure at the equilibrium temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dp_sat_dT_adsorpt(unit="Pa/K")
+    "Partial derivative of saturation pressure at the equilibrium temperature 
+    w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ddp_sat_dT_adsorpt_dT_adsorpt(unit="Pa/K2")
+    "Second-order partial derivative of saturation pressure at the equilibrium 
+    temperature w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerMolarAdsorptionPotentialByTemperatureTemperature ddA_dT_adsorpt_dT_adsorpt
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    equilibrium temperature at constant pressure"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+algorithm
+  ddA_dT_adsorpt_dT_adsorpt := Modelica.Constants.R * (
+    1 / p_sat * dp_sat_dT_adsorpt +
+    (1 / p_sat * dp_sat_dT_adsorpt -
+    T_adsorpt / p_sat^2 * dp_sat_dT_adsorpt^2 +
+    T_adsorpt / p_sat * ddp_sat_dT_adsorpt_dT_adsorpt))
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    equilibrium temperature at constant pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the second-order partial derivative of the molar adsorption 
+potential with respect to the equilibrium temperature <i>ddA_dT_adsorpt_dT_adsorpt</i> 
+at constant pressure. For more information about the molar adsorption potential 
+<i>A</i>, check the documentation of the function
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT\">SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddA_dT_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dp_dT.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dp_dT.mo
new file mode 100644
index 0000000..7927936
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dp_dT.mo
@@ -0,0 +1,55 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities;
+function ddA_dp_dT
+  "Calculates the second-order partial derivative of molar adsorption potential w.r.t. equilibrium pressure and temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure at the equilibrium temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerMolarAdsorptionPotentialByPressureTemperature ddA_dp_adsorpt_dT_adsorpt
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    equilibrium pressure and temperature"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+algorithm
+  ddA_dp_adsorpt_dT_adsorpt := -Modelica.Constants.R / p_adsorpt
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    equilibrium pressure and temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the second-prder partial derivative of the molar adsorption 
+potential with respect to the equilibrium pressure and temperature 
+<i>ddA_dp_adsorpt_dT_adsorpt</i>. For more information about the molar adsorption 
+potential <i>A</i>, check the documentation of the function
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT\">SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddA_dp_dT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dp_dp.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dp_dp.mo
new file mode 100644
index 0000000..43def63
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/ddA_dp_dp.mo
@@ -0,0 +1,56 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities;
+function ddA_dp_dp
+  "Calculates the second-order partial derivative of molar adsorption potential w.r.t. equilibrium pressure at constant temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure at the equilibrium temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressurePressure dA_dp_adsorpt
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    equilibrium pressure at constant temperature"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+algorithm
+  dA_dp_adsorpt := Modelica.Constants.R * T_adsorpt / p_adsorpt^2
+    "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    equilibrium pressure at constant temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the second-orderpartial derivative of the molar adsorption 
+potential with respect to the equilibrium pressure <i>ddA_dp_adsorpt_dp_adsorpt</i> 
+at constant temperature. For more information about the molar adsorption potential 
+<i>A</i>, check the documentation of the function
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT\">SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddA_dp_dp;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/p_ApsT.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/p_ApsT.mo
new file mode 100644
index 0000000..7531987
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/p_ApsT.mo
@@ -0,0 +1,65 @@
+within SorpLib.Media.Functions.SorptionEquilibria.Utilities;
+function p_ApsT
+  "Calculates the inverse of the molar adsorption potential"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.MolarAdsorptionPotential A "Molar adsorption potential"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure at the equilibrium temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure of the adsorpt phase"
+    annotation (Dialog(tab="General", group="Outputs",
+                enable=false));
+
+algorithm
+  p_adsorpt := p_sat / exp(A / (Modelica.Constants.R * T_adsorpt))
+    "Equilibrium pressure of the adsorpt phase";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+inverse(A=A_ppsT(p_adsorpt,p_sat,T_adsorpt)),
+Documentation(info="<html>
+<p>
+This function calculates the equilibrium pressure <i>p<sub>adsorpt</sub></i> for
+a given molar adsorption potential <i>A</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The equilibrium pressure <i>p<sub>adsorpt</sub></i> is defined as follows:
+</p>
+<pre>
+    p<sub>adsorpt</sub> = p<sub>sat</sub> * <strong>exp</strong>(-A / (R * T<sub>adsorpt</sub>));
+</pre>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Do, D. D. (1998). Adsorption Analysis: Equilibria and Kinetics, 1st Edition, ISBN 978-1-86094-130-6, Imperial College Press.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 2, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end p_ApsT;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/package.mo
new file mode 100644
index 0000000..bc3bd70
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SorptionEquilibria;
+package Utilities "Package containing utility functions and models for calculating sorption equilibria"
+extends Modelica.Icons.UtilitiesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains utility functions and models required to calculate sorption
+equilibria of pure component or multicomponent adsorption.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Utilities;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/Utilities/package.order b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/package.order
new file mode 100644
index 0000000..d798135
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/Utilities/package.order
@@ -0,0 +1,8 @@
+A_ppsT
+p_ApsT
+dA_dp
+dA_dT
+ddA_dp_dp
+ddA_dT_dT
+ddA_dp_dT
+Testers
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/package.mo b/SorpLib/Media/Functions/SorptionEquilibria/package.mo
new file mode 100644
index 0000000..4d9634c
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions;
+package SorptionEquilibria "Functions required to calculate sorption equilibria"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains isotherm models for pure component and multi-component 
+adsorption. Please check the documentation of the individual packages for more 
+details on the implemented isotherm models and functions provided for each
+isotherm model.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end SorptionEquilibria;
diff --git a/SorpLib/Media/Functions/SorptionEquilibria/package.order b/SorpLib/Media/Functions/SorptionEquilibria/package.order
new file mode 100644
index 0000000..89e2f43
--- /dev/null
+++ b/SorpLib/Media/Functions/SorptionEquilibria/package.order
@@ -0,0 +1,6 @@
+BaseClasses
+Interfaces
+Records
+PureComponents
+MultiComponents
+Utilities
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPureIntegrad_cp.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPureIntegrad_cp.mo
new file mode 100644
index 0000000..0c5fe50
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPureIntegrad_cp.mo
@@ -0,0 +1,77 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses;
+partial function PartialPureIntegrad_cp
+  "Base function for integrand-based functions calculating the specific heat capacities of adsorpt phases for pure components"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPure_cp;
+  input SorpLib.Units.Uptake x_adsorpt
+    "Uptake"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input Real dc_dT[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+  input Real ddc_dT_dT[:]
+    "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT
+    "Pressure as function of uptake and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dT func_dx_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dp func_ddx_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dT_dT func_ddx_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at constant 
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dT func_ddx_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the
+specific heat capacities of the adsorpt phase for pure components. These function
+use integrals and, thus, integrad functions to calculate the specific heat 
+capacity.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureIntegrad_cp;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPureIntegrand.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPureIntegrand.mo
new file mode 100644
index 0000000..bb41a7e
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPureIntegrand.mo
@@ -0,0 +1,96 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses;
+partial function PartialPureIntegrand
+  "Base function for integrand functions for pure components"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ddc_dT_dT[:]
+    "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT func_p_xT
+    "Pressure as function of uptake and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp func_dx_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dT func_dx_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dp func_ddx_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dT_dT func_ddx_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at constant 
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dT func_ddx_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for integrand functions that may be
+required to calculate specific heat capacities of the adsorpt phase for pure 
+components.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureIntegrand;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPure_cp.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPure_cp.mo
new file mode 100644
index 0000000..77d8d08
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialPure_cp.mo
@@ -0,0 +1,42 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses;
+partial function PartialPure_cp
+  "Base function for functions calculating the specific heat capacities of adsorpt phases for pure components"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt
+    "Specific heat capacitiy of adsorpt"
+  annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the
+specific heat capacities of the adsorpt phase for pure components.
+<br/><br/>
+This partial function defines the temperature <i>T_adsorpt</i> as input and the
+specific heat capacity <i>cp_adsorpt</i> as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPure_cp;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialTestPure.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialTestPure.mo
new file mode 100644
index 0000000..ceb1764
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/PartialTestPure.mo
@@ -0,0 +1,173 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses;
+partial model PartialTestPure
+  "Base model for testers of specific heat capacity models of the adsorpt phase describing pure component adsorption"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_ph
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Medium"),
+                choicesAllMatching = true);
+
+  parameter Integer no_coefficients = 6
+    "Number of coefficients of selected isotherm model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Pressure p_adsorpt_start = 700
+    "Start value of equilibrium pressure"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_start = 278.15
+    "Start value of equilibrium temperature"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.MolarMass M_adsorptive = 0.018
+    "Molar mass of adsorptive"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used to calculated partial derivatives numerically"
+    annotation (Dialog(tab="General",group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculated partial derivatives numerically"
+    annotation (Dialog(tab="General",group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Units.Uptake dx = 1e-3
+    "Uptake difference used to calculated partial derivatives numerically"
+    annotation (Dialog(tab="General",group="Numerics"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt(start=p_adsorpt_start, fixed=true)
+    "Pressure";
+  Modelica.Units.SI.Temperature T_adsorpt(start=T_adsorpt_start, fixed=true)
+    "Temperature";
+  SorpLib.Units.Uptake x_adsorpt
+    "Uptake";
+
+  Medium.ThermodynamicState state_adsorptive_pT
+    "State properties of adsorptive at p_adsorpt and T_adsorpt";
+  Medium.ThermodynamicState state_bubble_T
+    "State properties of bubble point at T_adsorpt";
+  Medium.ThermodynamicState state_dew_T
+    "State properties of dew point at T_adsorpt";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp_adsorptive
+    "Specific heat capacitiy of adsorptive";
+  Modelica.Units.SI.SpecificHeatCapacity cp_sat_bubble
+    "Specific heat capacitiy at saturated bubble line at T_adsorpt";
+  Modelica.Units.SI.SpecificHeatCapacity cp_sat_dew
+    "Specific heat capacitiy at saturated dew line at T_adsorpt";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt
+    "Specific heat capacitiy of adsorpt";
+  Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt_CC
+    "Specific heat capacitiy of adsorpt calculated using molar adsorption enthalpy
+    according to Clausius Clapeyron";
+  Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt_Dubinin
+    "Specific heat capacitiy of adsorptive using molar adsorption enthalpy
+    according to Dubinin model";
+
+protected
+  Real c[no_coefficients]
+    "Coefficients of the isotherm model";
+  Real c_pdT[no_coefficients]
+    "Coefficients of the isotherm model: T + dT";
+  Real c_mdT[no_coefficients]
+    "Coefficients of the isotherm model: T - dT";
+
+  Real dc_dT[no_coefficients]
+    "Partial derivative of coefficients of the isotherm model w.r.t. temperature";
+  Real dc_dT_pdT[no_coefficients]
+    "Partial derivative of coefficients of the isotherm model w.r.t. temperature:
+    T + dT";
+  Real dc_dT_mdT[no_coefficients]
+    "Partial derivative of coefficients of the isotherm model w.r.t. temperature:
+    T - dT";
+
+  Real ddc_dT_dT[no_coefficients]
+    "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature";
+
+  Medium.SaturationProperties sat_T
+    "Saturated state properties at T_adsorpt";
+  Medium.SaturationProperties sat_T_pdT
+    "Saturated state properties at T_adsorpt: T + dT";
+  Medium.SaturationProperties sat_T_mdT
+    "Saturated state properties at T_adsorpt: T - dT";
+
+equation
+  //
+  // Calculation of state properties
+  //
+  sat_T = Medium.setSat_T(T=T_adsorpt)
+    "Saturated state properties at T_adsorpt";
+  sat_T_pdT = Medium.setSat_T(T=T_adsorpt+dT)
+    "Saturated state properties at T_adsorpt: T + dT";
+  sat_T_mdT = Medium.setSat_T(T=T_adsorpt-dT)
+    "Saturated state properties at T_adsorpt: T - dT";
+
+  state_adsorptive_pT = Medium.setState_pTX(
+    p=p_adsorpt,
+    T=T_adsorpt)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt";
+
+  state_bubble_T = Medium.setBubbleState(sat=sat_T)
+    "State properties of bubble point at T_adsorpt";
+  state_dew_T = Medium.setDewState(sat=sat_T)
+    "State properties of dew point at T_adsorpt";
+
+  //
+  // Calculate properties
+  //
+  cp_adsorptive = Medium.specificHeatCapacityCp(state=state_adsorptive_pT)
+    "Specific heat capacitiy of adsorptive";
+  cp_sat_bubble = Medium.specificHeatCapacityCp(state=state_bubble_T)
+    "Specific heat capacitiy at saturated bubble line at T_adsorpt";
+  cp_sat_dew = Medium.specificHeatCapacityCp(state=state_dew_T)
+    "Specific heat capacitiy at saturated dew line at T_adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (
+    Icon(coordinateSystem(preserveAspectRatio=false)),
+    Diagram(coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the basic model for all testers of specific heat capacities
+of the adsorpt phase for pure components. This partial model defines all some 
+relevant parameters and variables that are required for most specific heat capacity
+models.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the 
+<i>medium</i> and test setup. Besides, the coefficients of the isotherm model 
+(i.e., <i>c</i>, <i>c_pdT</i>, and <i>c_mdT</i>) and their partial derivatives 
+with respect to temperature (i.e., <i>dc_dT</i>, <i>dc_dT_pdT</i>, <i>dc_dT_mdT</i>, 
+and <i>ddc_dT_dT</i>) have to be implemented. Additionally, equations for the
+following variables must be implemted: <i>p_adsorpt</i>, <i>T_adsorpt</i>, 
+<i>x_adsorpt</i>, <i>cp_adsorpt</i>, <i>cp_adsorpt_CC</i>, and <i>cp_adsorpt_Dubinin</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialTestPure;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/package.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/package.mo
new file mode 100644
index 0000000..99f2c02
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt;
+package BasesClasses "Base classes used to build new functions calculating specific heat capacities"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This package contains partial basic functions and models. These partial functions
+and models contain fundamental definitions of functions calculating specific heat
+capacities of adsorpt phases for pure and multi-component adsorption. The content 
+of this package is only of interest when adding new functions to the library.
+</p>
+</html>"));
+end BasesClasses;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/package.order b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/package.order
new file mode 100644
index 0000000..282c03f
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/BasesClasses/package.order
@@ -0,0 +1,4 @@
+PartialPureIntegrand
+PartialPure_cp
+PartialPureIntegrad_cp
+PartialTestPure
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_beta_pT.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_beta_pT.mo
new file mode 100644
index 0000000..9c30424
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_beta_pT.mo
@@ -0,0 +1,46 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_beta_pT
+  "Base function for functions calculating isobaric expansion coefficients as function of pressure and temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.RelativePressureCoefficient beta
+    "Isobaric expansion coefficient"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate isobaric
+expansion coefficients <i>beta</i> as function of pressure <i>p</i> and temperature 
+<i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_beta_pT;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dbeta_dT.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dbeta_dT.mo
new file mode 100644
index 0000000..32a3225
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dbeta_dT.mo
@@ -0,0 +1,52 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_dbeta_dT
+  "Base function for functions calculating the partial derivative of isobaric expansion coefficients w.r.t. temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. temperature
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_dT
+    "Partial derivative of isobaric expansion coefficients w.r.t. temperature at 
+    constant pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate partial
+derivatives of isobaric expansion coefficients with respect to temperature at constant 
+pressure <i>dbeta_dT</i> as function of pressure <i>p</i> and temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dbeta_dT;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dbeta_dp.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dbeta_dp.mo
new file mode 100644
index 0000000..68782f9
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dbeta_dp.mo
@@ -0,0 +1,52 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_dbeta_dp
+  "Base function for functions calculating the partial derivative of isobaric expansion coefficients w.r.t. pressure at constant temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerIsobaricExpansionCoefficientByPressure dbeta_dp
+    "Partial derivative of isobaric expansion coefficients w.r.t. pressure at 
+    constant temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate partial
+derivatives of isobaric expansion coefficients with respect to pressure at constant 
+temperature <i>dbeta_dp</i> as function of pressure <i>p</i> and temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dbeta_dp;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_adsorptiveToLiquid_dT.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_adsorptiveToLiquid_dT.mo
new file mode 100644
index 0000000..a6677db
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_adsorptiveToLiquid_dT.mo
@@ -0,0 +1,53 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_dh_adsorptiveToLiquid_dT
+  "Base function for functions calculating the partial derivative of specific enthalpy differences between adsorptive state and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. temperature
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the partial
+derivative of specific enthalpies of vaprozation with respect to temperature at constant
+pressure <i>dh_vap_dp</i> as function of temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dh_adsorptiveToLiquid_dT;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_adsorptiveToLiquid_dp.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_adsorptiveToLiquid_dp.mo
new file mode 100644
index 0000000..1e1cd11
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_adsorptiveToLiquid_dp.mo
@@ -0,0 +1,53 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_dh_adsorptiveToLiquid_dp
+  "Base function for functions calculating the partial derivative of specific enthalpy differences between adsorptive state and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the partial
+derivative of specific enthalpies of vaprozation with respect to pressure at constant
+temperature <i>dh_vap_dp</i> as function of temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dh_adsorptiveToLiquid_dp;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_dT.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_dT.mo
new file mode 100644
index 0000000..89a6361
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dh_dT.mo
@@ -0,0 +1,52 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_dh_dT
+  "Base function for functions calculating the partial derivative of specific enthalpies w.r.t. temperautre at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. temperature
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificHeatCapacity dh_dT
+    "Partial derivative of the specific enthalpy w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate the partial
+derivative of specific enthalpies w.r.t. temperature at constant pressure <i>dh_dT</i>
+as function of pressure <i>p</i> and temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dh_dT;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dv_dT.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dv_dT.mo
new file mode 100644
index 0000000..c634b72
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dv_dT.mo
@@ -0,0 +1,51 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_dv_dT
+  "Base function for functions calculating the partial derivative of specific volumes w.r.t. temperature at constant pressure"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. temperature
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerSpecificVolumeByTemperature dv_dT
+    "Partial derivative of specific volume w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate partial
+derivatives of specific volumes with respect to temperature at constant pressure
+<i>dv_dT</i> as function of pressure <i>p</i> and temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dv_dT;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dv_dp.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dv_dp.mo
new file mode 100644
index 0000000..39aa0ee
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_dv_dp.mo
@@ -0,0 +1,51 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_dv_dp
+  "Base function for functions calculating the partial derivative of specific volumes w.r.t. pressure at constant temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerSpecificVolumeByPressure dv_dp
+    "Partial derivative of specific volume w.r.t. pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate partial
+derivatives of specific volumes with respect to pressure at constant temperature
+<i>dv_dp</i> as function of pressure <i>p</i> and temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dv_dp;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_h_adsorptiveToLiquid_pT.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_h_adsorptiveToLiquid_pT.mo
new file mode 100644
index 0000000..7cd6213
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_h_adsorptiveToLiquid_pT.mo
@@ -0,0 +1,46 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_h_adsorptiveToLiquid_pT
+  "Base function for functions calculating specific enthalpy differences between adsorptive state and saturated liquid state (i.e., bubble point)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate specific
+enthalpies of vaprozation <i>h_vap</i> as function of temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_h_adsorptiveToLiquid_pT;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_v_pT.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_v_pT.mo
new file mode 100644
index 0000000..7e04c07
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/Partial_v_pT.mo
@@ -0,0 +1,45 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces;
+partial function Partial_v_pT
+  "Base function for functions calculating specific volumes as function of pressure and temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificVolume v
+    "Specific volume"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotation
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for functions that calculate specific
+volumes <i>v</i> as function of pressure <i>p</i> and temperature <i>T</i>.
+<br/><br/>
+Specific functions derived from this partial function can be used as functional
+arguments in the integrad functions.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_v_pT;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/package.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/package.mo
new file mode 100644
index 0000000..e16ea8e
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands;
+package Interfaces "Package containing interfaces used as function inputs"
+extends Modelica.Icons.InterfacesPackage;
+
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This package contains partial functions used as functional arguments for integrand
+functions.
+</p>
+</html>"));
+end Interfaces;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/package.order b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/package.order
new file mode 100644
index 0000000..daec3ed
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/Interfaces/package.order
@@ -0,0 +1,10 @@
+Partial_v_pT
+Partial_dv_dp
+Partial_dv_dT
+Partial_beta_pT
+Partial_dbeta_dp
+Partial_dbeta_dT
+Partial_dh_dT
+Partial_h_adsorptiveToLiquid_pT
+Partial_dh_adsorptiveToLiquid_dp
+Partial_dh_adsorptiveToLiquid_dT
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x.mo
new file mode 100644
index 0000000..3f739d8
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x.mo
@@ -0,0 +1,284 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands;
+function dh_ads_dT_x
+  "Partial derivative of the molar adsorption enthalpy w.r.t. temperature at constant uptake"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrand;
+
+  //
+  // Definition of inputs
+  //
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorptive_pT "Specific volume of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorptive_dp "Partial derivative of the specific volume of the adsorptive w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorptive_dT "Partial derivative of the specific volume of the adsorptive w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs"));
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorpt_pT "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorpt_dp "Partial derivative of the specific volume of the adsorpt w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorpt_dT "Partial derivative of the specific volume of the adsorpt w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+protected
+  Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_adsorptive_dp
+    "Partial derivative of specific volume of the adsorptive w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorptive_dT
+    "Partial derivative of specific volume of the adsorptive w.r.t. temperature at
+    constant pressure";
+
+  Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+    "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+    "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+    constant pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := func_p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := func_dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := func_dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := func_ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := func_ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := func_ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    //
+    // Do not use Clausius Clyperon assumptions
+    //
+    v_adsorptive := func_v_adsorptive_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Specific volume of the adsorptive";
+    dv_adsorptive_dp :=func_dv_adsorptive_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of specific volume of the adsorptive w.r.t. pressure at
+      constant temperature";
+    dv_adsorptive_dT :=func_dv_adsorptive_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of specific volume of the adsorptive w.r.t. temperature at
+      constant pressure";
+
+    v_adsorpt :=func_v_adsorpt_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Specific volume of the adsorpt";
+    dv_adsorpt_dp :=func_dv_adsorpt_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+      constant temperature";
+    dv_adsorpt_dT :=func_dv_adsorpt_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+      constant pressure";
+
+    //
+    // Calculation of partial derivatives of molar sorption enthalpy
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dv_adsorptive_dp=dv_adsorptive_dp,
+        dv_adsorpt_dp=dv_adsorpt_dp,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dv_adsorptive_dT=dv_adsorptive_dT,
+        dv_adsorpt_dT=dv_adsorpt_dT,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  else
+    //
+    // Use Clausius Clyperon assumptions: No further propiertes are required
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  end if;
+
+    //
+    // Calculation of the integrand
+    //
+    y := dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp
+      "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+      at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the molar adsorption ethalpy
+with respect to temperature at constant uptake:
+</p>
+<pre>
+    (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>x</sub> = (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>p</sub> - (&part;&Delta;h<sub>ads</sub>/&part;p)<sub>T</sub> * (&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>;
+</pre>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> = T * M<sub>adsorptive</sub> * (v<sub>adsorptive</sub> - v<sub>adsorpt</sub>) (dp/dT) &asymp; T * M<sub>adsorptive</sub> * (v<sub>adsorptive</sub> - v<sub>adsorpt</sub>) * (-(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>);
+</pre>
+<p>
+Herein, <i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive, <i>T</i> 
+is the temperature, <i>v<sub>adsorptive</sub></i> ist the specific volume of the 
+adsorptive, <i>v<sub>adsorpt</sub></i> ist the specific volume of the adsorpt, 
+<i>dx/dp</i> is the partial derivative of the uptake with respect to the pressure
+at constant temperature, and <i>dx/dT</i> is the partial derivative of the uptake 
+with respect to the temperature at constant pressure.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Inert sorbent.
+  </li>
+  <li>
+  Neglecting the termn <i>(&part;p/&part;x)<sub>T</sub> * (dx/dp)</i> of term 
+  <i>dp/dT = -(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub> +
+  (&part;p/&part;x)<sub>T</sub> * 
+  (dx/dp)</i>.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Chakraborty, A. and Saha, B.B. and Ng, K.C. and Koyama (2006). On the thermodynamic modeling of the isosteric heat of adsorption and comparison with experiments, Applied Physics Letters, 89:171901. DOI: http://doi.org/10.1063/1.2360925.
+  </li>
+  <li>
+  Chakraborty, A. and Saha, B.B. and Ng, K.C. and Koyama, S. and Srinivasan, K. (2009). Theoretical Insight of Physical Adsorption for a Single-Component Adsorbent + Adsorbate System: I. Thermodynamic Property Surfaces, Langmuir, 25:2204-221. DOI: http://doi.org/10.1021/la803289p.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dT_x;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x_CC.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x_CC.mo
new file mode 100644
index 0000000..4510cfc
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x_CC.mo
@@ -0,0 +1,140 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands;
+function dh_ads_dT_x_CC
+  "Partial derivative of the molar adsorption enthalpy w.r.t. temperature at constant uptake according to Clausius Clapeyron"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrand;
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := func_p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := func_dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := func_dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := func_ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := func_ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := func_ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of partial derivatives of molar sorption enthalpy
+  //
+  dh_ads_dp_T :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+      ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+  "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+  temperature";
+  dh_ads_dT_p :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+      ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+  //
+  // Calculation of the integrand
+  //
+  y := dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp
+    "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the molar adsorption ethalpy
+with respect to temperature at constant uptake. The molar adsorption enthalpy is
+calculated using Clausius Clapeyron assumptions:
+</p>
+<pre>
+    (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>x</sub> = (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>p</sub> - (&part;&Delta;h<sub>ads</sub>/&part;p)<sub>T</sub> * (&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>;
+</pre>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> = R * T<sup>2</sup> / p * (&part;p/&part;T)<sub>x</sub> = R * T<sup>2</sup> / p * (-(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>);
+</pre>
+<p>
+Herein, <i>R</i> is the ideal gas constant, <i>p</i> is the pressure, <i>T</i> is
+the temperature, <i>(&part;x/&part;p)<sub>T</sub></i> is the partial derivative of 
+the uptake with respect to the pressure at constant temperature, and 
+<i>(&part;x/&part;T)<sub>p</sub></i> is the partial derivative  of the uptake with 
+respect to the temperature at constant pressure.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The specific volume of the adsorpt phase can be neglected compared to the specific
+  volume of the adsorptive phase.
+  </li>
+  <li>
+  The adsorptive can be treated as an ideal gas (i.e., p * V = n * R * T).
+  </li>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dT_x_CC;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x_Dubinin.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x_Dubinin.mo
new file mode 100644
index 0000000..cef25a3
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_ads_dT_x_Dubinin.mo
@@ -0,0 +1,410 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands;
+function dh_ads_dT_x_Dubinin
+  "Partial derivative of the molar adsorption enthalpy w.r.t. temperature at constant uptake according to the model of Dubinin"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrand;
+
+  //
+  // Definition of inputs
+  //
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_h_adsorptiveToLiquid_pT
+    func_h_adsorptiveToLiquid_pT "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dp
+    func_dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dT
+    func_dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorpt_pT "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorpt_dp "Partial derivative of the specific volume of the adsorpt 
+    w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorpt_dT
+    "Partial derivative of the specific volume of the adsorpt w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs"));
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_beta_pT
+    func_beta_adsorpt_pT
+    "Isobaric expansion coefficient of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dp
+    func_dbeta_adsorpt_dp
+    "Partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. 
+    pressure at constant temperature"
+                                     annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dT
+    func_dbeta_adsorpt_dT
+    "Partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. 
+    temperature at constant pressure"
+     annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dW_dA func_dW_dA
+    "Partial derivative of the characteristic curve w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dA func_ddW_dA_dA
+    "Second-order partial derivative of the characteristic curve w.r.t. molar 
+    adsorption potential at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dT func_ddW_dA_dT
+    "Second-order partial derivative of the characteristic curve w.r.t. molar 
+    adsorption potential and temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+protected
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+  Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+    "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+    "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+    constant pressure";
+
+  Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+    "Isobaric expansion coefficient of the adsorpt";
+  SorpLib.Units.DerIsobaricExpansionCoefficientByPressure dbeta_adsorpt_dp
+    "Partial derivative of isobaric expansion coefficient of the adsorpt w.r.t. 
+    pressure at constant temperature";
+  SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_adsorpt_dT
+    "Partial derivative of isobaric expansion coefficient of the adsorpt w.r.t. 
+    temperature at constant pressure";
+
+  SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential";
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp
+    "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT
+    "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential and temperature at constant pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := func_p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := func_dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := func_dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := func_ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := func_ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := func_ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    //
+    // Do not use Clausius Clyperon assumptions
+    //
+    h_adsorptiveToLiquid := func_h_adsorptiveToLiquid_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+      state (i.e., bubble point)";
+    dh_adsorptiveToLiquid_dp:=func_dh_adsorptiveToLiquid_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+      and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+      temperature";
+    dh_adsorptiveToLiquid_dT:=func_dh_adsorptiveToLiquid_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+      and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+      pressure";
+
+    v_adsorpt :=func_v_adsorpt_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Specific volume of the adsorpt";
+    dv_adsorpt_dp :=func_dv_adsorpt_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+      constant temperature";
+    dv_adsorpt_dT :=func_dv_adsorpt_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+      constant pressure";
+
+    beta_adsorpt:=func_beta_adsorpt_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Isobaric expansion coefficient of the adsorpt";
+    dbeta_adsorpt_dp:=func_dbeta_adsorpt_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of isobaric expansion coefficient of the adsorpt w.r.t. 
+      pressure at constant temperature";
+    dbeta_adsorpt_dT:=func_dbeta_adsorpt_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of isobaric expansion coefficient of the adsorpt w.r.t. 
+      temperature at constant pressure";
+
+    A := SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    dA_dp:=SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Partial derivative of molar adsorption potential w.r.t. pressure at
+      constant temperature";
+    dA_dT:=SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT[1])
+      "Partial derivative of molar adsorption potential w.r.t. temperature at
+      constant pressure";
+
+    dW_dA:=func_dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+      at constant pressure and temperature";
+    ddW_dA_dA:=func_ddW_dA_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+      at constant pressure and temperature";
+    ddW_dA_dT:=func_ddW_dA_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      A=A,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential and temperature at constant pressure";
+
+    //
+    // Calculation of partial derivatives of molar sorption enthalpy
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        x_adsorpt=u,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+        dh_adsorptiveToLiquid_dp=dh_adsorptiveToLiquid_dp,
+        v_adsorpt=v_adsorpt,
+        dv_adsorpt_dp=dv_adsorpt_dp,
+        beta_adsorpt=beta_adsorpt,
+        dbeta_adsorpt_dp=dbeta_adsorpt_dp,
+        dA_dp=dA_dp,
+        dW_dA=dW_dA,
+        ddW_dA_dA=ddW_dA_dA)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        x_adsorpt=u,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+        dh_adsorptiveToLiquid_dT=dh_adsorptiveToLiquid_dT,
+        v_adsorpt=v_adsorpt,
+        dv_adsorpt_dT=dv_adsorpt_dT,
+        beta_adsorpt=beta_adsorpt,
+        dbeta_adsorpt_dT=dbeta_adsorpt_dT,
+        dA_dT=dA_dT,
+        dW_dA=dW_dA,
+        ddW_dA_dT=ddW_dA_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  else
+    //
+    // Use Clausius Clyperon assumptions: No further propiertes are required
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  end if;
+
+    //
+    // Calculation of the integrand
+    //
+    y := dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp
+      "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+      at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the molar adsorption ethalpy
+with respect to temperature at constant uptake. The molar adsorption enthalpy is
+calculated according to the model of Dubinin:
+</p>
+<pre>
+    (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>x</sub> = (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>p</sub> - (&part;&Delta;h<sub>ads</sub>/&part;p)<sub>T</sub> * (&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>;
+</pre>
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> = M<sub>adsorptive</sub> * &Delta;h<sub>adsorptiveToLiquid</sub> + A - &beta; * T * v<sub>adsorpt</sub> * x * 1 / (&part;W/&part;A)<sub>p,T</sub>;
+</pre>
+<p>
+Herein, <i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive, <i>T</i> 
+is the temperature, <i>x</i> is the uptake, <i>v<sub>adsorpt</sub></i> is the specific 
+volume of the adsorpt, <i>&beta;</i> is the isobaric expansion coefficient of the 
+adsorpt, <i>&Delta;h<sub>adsorptiveToLiquid</sub></i> is the specific enthalpy difference
+between adsorptive phase and saturated liquid phase (i.e., bubble point), <i>A</i> is 
+the molar adsorption potential, and <i>(&part;W/&part;A)<sub>p,T</sub></i> is the partial 
+derivative of the filled pore volume with respect to the molar adsorption potential at 
+constant pressure and temperature.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schwamberger, V. (2016). Thermodynamic and numerical investigation of a novel sorption cycle for application in adsorption heat pumps and chillers (in German), PhD thesis, Karlsruhe.
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_ads_dT_x_Dubinin;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x.mo
new file mode 100644
index 0000000..6a854e1
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x.mo
@@ -0,0 +1,318 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands;
+function dh_adsorpt_dT_x
+  "Partial derivative of the adsorpt w.r.t. temperature at constant uptake"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrand;
+
+  //
+  // Definition of inputs
+  //
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorptive_pT "Specific volume of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorptive_dp "Partial derivative of the specific volume of the adsorptive w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorptive_dT "Partial derivative of the specific volume of the adsorptive w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs"));
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_ig_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive (ideal gas) 
+    w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorpt_pT "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorpt_dp "Partial derivative of the specific volume of the adsorpt w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorpt_dT "Partial derivative of the specific volume of the adsorpt w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+protected
+  Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_adsorptive_dp
+    "Partial derivative of specific volume of the adsorptive w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorptive_dT
+    "Partial derivative of specific volume of the adsorptive w.r.t. temperature at
+    constant pressure";
+
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptive_dT
+    "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure";
+
+  Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+    "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+    "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+    constant pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := func_p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := func_dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := func_dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := func_ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := func_ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := func_ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    //
+    // Do not use Clausius Clyperon assumptions
+    //
+    v_adsorptive := func_v_adsorptive_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Specific volume of the adsorptive";
+    dv_adsorptive_dp :=func_dv_adsorptive_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of specific volume of the adsorptive w.r.t. pressure at
+      constant temperature";
+    dv_adsorptive_dT :=func_dv_adsorptive_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of specific volume of the adsorptive w.r.t. temperature at
+      constant pressure";
+
+    dh_adsorptive_dT := func_dh_adsorptive_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+      at constant pressure";
+
+    v_adsorpt :=func_v_adsorpt_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Specific volume of the adsorpt";
+    dv_adsorpt_dp :=func_dv_adsorpt_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+      constant temperature";
+    dv_adsorpt_dT :=func_dv_adsorpt_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+      constant pressure";
+
+    //
+    // Calculation of partial derivatives of molar sorption enthalpy
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dv_adsorptive_dp=dv_adsorptive_dp,
+        dv_adsorpt_dp=dv_adsorpt_dp,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dv_adsorptive_dT=dv_adsorptive_dT,
+        dv_adsorpt_dT=dv_adsorpt_dT,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  else
+    //
+    // Use Clausius Clyperon assumptions
+    //
+    dh_adsorptive_dT := func_dh_adsorptive_ig_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+      at constant pressure";
+
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  end if;
+
+  //
+  // Calculation of the integrand
+  //
+  y := dh_adsorptive_dT -
+    (dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp) / M_adsorptive
+    "Integrand: Partial derivative of the specific enthalpy of the adsorpt w.r.t. 
+    temperature at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of the 
+adsorpt with respect to temperature at constant uptake:
+</p>
+<pre>
+    (&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub> = (&part;h<sub>adsorptive</sub>/&part;T)<sub>x</sub> - (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>x</sub>;
+</pre>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> =T * M<sub>adsorptive</sub> * (v<sub>adsorptive</sub> - v<sub>adsorpt</sub>) (dp/dT) &asymp; T * M<sub>adsorptive</sub> * (v<sub>adsorptive</sub> - v<sub>adsorpt</sub>) * (-(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>);
+</pre>
+<p>
+Herein, <i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive, <i>T</i> 
+is the temperature, <i>v<sub>adsorptive</sub></i> ist the specific volume of the 
+adsorptive, <i>v<sub>adsorpt</sub></i> ist the specific volume of the adsorpt, 
+<i>dx/dp</i> is the partial derivative of the uptake with respect to the pressure
+at constant temperature, and <i>dx/dT</i> is the partial derivative of the uptake 
+with respect to the temperature at constant pressure.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Inert sorbent.
+  </li>
+  <li>
+  Neglecting the termn <i>(&part;p/&part;x)<sub>T</sub> * (dx/dp)</i> of term 
+  <i>dp/dT = -(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub> +
+  (&part;p/&part;x)<sub>T</sub> * 
+  (dx/dp)</i>.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+  <li>
+  Chakraborty, A. and Saha, B.B. and Ng, K.C. and Koyama (2006). On the thermodynamic modeling of the isosteric heat of adsorption and comparison with experiments, Applied Physics Letters, 89:171901. DOI: http://doi.org/10.1063/1.2360925.
+  </li>
+  <li>
+  Chakraborty, A. and Saha, B.B. and Ng, K.C. and Koyama, S. and Srinivasan, K. (2009). Theoretical Insight of Physical Adsorption for a Single-Component Adsorbent + Adsorbate System: I. Thermodynamic Property Surfaces, Langmuir, 25:2204-221. DOI: http://doi.org/10.1021/la803289p.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_adsorpt_dT_x;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x_CC.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x_CC.mo
new file mode 100644
index 0000000..9f09d04
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x_CC.mo
@@ -0,0 +1,198 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands;
+function dh_adsorpt_dT_x_CC
+  "Partial derivative of the adsorpt w.r.t. temperature at constant uptake according to Clausius Clapeyron"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrand;
+
+  //
+  // Definition of inputs
+  //
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_ig_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive (ideal gas) 
+    w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the specific enthalpy of the adsorptive is
+    calculated as an ideal gas"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+protected
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptive_dT
+    "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := func_p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := func_dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := func_dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := func_ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := func_ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := func_ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    dh_adsorptive_dT := func_dh_adsorptive_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+      at constant pressure";
+
+  else
+    dh_adsorptive_dT := func_dh_adsorptive_ig_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+      at constant pressure";
+
+  end if;
+
+  //
+  // Calculation of partial derivatives of molar sorption enthalpy
+  //
+  dh_ads_dp_T :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+      ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+  "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+  temperature";
+  dh_ads_dT_p :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+      ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+  //
+  // Calculation of the integrand
+  //
+  y := dh_adsorptive_dT -
+    (dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp) / M_adsorptive
+    "Integrand: Partial derivative of the specific enthalpy of the adsorpt w.r.t. 
+    temperature at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of the
+adsorpt with respect to temperature at constant uptake:
+</p>
+<pre>
+    (&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub> = (&part;h<sub>adsorptive</sub>/&part;T)<sub>x</sub> - (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>x</sub>;
+</pre>
+<p>
+The molar adsorption enthalpy is calculated using Clausius Clapeyron assumptions.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> = R * T<sup>2</sup> / p * (&part;p/&part;T)<sub>x</sub> = R * T<sup>2</sup> / p * (-(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub>);
+</pre>
+<p>
+Herein, <i>R</i> is the ideal gas constant, <i>p</i> is the pressure, <i>T</i> is
+the temperature, <i>(&part;x/&part;p)<sub>T</sub></i> is the partial derivative of 
+the uptake with respect to the pressure at constant temperature, and 
+<i>(&part;x/&part;T)<sub>p</sub></i> is the partial derivative  of the uptake with 
+respect to the temperature at constant pressure.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  The specific volume of the adsorpt phase can be neglected compared to the specific
+  volume of the adsorptive phase.
+  </li>
+  <li>
+  The adsorptive can be treated as an ideal gas (i.e., p * V = n * R * T).
+  </li>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Bathen, D. and Breitbach, M. (2001). Adsorptionstechnik (in German), 1st Edition, ISBN 3-540-41908-X, Springer-Verlag Berlin Heidelberg New York.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_adsorpt_dT_x_CC;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x_Dubinin.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x_Dubinin.mo
new file mode 100644
index 0000000..1d9659d
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/dh_adsorpt_dT_x_Dubinin.mo
@@ -0,0 +1,446 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands;
+function dh_adsorpt_dT_x_Dubinin
+  "Partial derivative of the adsorpt w.r.t. temperature at constant uptake according to the model of Dubinin"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrand;
+
+  //
+  // Definition of inputs
+  //
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_ig_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive (ideal gas) 
+    w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_h_adsorptiveToLiquid_pT
+    func_h_adsorptiveToLiquid_pT "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dp
+    func_dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dT
+    func_dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorpt_pT "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorpt_dp "Partial derivative of the specific volume of the adsorpt 
+    w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorpt_dT
+    "Partial derivative of the specific volume of the adsorpt w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs"));
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_beta_pT
+    func_beta_adsorpt_pT
+    "Isobaric expansion coefficient of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dp
+    func_dbeta_adsorpt_dp
+    "Partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. 
+    pressure at constant temperature"
+                                     annotation (Dialog(tab="General", group="Inputs"));
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dT
+    func_dbeta_adsorpt_dT
+    "Partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. 
+    temperature at constant pressure"
+     annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dW_dA func_dW_dA
+    "Partial derivative of the characteristic curve w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dA func_ddW_dA_dA
+    "Second-order partial derivative of the characteristic curve w.r.t. molar 
+    adsorption potential at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dT func_ddW_dA_dT
+    "Second-order partial derivative of the characteristic curve w.r.t. molar 
+    adsorption potential and temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+protected
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptive_dT
+    "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure";
+
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+  Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+    "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+    "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+    constant pressure";
+
+  Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+    "Isobaric expansion coefficient of the adsorpt";
+  SorpLib.Units.DerIsobaricExpansionCoefficientByPressure dbeta_adsorpt_dp
+    "Partial derivative of isobaric expansion coefficient of the adsorpt w.r.t. 
+    pressure at constant temperature";
+  SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_adsorpt_dT
+    "Partial derivative of isobaric expansion coefficient of the adsorpt w.r.t. 
+    temperature at constant pressure";
+
+  SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential";
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp
+    "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT
+    "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential and temperature at constant pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := func_p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := func_dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := func_dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := func_ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := func_ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := func_ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    //
+    // Do not use Clausius Clyperon assumptions
+    //
+    dh_adsorptive_dT := func_dh_adsorptive_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+      at constant pressure";
+
+    h_adsorptiveToLiquid := func_h_adsorptiveToLiquid_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+      state (i.e., bubble point)";
+    dh_adsorptiveToLiquid_dp:=func_dh_adsorptiveToLiquid_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+      and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+      temperature";
+    dh_adsorptiveToLiquid_dT:=func_dh_adsorptiveToLiquid_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+      and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+      pressure";
+
+    v_adsorpt :=func_v_adsorpt_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Specific volume of the adsorpt";
+    dv_adsorpt_dp :=func_dv_adsorpt_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+      constant temperature";
+    dv_adsorpt_dT :=func_dv_adsorpt_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+      constant pressure";
+
+    beta_adsorpt:=func_beta_adsorpt_pT(
+      p=p_adsorpt,
+      T=T_adsorpt)
+      "Isobaric expansion coefficient of the adsorpt";
+    dbeta_adsorpt_dp:=func_dbeta_adsorpt_dp(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp)
+      "Partial derivative of isobaric expansion coefficient of the adsorpt w.r.t. 
+      pressure at constant temperature";
+    dbeta_adsorpt_dT:=func_dbeta_adsorpt_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of isobaric expansion coefficient of the adsorpt w.r.t. 
+      temperature at constant pressure";
+
+    A := SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    dA_dp:=SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt)
+      "Partial derivative of molar adsorption potential w.r.t. pressure at
+      constant temperature";
+    dA_dT:=SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+      p_adsorpt=p_adsorpt,
+      p_sat=c[1],
+      T_adsorpt=T_adsorpt,
+      dp_sat_dT_adsorpt=dc_dT[1])
+      "Partial derivative of molar adsorption potential w.r.t. temperature at
+      constant pressure";
+
+    dW_dA:=func_dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+      at constant pressure and temperature";
+    ddW_dA_dA:=func_ddW_dA_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+      at constant pressure and temperature";
+    ddW_dA_dT:=func_ddW_dA_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      A=A,
+      c=c,
+      dc_dT_adsorpt=dc_dT)
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential and temperature at constant pressure";
+
+    //
+    // Calculation of partial derivatives of molar sorption enthalpy
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        x_adsorpt=u,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+        dh_adsorptiveToLiquid_dp=dh_adsorptiveToLiquid_dp,
+        v_adsorpt=v_adsorpt,
+        dv_adsorpt_dp=dv_adsorpt_dp,
+        beta_adsorpt=beta_adsorpt,
+        dbeta_adsorpt_dp=dbeta_adsorpt_dp,
+        dA_dp=dA_dp,
+        dW_dA=dW_dA,
+        ddW_dA_dA=ddW_dA_dA)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        x_adsorpt=u,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+        dh_adsorptiveToLiquid_dT=dh_adsorptiveToLiquid_dT,
+        v_adsorpt=v_adsorpt,
+        dv_adsorpt_dT=dv_adsorpt_dT,
+        beta_adsorpt=beta_adsorpt,
+        dbeta_adsorpt_dT=dbeta_adsorpt_dT,
+        dA_dT=dA_dT,
+        dW_dA=dW_dA,
+        ddW_dA_dT=ddW_dA_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+
+  else
+    //
+    // Use Clausius Clyperon assumptions
+    //
+    dh_adsorptive_dT := func_dh_adsorptive_ig_dT(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dT=dT)
+      "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+      at constant pressure";
+
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  end if;
+
+  //
+  // Calculation of the integrand
+  //
+  y := dh_adsorptive_dT -
+    (dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp) / M_adsorptive
+    "Integrand: Partial derivative of the specific enthalpy of the adsorpt w.r.t. 
+    temperature at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of the
+adsorpt with respect to temperature at constant uptake:
+</p>
+<pre>
+    (&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub> = (&part;h<sub>adsorptive</sub>/&part;T)<sub>x</sub> - (&part;&Delta;h<sub>ads</sub>/&part;T)<sub>x</sub>;
+</pre>
+<p>
+The molar adsorption enthalpy is calculated according to the model of Dubinin.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The molar adsorption enthalpy <i>&Delta;h<sub>ads</sub></i> is defined as difference
+of the specific enthalpy of the gas/vapor phase <i>h<sub>adsorptive</sub></i> and the
+adsorpt phase <i>h<sub>adsorpt</sub></i>:
+</p>
+<pre>
+    &Delta;h<sub>ads</sub> = h<sub>adsorptive</sub> - h<sub>adsorpt</sub> = M<sub>adsorptive</sub> * &Delta;h<sub>adsorptiveToLiquid</sub> + A - &beta; * T * v<sub>adsorpt</sub> * x * 1 / (&part;W/&part;A)<sub>p,T</sub>;
+</pre>
+<p>
+Herein, <i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive, <i>T</i> 
+is the temperature, <i>x</i> is the uptake, <i>v<sub>adsorpt</sub></i> is the specific 
+volume of the adsorpt, <i>&beta;</i> is the isobaric expansion coefficient of the 
+adsorpt, <i>&Delta;h<sub>adsorptiveToLiquid</sub></i> is the specific enthalpy difference
+between adsorptive phase and saturated liquid phase (i.e., bubble point), <i>A</i> is 
+the molar adsorption potential, and <i>(&part;W/&part;A)<sub>p,T</sub></i> is the partial 
+derivative of the filled pore volume with respect to the molar adsorption potential at 
+constant pressure and temperature.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Inert sorbent.
+  </li>
+</ul>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schwamberger, V. (2016). Thermodynamic and numerical investigation of a novel sorption cycle for application in adsorption heat pumps and chillers (in German), PhD thesis, Karlsruhe.
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_adsorpt_dT_x_Dubinin;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/package.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/package.mo
new file mode 100644
index 0000000..8293d2f
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/package.mo
@@ -0,0 +1,24 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+package Integrands "Package containing functions defining integrands for numerical integration"
+extends Modelica.Icons.InternalPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains functions defining integrands. These integrands are used
+while numerical integration, which is sometimes requied depending on the calculation
+approach of the specific heat capacity of the adsorpt phase. Numerical integration is 
+performed using the very efficient function
+<a href=\"Modelica://Modelica.Math.Nonlinear.quadratureLobatto\">Modelica.Math.Nonlinear.quadratureLobatto</a>.
+<br><br>
+The content of this package is only of interest when adding new functions to the 
+library or when adding new approach for calculating the molar adsorption enthalpy.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Integrands;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/package.order b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/package.order
new file mode 100644
index 0000000..064e616
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Integrands/package.order
@@ -0,0 +1,7 @@
+Interfaces
+dh_ads_dT_x
+dh_ads_dT_x_CC
+dh_ads_dT_x_Dubinin
+dh_adsorpt_dT_x
+dh_adsorpt_dT_x_CC
+dh_adsorpt_dT_x_Dubinin
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/MediumSpecificFunctions/package.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/MediumSpecificFunctions/package.mo
new file mode 100644
index 0000000..7fe37d4
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/MediumSpecificFunctions/package.mo
@@ -0,0 +1,333 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Testers;
+package MediumSpecificFunctions "Package containing medium specific functions that are used as functional arguments in integrand functions"
+  extends Modelica.Icons.InternalPackage;
+
+  //
+  // Definition of replaceable medium package: This is required to have access to
+  // functions that change with the selected medium. These functions are used as
+  // functional input arguments.
+  //
+  replaceable package Medium = Modelica.Media.Water.WaterIF97_ph
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Medium"),
+                choicesAllMatching = true);
+  //
+  // Redeclaration of all replacable partial functions regarding the adsorptive
+  //
+  replaceable function v_adsorptive_pT
+  "Calculates specific volume of adsorptive as function pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT;
+
+  algorithm
+    v :=1/Medium.density_pT(p=p, T=T)
+      "Specific volume of the adsorptive";
+  end v_adsorptive_pT;
+
+  replaceable function dv_adsorptive_dp
+    "Calculates the partial derivative of the specific volume of the adsotpive w.r.t. pressure at constant temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp;
+
+  algorithm
+    dv_dp :=
+      (1/Medium.density_pT(p=p+dp, T=T) - 1/Medium.density_pT(p=p-dp, T=T)) /
+      (2*dp)
+      "Partial derivative of the specific volume of the adsorptive w.r.t.
+      pressure at constant temperature";
+  end dv_adsorptive_dp;
+
+  replaceable function dv_adsorptive_dT
+    "Calculates the partial derivative of the specific volume of the adsotpive w.r.t. temperature at constant pressure"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT;
+
+  algorithm
+    dv_dT :=
+      (1/Medium.density_pT(p=p, T=T+dT) - 1/Medium.density_pT(p=p, T=T-dT)) /
+      (2*dT)
+      "Partial derivative of the specific volume of the adsorptive w.r.t.
+      temperature at constant pressure";
+  end dv_adsorptive_dT;
+
+  replaceable function dh_adsorptive_dT
+  "Calculates specific enthalpy of adsorptive as function pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT;
+
+  algorithm
+    dh_dT := (Medium.specificEnthalpy_pT(p=p, T=T+dT) -
+      Medium.specificEnthalpy_pT(p=p, T=T-dT)) / (2 * dT)
+      "Partial derivative of the specific enthalpy w.r.t. temperature at constant
+    pressure";
+  end dh_adsorptive_dT;
+
+  replaceable function dh_adsorptive_ig_dT
+    "Calculates specific volume of the adsorptive (ideal gas) as function temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT;
+
+  algorithm
+    dh_dT := 1860
+      "Partial derivative of the specific enthalpy w.r.t. temperature at constant
+    pressure";
+  end dh_adsorptive_ig_dT;
+
+  replaceable function h_adsorptiveToLiquid_pT
+    "Base function for functions calculating specific enthalpy differences between adsorptive state and saturated liquid state (i.e., bubble point)"
+    extends
+      SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_h_adsorptiveToLiquid_pT;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.ThermodynamicState state_pT
+      "State properties at p and T";
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+
+  algorithm
+    state_pT := Medium.setState_pT(p=p, T=T)
+      "State properties at p and T";
+    sat_T :=Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+
+    h_adsorptiveToLiquid :=Medium.specificEnthalpy(state=state_pT) -
+      Medium.bubbleEnthalpy(sat=sat_T)
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+  end h_adsorptiveToLiquid_pT;
+
+  replaceable function dh_adsorptiveToLiquid_dp
+    "Base function for functions calculating the partial derivative of specific enthalpy differences between adsorptive state and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dp;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.ThermodynamicState state_pT
+      "State properties at p and T";
+
+  algorithm
+    //
+    // The second summand of the partial derivative is zero because the specific
+    // enthalpy of vaporization does only depend on the temperature, which determines
+    // the saturation state but is constant
+    //
+    state_pT := Medium.setState_pT(p=p, T=T)
+      "State properties at p and T";
+
+    dh_adsorptiveToLiquid_dp := 1/Medium.density(state=state_pT) * (1 - T *
+      Medium.isobaricExpansionCoefficient(state=state_pT)) - 0
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+  end dh_adsorptiveToLiquid_dp;
+
+  replaceable function dh_adsorptiveToLiquid_dT
+    "Base function for functions calculating the partial derivative of specific enthalpy differences between adsorptive state and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant pressure"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dT;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+    Medium.ThermodynamicState state_pT
+      "State properties at p and T";
+    Medium.ThermodynamicState state_bubble_T
+      "Bubble state properties at p and T";
+
+  algorithm
+    sat_T :=Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+    state_pT := Medium.setState_pT(p=p, T=T)
+      "State properties at p and T";
+    state_bubble_T := Medium.setBubbleState(sat=sat_T)
+      "Bubble state properties at T";
+
+    dh_adsorptiveToLiquid_dT :=
+      Medium.specificHeatCapacityCp(state=state_pT) -
+      Medium.specificHeatCapacityCp(state=state_bubble_T)
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+  end dh_adsorptiveToLiquid_dT;
+  //
+  // Redeclaration of all replacable partial functions regarding the adsorpt
+  //
+  replaceable function v_adsorpt_pT
+    "Calculates specific volume of the adsorpt as function pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT;
+
+  algorithm
+    v := 1 / Medium.bubbleDensity(sat=Medium.setSat_T(T=T))
+      "Specific volume of the adsorptive";
+  end v_adsorpt_pT;
+
+  replaceable function dv_adsorpt_dp
+    "Calculates the partial derivative of specific volume of the adsorpt w.r.t. pressure at constant temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+
+  algorithm
+    //
+    // The partial derivative is zero because the specific volume of the adsorpt
+    // does only depend on the temperature, which determines the saturation state
+    // but is constant
+    //
+    sat_T :=Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+    dv_dp := dv_adsorpt_dT(p=p, T=T, dT=dp*1)
+      * Medium.saturationTemperature_derp_sat(sat=sat_T) * 0
+      "Partial derivative of the specific volume of the adsorptive w.r.t.
+      pressure at constant temperature";
+  end dv_adsorpt_dp;
+
+  replaceable function dv_adsorpt_dT
+    "Calculates the partial derivative of specific volume of the adsorpt w.r.t. temperature at constant pressure"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+
+  algorithm
+    sat_T :=Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+    dv_dT := -(1 / Medium.bubbleDensity(sat=sat_T)) ^ 2 *
+      Medium.dBubbleDensity_dPressure(sat=sat_T) /
+      Medium.saturationTemperature_derp_sat(sat=sat_T)
+      "Partial derivative of the specific volume of the adsorptive w.r.t.
+      temperature at constant pressure";
+  end dv_adsorpt_dT;
+
+  replaceable function beta_adsorpt_pT
+    "Calculates isobaric expansion coefficient of the adsorpt as function pressure and temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_beta_pT;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+    Medium.ThermodynamicState state_bubble_T
+      "State properties of ubble point at T";
+
+  algorithm
+    sat_T :=Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+    state_bubble_T :=Medium.setBubbleState(sat=sat_T)
+      "State properties of ubble point at T";
+
+    beta :=Medium.isobaricExpansionCoefficient(state=state_bubble_T)
+      "Isobaric expansion coefficient";
+  end beta_adsorpt_pT;
+
+  replaceable function dbeta_adsorpt_dp
+    "Calculates the partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. pressure at constant temperature"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dp;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+
+  algorithm
+    //
+    // The partial derivative is zero because the isobaric expansion coefficient of
+    // the adsorpt does only depend on the temperature, which determines the saturation
+    // state but is constant
+    //
+    sat_T :=Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+    dbeta_dp := dbeta_adsorpt_dT(p=p, T=T, dT=dp*1)
+      * Medium.saturationTemperature_derp_sat(sat=sat_T) * 0
+      "Partial derivative of isobaric expansion coefficients w.r.t. pressure at 
+     constant temperature";
+  end dbeta_adsorpt_dp;
+
+  replaceable function dbeta_adsorpt_dT
+    "Calculates the partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. temperature at constant pressure"
+    extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dT;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.SaturationProperties sat_T_pdT
+      "Saturated state properties at T + dT";
+    Medium.SaturationProperties sat_T_mdT
+      "Saturated state properties at T - dT";
+
+    Medium.ThermodynamicState state_bubble_T_pdT
+      "State properties of ubble point at T + dT";
+    Medium.ThermodynamicState state_bubble_T_mdT
+      "State properties of ubble point at T - dT";
+
+  algorithm
+    sat_T_pdT :=Medium.setSat_T(T=T+dT)
+      "Saturated state properties at T + dT";
+    sat_T_mdT :=Medium.setSat_T(T=T-dT)
+      "Saturated state properties at T - dT";
+
+    state_bubble_T_pdT :=Medium.setBubbleState(sat=sat_T_pdT)
+      "State properties of ubble point at T + dT";
+    state_bubble_T_mdT :=Medium.setBubbleState(sat=sat_T_mdT)
+      "State properties of ubble point at T - dT";
+
+    dbeta_dT :=
+      (Medium.isobaricExpansionCoefficient(state=state_bubble_T_pdT) -
+      Medium.isobaricExpansionCoefficient(state=state_bubble_T_mdT)) / (2 * dT)
+      "Partial derivative of isobaric expansion coefficients w.r.t. temperature at 
+      constant pressure";
+  end dbeta_adsorpt_dT;
+  //
+  // Annoations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This package defines functions that are used as functional arguments in integrante 
+functions and use media-specific functions. More details on the integand functions 
+can be found here:
+<a href=\"Modelica://SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.Integrands\">SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.Integrands</a>.
+<br><br>
+Within this package, the media-specific functions are provided via the media library 
+of the Modelica standard Library. This package demonstrates one possibility to build
+genral models that can use different Modelica libraries for media property calculation
+by just exchaning this package. This package is only used for the testers and it should
+not be used within other simulation models.
+</p>
+</html>"));
+end MediumSpecificFunctions;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/MediumSpecificFunctions/package.order b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/MediumSpecificFunctions/package.order
new file mode 100644
index 0000000..866500e
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/MediumSpecificFunctions/package.order
@@ -0,0 +1,15 @@
+Medium
+v_adsorptive_pT
+dv_adsorptive_dp
+dv_adsorptive_dT
+dh_adsorptive_dT
+dh_adsorptive_ig_dT
+h_adsorptiveToLiquid_pT
+dh_adsorptiveToLiquid_dp
+dh_adsorptiveToLiquid_dT
+v_adsorpt_pT
+dv_adsorpt_dp
+dv_adsorpt_dT
+beta_adsorpt_pT
+dbeta_adsorpt_dp
+dbeta_adsorpt_dT
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_ChakrabortyEtAl.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_ChakrabortyEtAl.mo
new file mode 100644
index 0000000..c9e6018
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_ChakrabortyEtAl.mo
@@ -0,0 +1,493 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Testers;
+model Test_cp_ChakrabortyEtAl
+  "Tester for the function 'cp_ChakrabortyEtAl' and all corresponding functions"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialTestPure;
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.MolarEnthalpy h_ads
+    "Molar adsorption enthalpy";
+  Modelica.Units.SI.MolarEnthalpy h_ads_CC
+    "Molar adsorption enthalpy according to Clausius Clapeyron";
+  Modelica.Units.SI.MolarEnthalpy h_ads_Dubinin
+    "Molar adsorption enthalpy according to Dubinin model";
+
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T_CC
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature according to Clausius Clapeyron";
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T_Dubinin
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature according to Dubinin model";
+
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p_CC
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure according to Clausius Clapeyron";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p_Dubinin
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure according to Dubinin model";
+
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_x
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_x_CC
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake according to Clausius Clapeyron";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_x_Dubinin
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake according to Dubinin model";
+
+protected
+  Medium.ThermodynamicState state_adsorptive_pT_pdp
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: p + dp";
+  Medium.ThermodynamicState state_adsorptive_pT_mdp
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: p - dp";
+  Medium.ThermodynamicState state_adsorptive_pT_pdT
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: T + dT";
+  Medium.ThermodynamicState state_adsorptive_pT_mdT
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: T - dT";
+
+  Medium.ThermodynamicState state_bubble_T_pdT
+    "State properties of bubble point at T_adsorpt: T + dT";
+  Medium.ThermodynamicState state_bubble_T_mdT
+    "State properties of bubble point at T_adsorpt: T - dT";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant prssure";
+
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+  Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+    "Isobaric expansion coefficient of the adsorpt phase";
+  SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_adsorpt_dT
+    "Partial derivative of isobaric expansion coefficient of the adsorpt phase
+    w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.MolarAdsorptionPotential A
+    "Molar adsorption potential";
+  SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp
+    "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT
+    "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+    "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential and temperature at constant pressure";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 0.75 * dc_dT[1]
+    "Predecsriped slope of p_adsorpt";
+  der(T_adsorpt) = 90/20
+    "Predecsriped slope of T_adsorpt";
+
+  //
+  // Calculate coefficients of the isotherm model
+  //
+  c[1] = state_bubble_T.p;
+  c[2] = state_bubble_T.d;
+  c[3] = 5.072313e-1 / 1000;
+  c[4] = 1.305531e2 * 1000 * 0.018;
+  c[5] = -8.492403e1 * 1000 * 0.018;
+  c[6] = 4.128962e-3 / 1000;
+
+  c_pdT[1] = sat_T_pdT.psat;
+  c_pdT[2] = Medium.bubbleDensity(sat=sat_T_pdT);
+  c_pdT[3] = 5.072313e-1 / 1000;
+  c_pdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_pdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_pdT[6] = 4.128962e-3 / 1000;
+
+  c_mdT[1] = sat_T_mdT.psat;
+  c_mdT[2] = Medium.bubbleDensity(sat=sat_T_mdT);
+  c_mdT[3] = 5.072313e-1 / 1000;
+  c_mdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_mdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_mdT[6] = 4.128962e-3 / 1000;
+
+  //
+  // Calculate partial derivatives of coefficients of the isotherm model w.r.t.
+  // temperature
+  //
+  dc_dT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T);
+  dc_dT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T) * dc_dT[1];
+  dc_dT[3] = 0;
+  dc_dT[4] = 0;
+  dc_dT[5] = 0;
+  dc_dT[6] = 0;
+
+  dc_dT_pdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_pdT);
+  dc_dT_pdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_pdT) * dc_dT_pdT[1];
+  dc_dT_pdT[3] = 0;
+  dc_dT_pdT[4] = 0;
+  dc_dT_pdT[5] = 0;
+  dc_dT_pdT[6] = 0;
+
+  dc_dT_mdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_mdT);
+  dc_dT_mdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_mdT) * dc_dT_mdT[1];
+  dc_dT_mdT[3] = 0;
+  dc_dT_mdT[4] = 0;
+  dc_dT_mdT[5] = 0;
+  dc_dT_mdT[6] = 0;
+
+  //
+  // Calculate second-order partial derivatives of coefficients of the isotherm
+  // model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (dc_dT_pdT[1] - dc_dT_mdT[1]) / (2*dT);
+  ddc_dT_dT[2] = (dc_dT_pdT[2] - dc_dT_mdT[2]) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Calculation of state properties
+  //
+  state_adsorptive_pT_pdp = Medium.setState_pTX(
+    p=p_adsorpt+dp,
+    T=T_adsorpt)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: p + dp";
+  state_adsorptive_pT_mdp = Medium.setState_pTX(
+    p=p_adsorpt-dp,
+    T=T_adsorpt)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: p - dp";
+
+  state_adsorptive_pT_pdT = Medium.setState_pTX(
+    p=p_adsorpt,
+    T=T_adsorpt+dT)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: T + dT";
+  state_adsorptive_pT_mdT = Medium.setState_pTX(
+    p=p_adsorpt,
+    T=T_adsorpt-dT)
+    "State properties of adsorptive at p_adsorpt and T_adsorpt: T - dT";
+
+  state_bubble_T_pdT = Medium.setBubbleState(sat=sat_T_pdT)
+    "State properties of bubble point at T_adsorpt: T + dT";
+  state_bubble_T_mdT = Medium.setBubbleState(sat=sat_T_mdT)
+    "State properties of bubble point at T_adsorpt: T - dT";
+
+  //
+  // Calculate properties
+  //
+  x_adsorpt = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake";
+
+  dx_adsorpt_dp = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dT_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT,
+    ddc_dT_adsorpt_dT_adsorpt=ddc_dT_dT)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  h_adsorptiveToLiquid = state_adsorptive_pT.h - state_bubble_T.h
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+  dh_adsorptiveToLiquid_dp = 1/state_adsorptive_pT.d * (1 - T_adsorpt *
+    Medium.isobaricExpansionCoefficient(state=state_adsorptive_pT)) - 0
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+  dh_adsorptiveToLiquid_dT =
+    Medium.specificHeatCapacityCp(state=state_adsorptive_pT) -
+    Medium.specificHeatCapacityCp(state=state_bubble_T)
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+  beta_adsorpt = Medium.isobaricExpansionCoefficient(state=state_bubble_T)
+    "Isobaric expansion coefficient of the adsorpt phase";
+  dbeta_adsorpt_dT =
+    (Medium.isobaricExpansionCoefficient(state=state_bubble_T_pdT) -
+     Medium.isobaricExpansionCoefficient(state=state_bubble_T_mdT)) /(2*dT)
+    "Partial derivative of the ssobaric expansion coefficient of the adsorpt phase
+    w.r.t. temperature at constant pressure";
+
+  A =SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+    p_adsorpt=p_adsorpt,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Molar adsorption potential";
+  dA_dp =SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+    p_adsorpt=p_adsorpt,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt)
+    "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+  dA_dT =SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+    p_adsorpt=p_adsorpt,
+    p_sat=c[1],
+    T_adsorpt=T_adsorpt,
+    dp_sat_dT_adsorpt=dc_dT[1])
+    "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+  dW_dA = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA(
+    A=A,
+    c=c)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  ddW_dA_dA = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dA(
+    A=A,
+    c=c)
+    "Second-order prtial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+  ddW_dA_dT = SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    A=A,
+    c=c,
+    dc_dT_adsorpt=dc_dT)
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    and temperature at constant pressure";
+
+  //
+  // Calculate molar adsorption enthalpies and their derivatives
+  //
+  h_ads = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar adsorption enthalpy";
+  h_ads_CC = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar adsorption enthalpy according to Clausius Clapeyron";
+  h_ads_Dubinin = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+    v_adsorpt=1/state_bubble_T.d,
+    beta_adsorpt=beta_adsorpt,
+    A=A,
+    dW_dA=dW_dA)
+    "Molar adsorption enthalpy according to Dubinin model";
+
+  dh_ads_dp_T = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dv_adsorptive_dp=(1/state_adsorptive_pT_pdp.d - 1/state_adsorptive_pT_mdp.d) /
+      (2*dp),
+    dv_adsorpt_dp=0,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+    ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+  dh_ads_dp_T_CC = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+    ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature according to Clausius Clapeyron";
+  dh_ads_dp_T_Dubinin = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+    dh_adsorptiveToLiquid_dp=dh_adsorptiveToLiquid_dp,
+    v_adsorpt=1/state_bubble_T.d,
+    dv_adsorpt_dp=0,
+    beta_adsorpt=beta_adsorpt,
+    dbeta_adsorpt_dp=0,
+    dA_dp=dA_dp,
+    dW_dA=dW_dA,
+    ddW_dA_dA=ddW_dA_dA)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature according to Dubinin model";
+
+  dh_ads_dT_p =  SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    v_adsorpt=1/state_bubble_T.d,
+    dv_adsorptive_dT=(1/state_adsorptive_pT_pdT.d - 1/state_adsorptive_pT_mdT.d) /
+      (2*dT),
+    dv_adsorpt_dT=-1/state_bubble_T.d^2 * dc_dT[2],
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT,
+    ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+  dh_ads_dT_p_CC = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    dx_adsorpt_dp=dx_adsorpt_dp,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+    ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure according to Clausius Clapeyron";
+  dh_ads_dT_p_Dubinin = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    dx_adsorpt_dT=dx_adsorpt_dT,
+    h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+    dh_adsorptiveToLiquid_dT=dh_adsorptiveToLiquid_dT,
+    v_adsorpt=1/state_bubble_T.d,
+    dv_adsorpt_dT=-1/state_bubble_T.d^2 * dc_dT[2],
+    beta_adsorpt=beta_adsorpt,
+    dbeta_adsorpt_dT=dbeta_adsorpt_dT,
+    dA_dT=dA_dT,
+    dW_dA=dW_dA,
+    ddW_dA_dT=ddW_dA_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure according to Dubinin model";
+
+  dh_ads_dT_x = dh_ads_dT_p - dh_ads_dp_T *
+    dx_adsorpt_dT / dx_adsorpt_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake";
+  dh_ads_dT_x_CC = dh_ads_dT_p_CC - dh_ads_dp_T_CC *
+    dx_adsorpt_dT / dx_adsorpt_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake according to Clausius Clapeyron";
+  dh_ads_dT_x_Dubinin = dh_ads_dT_p_Dubinin - dh_ads_dp_T_Dubinin *
+    dx_adsorpt_dT / dx_adsorpt_dp
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake according to Dubinin model";
+
+  //
+  // Calculate specific heat capacities of adsorpt phase
+  //
+  cp_adsorpt = SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_ChakrabortyEtAl(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    cp_adsorptive=cp_adsorptive,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    dv_adsorptive_dT=(1/state_adsorptive_pT_pdT.d - 1/state_adsorptive_pT_mdT.d) /
+      (2*dT),
+    v_adsorpt=1/state_bubble_T.d,
+    h_ads=h_ads,
+    dh_ads_dT_x=dh_ads_dT_x)
+    "Specific heat capacitiy of adsorpt";
+  cp_adsorpt_CC = SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_ChakrabortyEtAl(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    cp_adsorptive=cp_adsorptive,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    dv_adsorptive_dT=(1/state_adsorptive_pT_pdT.d - 1/state_adsorptive_pT_mdT.d) /
+      (2*dT),
+    v_adsorpt=1/state_bubble_T.d,
+    h_ads=h_ads_CC,
+    dh_ads_dT_x=dh_ads_dT_x_CC)
+    "Specific heat capacitiy of adsorpt calculated using molar adsorption enthalpy
+    according to Clausius Clapeyron";
+  cp_adsorpt_Dubinin = SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_ChakrabortyEtAl(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    cp_adsorptive=cp_adsorptive,
+    v_adsorptive=1/state_adsorptive_pT.d,
+    dv_adsorptive_dT=(1/state_adsorptive_pT_pdT.d - 1/state_adsorptive_pT_mdT.d) /
+      (2*dT),
+    v_adsorpt=1/state_bubble_T.d,
+    h_ads=h_ads_Dubinin,
+    dh_ads_dT_x=dh_ads_dT_x_Dubinin)
+    "Specific heat capacitiy of adsorptive using molar adsorption enthalpy
+    according to Dubinin model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'cp_ChakrabortyEtAl' function.
+<br/><br/>
+To see the function behavior, plot the variables <i>cp_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_cp_ChakrabortyEtAl;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_SchwambergerSchmidt.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_SchwambergerSchmidt.mo
new file mode 100644
index 0000000..bdbb51e
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_SchwambergerSchmidt.mo
@@ -0,0 +1,291 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Testers;
+model Test_cp_SchwambergerSchmidt
+  "Tester for the function 'cp_SchwambergerSchmidt' and all corresponding functions"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialTestPure;
+
+  //
+  // Load functions package and select correct medium
+  //
+  package MediumSpecificFunctionsForIntegrands =
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Testers.MediumSpecificFunctions
+      (redeclare final package Medium = Medium)
+    "Library containing medium-specific functions that are used as functional
+    arguments"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters
+  //
+  replaceable function func_x_pT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT
+    "Classical form of isotherm model: Calculates uptake as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_p_xT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT
+    "Inverse form of General: Calculates pressure as function of uptake 
+    and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_dx_dp =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature as 
+    function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_dx_dT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure as 
+    function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddx_dp_dp =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dp
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature 
+    as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddx_dT_dT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dT_dT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure
+    as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddx_dp_dT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature
+    as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_dW_dA =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddW_dA_dA =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dA
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dA
+    "Second-order prtial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddW_dA_dT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dT
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    and temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 0.75 * dc_dT[1]
+    "Predecsriped slope of p_adsorpt";
+  der(T_adsorpt) = 90/20
+    "Predecsriped slope of T_adsorpt";
+
+  //
+  // Calculate coefficients of the isotherm model
+  //
+  c[1] = state_bubble_T.p;
+  c[2] = state_bubble_T.d;
+  c[3] = 5.072313e-1 / 1000;
+  c[4] = 1.305531e2 * 1000 * 0.018;
+  c[5] = -8.492403e1 * 1000 * 0.018;
+  c[6] = 4.128962e-3 / 1000;
+
+  c_pdT[1] = sat_T_pdT.psat;
+  c_pdT[2] = Medium.bubbleDensity(sat=sat_T_pdT);
+  c_pdT[3] = 5.072313e-1 / 1000;
+  c_pdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_pdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_pdT[6] = 4.128962e-3 / 1000;
+
+  c_mdT[1] = sat_T_mdT.psat;
+  c_mdT[2] = Medium.bubbleDensity(sat=sat_T_mdT);
+  c_mdT[3] = 5.072313e-1 / 1000;
+  c_mdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_mdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_mdT[6] = 4.128962e-3 / 1000;
+
+  //
+  // Calculate partial derivatives of coefficients of the isotherm model w.r.t.
+  // temperature
+  //
+  dc_dT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T);
+  dc_dT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T) * dc_dT[1];
+  dc_dT[3] = 0;
+  dc_dT[4] = 0;
+  dc_dT[5] = 0;
+  dc_dT[6] = 0;
+
+  dc_dT_pdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_pdT);
+  dc_dT_pdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_pdT) * dc_dT_pdT[1];
+  dc_dT_pdT[3] = 0;
+  dc_dT_pdT[4] = 0;
+  dc_dT_pdT[5] = 0;
+  dc_dT_pdT[6] = 0;
+
+  dc_dT_mdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_mdT);
+  dc_dT_mdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_mdT) * dc_dT_mdT[1];
+  dc_dT_mdT[3] = 0;
+  dc_dT_mdT[4] = 0;
+  dc_dT_mdT[5] = 0;
+  dc_dT_mdT[6] = 0;
+
+  //
+  // Calculate second-order partial derivatives of coefficients of the isotherm
+  // model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (dc_dT_pdT[1] - dc_dT_mdT[1]) / (2*dT);
+  ddc_dT_dT[2] = (dc_dT_pdT[2] - dc_dT_mdT[2]) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Calculate properties
+  //
+  x_adsorpt = func_x_pT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake";
+
+  //
+  // Calculate specific heat capacities of adsorpt phase
+  //
+  cp_adsorpt = SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_SchwambergerSchmidt(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    c=c,
+    dc_dT=dc_dT,
+    ddc_dT_dT=ddc_dT_dT,
+    func_p_xT=function func_p_xT(),
+    func_dx_dp=function func_dx_dp(),
+    func_dx_dT=function func_dx_dT(),
+    func_ddx_dp_dp=function func_ddx_dp_dp(),
+    func_ddx_dT_dT=function func_ddx_dT_dT(),
+    func_ddx_dp_dT=function func_ddx_dp_dT(),
+    func_dh_adsorptive_dT=function MediumSpecificFunctionsForIntegrands.dh_adsorptive_dT(),
+    func_dh_adsorptive_ig_dT=function MediumSpecificFunctionsForIntegrands.dh_adsorptive_ig_dT(),
+    func_v_adsorptive_pT=function MediumSpecificFunctionsForIntegrands.v_adsorptive_pT(),
+    func_dv_adsorptive_dp=function MediumSpecificFunctionsForIntegrands.dv_adsorptive_dp(),
+    func_dv_adsorptive_dT=function MediumSpecificFunctionsForIntegrands.dv_adsorptive_dT(),
+    func_v_adsorpt_pT=function MediumSpecificFunctionsForIntegrands.v_adsorpt_pT(),
+    func_dv_adsorpt_dp=function MediumSpecificFunctionsForIntegrands.dv_adsorpt_dp(),
+    func_dv_adsorpt_dT=function MediumSpecificFunctionsForIntegrands.dv_adsorpt_dT(),
+    p_clausiusClyperon=615,
+    x_adsorpt_lb=0.006,
+    tolerance=1e-2,
+    dp=dp,
+    dT=dT)
+    "Specific heat capacitiy of adsorpt";
+
+  cp_adsorpt_CC = SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_SchwambergerSchmidt_clausiusClapeyron(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    c=c,
+    dc_dT=dc_dT,
+    ddc_dT_dT=ddc_dT_dT,
+    func_p_xT=function func_p_xT(),
+    func_dx_dp=function func_dx_dp(),
+    func_dx_dT=function func_dx_dT(),
+    func_ddx_dp_dp=function func_ddx_dp_dp(),
+    func_ddx_dT_dT=function func_ddx_dT_dT(),
+    func_ddx_dp_dT=function func_ddx_dp_dT(),
+    func_dh_adsorptive_dT=function MediumSpecificFunctionsForIntegrands.dh_adsorptive_dT(),
+    func_dh_adsorptive_ig_dT=function MediumSpecificFunctionsForIntegrands.dh_adsorptive_ig_dT(),
+    p_clausiusClyperon=615,
+    x_adsorpt_lb=0.006,
+    tolerance=1e-2,
+    dT=dT)
+    "Specific heat capacitiy of adsorpt calculated using molar adsorption enthalpy
+    according to Clausius Clapeyron";
+
+  cp_adsorpt_Dubinin = SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_SchwambergerSchmidt_Dubinin(
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    c=c,
+    dc_dT=dc_dT,
+    ddc_dT_dT=ddc_dT_dT,
+    func_p_xT=function func_p_xT(),
+    func_dx_dp=function func_dx_dp(),
+    func_dx_dT=function func_dx_dT(),
+    func_ddx_dp_dp=function func_ddx_dp_dp(),
+    func_ddx_dT_dT=function func_ddx_dT_dT(),
+    func_ddx_dp_dT=function func_ddx_dp_dT(),
+    func_dh_adsorptive_dT=function MediumSpecificFunctionsForIntegrands.dh_adsorptive_dT(),
+    func_dh_adsorptive_ig_dT=function MediumSpecificFunctionsForIntegrands.dh_adsorptive_ig_dT(),
+    func_h_adsorptiveToLiquid_pT=function MediumSpecificFunctions.h_adsorptiveToLiquid_pT(),
+    func_dh_adsorptiveToLiquid_dp=function MediumSpecificFunctionsForIntegrands.dh_adsorptiveToLiquid_dp(),
+    func_dh_adsorptiveToLiquid_dT=function MediumSpecificFunctionsForIntegrands.dh_adsorptiveToLiquid_dT(),
+    func_v_adsorpt_pT=function MediumSpecificFunctionsForIntegrands.v_adsorpt_pT(),
+    func_dv_adsorpt_dp=function MediumSpecificFunctionsForIntegrands.dv_adsorpt_dp(),
+    func_dv_adsorpt_dT=function MediumSpecificFunctionsForIntegrands.dv_adsorpt_dT(),
+    func_beta_adsorpt_pT=function MediumSpecificFunctionsForIntegrands.beta_adsorpt_pT(),
+    func_dbeta_adsorpt_dp=function MediumSpecificFunctionsForIntegrands.dbeta_adsorpt_dp(),
+    func_dbeta_adsorpt_dT=function MediumSpecificFunctionsForIntegrands.dbeta_adsorpt_dT(),
+    func_dW_dA=function func_dW_dA(),
+    func_ddW_dA_dA=function func_ddW_dA_dA(),
+    func_ddW_dA_dT=function func_ddW_dA_dT(),
+    p_clausiusClyperon=615,
+    x_adsorpt_lb=0.006,
+    tolerance=1e-2,
+    dp=dp,
+    dT=dT)
+    "Specific heat capacitiy of adsorptive using molar adsorption enthalpy
+    according to Dubinin model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'cp_WaltonLeVan' function.
+<br/><br/>
+To see the function behavior, plot the variables <i>cp_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_cp_SchwambergerSchmidt;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_WaltonLeVan.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_WaltonLeVan.mo
new file mode 100644
index 0000000..0ded5d4
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/Test_cp_WaltonLeVan.mo
@@ -0,0 +1,287 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Testers;
+model Test_cp_WaltonLeVan
+  "Tester for the function 'cp_WaltonLeVan' and all corresponding functions"
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialTestPure;
+
+  //
+  // Load functions package and select correct medium
+  //
+  package MediumSpecificFunctionsForIntegrands =
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Testers.MediumSpecificFunctions
+      (redeclare final package Medium = Medium)
+    "Library containing medium-specific functions that are used as functional
+    arguments"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+
+  //
+  // Definition of parameters
+  //
+  replaceable function func_x_pT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.x_pT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_x_pT
+    "Classical form of isotherm model: Calculates uptake as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_p_xT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.p_xT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_p_xT
+    "Inverse form of General: Calculates pressure as function of uptake 
+    and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_dx_dp =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dp
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature as 
+    function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_dx_dT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dx_dT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dx_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure as 
+    function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddx_dp_dp =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dp
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature 
+    as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddx_dT_dT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dT_dT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure
+    as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddx_dp_dT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddx_dp_dT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddx_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature
+    as function of pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_dW_dA =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.dW_dA
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dW_dA
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddW_dA_dA =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dA
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dA
+    "Second-order prtial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+  replaceable function func_ddW_dA_dT =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative.ddW_dA_dT
+    constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dT
+    "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    and temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Functions"),
+                choicesAllMatching=true);
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(p_adsorpt) = 0.75 * dc_dT[1]
+    "Predecsriped slope of p_adsorpt";
+  der(T_adsorpt) = 90/20
+    "Predecsriped slope of T_adsorpt";
+
+  //
+  // Calculate coefficients of the isotherm model
+  //
+  c[1] = state_bubble_T.p;
+  c[2] = state_bubble_T.d;
+  c[3] = 5.072313e-1 / 1000;
+  c[4] = 1.305531e2 * 1000 * 0.018;
+  c[5] = -8.492403e1 * 1000 * 0.018;
+  c[6] = 4.128962e-3 / 1000;
+
+  c_pdT[1] = sat_T_pdT.psat;
+  c_pdT[2] = Medium.bubbleDensity(sat=sat_T_pdT);
+  c_pdT[3] = 5.072313e-1 / 1000;
+  c_pdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_pdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_pdT[6] = 4.128962e-3 / 1000;
+
+  c_mdT[1] = sat_T_mdT.psat;
+  c_mdT[2] = Medium.bubbleDensity(sat=sat_T_mdT);
+  c_mdT[3] = 5.072313e-1 / 1000;
+  c_mdT[4] = 1.305531e2 * 1000 * 0.018;
+  c_mdT[5] = -8.492403e1 * 1000 * 0.018;
+  c_mdT[6] = 4.128962e-3 / 1000;
+
+  //
+  // Calculate partial derivatives of coefficients of the isotherm model w.r.t.
+  // temperature
+  //
+  dc_dT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T);
+  dc_dT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T) * dc_dT[1];
+  dc_dT[3] = 0;
+  dc_dT[4] = 0;
+  dc_dT[5] = 0;
+  dc_dT[6] = 0;
+
+  dc_dT_pdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_pdT);
+  dc_dT_pdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_pdT) * dc_dT_pdT[1];
+  dc_dT_pdT[3] = 0;
+  dc_dT_pdT[4] = 0;
+  dc_dT_pdT[5] = 0;
+  dc_dT_pdT[6] = 0;
+
+  dc_dT_mdT[1] = 1/Medium.saturationTemperature_derp_sat(sat=sat_T_mdT);
+  dc_dT_mdT[2] = Medium.dBubbleDensity_dPressure(sat=sat_T_mdT) * dc_dT_mdT[1];
+  dc_dT_mdT[3] = 0;
+  dc_dT_mdT[4] = 0;
+  dc_dT_mdT[5] = 0;
+  dc_dT_mdT[6] = 0;
+
+  //
+  // Calculate second-order partial derivatives of coefficients of the isotherm
+  // model w.r.t. temperature
+  //
+  ddc_dT_dT[1] = (dc_dT_pdT[1] - dc_dT_mdT[1]) / (2*dT);
+  ddc_dT_dT[2] = (dc_dT_pdT[2] - dc_dT_mdT[2]) / (2*dT);
+  ddc_dT_dT[3] = 0;
+  ddc_dT_dT[4] = 0;
+  ddc_dT_dT[5] = 0;
+  ddc_dT_dT[6] = 0;
+
+  //
+  // Calculate properties
+  //
+  x_adsorpt = func_x_pT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    p_adsorpt_lb_start=1,
+    p_adsorpt_ub_start=10,
+    tolerance=100*Modelica.Constants.eps)
+    "Uptake";
+
+  //
+  // Calculate specific heat capacities of adsorpt phase
+  //
+  cp_adsorpt = SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_WaltonLeVan(
+    cp_adsorptive=cp_adsorptive,
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    c=c,
+    dc_dT=dc_dT,
+    ddc_dT_dT=ddc_dT_dT,
+    func_p_xT=function func_p_xT(),
+    func_dx_dp=function func_dx_dp(),
+    func_dx_dT=function func_dx_dT(),
+    func_ddx_dp_dp=function func_ddx_dp_dp(),
+    func_ddx_dT_dT=function func_ddx_dT_dT(),
+    func_ddx_dp_dT=function func_ddx_dp_dT(),
+    func_v_adsorptive_pT=function MediumSpecificFunctionsForIntegrands.v_adsorptive_pT(),
+    func_dv_adsorptive_dp=function MediumSpecificFunctionsForIntegrands.dv_adsorptive_dp(),
+    func_dv_adsorptive_dT=function MediumSpecificFunctionsForIntegrands.dv_adsorptive_dT(),
+    func_v_adsorpt_pT=function MediumSpecificFunctionsForIntegrands.v_adsorpt_pT(),
+    func_dv_adsorpt_dp=function MediumSpecificFunctionsForIntegrands.dv_adsorpt_dp(),
+    func_dv_adsorpt_dT=function MediumSpecificFunctionsForIntegrands.dv_adsorpt_dT(),
+    p_clausiusClyperon=615,
+    x_adsorpt_lb=0.006,
+    tolerance=1e-2,
+    dp=dp,
+    dT=dT)
+    "Specific heat capacitiy of adsorpt";
+
+  cp_adsorpt_CC = SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_WaltonLeVan_clausiusClapeyron(
+    cp_adsorptive=cp_adsorptive,
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    c=c,
+    dc_dT=dc_dT,
+    ddc_dT_dT=ddc_dT_dT,
+    func_p_xT=function func_p_xT(),
+    func_dx_dp=function func_dx_dp(),
+    func_dx_dT=function func_dx_dT(),
+    func_ddx_dp_dp=function func_ddx_dp_dp(),
+    func_ddx_dT_dT=function func_ddx_dT_dT(),
+    func_ddx_dp_dT=function func_ddx_dp_dT(),
+    x_adsorpt_lb=0.006,
+    tolerance=1e-2)
+    "Specific heat capacitiy of adsorpt calculated using molar adsorption enthalpy
+    according to Clausius Clapeyron";
+
+  cp_adsorpt_Dubinin =
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_WaltonLeVan_Dubinin(
+    cp_adsorptive=cp_adsorptive,
+    M_adsorptive=M_adsorptive,
+    T_adsorpt=T_adsorpt,
+    x_adsorpt=x_adsorpt,
+    c=c,
+    dc_dT=dc_dT,
+    ddc_dT_dT=ddc_dT_dT,
+    func_p_xT=function func_p_xT(),
+    func_dx_dp=function func_dx_dp(),
+    func_dx_dT=function func_dx_dT(),
+    func_ddx_dp_dp=function func_ddx_dp_dp(),
+    func_ddx_dT_dT=function func_ddx_dT_dT(),
+    func_ddx_dp_dT=function func_ddx_dp_dT(),
+    func_h_adsorptiveToLiquid_pT=function MediumSpecificFunctions.h_adsorptiveToLiquid_pT(),
+    func_dh_adsorptiveToLiquid_dp=function MediumSpecificFunctionsForIntegrands.dh_adsorptiveToLiquid_dp(),
+    func_dh_adsorptiveToLiquid_dT=function MediumSpecificFunctionsForIntegrands.dh_adsorptiveToLiquid_dT(),
+    func_v_adsorpt_pT=function MediumSpecificFunctionsForIntegrands.v_adsorpt_pT(),
+    func_dv_adsorpt_dp=function MediumSpecificFunctionsForIntegrands.dv_adsorpt_dp(),
+    func_dv_adsorpt_dT=function MediumSpecificFunctionsForIntegrands.dv_adsorpt_dT(),
+    func_beta_adsorpt_pT=function MediumSpecificFunctionsForIntegrands.beta_adsorpt_pT(),
+    func_dbeta_adsorpt_dp=function MediumSpecificFunctionsForIntegrands.dbeta_adsorpt_dp(),
+    func_dbeta_adsorpt_dT=function MediumSpecificFunctionsForIntegrands.dbeta_adsorpt_dT(),
+    func_dW_dA=function func_dW_dA(),
+    func_ddW_dA_dA=function func_ddW_dA_dA(),
+    func_ddW_dA_dT=function func_ddW_dA_dT(),
+    p_clausiusClyperon=615,
+    x_adsorpt_lb=0.006,
+    tolerance=1e-2,
+    dp=dp,
+    dT=dT)
+    "Specific heat capacitiy of adsorptive using molar adsorption enthalpy
+    according to Dubinin model";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'cp_WaltonLeVan' function.
+<br/><br/>
+To see the function behavior, plot the variables <i>cp_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_cp_WaltonLeVan;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/package.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/package.mo
new file mode 100644
index 0000000..199eb35
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+package Testers "Models to test and varify functions for specific heat capacities of adsorpt phases for pure components"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions and models of the
+'PureComponents' package. The test models check the implementation of the functions 
+and models and enable verification of their behavior. In addition, the test models 
+demonstrate the functions' and models' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/package.order b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/package.order
new file mode 100644
index 0000000..dafb296
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/Testers/package.order
@@ -0,0 +1,4 @@
+MediumSpecificFunctions
+Test_cp_ChakrabortyEtAl
+Test_cp_WaltonLeVan
+Test_cp_SchwambergerSchmidt
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_ChakrabortyEtAl.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_ChakrabortyEtAl.mo
new file mode 100644
index 0000000..ab54d18
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_ChakrabortyEtAl.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+function cp_ChakrabortyEtAl
+  "Specific heat capacity of adsorpt phase according to Chakraborty et al. (2007)"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPure_cp;
+
+  input Modelica.Units.SI.SpecificHeatCapacity cp_adsorptive
+    "Specific heat capacity of adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorptive_dT
+    "Partial derivative of specific volume of the adsorptive w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the v_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.MolarEnthalpy h_ads
+    "Molar adsorption enthalpy"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_x
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  cp_adsorpt := cp_adsorptive + (v_adsorptive - T_adsorpt * dv_adsorptive_dT) *
+    h_ads / (M_adsorptive * T_adsorpt * (v_adsorptive - v_adsorpt)) -
+    dh_ads_dT_x / M_adsorptive
+    "Specific heat capacitiy of adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the adsorpt phase for a
+pure component according to Chakraborty et al. (2009).
+</p>
+
+<h4>Main equations</h4>
+<p>
+The specific heat capacity is defined as follows:
+</p>
+<pre>
+    c<sub>x,adsorpt</sub> = (&part;h<sub>adsorpt</sub>/&part;T<sub>adsorpt</sub>)<sub>p</sub> + (&part;h<sub>adsorpt</sub>/&part;p<sub>adsorpt</sub>)<sub>T</sub> * (&part;p<sub>adsorpt</sub>/&part;T<sub>adsorpt</sub>)<sub>x</sub>;
+</pre>
+<p>
+Herein, <i>(&part;h<sub>adsorpt</sub>/&part;T<sub>adsorpt</sub>)<sub>p</sub></i>
+is the partial derivative of the specific enthalpy of the adsorpt w.r.t. temperature
+at constant pressure
+<i>(&part;h<sub>adsorpt</sub>/&part;p<sub>adsorpt</sub>)<sub>T</sub></i>
+is the partial derivative of the specific enthalpy of the adsorpt w.r.t. pressure
+at constant temperature, and 
+<i>(&part;p<sub>adsorpt</sub>/&part;T<sub>adsorpt</sub>)<sub>x</sub></i>
+is the partial derivative of the pressure w.r.t. temperature at constant uptake. Now,
+Chakraborty et al. assume that the adsorpt properties can be substituted by adsorptive
+properties (i.e., gas/vapor phase) and they substitute the Clapeyron equation. Thus, the
+specific heat capacity can be expressed as:
+</p>
+<pre>
+    c<sub>x,adsorpt</sub> = c<sub>p,adsorptive</sub> + (v<sub>adsorptive</sub> - T<sub>adsorpt</sub> * (&part;v<sub>adsorptive</sub>/&part;T)<sub>p</sub>) * h<sub>ads</sub> / (M<sub>adsorptive</sub> * T<sub>adsoropt</sub> * (v<sub>adsorptive</sub> - v<sub>adsorpt</sub>)) - (&part;h<sub>ads</sub>/&part;T)<sub>x</sub>
+</pre>
+<p>
+Herein, <i>T<sub>adsorpt</sub></i> is the equilibrium temperature, <i>c<sub>p,adsorptive</sub></i> 
+is the specific heat capacity of the adsorptive, <i>v<sub>adsorptive</sub></i> is 
+the specific volume of the adsorptive,<i><i>v<sub>adsorpt</sub></i></i> is the
+specific volume of the adsorpt, <i>(&part;v<sub>adsorptive</sub>/&part;T)<sub>p</sub></i> 
+is the partial derivative of the specic volume of the adsorptive w.r.t. temperature
+at constant pressure, <i>h<sub>ads</sub></i> is the molar adsorption enthalpy, 
+<i>(&part;h<sub>ads</sub>/&part;T)<sub>x</sub></i> is the partial derivative of the
+molar enthalpy w.r.t. temperature at constant uptake, and <i>M<sub>adsorptive</sub></i>
+is the molar mass of the adsorptive.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Chakraborty, A. and Saha, B.B. and Ng, K.C. and Koyama, S. and Srinivasan, K. (2009). Theoretical Insight of Physical Adsorption for a Single-Component Adsorbent + Adsorbate System: I. Thermodynamic Property Surfaces, Langmuir, 25:2204-221. DOI: http://doi.org/10.1021/la803289p.
+  </li>
+  <li>
+  Schwamberger, V. and Schmidt, F.P. (2013). Estimating the Heat Capacity of the Adsorbate−Adsorbent System from Adsorption Equilibria Regarding Thermodynamic Consistency, Industrial & Engineering Chemostry Research, 52:16958−16965. DOI: https://doi.org/10.1021/ie4011832.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end cp_ChakrabortyEtAl;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt.mo
new file mode 100644
index 0000000..d6251e9
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt.mo
@@ -0,0 +1,162 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+function cp_SchwambergerSchmidt
+  "Specific heat capacity of adsorpt phase according to Schwamberger and Schmidt (2013)"
+
+  //
+  // Definition of inputs
+  //
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrad_cp;
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorptive_pT "Specific volume of the adsorptive" annotation (Dialog(
+        tab="General", group="Inputs - Functions"), choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorptive_dp "Partial derivative of the specific volume of the adsorptive w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs - Functions"),
+      choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorptive_dT "Partial derivative of the specific volume of the adsorptive w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs - Functions"),
+      choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_ig_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive (ideal gas) 
+    w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorpt_pT "Specific volume of the adsorpt" annotation (Dialog(tab="General",
+        group="Inputs - Functions"), choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorpt_dp "Partial derivative of the specific volume of the adsorpt w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs - Functions"),
+      choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorpt_dT "Partial derivative of the specific volume of the adsorpt w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs - Functions"),
+      choicesAllMatching=true);
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon = 615
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Units.Uptake x_adsorpt_lb = 0
+    "Lower limit for integral (i.e., should be zero)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for solution of integral calculated numerically"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.IntegralSpecificHeatCapacityByUptake int_dh_adsorpt_dT_x
+    "Partial derivative of specific enthalpy of adsorpt w.r.t. temperature at constant
+    uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+algorithm
+  //
+  // Calculate integral
+  //
+  int_dh_adsorpt_dT_x :=Modelica.Math.Nonlinear.quadratureLobatto(
+    f=function
+      SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x(
+      T_adsorpt=T_adsorpt,
+      M_adsorptive=M_adsorptive,
+      c=c,
+      dc_dT=dc_dT,
+      ddc_dT_dT=ddc_dT_dT,
+      func_p_xT=function func_p_xT(),
+      func_dx_dp=function func_dx_dp(),
+      func_dx_dT=function func_dx_dT(),
+      func_ddx_dp_dp=function func_ddx_dp_dp(),
+      func_ddx_dT_dT=function func_ddx_dT_dT(),
+      func_ddx_dp_dT=function func_ddx_dp_dT(),
+      func_v_adsorptive_pT=function func_v_adsorptive_pT(),
+      func_dv_adsorptive_dp=function func_dv_adsorptive_dp(),
+      func_dv_adsorptive_dT=function func_dv_adsorptive_dT(),
+      func_dh_adsorptive_dT=function func_dh_adsorptive_dT(),
+      func_dh_adsorptive_ig_dT=function func_dh_adsorptive_ig_dT(),
+      func_v_adsorpt_pT=function func_v_adsorpt_pT(),
+      func_dv_adsorpt_dp=function func_dv_adsorpt_dp(),
+      func_dv_adsorpt_dT=function func_dv_adsorpt_dT(),
+      p_clausiusClyperon=p_clausiusClyperon,
+      dp=dp,
+      dT=dT),
+    a=x_adsorpt_lb,
+    b=x_adsorpt,
+    tolerance=tolerance)
+  "Partial derivative of the specific enthalpy of the adsorpt w.r.t. temperature 
+  at constant uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+  //
+  // Calculate final result
+  //
+  cp_adsorpt := 1 / (x_adsorpt-x_adsorpt_lb) * int_dh_adsorpt_dT_x
+    "Specific heat capacitiy of adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the adsorpt phase for a
+pure component according to Schwamberger and Schmidt (2013).
+</p>
+
+<h4>Main equations</h4>
+<p>
+The specific heat capacity is defined as follows:
+</p>
+<pre>
+    c<sub>x,adsorpt</sub> = 1 / (x<sub>adsorpt</sub> - x<sub>adsorpt,lb</sub>) * &int; [(&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub>] * dx
+</pre>
+<p>
+Herein, <i>x<sub>adsorpt</sub></i> is the equilibrium uptake, <i>x<sub>adsorpt,lb</sub></i> 
+is the lower bound of the equilibrium uptake, and <i>(&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub></i> 
+is the partial derivative of the specific enthalpy of the adsorpt w.r.t. temperature 
+at constant uptake.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schwamberger, V. and Schmidt, F.P. (2013). Estimating the Heat Capacity of the Adsorbate−Adsorbent System from Adsorption Equilibria Regarding Thermodynamic Consistency, Industrial & Engineering Chemistry Research, 52:16958−16965. DOI: https://doi.org/10.1021/ie4011832.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end cp_SchwambergerSchmidt;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt_Dubinin.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt_Dubinin.mo
new file mode 100644
index 0000000..0bc39c5
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt_Dubinin.mo
@@ -0,0 +1,216 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+function cp_SchwambergerSchmidt_Dubinin
+  "Specific heat capacity of adsorpt phase according to Schwamberger and Schmidt (2013) using the molar adsorption enthalpy accourding to Dubinin"
+
+  //
+  // Definition of inputs
+  //
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrad_cp;
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_ig_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive (ideal gas) 
+    w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_h_adsorptiveToLiquid_pT
+    func_h_adsorptiveToLiquid_pT "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)" annotation (Dialog(tab="General", group=
+          "Inputs - Functions"), choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dp
+    func_dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General",
+        group="Inputs - Functions"), choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dT
+    func_dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General",
+        group="Inputs - Functions"), choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorpt_pT "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorpt_dp "Partial derivative of the specific volume of the adsorpt w.r.t. pressure
+    at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorpt_dT "Partial derivative of the specific volume of the adsorpt w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_beta_pT
+    func_beta_adsorpt_pT
+    "Isobaric expansion coefficient of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dp
+    func_dbeta_adsorpt_dp
+    "Partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. 
+    pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dT
+    func_dbeta_adsorpt_dT
+    "Partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. 
+    temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dW_dA func_dW_dA
+    "Partial derivative of the characteristic curve w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dA func_ddW_dA_dA
+    "Second-order partial derivative of the characteristic curve w.r.t. molar 
+    adsorption potential at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dT func_ddW_dA_dT
+    "Second-order partial derivative of the characteristic curve w.r.t. molar 
+    adsorption potential and temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon = 615
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Units.Uptake x_adsorpt_lb = 0
+    "Lower limit for integral (i.e., should be zero)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for solution of integral calculated numerically"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.IntegralSpecificHeatCapacityByUptake int_dh_adsorpt_dT_x
+    "Partial derivative of specific enthalpy of adsorpt w.r.t. temperature at constant
+    uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+algorithm
+  //
+  // Calculate integral
+  //
+  int_dh_adsorpt_dT_x :=Modelica.Math.Nonlinear.quadratureLobatto(
+    f=function
+      SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x_Dubinin(
+      T_adsorpt=T_adsorpt,
+      M_adsorptive=M_adsorptive,
+      c=c,
+      dc_dT=dc_dT,
+      ddc_dT_dT=ddc_dT_dT,
+      func_p_xT=function func_p_xT(),
+      func_dx_dp=function func_dx_dp(),
+      func_dx_dT=function func_dx_dT(),
+      func_ddx_dp_dp=function func_ddx_dp_dp(),
+      func_ddx_dT_dT=function func_ddx_dT_dT(),
+      func_ddx_dp_dT=function func_ddx_dp_dT(),
+      func_dh_adsorptive_dT=function func_dh_adsorptive_dT(),
+      func_dh_adsorptive_ig_dT=function func_dh_adsorptive_ig_dT(),
+      func_h_adsorptiveToLiquid_pT=function func_h_adsorptiveToLiquid_pT(),
+      func_dh_adsorptiveToLiquid_dp=function func_dh_adsorptiveToLiquid_dp(),
+      func_dh_adsorptiveToLiquid_dT=function func_dh_adsorptiveToLiquid_dT(),
+      func_v_adsorpt_pT=function func_v_adsorpt_pT(),
+      func_dv_adsorpt_dp=function func_dv_adsorpt_dp(),
+      func_dv_adsorpt_dT=function func_dv_adsorpt_dT(),
+      func_beta_adsorpt_pT=function func_beta_adsorpt_pT(),
+      func_dbeta_adsorpt_dp=function func_dbeta_adsorpt_dp(),
+      func_dbeta_adsorpt_dT=function func_dbeta_adsorpt_dT(),
+      func_dW_dA=function func_dW_dA(),
+      func_ddW_dA_dA=function func_ddW_dA_dA(),
+      func_ddW_dA_dT=function func_ddW_dA_dT(),
+      p_clausiusClyperon=p_clausiusClyperon,
+      dp=dp,
+      dT=dT),
+    a=x_adsorpt_lb,
+    b=x_adsorpt,
+    tolerance=tolerance)
+  "Partial derivative of the specific enthalpy of the adsorpt w.r.t. temperature 
+  at constant uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+  //
+  // Calculate final result
+  //
+  cp_adsorpt := 1 / (x_adsorpt-x_adsorpt_lb) * int_dh_adsorpt_dT_x
+    "Specific heat capacitiy of adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the adsorpt phase for a
+pure component according to Schwamberger and Schmidt (2013). The molar sorption enthalpy
+is calculated according to the model of Dubinin.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The specific heat capacity is defined as follows:
+</p>
+<pre>
+    c<sub>x,adsorpt</sub> = 1 / (x<sub>adsorpt</sub> - x<sub>adsorpt,lb</sub>) * &int; [(&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub>] * dx
+</pre>
+<p>
+Herein, <i>x<sub>adsorpt</sub></i> is the equilibrium uptake, <i>x<sub>adsorpt,lb</sub></i> 
+is the lower bound of the equilibrium uptake, and <i>(&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub></i> 
+is the partial derivative of the specific enthalpy of the adsorpt w.r.t. temperature 
+at constant uptake.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schwamberger, V. and Schmidt, F.P. (2013). Estimating the Heat Capacity of the Adsorbate−Adsorbent System from Adsorption Equilibria Regarding Thermodynamic Consistency, Industrial & Engineering Chemistry Research, 52:16958−16965. DOI: https://doi.org/10.1021/ie4011832.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end cp_SchwambergerSchmidt_Dubinin;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt_clausiusClapeyron.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt_clausiusClapeyron.mo
new file mode 100644
index 0000000..dc7b6ae
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_SchwambergerSchmidt_clausiusClapeyron.mo
@@ -0,0 +1,122 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+function cp_SchwambergerSchmidt_clausiusClapeyron
+  "Specific heat capacity of adsorpt phase according to Schwamberger and Schmidt (2013) using the molar adsorption enthalpy accourding to Clausius Clapeyon"
+
+  //
+  // Definition of inputs
+  //
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrad_cp;
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_dT
+    func_dh_adsorptive_ig_dT
+    "Partial deriivative of the specific enthalpy of the adsorptive (ideal gas) 
+    w.r.t. temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon = 615
+    "Maximum pressure up to which the specific enthalpy of the adsorptive is
+    calculated as an ideal gas"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Units.Uptake x_adsorpt_lb = 0
+    "Lower limit for integral (i.e., should be zero)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for solution of integral calculated numerically"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.IntegralSpecificHeatCapacityByUptake int_dh_adsorpt_dT_x
+    "Partial derivative of specific enthalpy of adsorpt w.r.t. temperature at constant
+    uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+algorithm
+  //
+  // Calculate integral
+  //
+  int_dh_adsorpt_dT_x :=Modelica.Math.Nonlinear.quadratureLobatto(
+    f=function
+      SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x_CC(
+      T_adsorpt=T_adsorpt,
+      M_adsorptive=M_adsorptive,
+      c=c,
+      dc_dT=dc_dT,
+      ddc_dT_dT=ddc_dT_dT,
+      func_p_xT=function func_p_xT(),
+      func_dx_dp=function func_dx_dp(),
+      func_dx_dT=function func_dx_dT(),
+      func_ddx_dp_dp=function func_ddx_dp_dp(),
+      func_ddx_dT_dT=function func_ddx_dT_dT(),
+      func_ddx_dp_dT=function func_ddx_dp_dT(),
+      func_dh_adsorptive_dT=function func_dh_adsorptive_dT(),
+      func_dh_adsorptive_ig_dT=function func_dh_adsorptive_ig_dT(),
+      p_clausiusClyperon=p_clausiusClyperon,
+      dT=dT),
+    a=x_adsorpt_lb,
+    b=x_adsorpt,
+    tolerance=tolerance)
+  "Partial derivative of the specific enthalpy of the adsorpt w.r.t. temperature 
+  at constant uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+  //
+  // Calculate final result
+  //
+  cp_adsorpt := 1 / (x_adsorpt-x_adsorpt_lb) * int_dh_adsorpt_dT_x
+    "Specific heat capacitiy of adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the adsorpt phase for a
+pure component according to Schwamberger and Schmidt (2013). The molar sorption 
+enthalpy is calculated according to the Clausius Clapeyron assumptions.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The specific heat capacity is defined as follows:
+</p>
+<pre>
+    c<sub>x,adsorpt</sub> = 1 / (x<sub>adsorpt</sub> - x<sub>adsorpt,lb</sub>) * &int; [(&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub>] * dx
+</pre>
+<p>
+Herein, <i>x<sub>adsorpt</sub></i> is the equilibrium uptake, <i>x<sub>adsorpt,lb</sub></i> 
+is the lower bound of the equilibrium uptake, and <i>(&part;h<sub>adsorpt</sub>/&part;T)<sub>x</sub></i> 
+is the partial derivative of the specific enthalpy of the adsorpt w.r.t. temperature 
+at constant uptake.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schwamberger, V. and Schmidt, F.P. (2013). Estimating the Heat Capacity of the Adsorbate−Adsorbent System from Adsorption Equilibria Regarding Thermodynamic Consistency, Industrial & Engineering Chemistry Research, 52:16958−16965. DOI: https://doi.org/10.1021/ie4011832.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end cp_SchwambergerSchmidt_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan.mo
new file mode 100644
index 0000000..634a674
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan.mo
@@ -0,0 +1,151 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+function cp_WaltonLeVan
+  "Specific heat capacity of adsorpt phase according to Walton and LeVan (2005)"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.SpecificHeatCapacity cp_adsorptive
+    "Specific heat capacity of adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrad_cp;
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorptive_pT "Specific volume of the adsorptive" annotation (Dialog(
+        tab="General", group="Inputs - Functions"), choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorptive_dp "Partial derivative of the specific volume of the adsorptive w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs - Functions"),
+      choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorptive_dT "Partial derivative of the specific volume of the adsorptive w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs - Functions"),
+      choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorpt_pT "Specific volume of the adsorpt" annotation (Dialog(tab="General",
+        group="Inputs - Functions"), choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorpt_dp "Partial derivative of the specific volume of the adsorpt w.r.t. pressure
+    at constant temperature" annotation (Dialog(tab="General", group="Inputs - Functions"),
+      choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorpt_dT "Partial derivative of the specific volume of the adsorpt w.r.t. temperature
+    at constant pressure" annotation (Dialog(tab="General", group="Inputs - Functions"),
+      choicesAllMatching=true);
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon = 615
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Units.Uptake x_adsorpt_lb = 0
+    "Lower limit for integral (i.e., should be zero)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for solution of integral calculated numerically"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.IntegralMolarHeatCapacityByUptake int_dh_ads_dT_x
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+algorithm
+  //
+  // Calculate integral
+  //
+  int_dh_ads_dT_x :=Modelica.Math.Nonlinear.quadratureLobatto(
+    f=function
+      SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x(
+      T_adsorpt=T_adsorpt,
+      M_adsorptive=M_adsorptive,
+      c=c,
+      dc_dT=dc_dT,
+      ddc_dT_dT=ddc_dT_dT,
+      func_p_xT=function func_p_xT(),
+      func_dx_dp=function func_dx_dp(),
+      func_dx_dT=function func_dx_dT(),
+      func_ddx_dp_dp=function func_ddx_dp_dp(),
+      func_ddx_dT_dT=function func_ddx_dT_dT(),
+      func_ddx_dp_dT=function func_ddx_dp_dT(),
+      func_v_adsorptive_pT=function func_v_adsorptive_pT(),
+      func_dv_adsorptive_dp=function func_dv_adsorptive_dp(),
+      func_dv_adsorptive_dT=function func_dv_adsorptive_dT(),
+      func_v_adsorpt_pT=function func_v_adsorpt_pT(),
+      func_dv_adsorpt_dp=function func_dv_adsorpt_dp(),
+      func_dv_adsorpt_dT=function func_dv_adsorpt_dT(),
+      p_clausiusClyperon=p_clausiusClyperon,
+      dp=dp,
+      dT=dT),
+    a=x_adsorpt_lb,
+    b=x_adsorpt,
+    tolerance=tolerance)
+  "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+  uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+  //
+  // Calculate final result
+  //
+  cp_adsorpt := cp_adsorptive - 1 / (x_adsorpt-x_adsorpt_lb) * int_dh_ads_dT_x /
+    M_adsorptive
+    "Specific heat capacitiy of adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the adsorpt phase for a
+pure component according to Walton and LeVan (2005).
+</p>
+
+<h4>Main equations</h4>
+<p>
+The specific heat capacity is defined as follows:
+</p>
+<pre>
+    c<sub>x,adsorpt</sub> = c<sub>p,adsorptive</sub> - 1 / (M<sub>adsorptive</sub> * (x<sub>adsorpt</sub> - x<sub>adsorpt,lb</sub>)) * &int; [(&part;h<sub>ads</sub>/&part;T)<sub>x</sub>] * dx
+</pre>
+<p>
+Herein, <i>x<sub>adsorpt</sub></i> is the equilibrium uptake, <i>x<sub>adsorpt,lb</sub></i> 
+is the lower bound of the equilibrium uptake, <i>(&part;h<sub>ads</sub>/&part;T)<sub>x</sub></i> 
+is the partial derivative of the molar enthalpy w.r.t. temperature at constant uptake, and 
+<i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Walton, K.S. and LeVan, M.D. (2005). Adsorbed-Phase Heat Capacities: Thermodynamically Consistent Values Determined from Temperature-Dependent Equilibrium Models, Industrial & Engineering Chemistry Researc, 44(1):178-182. DOI: https://doi.org/10.1021/ie049394j.
+  </li>
+  <li>
+  Schwamberger, V. and Schmidt, F.P. (2013). Estimating the Heat Capacity of the Adsorbate−Adsorbent System from Adsorption Equilibria Regarding Thermodynamic Consistency, Industrial & Engineering Chemistry Research, 52:16958−16965. DOI: https://doi.org/10.1021/ie4011832.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end cp_WaltonLeVan;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan_Dubinin.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan_Dubinin.mo
new file mode 100644
index 0000000..2d14bc3
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan_Dubinin.mo
@@ -0,0 +1,206 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+function cp_WaltonLeVan_Dubinin
+  "Specific heat capacity of adsorpt phase according to Walton and LeVan (2005) using the molar adsorption enthalpy accourding to Dubinin"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.SpecificHeatCapacity cp_adsorptive
+    "Specific heat capacity of adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrad_cp;
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_h_adsorptiveToLiquid_pT
+    func_h_adsorptiveToLiquid_pT "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)" annotation (Dialog(tab="General", group=
+          "Inputs - Functions"), choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dp
+    func_dh_adsorptiveToLiquid_dp
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature"
+    annotation (Dialog(tab="General",
+        group="Inputs - Functions"), choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dh_adsorptiveToLiquid_dT
+    func_dh_adsorptiveToLiquid_dT
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure"
+    annotation (Dialog(tab="General",
+        group="Inputs - Functions"), choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_v_pT
+    func_v_adsorpt_pT "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dp
+    func_dv_adsorpt_dp "Partial derivative of the specific volume of the adsorpt w.r.t. pressure
+    at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dv_dT
+    func_dv_adsorpt_dT "Partial derivative of the specific volume of the adsorpt w.r.t. temperature
+    at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_beta_pT
+    func_beta_adsorpt_pT
+    "Isobaric expansion coefficient of the adsorpt"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dp
+    func_dbeta_adsorpt_dp
+    "Partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. 
+    pressure at constant temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.Interfaces.Partial_dbeta_dT
+    func_dbeta_adsorpt_dT
+    "Partial derivative of the isobaric expansion coefficient of the adsorpt w.r.t. 
+    temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_dW_dA func_dW_dA
+    "Partial derivative of the characteristic curve w.r.t. molar adsorption potential
+    at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dA func_ddW_dA_dA
+    "Second-order partial derivative of the characteristic curve w.r.t. molar 
+    adsorption potential at constant pressure and temperature"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+  input SorpLib.Media.Functions.SorptionEquilibria.BaseClasses.PartialPure_ddW_dA_dT func_ddW_dA_dT
+    "Second-order partial derivative of the characteristic curve w.r.t. molar 
+    adsorption potential and temperature at constant pressure"
+    annotation (Dialog(tab="General", group="Inputs - Functions"),
+                choicesAllMatching=true);
+
+  input Modelica.Units.SI.Pressure p_clausiusClyperon = 615
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs - Functions"));
+
+  input SorpLib.Units.Uptake x_adsorpt_lb = 0
+    "Lower limit for integral (i.e., should be zero)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for solution of integral calculated numerically"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.IntegralMolarHeatCapacityByUptake int_dh_ads_dT_x
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+algorithm
+  //
+  // Calculate integral
+  //
+  int_dh_ads_dT_x :=Modelica.Math.Nonlinear.quadratureLobatto(
+    f=function
+      SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x_Dubinin(
+      T_adsorpt=T_adsorpt,
+      M_adsorptive=M_adsorptive,
+      c=c,
+      dc_dT=dc_dT,
+      ddc_dT_dT=ddc_dT_dT,
+      func_p_xT=function func_p_xT(),
+      func_dx_dp=function func_dx_dp(),
+      func_dx_dT=function func_dx_dT(),
+      func_ddx_dp_dp=function func_ddx_dp_dp(),
+      func_ddx_dT_dT=function func_ddx_dT_dT(),
+      func_ddx_dp_dT=function func_ddx_dp_dT(),
+      func_h_adsorptiveToLiquid_pT=function func_h_adsorptiveToLiquid_pT(),
+      func_dh_adsorptiveToLiquid_dp=function func_dh_adsorptiveToLiquid_dp(),
+      func_dh_adsorptiveToLiquid_dT=function func_dh_adsorptiveToLiquid_dT(),
+      func_v_adsorpt_pT=function func_v_adsorpt_pT(),
+      func_dv_adsorpt_dp=function func_dv_adsorpt_dp(),
+      func_dv_adsorpt_dT=function func_dv_adsorpt_dT(),
+      func_beta_adsorpt_pT=function func_beta_adsorpt_pT(),
+      func_dbeta_adsorpt_dp=function func_dbeta_adsorpt_dp(),
+      func_dbeta_adsorpt_dT=function func_dbeta_adsorpt_dT(),
+      func_dW_dA=function func_dW_dA(),
+      func_ddW_dA_dA=function func_ddW_dA_dA(),
+      func_ddW_dA_dT=function func_ddW_dA_dT(),
+      p_clausiusClyperon=p_clausiusClyperon,
+      dp=dp,
+      dT=dT),
+    a=x_adsorpt_lb,
+    b=x_adsorpt,
+    tolerance=tolerance)
+  "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+  uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+  //
+  // Calculate final result
+  //
+  cp_adsorpt := cp_adsorptive - 1 / (x_adsorpt-x_adsorpt_lb) * int_dh_ads_dT_x /
+    M_adsorptive
+    "Specific heat capacitiy of adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the adsorpt phase for a
+pure component according to Walton and LeVan (2005). The molar sorption enthalpy
+is calculated according to the model of Dubinin.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The specific heat capacity is defined as follows:
+</p>
+<pre>
+    c<sub>x,adsorpt</sub> = c<sub>p,adsorptive</sub> - 1 / (M<sub>adsorptive</sub> * (x<sub>adsorpt</sub> - x<sub>adsorpt,lb</sub>)) * &int; [(&part;h<sub>ads</sub>/&part;T)<sub>x</sub>] * dx
+</pre>
+<p>
+Herein, <i>x<sub>adsorpt</sub></i> is the equilibrium uptake, <i>x<sub>adsorpt,lb</sub></i> 
+is the lower bound of the equilibrium uptake, <i>(&part;h<sub>ads</sub>/&part;T)<sub>x</sub></i> 
+is the partial derivative of the molar enthalpy w.r.t. temperature at constant uptake, and 
+<i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Walton, K.S. and LeVan, M.D. (2005). Adsorbed-Phase Heat Capacities: Thermodynamically Consistent Values Determined from Temperature-Dependent Equilibrium Models, Industrial & Engineering Chemistry Researc, 44(1):178-182. DOI: https://doi.org/10.1021/ie049394j.
+  </li>
+  <li>
+  Schwamberger, V. and Schmidt, F.P. (2013). Estimating the Heat Capacity of the Adsorbate−Adsorbent System from Adsorption Equilibria Regarding Thermodynamic Consistency, Industrial & Engineering Chemistry Research, 52:16958−16965. DOI: https://doi.org/10.1021/ie4011832.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end cp_WaltonLeVan_Dubinin;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan_clausiusClapeyron.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan_clausiusClapeyron.mo
new file mode 100644
index 0000000..29e51ae
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/cp_WaltonLeVan_clausiusClapeyron.mo
@@ -0,0 +1,101 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents;
+function cp_WaltonLeVan_clausiusClapeyron
+  "Specific heat capacity of adsorpt phase according to Walton and LeVan (2005) using the molar adsorption enthalpy accourding to Clausius Clapeyon"
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.SpecificHeatCapacity cp_adsorptive
+    "Specific heat capacity of adsorptive"
+    annotation (Dialog(tab="General", group="Inputs"));
+  extends
+    SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.BasesClasses.PartialPureIntegrad_cp;
+
+  input SorpLib.Units.Uptake x_adsorpt_lb = 0
+    "Lower limit for integral (i.e., should be zero)"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance for solution of integral calculated numerically"
+    annotation (Dialog(tab="General", group="Inputs - Numerics"));
+
+  //
+  // Definition of variables
+  //
+protected
+  SorpLib.Units.IntegralMolarHeatCapacityByUptake int_dh_ads_dT_x
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+algorithm
+  //
+  // Calculate integral
+  //
+  int_dh_ads_dT_x :=Modelica.Math.Nonlinear.quadratureLobatto(
+    f=function
+      SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x_CC(
+      T_adsorpt=T_adsorpt,
+      M_adsorptive=M_adsorptive,
+      c=c,
+      dc_dT=dc_dT,
+      ddc_dT_dT=ddc_dT_dT,
+      func_p_xT=function func_p_xT(),
+      func_dx_dp=function func_dx_dp(),
+      func_dx_dT=function func_dx_dT(),
+      func_ddx_dp_dp=function func_ddx_dp_dp(),
+      func_ddx_dT_dT=function func_ddx_dT_dT(),
+      func_ddx_dp_dT=function func_ddx_dp_dT()),
+    a=x_adsorpt_lb,
+    b=x_adsorpt,
+    tolerance=tolerance)
+  "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+  uptake integrated from x_adsorpt_lb to x_adsorpt";
+
+  //
+  // Calculate final result
+  //
+  cp_adsorpt := cp_adsorptive - 1 / (x_adsorpt-x_adsorpt_lb) * int_dh_ads_dT_x /
+    M_adsorptive
+    "Specific heat capacitiy of adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the adsorpt phase for a
+pure component according to Walton and LeVan (2005). The molar sorption enthalpy
+is calculated according to the Clausius Clapeyron assumptions.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The specific heat capacity is defined as follows:
+</p>
+<pre>
+    c<sub>x,adsorpt</sub> = c<sub>p,adsorptive</sub> - 1 / (M<sub>adsorptive</sub> * (x<sub>adsorpt</sub> - x<sub>adsorpt,lb</sub>)) * &int; [(&part;h<sub>ads</sub>/&part;T)<sub>x</sub>] * dx
+</pre>
+<p>
+Herein, <i>x<sub>adsorpt</sub></i> is the equilibrium uptake, <i>x<sub>adsorpt,lb</sub></i> 
+is the lower bound of the equilibrium uptake, <i>(&part;h<sub>ads</sub>/&part;T)<sub>x</sub></i> 
+is the partial derivative of the molar enthalpy w.r.t. temperature at constant uptake, and 
+<i>M<sub>adsorptive</sub></i> is the molar mass of the adsorptive.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Walton, K.S. and LeVan, M.D. (2005). Adsorbed-Phase Heat Capacities: Thermodynamically Consistent Values Determined from Temperature-Dependent Equilibrium Models, Industrial & Engineering Chemistry Researc, 44(1):178-182. DOI: https://doi.org/10.1021/ie049394j.
+  </li>
+  <li>
+  Schwamberger, V. and Schmidt, F.P. (2013). Estimating the Heat Capacity of the Adsorbate−Adsorbent System from Adsorption Equilibria Regarding Thermodynamic Consistency, Industrial & Engineering Chemistry Research, 52:16958−16965. DOI: https://doi.org/10.1021/ie4011832.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 20, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end cp_WaltonLeVan_clausiusClapeyron;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/package.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/package.mo
new file mode 100644
index 0000000..40a6233
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/package.mo
@@ -0,0 +1,28 @@
+within SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt;
+package PureComponents "Functions required to calculate specific heat capacities of adsorpt phases for pure components"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models to calculate specific heat capacities of adsorpt 
+phases for pure component adsorption.
+</p>
+
+<h4>Implemented functions for each specific heat capacity model</h4>
+<p>
+The following functions are provided for each specific heat capacity model:
+</p>
+<ul>
+  <li>
+  Specific heat capacity.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PureComponents;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/package.order b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/package.order
new file mode 100644
index 0000000..0bf2ab5
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/PureComponents/package.order
@@ -0,0 +1,9 @@
+Integrands
+cp_ChakrabortyEtAl
+cp_WaltonLeVan
+cp_WaltonLeVan_clausiusClapeyron
+cp_WaltonLeVan_Dubinin
+cp_SchwambergerSchmidt
+cp_SchwambergerSchmidt_clausiusClapeyron
+cp_SchwambergerSchmidt_Dubinin
+Testers
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/package.mo b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/package.mo
new file mode 100644
index 0000000..16dec94
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions;
+package SpecificHeatCapacitiesAdsorpt "Functions required to calculate specific heat capacities of adsorpt phases"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models to calculate specific heat capacities of adsorpt
+phases for pure component and multi-component adsorption. Please check the 
+documentation of the individual packages for more details on the implemented 
+specific heat capacity models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SpecificHeatCapacitiesAdsorpt;
diff --git a/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/package.order b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/package.order
new file mode 100644
index 0000000..2993586
--- /dev/null
+++ b/SorpLib/Media/Functions/SpecificHeatCapacitiesAdsorpt/package.order
@@ -0,0 +1,2 @@
+BasesClasses
+PureComponents
diff --git a/SorpLib/Media/Functions/Testers/TestCharCurve1Arctan.mo b/SorpLib/Media/Functions/Testers/TestCharCurve1Arctan.mo
deleted file mode 100644
index d86b3c6..0000000
--- a/SorpLib/Media/Functions/Testers/TestCharCurve1Arctan.mo
+++ /dev/null
@@ -1,19 +0,0 @@
-within SorpLib.Media.Functions.Testers;
-model TestCharCurve1Arctan
-
-  Modelica.SIunits.SpecificVolume W(start=7.9e-5)
-    "Specific volume of adsorbate";
-  Real dWdA(unit="m3/J")
-    "Derivative of specific volume of adsorbate with respect to the adsorption potential";
-  Modelica.SIunits.SpecificEnergy A(start=3e5) "Adsorption Potential";
-  final parameter Real[4] c={5.072313e-4,1.305531e5,-8.492403e4,4.128962e-6}
-    "Coefficients for characteristic curve";
-
-equation
-  W = SorpLib.Media.Functions.CharCurve1Arctan(A, c);
-  dWdA = SorpLib.Media.Functions.CharCurve1Arctan_dWdA(A, c);
-  A = 1e2 + time*1e4;
-  //W = 7.9e-5+time*1e-5;
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)));
-end TestCharCurve1Arctan;
diff --git a/SorpLib/Media/Functions/Testers/TestCharCurve2Polynomial.mo b/SorpLib/Media/Functions/Testers/TestCharCurve2Polynomial.mo
deleted file mode 100644
index 917226a..0000000
--- a/SorpLib/Media/Functions/Testers/TestCharCurve2Polynomial.mo
+++ /dev/null
@@ -1,28 +0,0 @@
-within SorpLib.Media.Functions.Testers;
-model TestCharCurve2Polynomial
-
-  Modelica.SIunits.SpecificVolume W(start=7.9e-5)
-    "Specific volume of adsorbate";
-  Real dWdA(unit="m3/J")
-    "Derivative of specific volume of adsorbate with respect to the adsorption potential";
-  Modelica.SIunits.SpecificEnergy A(start=3e5) "Adsorption Potential";
-  final parameter Real[3] cNom={5,2,1}
-    "Coefficients for nominator of characteristic curve";
-  final parameter Real[2] cDenom={2,1}
-    "Coefficients for denominator of characteristic curve";
-
-equation
-  W = SorpLib.Media.Functions.CharCurve2Polynomial(
-    A,
-    cNom,
-    cDenom);
-  dWdA =
-    SorpLib.Media.Functions.CharCurve2Polynomial_dWdA(
-    A,
-    cNom,
-    cDenom);
-  A = 1e2 + time*1e4;
-  //W = 7.9e-5+time*1e-5;
-  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
-        coordinateSystem(preserveAspectRatio=false)));
-end TestCharCurve2Polynomial;
diff --git a/SorpLib/Media/Functions/Testers/package.mo b/SorpLib/Media/Functions/Testers/package.mo
deleted file mode 100644
index 83942fd..0000000
--- a/SorpLib/Media/Functions/Testers/package.mo
+++ /dev/null
@@ -1,6 +0,0 @@
-within SorpLib.Media.Functions;
-package Testers
-extends SorpLib.Internals.ClassTypes.ApplicationPackage;
-
-
-end Testers;
diff --git a/SorpLib/Media/Functions/Testers/package.order b/SorpLib/Media/Functions/Testers/package.order
deleted file mode 100644
index 5fdf775..0000000
--- a/SorpLib/Media/Functions/Testers/package.order
+++ /dev/null
@@ -1,2 +0,0 @@
-TestCharCurve1Arctan
-TestCharCurve2Polynomial
diff --git a/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_ddz_dT_dT.mo b/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_ddz_dT_dT.mo
new file mode 100644
index 0000000..c036f0d
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_ddz_dT_dT.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.Functions.Utilities.BasesClasses;
+partial function Partial_ddz_dT_dT
+  "Base function for utility functions calculating the second-order partial derivative of properties w.r.t. temperature as a function of temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real ddz_dT_dT
+    "Second-order partial derivative of fluid property data w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for utility functions that calculate
+the second-order partial derivative of an arbitrary property with respect to 
+temperature as a function of temperature.
+<br/><br/>
+This partial function defines the temperature <i>T</i> as input and the second-
+order partial derivative of the arbitrary property with respect to temperature 
+<i>dz_dT</i> as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+further inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_ddz_dT_dT;
diff --git a/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_dz_dT.mo b/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_dz_dT.mo
new file mode 100644
index 0000000..b4107da
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_dz_dT.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.Functions.Utilities.BasesClasses;
+partial function Partial_dz_dT
+  "Base function for utility functions calculating the partial derivative of properties w.r.t. temperature as a function of temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real dz_dT
+    "Partial derivative of fluid property data w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for utility functions that calculate
+the partial derivative of an arbitrary property with respect to temperature 
+as a function of temperature.
+<br/><br/>
+This partial function defines the temperature <i>T</i> as input and the partial
+derivative of the arbitrary property with respect to temperature <i>dz_dT</i> as 
+output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+further inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dz_dT;
diff --git a/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_int_z_dT.mo b/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_int_z_dT.mo
new file mode 100644
index 0000000..c64e8fb
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_int_z_dT.mo
@@ -0,0 +1,45 @@
+within SorpLib.Media.Functions.Utilities.BasesClasses;
+partial function Partial_int_z_dT
+  "Base function for utility functions calculating the indefinite integral of properties w.r.t. temperature as a function of temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real int_z_dT
+    "Indefinite integral of fluid property data w.r.t. temperature without integration
+    constant"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for utility functions that calculate
+the indefinite integral of an arbitrary property with respect to temperature 
+as a function of temperature.
+<br/><br/>
+This partial function defines the temperature <i>T</i> as input and the indefinite
+integral of the arbitrary property with respect to temperature <i>int_z_dT</i> as 
+output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+further inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_int_z_dT;
diff --git a/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_z_T.mo b/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_z_T.mo
new file mode 100644
index 0000000..4098282
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/BasesClasses/Partial_z_T.mo
@@ -0,0 +1,45 @@
+within SorpLib.Media.Functions.Utilities.BasesClasses;
+partial function Partial_z_T
+  "Base function for utility functions calculating properties as a function of temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real z
+    "Fluid property data"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for utility functions that calculate
+an arbitrary property as a function of temperature.
+<br/><br/>
+This partial function defines the temperature <i>T</i> as input and the arbitrary 
+property <i>z</i> as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+further inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_z_T;
diff --git a/SorpLib/Media/Functions/Utilities/BasesClasses/package.mo b/SorpLib/Media/Functions/Utilities/BasesClasses/package.mo
new file mode 100644
index 0000000..ff7b4eb
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/BasesClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.Functions.Utilities;
+package BasesClasses "Base classes used to build new utility functions"
+  extends Modelica.Icons.BasesPackage;
+
+annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This package contains partial basic functions and models. These partial functions
+and models contain fundamental definitions of utility functions. The content of this 
+package is only of interest when adding new utility functions to the library.
+</p>
+</html>"));
+end BasesClasses;
diff --git a/SorpLib/Media/Functions/Utilities/BasesClasses/package.order b/SorpLib/Media/Functions/Utilities/BasesClasses/package.order
new file mode 100644
index 0000000..920946b
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/BasesClasses/package.order
@@ -0,0 +1,4 @@
+Partial_z_T
+Partial_dz_dT
+Partial_ddz_dT_dT
+Partial_int_z_dT
diff --git a/SorpLib/Media/Functions/Utilities/Testers/Test_cubicSplineInterpolation_T.mo b/SorpLib/Media/Functions/Utilities/Testers/Test_cubicSplineInterpolation_T.mo
new file mode 100644
index 0000000..8c7eab3
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/Testers/Test_cubicSplineInterpolation_T.mo
@@ -0,0 +1,177 @@
+within SorpLib.Media.Functions.Utilities.Testers;
+model Test_cubicSplineInterpolation_T
+  "Tester for the function 'cubicSplineInterpolation_T' and all corresponding functions"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real[21] abscissa = {
+    0.01, 5, 10, 15, 20, 25, 30, 35, 40, 45,
+    50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100} .+ 273.15
+    "Abscissa values";
+  parameter Real[21] ordinate = {
+    206.14, 147.12, 106.38, 77.93, 57.79, 43.36, 32.89, 25.22, 19.52, 15.26,
+    12.03, 9.586, 7.671, 6.197, 5.042, 4.131, 3.407, 2.828, 2.361, 1.982, 1.6729}
+    "Abscissa values";
+
+  final parameter Real[21,4] coefficients=
+    SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients(
+    abscissa=abscissa,
+    ordinate=ordinate)
+    "Coefficient a to d for cubic polynomials";
+
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculated partial derivatives numerically";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Temperature T(start=263.15, fixed=true)
+    "Temperature";
+
+  Real z
+    "Cubic spline interpolation";
+  Real z_num
+    "Linear interpolation calculated numerically";
+
+  Real dz_dT
+    "Partial derivative of cubic spline interpolation w.r.t. temperature";
+  Real dz_dT_num
+    "Partial derivative of cubic spline interpolation w.r.t. temperature calculated 
+    numerically";
+
+  Real ddz_dT_dT
+    "Second-order partial derivative of linear interpolation w.r.t. temperature";
+  Real ddz_dT_dT_num
+    "Second-order partial derivative of linear interpolation w.r.t. temperature
+    calculated numerically";
+
+  Real int_z_dT
+    "Indefinite integral of linear interpolation w.r.t. temperature";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(T) = 120/20
+    "Predecsriped slope of T";
+
+  //
+  // Calculate properties
+  //
+  z=SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+    T=T,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients)
+    "Cubic spline interpolation";
+
+  dz_dT=
+    SorpLib.Media.Functions.Utilities.dcubicSplineInterpolation_dT(
+    T=T,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients)
+    "Partial derivative of cubic spline interpolation w.r.t. temperature";
+  dz_dT_num=
+    (SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+    T=T+dT,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients) -
+    SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+    T=T-dT,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients)) /
+    (2*dT)
+    "Partial derivative of cubic spline interpolation w.r.t. temperature calculated 
+    numerically";
+
+  ddz_dT_dT=
+    SorpLib.Media.Functions.Utilities.ddcubicSplineInterpolation_dT_dT(
+    T=T,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients)
+    "Second-order partial derivative of linear interpolation w.r.t. temperature";
+  ddz_dT_dT_num=
+    (SorpLib.Media.Functions.Utilities.dcubicSplineInterpolation_dT(
+    T=T+dT,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients) -
+    SorpLib.Media.Functions.Utilities.dcubicSplineInterpolation_dT(
+    T=T-dT,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients)) /
+    (2*dT)
+    "Second-order partial derivative of linear interpolation w.r.t. temperature
+    calculated numerically";
+
+  int_z_dT = SorpLib.Media.Functions.Utilities.intCubicSplineInterpolation_dT(
+    T=T,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients)
+    "Indefinite integral of linear interpolation w.r.t. temperature";
+  z_num = (
+    SorpLib.Media.Functions.Utilities.intCubicSplineInterpolation_dT(
+    T=T+dT,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients) -
+    SorpLib.Media.Functions.Utilities.intCubicSplineInterpolation_dT(
+    T=T-dT,
+    abscissa=abscissa,
+    ordinate=ordinate,
+    coefficients=coefficients)) / (2 * dT)
+    "Linear interpolation calculated numerically";
+
+  //
+  // Definition of assertions: Check numerical implementations
+  //
+  assert(abs(dz_dT-dz_dT_num) < 1e-6,
+    "Partial derivative of z is not valied: Deviation (|" +
+    String(abs(dz_dT-dz_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  assert(abs(ddz_dT_dT-ddz_dT_dT_num) < 1e-6,
+    "Second-order partial derivative of z is not valied: Deviation (|" +
+    String(abs(ddz_dT_dT-ddz_dT_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  assert(abs(z-z_num) < 1e-6,
+    "Indefinite integral of of z is not valied: Deviation (|" +
+    String(abs(z-z_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'cubicSplineInterpolation_T' function, its 
+partial derivative with respect to temperature, and its indefinite integral with 
+respect to temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>z_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_cubicSplineInterpolation_T;
diff --git a/SorpLib/Media/Functions/Utilities/Testers/Test_generalizedFunction_T.mo b/SorpLib/Media/Functions/Utilities/Testers/Test_generalizedFunction_T.mo
new file mode 100644
index 0000000..345d626
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/Testers/Test_generalizedFunction_T.mo
@@ -0,0 +1,617 @@
+within SorpLib.Media.Functions.Utilities.Testers;
+model Test_generalizedFunction_T
+  "Tester for the function 'generalizedFunction_T' and all corresponding functions"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculated partial derivatives numerically";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Temperature T(start=273.15, fixed=true)
+    "Temperature";
+
+  //
+  // Generalized function
+  //
+  Real z_polynomialTemperature
+    "Polynomial function using temperature for calculation";
+  Real z_polynomialReducedTemperature
+    "Polynomial function using reduced temperature for calculation";
+  Real z_exponentialTemperature
+    "Exponential function using temperature for calculation";
+  Real z_exponentialReducedTemperature
+    "Exponential function using reduced temperature for calculation";
+
+  Real z_polynomialTemperatureNum
+    "Polynomial function using temperature for calculation calculated numerically
+    from integral";
+  Real z_polynomialReducedTemperatureNum
+    "Polynomial function using reduced temperature for calculation calculated 
+    numerically from integral";
+  Real z_exponentialTemperatureNum
+    "Exponential function using temperature for calculation calculated numerically
+    from integral";
+  Real z_exponentialReducedTemperatureNum
+    "Exponential function using reduced temperature for calculation calculated
+    numerically from integral";
+
+  //
+  // Partial derivative of generalized function w.r.t. temperature
+  //
+  Real dz_dT_polynomialTemperature
+    "Partial derivative of polynomial function using temperature for calculation
+    w.r.t. temperature";
+  Real dz_dT_polynomialReducedTemperature
+    "Partial derivative of polynomial function using reduced temperature for 
+    calculation w.r.t. temperature";
+  Real dz_dT_exponentialTemperature
+    "Partial derivative of exponential function using temperature for calculation
+    w.r.t. temperature";
+  Real dz_dT_exponentialReducedTemperature
+    "Partial derivative of exponential function using reduced temperature for 
+    calculation w.r.t. temperature";
+
+  Real dz_dT_polynomialTemperatureNum
+    "Partial derivative of polynomial function using temperature for calculation
+    w.r.t. temperature calculated numerically";
+  Real dz_dT_polynomialReducedTemperatureNum
+    "Partial derivative of polynomial function using reduced temperature for 
+    calculation w.r.t. temperature calculated numerically";
+  Real dz_dT_exponentialTemperatureNum
+    "Partial derivative of exponential function using temperature for calculation
+    w.r.t. temperature calculated numerically";
+  Real dz_dT_exponentialReducedTemperatureNum
+    "Partial derivative of exponential function using reduced temperature for 
+    calculation w.r.t. temperature calculated numerically";
+
+  //
+  // Second-order partial derivative of generalized function w.r.t. temperature
+  //
+  Real ddz_dT_dT_polynomialTemperature
+    "Second-order partial derivative of polynomial function using temperature for 
+    calculation w.r.t. temperature";
+  Real ddz_dT_dT_polynomialReducedTemperature
+    "Second-order partial derivative of polynomial function using reduced 
+    temperature for calculation w.r.t. temperature";
+  Real ddz_dT_dT_exponentialTemperature
+    "Second-order partial derivative of exponential function using temperature 
+    for calculation  w.r.t. temperature";
+  Real ddz_dT_dT_exponentialReducedTemperature
+    "Second-order partial derivative of exponential function using reduced 
+    temperature for  calculation w.r.t. temperature";
+
+  Real ddz_dT_dT_polynomialTemperatureNum
+    "Second-order partial derivative of polynomial function using temperature for 
+    calculation w.r.t. temperature calculated numerically";
+  Real ddz_dT_dT_polynomialReducedTemperatureNum
+    "Second-order partial derivative of polynomial function using reduced 
+    temperature for calculation w.r.t. temperature calculated numerically";
+  Real ddz_dT_dT_exponentialTemperatureNum
+    "Second-order partial derivative of exponential function using temperature 
+    for calculation  w.r.t. temperature calculated numerically";
+  Real ddz_dT_dT_exponentialReducedTemperatureNum
+    "Second-order partial derivative of exponential function using reduced 
+    temperature for  calculation w.r.t. temperature calculated numerically";
+
+  //
+  // Idefinite integral of generalized function w.r.t. temperature
+  //
+  Real int_z_dT_polynomialTemperature
+    "Indefinite integral of polynomial function using temperature for calculation
+    w.r.t. temperature";
+  Real int_z_dT_polynomialReducedTemperature
+    "Indefinite integral of polynomial function using reduced temperature for 
+    calculation w.r.t. temperature";
+  Real int_z_dT_exponentialTemperature
+    "Indefinite integral of exponential function using temperature for calculation
+    w.r.t. temperature";
+  Real int_z_dT_exponentialReducedTemperature
+    "Indefinite integral of exponential function using reduced temperature for 
+    calculation w.r.t. temperature";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(T) = 100/20
+    "Predecsriped slope of T";
+
+  //
+  // Generalized function
+  //
+  z_polynomialTemperature=
+    SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Polynomial function using temperature for calculation";
+  z_polynomialReducedTemperature=
+    SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature)
+    "Polynomial function using reduced temperature for calculation";
+  z_exponentialTemperature=
+    SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature)
+    "Exponential function using temperature for calculation";
+  z_exponentialReducedTemperature=
+    SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature)
+    "Exponential function using reduced temperature for calculation";
+
+  //
+  // Partial derivative of generalized function w.r.t. temperature
+  //
+  dz_dT_polynomialTemperature=
+    SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Partial derivative of polynomial function using temperature for calculation
+    w.r.t. temperature";
+  dz_dT_polynomialReducedTemperature=
+    SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature)
+    "Partial derivative of polynomial function using reduced temperature for 
+    calculation w.r.t. temperature";
+  dz_dT_exponentialTemperature=
+    SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature)
+    "Partial derivative of exponential function using temperature for calculation
+    w.r.t. temperature";
+  dz_dT_exponentialReducedTemperature=
+    SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature)
+    "Partial derivative of exponential function using reduced temperature for 
+    calculation w.r.t. temperature";
+
+  dz_dT_polynomialTemperatureNum=(
+    SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+     - SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature))
+    /(2*dT)
+    "Partial derivative of polynomial function using temperature for calculation
+    w.r.t. temperature calculated numerically";
+  dz_dT_polynomialReducedTemperatureNum=(
+    SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature)
+     - SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature))
+    /(2*dT)
+    "Partial derivative of polynomial function using reduced temperature for 
+    calculation w.r.t. temperature calculated numerically";
+  dz_dT_exponentialTemperatureNum=(
+    SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature)
+     - SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature))
+    /(2*dT)
+    "Partial derivative of exponential function using temperature for calculation
+    w.r.t. temperature calculated numerically";
+  dz_dT_exponentialReducedTemperatureNum=(
+    SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature)
+     - SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature))
+    /(2*dT)
+    "Partial derivative of exponential function using reduced temperature for 
+    calculation w.r.t. temperature calculated numerically";
+
+  //
+  // Second-order partial derivative of generalized function w.r.t. temperature
+  //
+  ddz_dT_dT_polynomialTemperature=
+    SorpLib.Media.Functions.Utilities.ddgeneralizedFunction_dT_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Second-order partial derivative of polynomial function using temperature for 
+    calculation w.r.t. temperature";
+  ddz_dT_dT_polynomialReducedTemperature=
+    SorpLib.Media.Functions.Utilities.ddgeneralizedFunction_dT_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature)
+    "Second-order partial derivative of polynomial function using reduced 
+    temperature for calculation w.r.t. temperature";
+  ddz_dT_dT_exponentialTemperature=
+    SorpLib.Media.Functions.Utilities.ddgeneralizedFunction_dT_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature)
+    "Second-order partial derivative of exponential function using temperature 
+    for calculation  w.r.t. temperature";
+  ddz_dT_dT_exponentialReducedTemperature=
+    SorpLib.Media.Functions.Utilities.ddgeneralizedFunction_dT_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature)
+    "Second-order partial derivative of exponential function using reduced 
+    temperature for  calculation w.r.t. temperature";
+
+  ddz_dT_dT_polynomialTemperatureNum=(
+    SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+     - SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature))
+    /(2*dT)
+    "Second-order partial derivative of polynomial function using temperature for 
+    calculation w.r.t. temperature calculated numerically";
+  ddz_dT_dT_polynomialReducedTemperatureNum=(
+    SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature)
+     - SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature))
+    /(2*dT)
+    "Second-order partial derivative of polynomial function using reduced 
+    temperature for calculation w.r.t. temperature calculated numerically";
+  ddz_dT_dT_exponentialTemperatureNum=(
+    SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature)
+     - SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature))
+    /(2*dT)
+    "Second-order partial derivative of exponential function using temperature 
+    for calculation  w.r.t. temperature calculated numerically";
+  ddz_dT_dT_exponentialReducedTemperatureNum=(
+    SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature)
+     - SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature))
+    /(2*dT)
+    "Second-order partial derivative of exponential function using reduced 
+    temperature for  calculation w.r.t. temperature calculated numerically";
+
+  //
+  // Idefinite integral of generalized function w.r.t. temperature
+  //
+  int_z_dT_polynomialTemperature =
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Indefinite integral of polynomial function using temperature for calculation
+    w.r.t. temperature";
+  int_z_dT_polynomialReducedTemperature =
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature)
+    "Indefinite integral of polynomial function using reduced temperature for 
+    calculation w.r.t. temperature";
+  int_z_dT_exponentialTemperature =
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature)
+    "Indefinite integral of exponential function using temperature for calculation
+    w.r.t. temperature";
+  int_z_dT_exponentialReducedTemperature =
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature)
+    "Indefinite integral of exponential function using reduced temperature for 
+    calculation w.r.t. temperature";
+
+  z_polynomialTemperatureNum =(
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+     - SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.1,0.2,0.3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature))
+    /(2*dT)
+    "Polynomial function using temperature for calculation calculated numerically
+    from integral";
+  z_polynomialReducedTemperatureNum =(
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature)
+     - SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={1,1.99274064,1.09965342,-0.510839303,-1.75493479,-45.5170352,
+      -6.74694450e5},
+    exponents={0,1/3,2/3,5/3,16/3,43/3,110/3},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature))
+    /(2*dT)
+    "Polynomial function using reduced temperature for calculation calculated 
+    numerically from integral";
+  z_exponentialTemperatureNum =(
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature)
+     - SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=5,
+    coefficients={0,1,1,3},
+    exponents={0,0.01,0.02,0.03},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature))
+    /(2*dT)
+    "Exponential function using temperature for calculation calculated numerically
+    from integral";
+  z_exponentialReducedTemperatureNum =(
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T + dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature)
+     - SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+    T=T - dT,
+    T_ref=647.096,
+    z_ref=322,
+    coefficients={-2.03150240,-2.68302940,-5.38626492,-17.2991605,-44.7586581,-63.9201063},
+    exponents={2/6,4/6,8/6,18/6,37/6,71/6},
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature))
+    /(2*dT)
+    "Exponential function using reduced temperature for calculation calculated
+    numerically from integral";
+
+  //
+  // Definition of assertions: Check numerical implementations
+  //
+  assert(abs(dz_dT_polynomialTemperature-dz_dT_polynomialTemperatureNum) < 1e-6,
+    "Partial derivative of dz_dT_polynomialTemperature is not valied: Deviation (|" +
+    String(abs(dz_dT_polynomialTemperature-dz_dT_polynomialTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(dz_dT_polynomialReducedTemperature-dz_dT_polynomialReducedTemperatureNum) < 1e-6,
+    "Partial derivative of dz_dT_polynomialTemperature is not valied: Deviation (|" +
+    String(abs(dz_dT_polynomialReducedTemperature-dz_dT_polynomialReducedTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(dz_dT_exponentialTemperature-dz_dT_exponentialTemperatureNum) < 1e-6,
+    "Partial derivative of dz_dT_polynomialTemperature is not valied: Deviation (|" +
+    String(abs(dz_dT_exponentialTemperature-dz_dT_exponentialTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(dz_dT_exponentialReducedTemperature-dz_dT_exponentialReducedTemperatureNum) < 1e-6,
+    "Partial derivative of dz_dT_polynomialTemperature is not valied: Deviation (|" +
+    String(abs(dz_dT_exponentialReducedTemperature-dz_dT_exponentialReducedTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  assert(abs(ddz_dT_dT_polynomialTemperature-ddz_dT_dT_polynomialTemperatureNum) < 1e-6,
+    "Second-order partial derivative of ddz_dT_dT_polynomialTemperature is not " +
+    "valied: Deviation (|" +
+    String(abs(ddz_dT_dT_polynomialTemperature-ddz_dT_dT_polynomialTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(ddz_dT_dT_polynomialReducedTemperature-ddz_dT_dT_polynomialReducedTemperatureNum) < 1e-6,
+    "Second-order partial derivative of ddz_dT_dT_polynomialTemperature is not " +
+    "valied: Deviation (|" +
+    String(abs(ddz_dT_dT_polynomialReducedTemperature-ddz_dT_dT_polynomialReducedTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(ddz_dT_dT_exponentialTemperature-ddz_dT_dT_exponentialTemperatureNum) < 1e-6,
+    "Second-order partial derivative of ddz_dT_dT_polynomialTemperature is not " +
+    "valied: Deviation (|" +
+    String(abs(ddz_dT_dT_exponentialTemperature-ddz_dT_dT_exponentialTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(ddz_dT_dT_exponentialReducedTemperature-ddz_dT_dT_exponentialReducedTemperatureNum) < 1e-6,
+    "Second-order partial derivative of ddz_dT_dT_polynomialTemperature is not " +
+    "valied: Deviation (|" +
+    String(abs(ddz_dT_dT_exponentialReducedTemperature-ddz_dT_dT_exponentialReducedTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  assert(abs(z_polynomialTemperature-z_polynomialTemperatureNum) < 1e-6,
+    "Indefinite integral of z_polynomialTemperature is not valied: Deviation (|" +
+    String(abs(z_polynomialTemperature-z_polynomialTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(z_polynomialReducedTemperature-z_polynomialReducedTemperatureNum) < 1e-6,
+    "Indefinite integral of z_polynomialTemperature is not valied: Deviation (|" +
+    String(abs(z_polynomialReducedTemperature-z_polynomialReducedTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(z_exponentialTemperature-z_exponentialTemperatureNum) < 1e-6,
+    "Indefinite integral of z_polynomialTemperature is not valied: Deviation (|" +
+    String(abs(z_exponentialTemperature-z_exponentialTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(z_exponentialReducedTemperature-z_exponentialReducedTemperatureNum) < 1e-6,
+    "Indefinite integral of z_polynomialTemperature is not valied: Deviation (|" +
+    String(abs(z_exponentialReducedTemperature-z_exponentialReducedTemperatureNum)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'generalizedFunction_T' function, its partial 
+derivative with respect to temperature, and its indefinite integral with respect to 
+temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>z_polynomialTemperatureI</i>
+over the time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s).  
+</p>
+</html>"));
+end Test_generalizedFunction_T;
diff --git a/SorpLib/Media/Functions/Utilities/Testers/Test_linearInterpolation_T.mo b/SorpLib/Media/Functions/Utilities/Testers/Test_linearInterpolation_T.mo
new file mode 100644
index 0000000..330eda8
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/Testers/Test_linearInterpolation_T.mo
@@ -0,0 +1,161 @@
+within SorpLib.Media.Functions.Utilities.Testers;
+model Test_linearInterpolation_T
+  "Tester for the function 'linearInterpolation_T' and all corresponding functions"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real[21] abscissa = {
+    0.01, 5, 10, 15, 20, 25, 30, 35, 40, 45,
+    50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100} .+ 273.15
+    "Abscissa values";
+  parameter Real[21] ordinate = {
+    206.14, 147.12, 106.38, 77.93, 57.79, 43.36, 32.89, 25.22, 19.52, 15.26,
+    12.03, 9.586, 7.671, 6.197, 5.042, 4.131, 3.407, 2.828, 2.361, 1.982, 1.6729}
+    "Abscissa values";
+
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculated partial derivatives numerically";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Temperature T(start=263.15, fixed=true)
+    "Temperature";
+
+  Real z
+    "Linear interpolation";
+  Real z_num
+    "Linear interpolation calculated numerically";
+
+  Real dz_dT
+    "Partial derivative of linear interpolation w.r.t. temperature";
+  Real dz_dT_num
+    "Partial derivative of linear interpolation w.r.t. temperature calculated 
+    numerically";
+
+  Real ddz_dT_dT
+    "Second-order partial derivative of linear interpolation w.r.t. temperature";
+  Real ddz_dT_dT_num
+    "Second-order partial derivative of linear interpolation w.r.t. temperature
+    calculated numerically";
+
+  Real int_z_dT
+    "Indefinite integral of linear interpolation w.r.t. temperature";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(T) = 120/20
+    "Predecsriped slope of T";
+
+  //
+  // Calculate properties
+  //
+  z=SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+    T=T,
+    abscissa=abscissa,
+    ordinate=ordinate)
+    "Linear interpolation";
+
+  dz_dT=
+    SorpLib.Media.Functions.Utilities.dlinearInterpolation_dT(
+    T=T,
+    abscissa=abscissa,
+    ordinate=ordinate)
+    "Partial derivative of linear interpolation w.r.t. temperature";
+  dz_dT_num=
+    (SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+    T=T+dT,
+    abscissa=abscissa,
+    ordinate=ordinate) -
+    SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+    T=T-dT,
+    abscissa=abscissa,
+    ordinate=ordinate)) /
+    (2*dT)
+    "Partial derivative of linear interpolation w.r.t. temperature calculated 
+    numerically";
+
+  ddz_dT_dT=
+    SorpLib.Media.Functions.Utilities.ddlinearInterpolation_dT_dT(
+    T=T,
+    abscissa=abscissa,
+    ordinate=ordinate)
+    "Second-order partial derivative of linear interpolation w.r.t. temperature";
+  ddz_dT_dT_num=
+    (SorpLib.Media.Functions.Utilities.dlinearInterpolation_dT(
+    T=T+dT,
+    abscissa=abscissa,
+    ordinate=ordinate) -
+    SorpLib.Media.Functions.Utilities.dlinearInterpolation_dT(
+    T=T-dT,
+    abscissa=abscissa,
+    ordinate=ordinate)) /
+    (2*dT)
+    "Second-order partial derivative of linear interpolation w.r.t. temperature
+    calculated numerically";
+
+  int_z_dT = SorpLib.Media.Functions.Utilities.intLinearInterpolation_dT(
+    T=T,
+    abscissa=abscissa,
+    ordinate=ordinate)
+    "Indefinite integral of linear interpolation w.r.t. temperature";
+  z_num = (
+    SorpLib.Media.Functions.Utilities.intLinearInterpolation_dT(
+    T=T+dT,
+    abscissa=abscissa,
+    ordinate=ordinate) -
+    SorpLib.Media.Functions.Utilities.intLinearInterpolation_dT(
+    T=T-dT,
+    abscissa=abscissa,
+    ordinate=ordinate)) / (2 * dT)
+    "Linear interpolation calculated numerically";
+
+  //
+  // Definition of assertions: Check numerical implementations
+  //
+  assert(abs(dz_dT-dz_dT_num) < 1e-6,
+    "Partial derivative of z is not valied: Deviation (|" +
+    String(abs(dz_dT-dz_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  assert(abs(ddz_dT_dT-ddz_dT_dT_num) < 1e-6,
+    "Second-order partial derivative of z is not valied: Deviation (|" +
+    String(abs(ddz_dT_dT-ddz_dT_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  assert(abs(z-z_num) < 1e-6,
+    "Indefinite integral of of z is not valied: Deviation (|" +
+    String(abs(z-z_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'linearInterpolation_T' function, its partial 
+derivative with respect to temperature, and its indefinite integral with respect to 
+temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>z_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_linearInterpolation_T;
diff --git a/SorpLib/Media/Functions/Utilities/Testers/package.mo b/SorpLib/Media/Functions/Utilities/Testers/package.mo
new file mode 100644
index 0000000..b7b8530
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/Testers/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.Functions.Utilities;
+package Testers "Models to test and/or varify utility functions or models"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions and models of the
+'Utilities' package. The test models check the implementation of the functions and
+models and enable verification of their behavior. In addition, the test models 
+demonstrate the functions' and models' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Functions/Utilities/Testers/package.order b/SorpLib/Media/Functions/Utilities/Testers/package.order
new file mode 100644
index 0000000..901be58
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/Testers/package.order
@@ -0,0 +1,3 @@
+Test_generalizedFunction_T
+Test_linearInterpolation_T
+Test_cubicSplineInterpolation_T
diff --git a/SorpLib/Media/Functions/Utilities/calcCubicSplineCoefficients.mo b/SorpLib/Media/Functions/Utilities/calcCubicSplineCoefficients.mo
new file mode 100644
index 0000000..a526a3d
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/calcCubicSplineCoefficients.mo
@@ -0,0 +1,176 @@
+within SorpLib.Media.Functions.Utilities;
+function calcCubicSplineCoefficients
+  "Calculates coefficients a, b, c, and d for cubic spline interpolation as a function of abscissa and ordinate values"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real coefficients[size(abscissa,1), 4]
+    "Coefficient a to d for cubic polynomials"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real h[size(abscissa,1)-1]
+    "Interval lengths";
+
+  Real alpha[size(abscissa,1)-1]
+    "Intermediate values for solving system";
+  Real l[size(abscissa,1)]
+    "Lower diagonal of tridiagonal matrix";
+  Real mu[size(abscissa,1)-1]
+    "Upper diagonal of tridiagonal matrix";
+  Real zeta[size(abscissa,1)]
+    "Solution vector for second derivatives";
+
+  Real a[size(abscissa,1)]
+    "Coefficient a for cubic polynomials";
+  Real b[size(abscissa,1)]
+    "Coefficient b for cubic polynomials";
+  Real c[size(abscissa,1)]
+    "Coefficient c for cubic polynomials (i.e., second derivatives at data 
+    points)";
+  Real d[size(abscissa,1)]
+    "Coefficient d for cubic polynomials";
+
+algorithm
+  //
+  // Initialize values
+  //
+  for ind in 1:size(abscissa,1) - 1 loop
+    h[ind]:= abscissa[ind + 1] - abscissa[ind]
+      "Interval lengths";
+  end for;
+
+  alpha := zeros(size(abscissa,1)-1)
+    "Intermediate values for solving system";
+  l := ones(size(abscissa,1))
+    "Lower diagonal of tridiagonal matrix";
+  mu := zeros(size(abscissa,1)-1)
+    "Upper diagonal of tridiagonal matrix";
+  zeta := zeros(size(abscissa,1))
+    "Solution vector for second derivatives";
+
+  a := ordinate
+    "Coefficient a for cubic polynomials";
+  b := zeros(size(abscissa,1))
+    "Coefficient b for cubic polynomials";
+  c := zeros(size(abscissa,1))
+    "Coefficient c for cubic polynomials (i.e., second derivatives at data 
+    points)";
+  d := zeros(size(abscissa,1))
+    "Coefficient d for cubic polynomials";
+
+  //
+  // System of equations required to solve for the second derivatives
+  //
+  for ind in 2:size(abscissa,1)-1 loop
+    alpha[ind] := (3/h[ind]) * (ordinate[ind+1] - ordinate[ind]) -
+      (3/h[ind-1]) * (ordinate[ind] - ordinate[ind-1])
+      "Intermediate values for solving system";
+  end for;
+
+  //
+  // Solve the tridiagonal system using the Thomas algorithm
+  //
+  for ind in 2:size(abscissa,1)-1 loop
+    l[ind] := 2 * (abscissa[ind+1] - abscissa[ind-1]) - h[ind-1] * mu[ind-1]
+      "Lower diagonal of tridiagonal matrix";
+    mu[ind] := h[ind] / l[ind]
+      "Upper diagonal of tridiagonal matrix";
+    zeta[ind] := (alpha[ind] - h[ind-1] * zeta[ind-1]) / l[ind]
+      "Solution vector for second derivatives";
+  end for;
+
+  //
+  // Back substitution to find the c-values
+  //
+  for ind in 1:size(abscissa,1)-1 loop
+    c[size(abscissa,1)-ind] := zeta[size(abscissa,1)-ind] -
+      mu[size(abscissa,1)-ind] * c[size(abscissa,1)-ind+1]
+      "Coefficient c for cubic pilynomials (i.e., second derivatives at data 
+      points)";
+  end for;
+
+  //
+  // Calculate the b- and d-values
+  //
+  for ind in 1:size(abscissa,1)-1 loop
+    b[ind] := (ordinate[ind+1] - ordinate[ind]) / h[ind] -
+      h[ind] * (c[ind+1] + 2 * c[ind]) / 3
+      "Coefficient b for cubic polynomials";
+    d[ind] := (c[ind+1] - c[ind]) / (3 * h[ind])
+      "Coefficient d for cubic polynomials";
+  end for;
+
+  //
+  // Return coefficients
+  //
+  coefficients[:, 1] :=a
+    "Coefficient a for cubic polynomials";
+  coefficients[:, 2] :=b
+    "Coefficient b for cubic polynomials";
+  coefficients[:, 3] :=c
+    "Coefficient c for cubic polynomials";
+  coefficients[:, 4] :=d
+    "Coefficient d for cubic polynomials";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates piecewise cubic spline interpolation coefficients as 
+function abscissa and ordinate values. 
+</p>
+
+<h4>Main equations</h4>
+<p>
+Cubic spline interpolation involves fitting a third-degree polynomial for each 
+interval [<i>T<sub>i</sub></i>;<i>T<sub>i+1</sub></i>] between two neighboring  
+abscissa values:
+</p>
+<pre>
+    z<sub>i</sub>(T) = a<sub>i</sub></i> + b<sub>i</sub> * (T - T<sub>i</sub>) + c<sub>i</sub> * (T - T<sub>i</sub>)<sup>2</sup> + d<sub>i</sub> * (T - T<sub>i</sub>)<sup>3</sup>;
+</pre>
+<p>
+Herein, a, b, c , and d describe the coefficients of the polynomial. A system of 
+equations is created to determine the coefficients. For this purpose, the function 
+values and the first and second derivatives of the polynomials of two neighboring  
+intervals are equated at the common abscissa values. Natural cubic splines are 
+assumed as a further boundary condition, i.e., the second derivatives are zero at 
+the boundary points of the abscissa values. The resulting system of equations can 
+be solved efficiently using the tridiagonal matrix algorithm.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wikipedia - Spline Interpolation: https://en.wikipedia.org/wiki/Spline_interpolation.
+  </li>
+  <li>
+  Wikipedia - Tridiagonal Matrix Algorithm: https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calcCubicSplineCoefficients;
diff --git a/SorpLib/Media/Functions/Utilities/cubicSplineInterpolation_T.mo b/SorpLib/Media/Functions/Utilities/cubicSplineInterpolation_T.mo
new file mode 100644
index 0000000..10ba9ee
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/cubicSplineInterpolation_T.mo
@@ -0,0 +1,102 @@
+within SorpLib.Media.Functions.Utilities;
+function cubicSplineInterpolation_T
+  "Interpolates an arbitrary fluid property z via cubic splines"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_z_T;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real coefficients[size(abscissa,1),4]
+    "Coefficient a to d for cubic polynomials"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Integer ind_gv
+    "Index of abscissa that is greater than actual temperature";
+
+algorithm
+  if T <= abscissa[1] then
+    z := ordinate[1]
+      "Fluid property data";
+
+  elseif T >= abscissa[end] then
+    z := ordinate[end]
+      "Fluid property data";
+
+  else
+    ind_gv :=1
+      "Index of abscissa that is greater than actual temperature";
+
+    while T > abscissa[ind_gv+1] loop
+      ind_gv :=ind_gv + 1
+        "Index of abscissa that is greater than actual temperature";
+    end while;
+
+    z := coefficients[ind_gv,1] +
+      coefficients[ind_gv,2] * (T - abscissa[ind_gv]) +
+      coefficients[ind_gv,3] * (T - abscissa[ind_gv])^2 +
+      coefficients[ind_gv,4] * (T - abscissa[ind_gv])^3
+      "Fluid property data";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates an arbitrary fluid property z via piecewise cubic spline 
+interpolation as a function of temperature as well as known abscissa and ordinate 
+value. Examples of the arbitrary fluid property <i>z</i> are the specific
+heat capacity <i>c</i> or the specific volume <i>v</i>.
+<br><br>
+The coefficients of the cubic splines must be calculated via the function
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients\">SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients</a>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+Cubic spline interpolation involves fitting a third-degree polynomial for each 
+interval [<i>T<sub>i</sub></i>;<i>T<sub>i+1</sub></i>] between two neighboring  
+abscissa values:
+</p>
+<pre>
+    z<sub>i</sub>(T) = a<sub>i</sub></i> + b<sub>i</sub> * (T - T<sub>i</sub>) + c<sub>i</sub> * (T - T<sub>i</sub>)<sup>2</sup> + d<sub>i</sub> * (T - T<sub>i</sub>)<sup>3</sup>;
+</pre>
+<p>
+Herein, a, b, c , and d describe the coefficients of the polynomial. A system of 
+equations is created to determine the coefficients. For this purpose, the function 
+values and the first and second derivatives of the polynomials of two neighboring  
+intervals are equated at the common abscissa values. Natural cubic splines are 
+assumed as a further boundary condition, i.e., the second derivatives are zero at 
+the boundary points of the abscissa values. The resulting system of equations can 
+be solved efficiently using the tridiagonal matrix algorithm.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wikipedia - Spline Interpolation: https://en.wikipedia.org/wiki/Spline_interpolation.
+  </li>
+  <li>
+  Wikipedia - Tridiagonal Matrix Algorithm: https://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end cubicSplineInterpolation_T;
diff --git a/SorpLib/Media/Functions/Utilities/dcubicSplineInterpolation_dT.mo b/SorpLib/Media/Functions/Utilities/dcubicSplineInterpolation_dT.mo
new file mode 100644
index 0000000..cb23dfa
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/dcubicSplineInterpolation_dT.mo
@@ -0,0 +1,69 @@
+within SorpLib.Media.Functions.Utilities;
+function dcubicSplineInterpolation_dT
+  "Partial derivative of arbitrary fluid property z interpolated via cubic splines w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_dz_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real coefficients[size(abscissa,1),4]
+    "Coefficient a to d for cubic polynomials"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Integer ind_gv
+    "Index of abscissa that is greater than actual temperature";
+
+algorithm
+  if T <= abscissa[1] then
+    dz_dT := 0
+      "Partial derivative of fluid property data w.r.t. temperature";
+
+  elseif T >= abscissa[end] then
+    dz_dT := 0
+      "Partial derivative of fluid property data w.r.t. temperature";
+
+  else
+    ind_gv :=1
+      "Index of abscissa that is greater than actual temperature";
+
+    while T > abscissa[ind_gv+1] loop
+      ind_gv :=ind_gv + 1
+        "Index of abscissa that is greater than actual temperature";
+    end while;
+
+    dz_dT := coefficients[ind_gv,2] +
+      2 * coefficients[ind_gv,3] * (T - abscissa[ind_gv]) +
+      3 * coefficients[ind_gv,4] * (T - abscissa[ind_gv])^2
+      "Partial derivative of fluid property data w.r.t. temperature";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'cubicSplineInterpolation_T' 
+with respect to the temperature. For full details of the original function
+'cubicSplineInterpolation_T,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T\">SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dcubicSplineInterpolation_dT;
diff --git a/SorpLib/Media/Functions/Utilities/ddcubicSplineInterpolation_dT_dT.mo b/SorpLib/Media/Functions/Utilities/ddcubicSplineInterpolation_dT_dT.mo
new file mode 100644
index 0000000..e38739b
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/ddcubicSplineInterpolation_dT_dT.mo
@@ -0,0 +1,69 @@
+within SorpLib.Media.Functions.Utilities;
+function ddcubicSplineInterpolation_dT_dT
+  "Second-order partial derivative of arbitrary fluid property z interpolated via cubic splines w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_ddz_dT_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real coefficients[size(abscissa,1),4]
+    "Coefficient a to d for cubic polynomials"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Integer ind_gv
+    "Index of abscissa that is greater than actual temperature";
+
+algorithm
+  if T <= abscissa[1] then
+    ddz_dT_dT := 0
+      "Second-order partial derivative of fluid property data w.r.t. temperature";
+
+  elseif T >= abscissa[end] then
+    ddz_dT_dT := 0
+      "Second-order partial derivative of fluid property data w.r.t. temperature";
+
+  else
+    ind_gv :=1
+      "Index of abscissa that is greater than actual temperature";
+
+    while T > abscissa[ind_gv+1] loop
+      ind_gv :=ind_gv + 1
+        "Index of abscissa that is greater than actual temperature";
+    end while;
+
+    ddz_dT_dT := 2 * coefficients[ind_gv,3] +
+      6 * coefficients[ind_gv,4] * (T - abscissa[ind_gv])
+      "Second-order partial derivative of fluid property data w.r.t. temperature";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the second-order partial derivative of the function 
+'cubicSplineInterpolation_T' with respect to the temperature. For full details of 
+the original function 'cubicSplineInterpolation_T,' check the documentation of the 
+function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T\">SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddcubicSplineInterpolation_dT_dT;
diff --git a/SorpLib/Media/Functions/Utilities/ddgeneralizedFunction_dT_dT.mo b/SorpLib/Media/Functions/Utilities/ddgeneralizedFunction_dT_dT.mo
new file mode 100644
index 0000000..15de84e
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/ddgeneralizedFunction_dT_dT.mo
@@ -0,0 +1,140 @@
+within SorpLib.Media.Functions.Utilities;
+function ddgeneralizedFunction_dT_dT
+  "Calculates second-order partial derivative of an arbitrary media property z via a generalized function w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_ddz_dT_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_ref
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real z_ref
+    "Reference fluid property data"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real coefficients[:]
+    "Coefficients of generalized function"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real exponents[size(coefficients,1)]
+    "Exponents of generalized function"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Choices.GeneralizedFunctionApproach approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Function approach" annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real z
+    "Fluid property data";
+  Real dz_dT
+    "Partial derivative of fluid property data w.r.t. temperature";
+
+algorithm
+  //
+  // Check approach
+  //
+  z := 0
+    "Fluid property data";
+  dz_dT := 0
+    "Partial derivative of fluid property data w.r.t. temperature";
+  ddz_dT_dT := 0
+    "Second-order partial derivative of fluid property data w.r.t. temperature";
+
+  if approach == SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature then
+    for ind in 1:size(coefficients,1) loop
+      if not (Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) or
+        Modelica.Math.isEqual(s1=exponents[ind]-1, s2=0, eps=100*Modelica.Constants.eps)) then
+        ddz_dT_dT := ddz_dT_dT + (exponents[ind] * (exponents[ind] - 1) *
+          coefficients[ind] * T ^ (exponents[ind] - 2))
+          "Second-order partial derivative of fluid property data w.r.t. 
+          temperature";
+      end if;
+    end for;
+
+    ddz_dT_dT := z_ref * ddz_dT_dT
+      "Second-order partial derivative of fluid property data w.r.t. temperature";
+
+  elseif approach == SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature then
+    for ind in 1:size(coefficients,1) loop
+      if not (Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) or
+        Modelica.Math.isEqual(s1=exponents[ind]-1, s2=0, eps=100*Modelica.Constants.eps)) then
+        ddz_dT_dT := ddz_dT_dT + (exponents[ind] * (exponents[ind] - 1) *
+          coefficients[ind] * (1 - T / T_ref) ^ (exponents[ind] - 2))
+          "Second-order partial derivative of fluid property data w.r.t. 
+          temperature";
+      end if;
+    end for;
+
+    ddz_dT_dT := z_ref * (-1 / T_ref) ^ 2 * ddz_dT_dT
+      "Second-order partial derivative of fluid property data w.r.t. temperature";
+
+  elseif approach == SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature then
+    for ind in 1:size(coefficients,1) loop
+      z := z + coefficients[ind] * T ^ exponents[ind]
+        "Fluid property data";
+
+      if not Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) then
+        dz_dT := dz_dT + (exponents[ind] * coefficients[ind] *
+          T ^ (exponents[ind] - 1))
+          "Partial derivative of fluid property data w.r.t. temperature";
+      end if;
+
+      if not (Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) or
+        Modelica.Math.isEqual(s1=exponents[ind]-1, s2=0, eps=100*Modelica.Constants.eps)) then
+        ddz_dT_dT := ddz_dT_dT + (exponents[ind] * (exponents[ind] - 1) *
+          coefficients[ind] * T ^ (exponents[ind] - 2))
+          "Second-order partial derivative of fluid property data w.r.t. 
+          temperature";
+      end if;
+    end for;
+
+    ddz_dT_dT := z_ref * exp(z) * (dz_dT^2 + ddz_dT_dT)
+      "Second-order partial derivative of fluid property data w.r.t. temperature";
+
+  else
+    for ind in 1:size(coefficients,1) loop
+      z := z + coefficients[ind] * (1 - T/T_ref) ^ exponents[ind]
+        "Fluid property data";
+
+      if not Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) then
+        dz_dT := dz_dT + (exponents[ind] * coefficients[ind] * (1 - T / T_ref) ^
+          (exponents[ind] - 1))
+          "Partial derivative of fluid property data w.r.t. temperature";
+      end if;
+
+      if not (Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) or
+        Modelica.Math.isEqual(s1=exponents[ind]-1, s2=0, eps=100*Modelica.Constants.eps)) then
+        ddz_dT_dT := ddz_dT_dT + (exponents[ind] * (exponents[ind] - 1) *
+          coefficients[ind] * (1 - T / T_ref) ^ (exponents[ind] - 2))
+          "Second-order partial derivative of fluid property data w.r.t. 
+          temperature";
+      end if;
+    end for;
+
+    ddz_dT_dT := z_ref * exp(z) * (-1 / T_ref) ^2 * (dz_dT^2 + ddz_dT_dT)
+      "Second-order partial derivative of fluid property data w.r.t. temperature";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the second-order partial derivative of the function 
+'generalizedFunction_T' with respect to the temperature. For full details of the 
+original function 'generalizedFunction_T,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.generalizedFunction_T\">SorpLib.Media.Functions.Utilities.generalizedFunction_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddgeneralizedFunction_dT_dT;
diff --git a/SorpLib/Media/Functions/Utilities/ddlinearInterpolation_dT_dT.mo b/SorpLib/Media/Functions/Utilities/ddlinearInterpolation_dT_dT.mo
new file mode 100644
index 0000000..688b01d
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/ddlinearInterpolation_dT_dT.mo
@@ -0,0 +1,38 @@
+within SorpLib.Media.Functions.Utilities;
+function ddlinearInterpolation_dT_dT
+  "Second-order partial derivative of linearly interpolated arbitrary fluid property z w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_ddz_dT_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  ddz_dT_dT :=0
+    "Second-order partial derivative of fluid property data w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the second-order partial derivative of the function 
+'linearInterpolation_T' with respect to the temperature. For full details of the 
+original function 'linearInterpolation_T,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.linearInterpolation_T\">SorpLib.Media.Functions.Utilities.linearInterpolation_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddlinearInterpolation_dT_dT;
diff --git a/SorpLib/Media/Functions/Utilities/dgeneralizedFunction_dT.mo b/SorpLib/Media/Functions/Utilities/dgeneralizedFunction_dT.mo
new file mode 100644
index 0000000..3f395f1
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/dgeneralizedFunction_dT.mo
@@ -0,0 +1,116 @@
+within SorpLib.Media.Functions.Utilities;
+function dgeneralizedFunction_dT
+  "Calculates partial derivative of an arbitrary media property z via a generalized function w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_dz_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_ref
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real z_ref
+    "Reference fluid property data"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real coefficients[:]
+    "Coefficients of generalized function"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real exponents[size(coefficients,1)]
+    "Exponents of generalized function"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Choices.GeneralizedFunctionApproach approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Function approach" annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real z
+    "Fluid property data";
+
+algorithm
+  //
+  // Check approach
+  //
+  z := 0
+    "Fluid property data";
+  dz_dT :=0
+    "Partial derivative of fluid property data w.r.t. temperature";
+
+  if approach == SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature then
+    for ind in 1:size(coefficients,1) loop
+      if not Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) then
+        dz_dT := dz_dT + (exponents[ind] * coefficients[ind] *
+          T ^ (exponents[ind] - 1))
+          "Partial derivative of fluid property data w.r.t. temperature";
+      end if;
+    end for;
+
+    dz_dT := z_ref * dz_dT
+      "Partial derivative of fluid property data w.r.t. temperature";
+
+  elseif approach == SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature then
+    for ind in 1:size(coefficients,1) loop
+      if not Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) then
+        dz_dT := dz_dT + (exponents[ind] * coefficients[ind] * (1 - T / T_ref) ^
+          (exponents[ind] - 1))
+          "Partial derivative of fluid property data w.r.t. temperature";
+      end if;
+    end for;
+
+    dz_dT := z_ref * (-1 / T_ref) * dz_dT
+      "Partial derivative of fluid property data w.r.t. temperature";
+
+  elseif approach == SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature then
+    for ind in 1:size(coefficients,1) loop
+      z := z + coefficients[ind] * T ^ exponents[ind]
+        "Fluid property data";
+
+      if not Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) then
+        dz_dT := dz_dT + (exponents[ind] * coefficients[ind] *
+          T ^ (exponents[ind] - 1))
+          "Partial derivative of fluid property data w.r.t. temperature";
+      end if;
+    end for;
+
+    dz_dT := z_ref * exp(z) * dz_dT
+      "Partial derivative of fluid property data w.r.t. temperature";
+
+  else
+    for ind in 1:size(coefficients,1) loop
+      z := z + coefficients[ind] * (1 - T/T_ref) ^ exponents[ind]
+        "Fluid property data";
+
+      if not Modelica.Math.isEqual(s1=exponents[ind], s2=0, eps=100*Modelica.Constants.eps) then
+        dz_dT := dz_dT + (exponents[ind] * coefficients[ind] * (1 - T / T_ref) ^
+          (exponents[ind] - 1))
+          "Partial derivative of fluid property data w.r.t. temperature";
+      end if;
+    end for;
+
+    dz_dT := z_ref * exp(z) * (-1 / T_ref) * dz_dT
+      "Partial derivative of fluid property data w.r.t. temperature";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'generalizedFunction_T' 
+with respect to the temperature. For full details of the original function
+'generalizedFunction_T,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.generalizedFunction_T\">SorpLib.Media.Functions.Utilities.generalizedFunction_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dgeneralizedFunction_dT;
diff --git a/SorpLib/Media/Functions/Utilities/dlinearInterpolation_dT.mo b/SorpLib/Media/Functions/Utilities/dlinearInterpolation_dT.mo
new file mode 100644
index 0000000..0a4fa7d
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/dlinearInterpolation_dT.mo
@@ -0,0 +1,68 @@
+within SorpLib.Media.Functions.Utilities;
+function dlinearInterpolation_dT
+  "Partial derivative of linearly interpolated arbitrary fluid property z w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_dz_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Integer ind_gv
+    "Index of abscissa that is greater than actual temperature";
+
+algorithm
+  if T <= abscissa[1] then
+    dz_dT := 0
+    "Partial derivative of fluid property data w.r.t. temperature";
+
+  elseif T >= abscissa[end] then
+    dz_dT := 0
+    "Partial derivative of fluid property data w.r.t. temperature";
+
+  else
+    //
+    // Finde abscissa that is greater than actual temperature
+    //
+    ind_gv :=1
+      "Index of abscissa that is greater than actual temperature";
+
+      while T > abscissa[ind_gv] loop
+      ind_gv :=ind_gv + 1
+        "Index of abscissa that is greater than actual temperature";
+    end while;
+
+    dz_dT := (ordinate[ind_gv] - ordinate[ind_gv-1]) /
+      (abscissa[ind_gv] - abscissa[ind_gv-1])
+    "Partial derivative of fluid property data w.r.t. temperature";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'linearInterpolation_T' 
+with respect to the temperature. For full details of the original function
+'linearInterpolation_T,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.linearInterpolation_T\">SorpLib.Media.Functions.Utilities.linearInterpolation_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dlinearInterpolation_dT;
diff --git a/SorpLib/Media/Functions/Utilities/generalizedFunction_T.mo b/SorpLib/Media/Functions/Utilities/generalizedFunction_T.mo
new file mode 100644
index 0000000..53d1eeb
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/generalizedFunction_T.mo
@@ -0,0 +1,142 @@
+within SorpLib.Media.Functions.Utilities;
+function generalizedFunction_T
+  "Calculates an arbitrary fluid property z via a generalized function"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_z_T;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_ref
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real z_ref
+    "Reference fluid property data"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real coefficients[:]
+    "Coefficients of generalized function"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real exponents[size(coefficients,1)]
+    "Exponents of generalized function"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Choices.GeneralizedFunctionApproach approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Function approach" annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  //
+  // Check approach
+  //
+  z := 0
+    "Fluid property data";
+
+  if approach == SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature then
+    if not Modelica.Math.isEqual(s1=T, s2=0, eps=100*Modelica.Constants.eps) then
+      for ind in 1:size(coefficients,1) loop
+        z := z + coefficients[ind] * T ^ exponents[ind]
+          "Fluid property data";
+      end for;
+    end if;
+
+    z := z_ref * z
+      "Fluid property data";
+
+  elseif approach == SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature then
+    if not Modelica.Math.isEqual(s1=T, s2=T_ref, eps=100*Modelica.Constants.eps) then
+      for ind in 1:size(coefficients,1) loop
+        z := z + coefficients[ind] * (1 - T/T_ref) ^ exponents[ind]
+          "Fluid property data";
+      end for;
+    end if;
+
+    z := z_ref * z
+      "Fluid property data";
+
+
+  elseif approach == SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionTemperature then
+    if not Modelica.Math.isEqual(s1=T, s2=0, eps=100*Modelica.Constants.eps) then
+      for ind in 1:size(coefficients,1) loop
+        z := z + coefficients[ind] * T ^ exponents[ind]
+          "Fluid property data";
+      end for;
+    end if;
+
+    z := z_ref * exp(z)
+      "Fluid property data";
+
+  else
+    if not Modelica.Math.isEqual(s1=T, s2=T_ref, eps=100*Modelica.Constants.eps) then
+      for ind in 1:size(coefficients,1) loop
+        z := z + coefficients[ind] * (1 - T/T_ref) ^ exponents[ind]
+          "Fluid property data";
+      end for;
+    end if;
+
+    z := z_ref * exp(z)
+      "Fluid property data";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates an arbitrary fluid property <i>z</i> via a generalized function 
+as a function of temperature. Examples of the arbitrary fluid property <i>z</i> are
+the specific heat capacity <i>c</i> or the specific volume <i>v</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The generalized function comprises four function types often used for fluid
+property data calculation. The function type depends on the input <i>approach</i>:
+</p>
+<ol>
+  <li>
+  For <i>approach = PolynomialFunction_Temperature</i>:
+  <br>
+  <pre>z = z<sub>ref</sub> * &sum;<sub>i</sub> a<sub>i</sub> * T ^ (b<sub>i</sub>);</pre>
+  <br>
+  </li>
+  <li>
+  For <i>approach = PolynomialFunction_ReducedTemperature</i>:
+  <br>
+  <pre>z = z<sub>ref</sub> * &sum;<sub>i</sub> a<sub>i</sub> * (1 - T / T<sub>ref</sub>) ^ (b<sub>i</sub>);</pre>
+  <br>
+  </li>
+  <li>
+  For <i>approach = ExponentialFunction_Temperature</i>:
+  <br>
+  <pre>z = z<sub>ref</sub> * <strong>exp</strong>(&sum;<sub>i</sub> a<sub>i</sub> * T ^ (b<sub>i</sub>));</pre>
+  <br>
+  </li>
+  <li>
+  For <i>approach = ExponentialFunction_ReducedTemperature</i>:
+  <br>
+  <pre>z = z<sub>ref</sub> * <strong>exp</strong>(&sum;<sub>i</sub> a<sub>i</sub> * (1 - T / T<sub>ref</sub>) ^ (b<sub>i</sub>));</pre>
+  <br>
+  </li>
+</ol>
+<p>
+Herein, <i>z<sub>ref</sub></i> is either a pre-factor for approaches that use the 
+temperature or the fluid property at reference temperature <i>T<sub>ref</sub></i> 
+for approaches that use the reduced temperature. The vectors <i>a</i> and <i>b</i>
+contain the coefficients and exponents for each summand of the sum.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wagner, W. and Pru&szlig;, A (2002). The IAPWS Formulation 1995 for the Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use, Journal of Physical and Chemical Reference Data, 31:387. DOI: https://doi.org/10.1063/1.1461829.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end generalizedFunction_T;
diff --git a/SorpLib/Media/Functions/Utilities/intCubicSplineInterpolation_dT.mo b/SorpLib/Media/Functions/Utilities/intCubicSplineInterpolation_dT.mo
new file mode 100644
index 0000000..1c3693f
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/intCubicSplineInterpolation_dT.mo
@@ -0,0 +1,74 @@
+within SorpLib.Media.Functions.Utilities;
+function intCubicSplineInterpolation_dT
+  "Indefinite integral of arbitrary fluid property z interpolated via cubic splines w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_int_z_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real coefficients[size(abscissa,1),4]
+    "Coefficient a to d for cubic polynomials"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Integer ind_gv
+    "Index of abscissa that is greater than actual temperature";
+
+algorithm
+  if T <= abscissa[1] then
+    int_z_dT := ordinate[1] * T
+      "Indefinite integral of fluid property data w.r.t. temperature without 
+      integration constant";
+
+  elseif T >= abscissa[end] then
+    int_z_dT := ordinate[end] * T
+      "Indefinite integral of fluid property data w.r.t. temperature without 
+      integration constant";
+
+  else
+    ind_gv :=1
+      "Index of abscissa that is greater than actual temperature";
+
+    while T > abscissa[ind_gv+1] loop
+      ind_gv :=ind_gv + 1
+        "Index of abscissa that is greater than actual temperature";
+    end while;
+
+    int_z_dT := coefficients[ind_gv,1] * T +
+      coefficients[ind_gv,2] / 2 * (T - abscissa[ind_gv])^2 +
+      coefficients[ind_gv,3] / 3 * (T - abscissa[ind_gv])^3 +
+      coefficients[ind_gv,4] / 4 * (T - abscissa[ind_gv])^3
+      "Indefinite integral of fluid property data w.r.t. temperature without 
+      integration constant";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the indefinite integral of the function 'cubicSplineInterpolation_T' 
+with respect to the temperature. Note that the integration constant is neglected.
+For full details of the original function 'cubicSplineInterpolation_T,' check the 
+documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T\">SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end intCubicSplineInterpolation_dT;
diff --git a/SorpLib/Media/Functions/Utilities/intGeneralizedFunction_dT.mo b/SorpLib/Media/Functions/Utilities/intGeneralizedFunction_dT.mo
new file mode 100644
index 0000000..5305fe8
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/intGeneralizedFunction_dT.mo
@@ -0,0 +1,111 @@
+within SorpLib.Media.Functions.Utilities;
+function intGeneralizedFunction_dT
+  "Calculates indefinite integral of an arbitrary media property z via a generalized function w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_int_z_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_ref
+    "Reference temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real z_ref
+    "Reference fluid property data"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real coefficients[:]
+    "Coefficients of generalized function"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real exponents[size(coefficients,1)]
+    "Exponents of generalized function"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real tolerance = 100*Modelica.Constants.eps
+    "Tolerance if numerical integration is required"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input SorpLib.Choices.GeneralizedFunctionApproach approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Function approach" annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  //
+  // Check approach
+  //
+  int_z_dT := 0
+    "Indefinite integral of fluid property data w.r.t. temperature without integration
+    constant";
+
+  if approach == SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature then
+    //
+    // Analytical solution exists
+    //
+    for ind in 1:size(coefficients,1) loop
+      if not Modelica.Math.isEqual(s1=exponents[ind], s2=-1, eps=100*Modelica.Constants.eps) then
+        int_z_dT := int_z_dT + coefficients[ind] * T ^ (exponents[ind] + 1) /
+          (exponents[ind] + 1)
+          "Indefinite integral of fluid property data w.r.t. temperature without integration
+          constant";
+      else
+        int_z_dT := int_z_dT + coefficients[ind] * log(abs(T))
+          "Indefinite integral of fluid property data w.r.t. temperature without integration
+          constant";
+      end if;
+    end for;
+
+    int_z_dT := z_ref * int_z_dT
+      "Indefinite integral of fluid property data w.r.t. temperature without integration
+      constant";
+
+  elseif approach == SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature then
+    //
+    // Analytical solution exists
+    //
+    for ind in 1:size(coefficients,1) loop
+      if not Modelica.Math.isEqual(s1=exponents[ind], s2=-1, eps=100*Modelica.Constants.eps) then
+        int_z_dT := int_z_dT - coefficients[ind] * T_ref * (1 - T / T_ref) ^
+          (exponents[ind] + 1) / (exponents[ind] + 1)
+          "Indefinite integral of fluid property data w.r.t. temperature without integration
+          constant";
+      else
+        int_z_dT := int_z_dT - coefficients[ind] * T_ref * log(abs(1 - T / T_ref))
+          "Indefinite integral of fluid property data w.r.t. temperature without integration
+          constant";
+      end if;
+    end for;
+
+    int_z_dT := z_ref * int_z_dT
+      "Indefinite integral of fluid property data w.r.t. temperature without integration
+      constant";
+
+  else
+    //
+    // Analytical solution does not exist for 'ExponentialFunction_Temperature'
+    // and 'ExponentialFunction_ReducedTemperature'
+    //
+    assert(false,
+      "An analytical integral does not exist for the approach: " + String(approach) + ". Only a specific integral can be determined numerically.",
+      level = AssertionLevel.warning);
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the indefinite integral of the function 'generalizedFunction_T' 
+with respect to the temperature. The integral can only be solved analytically for
+the approaches 'PolynomialFunction_Temperature' and 'PolynomialFunction_ReducedTemperature.' 
+Note that the integration constant is neglected. For full details of the original 
+function 'generalizedFunction_T,' check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.generalizedFunction_T\">SorpLib.Media.Functions.Utilities.generalizedFunction_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end intGeneralizedFunction_dT;
diff --git a/SorpLib/Media/Functions/Utilities/intLinearInterpolation_dT.mo b/SorpLib/Media/Functions/Utilities/intLinearInterpolation_dT.mo
new file mode 100644
index 0000000..34e2b5d
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/intLinearInterpolation_dT.mo
@@ -0,0 +1,74 @@
+within SorpLib.Media.Functions.Utilities;
+function intLinearInterpolation_dT
+  "Indefinite integral of linearly interpolated arbitrary fluid property z w.r.t. temperature"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_int_z_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Integer ind_gv
+    "Index of abscissa that is greater than actual temperature";
+
+algorithm
+  if T <= abscissa[1] then
+    int_z_dT := ordinate[1] * T
+      "Indefinite integral of fluid property data w.r.t. temperature without 
+      integration constant";
+
+  elseif T >= abscissa[end] then
+    int_z_dT := ordinate[end] * T
+      "Indefinite integral of fluid property data w.r.t. temperature without 
+      integration constant";
+
+  else
+    //
+    // Finde abscissa that is greater than actual temperature
+    //
+    ind_gv :=1
+      "Index of abscissa that is greater than actual temperature";
+
+      while T > abscissa[ind_gv] loop
+      ind_gv :=ind_gv + 1
+        "Index of abscissa that is greater than actual temperature";
+    end while;
+
+    int_z_dT := ordinate[ind_gv-1] * T +
+      (ordinate[ind_gv] - ordinate[ind_gv-1]) /
+      (abscissa[ind_gv] - abscissa[ind_gv-1]) *
+      (T^2 / 2 - abscissa[ind_gv-1] * T)
+      "Indefinite integral of fluid property data w.r.t. temperature without 
+      integration constant";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the indefinite integral of the function 'linearInterpolation_T' 
+with respect to the temperature. Note that the integration constant is neglected.
+For full details of the original function 'linearInterpolation_T,' check the 
+documentation of the function 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.linearInterpolation_T\">SorpLib.Media.Functions.Utilities.linearInterpolation_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end intLinearInterpolation_dT;
diff --git a/SorpLib/Media/Functions/Utilities/linearInterpolation_T.mo b/SorpLib/Media/Functions/Utilities/linearInterpolation_T.mo
new file mode 100644
index 0000000..087c0d6
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/linearInterpolation_T.mo
@@ -0,0 +1,88 @@
+within SorpLib.Media.Functions.Utilities;
+function linearInterpolation_T
+  "Interpolates an arbitrary fluid property z linearly"
+  extends SorpLib.Media.Functions.Utilities.BasesClasses.Partial_z_T;
+
+  //
+  // Definition of inputs
+  //
+  input Real abscissa[:]
+    "Known abscissa values"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ordinate[size(abscissa,1)]
+    "Known ordinate values"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Integer ind_gv
+    "Index of abscissa that is greater than actual temperature";
+
+algorithm
+  if T <= abscissa[1] then
+    z := ordinate[1]
+      "Fluid property data";
+
+  elseif T >= abscissa[end] then
+    z := ordinate[end]
+      "Fluid property data";
+
+  else
+    //
+    // Finde abscissa that is greater than actual temperature
+    //
+    ind_gv :=1
+      "Index of abscissa that is greater than actual temperature";
+
+    while T > abscissa[ind_gv] loop
+      ind_gv :=ind_gv + 1
+        "Index of abscissa that is greater than actual temperature";
+    end while;
+
+    z := ordinate[ind_gv-1] +
+      (ordinate[ind_gv] - ordinate[ind_gv-1]) /
+      (abscissa[ind_gv] - abscissa[ind_gv-1]) *
+      (T - abscissa[ind_gv-1])
+      "Fluid property data";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates an arbitrary fluid property <i>z</i> via piecewise linear 
+interpolation as a function of temperature as well as known abscissa and ordinate 
+values. Examples for the arbitrary fluid property <i>z</i> are the specific heat 
+capacity <i>c</i> or the specific volume <i>v</i>.
+</p>
+
+<h4>Main equations</h4>
+<p>
+For a given temperature <i>T</i>, the arbitrary fluid property <i>z</i> is calculated
+using abscissa <i>z<sub>known</sub></i> and its corresponding ordinate <i>T<sub>known</sub></i>, 
+values that are closest to the given temperature <i>T</i>:
+</p>
+<pre>
+    z = z<sub>known,smaller</sub> + (z<sub>known,greater</sub> - z<sub>known,smaller</sub>) / (T<sub>known,greater</sub> - T<sub>known,smaller</sub>) * (T - T<sub>known,smaller</sub>);
+</pre>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  For temperatures outside the abscissa values, the ordinate values of the smallest or 
+  largest abscissa value are returned.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 15, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end linearInterpolation_T;
diff --git a/SorpLib/Media/Functions/Utilities/package.mo b/SorpLib/Media/Functions/Utilities/package.mo
new file mode 100644
index 0000000..6f75b4d
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Functions;
+package Utilities "Package containing utility functions and models for calculating media properties"
+extends Modelica.Icons.UtilitiesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains utility functions and models required to calculate fluid
+property data.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Utilities;
diff --git a/SorpLib/Media/Functions/Utilities/package.order b/SorpLib/Media/Functions/Utilities/package.order
new file mode 100644
index 0000000..4a5b9d3
--- /dev/null
+++ b/SorpLib/Media/Functions/Utilities/package.order
@@ -0,0 +1,15 @@
+BasesClasses
+generalizedFunction_T
+dgeneralizedFunction_dT
+ddgeneralizedFunction_dT_dT
+intGeneralizedFunction_dT
+linearInterpolation_T
+dlinearInterpolation_dT
+ddlinearInterpolation_dT_dT
+intLinearInterpolation_dT
+calcCubicSplineCoefficients
+cubicSplineInterpolation_T
+dcubicSplineInterpolation_dT
+ddcubicSplineInterpolation_dT_dT
+intCubicSplineInterpolation_dT
+Testers
diff --git a/SorpLib/Media/Functions/package.mo b/SorpLib/Media/Functions/package.mo
index 1a49c2a..7b1d123 100644
--- a/SorpLib/Media/Functions/package.mo
+++ b/SorpLib/Media/Functions/package.mo
@@ -1,10 +1,20 @@
 within SorpLib.Media;
-package Functions
-extends SorpLib.Internals.ClassTypes.InternalPackage;
-
-
-
-
-
+package Functions "Functions required to calculate fluid property data"
+  extends Modelica.Icons.FunctionsPackage;
 
+  annotation (Documentation(info="<html>
+<p>
+This package contains functions used to calculate fluid property data. In particular,
+these functions are required for calculating data for pure and multi-component
+adsorption. Please check the documentation of the individual packages for more 
+details on the implemented functions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
 end Functions;
diff --git a/SorpLib/Media/Functions/package.order b/SorpLib/Media/Functions/package.order
index 5fc8802..bb28e34 100644
--- a/SorpLib/Media/Functions/package.order
+++ b/SorpLib/Media/Functions/package.order
@@ -1,6 +1,4 @@
-CharCurve1Arctan
-CharCurve1Arctan_inverse
-CharCurve1Arctan_dWdA
-CharCurve2Polynomial
-CharCurve2Polynomial_dWdA
-Testers
+SorptionEquilibria
+SorptionEnthalpies
+SpecificHeatCapacitiesAdsorpt
+Utilities
diff --git a/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2/package.mo b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2/package.mo
new file mode 100644
index 0000000..ea93150
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2/package.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.IdealGasMixtures;
+package DryAir_N2_O2 "SorpLib: Simple dry air consisting of N2 and O2"
+  extends SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture(
+    mediumName="DryAir_N2_O2",
+    data={Modelica.Media.IdealGases.Common.SingleGasesData.N2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.O2},
+    fluidConstants={Modelica.Media.IdealGases.Common.FluidData.N2,
+                    Modelica.Media.IdealGases.Common.FluidData.O2},
+    substanceNames={"Nitrogen",
+                    "Oxygen"},
+    final reference_X={0.7655,0.2345});
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the fluid property of dry air modeled as ideal
+gas mixture of N<sub>2</sub> and O<sub>2</sub>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DryAir_N2_O2;
diff --git a/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2/package.order b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O/package.mo b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O/package.mo
new file mode 100644
index 0000000..30d9ec2
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O/package.mo
@@ -0,0 +1,51 @@
+within SorpLib.Media.IdealGasMixtures;
+package DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O "SorpLib: Simple dry air consisting of N2, O2, Ar, CO2, Ne, He, CH4, and H2O"
+  extends SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture(
+    mediumName="DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O",
+    data={Modelica.Media.IdealGases.Common.SingleGasesData.N2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.O2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.Ar,
+          Modelica.Media.IdealGases.Common.SingleGasesData.CO2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.Ne,
+          Modelica.Media.IdealGases.Common.SingleGasesData.He,
+          Modelica.Media.IdealGases.Common.SingleGasesData.CH4,
+          Modelica.Media.IdealGases.Common.SingleGasesData.H2O},
+    fluidConstants={Modelica.Media.IdealGases.Common.FluidData.N2,
+                    Modelica.Media.IdealGases.Common.FluidData.O2,
+                    Modelica.Media.IdealGases.Common.FluidData.Ar,
+                    Modelica.Media.IdealGases.Common.FluidData.CO2,
+                    Modelica.Media.IdealGases.Common.FluidData.Ne,
+                    Modelica.Media.IdealGases.Common.FluidData.He,
+                    Modelica.Media.IdealGases.Common.FluidData.CH4,
+                    Modelica.Media.IdealGases.Common.FluidData.H2O},
+    substanceNames={"Nitrogen",
+                    "Oxygen",
+                    "Argon",
+                    "Carbondioxide",
+                    "Neon",
+                    "Helium",
+                    "Methane",
+                    "Water"},
+    final reference_X={0.7552/1.00001439,0.2313/1.00001439,
+                       0.0129/1.00001439,5.90e-4/1.00001439,
+                       1.27e-05/1.00001439,7.20e-07/1.00001439,
+                       9.70e-07/1.00001439,1e-5/1.00001439});
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the fluid property of dry air modeled as ideal
+gas mixture of N<sub>2</sub>, O<sub>2</sub>, Ar, CO<sub>2</sub>, Ne, He,
+CH<sub>4</sub>, and H<sub>2</sub>0.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O;
diff --git a/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O/package.order b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_CO2_H2O/package.mo b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_CO2_H2O/package.mo
new file mode 100644
index 0000000..9179a2d
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_CO2_H2O/package.mo
@@ -0,0 +1,35 @@
+within SorpLib.Media.IdealGasMixtures;
+package DryAir_N2_O2_CO2_H2O "SorpLib: Simple dry air consisting of N2, O2, CO2, and H2O"
+  extends SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture(
+    mediumName="DryAir_N2_O2_CO2_H2O",
+    data={Modelica.Media.IdealGases.Common.SingleGasesData.N2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.O2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.CO2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.H2O},
+    fluidConstants={Modelica.Media.IdealGases.Common.FluidData.N2,
+                    Modelica.Media.IdealGases.Common.FluidData.O2,
+                    Modelica.Media.IdealGases.Common.FluidData.CO2,
+                    Modelica.Media.IdealGases.Common.FluidData.H2O},
+    substanceNames={"Nitrogen",
+                    "Oxygen",
+                    "Carbondioxide",
+                    "Water"},
+    final reference_X={0.7650,0.2344,5.90e-4,1e-5});
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the fluid property of dry air modeled as ideal
+gas mixture of N<sub>2</sub>, O<sub>2</sub>, CO<sub>2</sub>, and H<sub>2</sub>0.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DryAir_N2_O2_CO2_H2O;
diff --git a/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_CO2_H2O/package.order b/SorpLib/Media/IdealGasMixtures/DryAir_N2_O2_CO2_H2O/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/ddsaturationPressureH2O_dT_dT.mo b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/ddsaturationPressureH2O_dT_dT.mo
new file mode 100644
index 0000000..3b89399
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/ddsaturationPressureH2O_dT_dT.mo
@@ -0,0 +1,187 @@
+within SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture;
+function ddsaturationPressureH2O_dT_dT
+  "Returns second-order partial derivative of saturatation pressure of water w.r.t. temperature as function of temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_sat
+    "Saturation temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerPressureByTemperatureTemperature ddp_sat_dT_dT
+    "Second-order partial derivative of saturation pressure w.r.t. temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Modelica.Units.SI.Pressure p_trp = 611.657
+    "Triple point pressure";
+  constant Modelica.Units.SI.Pressure p_crit = 22.064e6
+    "Critical pressure";
+
+  constant Modelica.Units.SI.Temperature T_trp = 273.16
+    "Triple point temperature";
+  constant Modelica.Units.SI.Temperature T_crit = 647.096
+    "Critical temperature";
+
+  constant Real[2] coeff_s = {-13.9281690, 34.7078238}
+    "Coefficients of the gas-solid boundary";
+  constant Real[6] coeff_l = {-7.85951783, 1.84408259, -11.7866497,
+    22.6807411, -15.9618719, 1.80122502}
+    "Coefficients of the gas-liquid boundary";
+
+  constant Real[2] exp_s = {-1.5, -1.25}
+    "Exponents of the gas-solid boundary";
+  constant Real[6] exp_l = {1, 1.5, 3,
+    3.5, 4, 7.5}
+    "Exponents of the gas-liquid boundary";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_sat_s
+    "Saturation pressure of gas-solid boundary";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_s_dT
+    "First-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+  SorpLib.Units.DerPressureByTemperatureTemperature ddp_sat_s_dT_dT
+    "Second-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+
+  Modelica.Units.SI.Pressure p_sat_l
+    "Saturation pressure of gas-liquid boundary";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_l_dT
+    "First-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+  SorpLib.Units.DerPressureByTemperatureTemperature ddp_sat_l_dT_dT
+    "Second-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  Real T_red_s = T_sat/T_trp
+    "Reduced temperature required for gas-solid boundary";
+  Real T_red_fl = 1 - T_sat/T_crit
+    "Reduced temperature required for gas-liquid boundary";
+
+  Real lambda(unit="1") = SorpLib.Numerics.smoothTransition(
+    x=T_sat, transitionPoint=T_trp, transitionLength=1, noDiff=3)
+    "Transiation factor";
+  Real dlambda_dT(unit="1/K") = SorpLib.Numerics.smoothTransition_der(
+    x=T_sat, transitionPoint=T_trp, transitionLength=1, noDiff=3,
+    x_der=1)
+    "First-order derivative of transiation factor w.r.t. temperature";
+  Real ddlambda_dT_dT(unit="1/(K2)") = SorpLib.Numerics.smoothTransition_der2(
+    x=T_sat, transitionPoint=T_trp, transitionLength=1, noDiff=3,
+    x_der=1, x_der2=0)
+    "Second-order derivative of transiation factor w.r.t. temperature";
+
+  Real aux_s_1
+    "Auxiliary variable 1 of saturation pressure of gas-solid boundary";
+  Real aux_s_2
+    "Auxiliary variable 2 of saturation pressure of gas-solid boundary";
+
+  Real aux_l_1
+    "Auxiliary variable 1 of saturation pressure of gas-liquid boundary";
+  Real aux_l_2
+    "Auxiliary variable 2 of saturation pressure of gas-liquid boundary";
+
+algorithm
+  //
+  // Calculate pressures
+  //
+  p_sat_s := p_trp * exp(coeff_s[1] - coeff_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] - coeff_s[2] * T_red_s ^ exp_s[2])
+    "Saturation pressure of gas-solid boundary";
+  p_sat_l := p_crit * exp(T_crit/T_sat *
+    (coeff_l[1] * T_red_fl ^ exp_l[1] +
+    coeff_l[2] * T_red_fl ^ exp_l[2] +
+    coeff_l[3] * T_red_fl ^ exp_l[3] +
+    coeff_l[4] * T_red_fl ^ exp_l[4] +
+    coeff_l[5] * T_red_fl ^ exp_l[5] +
+    coeff_l[6] * T_red_fl ^ exp_l[6]))
+    "Saturation pressure of gas-liquid boundary";
+
+  //
+  // Calculate auxiliary variables
+  //
+  aux_s_1 := -p_sat_s/T_sat
+    "Auxiliary variable 1 of saturation pressure of gas-solid boundary";
+  aux_s_2 := (coeff_s[1] * exp_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] * exp_s[2] * T_red_s ^ exp_s[2])
+    "Auxiliary variable 2 of saturation pressure of gas-solid boundary";
+
+  aux_l_1 := -p_sat_l/T_sat
+    "Auxiliary variable 1 of saturation pressure of gas-liquid boundary";
+  aux_l_2 := log(p_sat_l/p_crit) + coeff_l[1] +
+    coeff_l[2] * exp_l[2] * T_red_fl^(exp_l[2]-1) +
+    coeff_l[3] * exp_l[3] * T_red_fl^(exp_l[3]-1) +
+    coeff_l[4] * exp_l[4] * T_red_fl^(exp_l[4]-1) +
+    coeff_l[5] * exp_l[5] * T_red_fl^(exp_l[5]-1) +
+    coeff_l[6] * exp_l[6] * T_red_fl^(exp_l[6]-1)
+    "Auxiliary variable 2 of saturation pressure of gas-liquid boundary";
+
+  //
+  // Calculate first-order partial derivatives of pressures w.r.t. temperature
+  //
+  dp_sat_s_dT := aux_s_1 * aux_s_2
+    "First-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+  dp_sat_l_dT := aux_l_1 * aux_l_2
+    "First-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  //
+  // Calculate second-order partial derivatives of pressures w.r.t. temperature
+  //
+  ddp_sat_s_dT_dT := (p_sat_s/T_sat^2 - dp_sat_s_dT/T_sat) * aux_s_2 +
+    aux_s_1/T_trp * (coeff_s[1] * exp_s[1]^2 * T_red_s ^ (exp_s[1]-1) +
+    coeff_s[2] * exp_s[2]^2 * T_red_s ^ (exp_s[2]-1))
+    "Second-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+  ddp_sat_l_dT_dT := (p_sat_l/T_sat^2 - dp_sat_l_dT/T_sat) * aux_l_2 +
+    aux_l_1 * (1/p_sat_l * dp_sat_l_dT + (-1/T_crit) *
+    (coeff_l[2] * exp_l[2] * (exp_l[2]-1) * T_red_fl^(exp_l[2]-2) +
+    coeff_l[3] * exp_l[3] * (exp_l[3]-1) * T_red_fl^(exp_l[3]-2) +
+    coeff_l[4] * exp_l[4] * (exp_l[4]-1) * T_red_fl^(exp_l[4]-2) +
+    coeff_l[5] * exp_l[5] * (exp_l[5]-1) * T_red_fl^(exp_l[5]-2) +
+    coeff_l[6] * exp_l[6] * (exp_l[6]-1) * T_red_fl^(exp_l[6]-2)))
+    "Second-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  //
+  // Check for boundary
+  //
+  ddp_sat_dT_dT :=ddlambda_dT_dT*p_sat_s +
+    2*dlambda_dT*dp_sat_s_dT +
+    lambda*ddp_sat_s_dT_dT +
+    (-ddlambda_dT_dT)*p_sat_l +
+    2*(-dlambda_dT)*dp_sat_l_dT +
+    (1-lambda)*ddp_sat_l_dT_dT
+    "Second-order partial derivative of saturation pressure w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the second-order partial saturation pressure of water 
+with respect to temperature depending on the temperature. This functions covers 
+both, the solid-gas and the gas-liquid boundary. For details, please check the
+function
+<a href=\"Modelica://SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture.saturationPressureH2O_T\">SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture.saturationPressureH2O_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddsaturationPressureH2O_dT_dT;
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/dsaturationPressureH2O_dT.mo b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/dsaturationPressureH2O_dT.mo
new file mode 100644
index 0000000..0976787
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/dsaturationPressureH2O_dT.mo
@@ -0,0 +1,136 @@
+within SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture;
+function dsaturationPressureH2O_dT
+  "Returns partial derivative of saturatation pressure of water w.r.t. temperature as function of temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_sat
+    "Saturation temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Media.Common.DerPressureByTemperature dp_sat_dT
+    "First-order partial derivative of saturation pressure w.r.t. temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Modelica.Units.SI.Pressure p_trp = 611.657
+    "Triple point pressure";
+  constant Modelica.Units.SI.Pressure p_crit = 22.064e6
+    "Critical pressure";
+
+  constant Modelica.Units.SI.Temperature T_trp = 273.16
+    "Triple point temperature";
+  constant Modelica.Units.SI.Temperature T_crit = 647.096
+    "Critical temperature";
+
+  constant Real[2] coeff_s = {-13.9281690, 34.7078238}
+    "Coefficients of the gas-solid boundary";
+  constant Real[6] coeff_l = {-7.85951783, 1.84408259, -11.7866497,
+    22.6807411, -15.9618719, 1.80122502}
+    "Coefficients of the gas-liquid boundary";
+
+  constant Real[2] exp_s = {-1.5, -1.25}
+    "Exponents of the gas-solid boundary";
+  constant Real[6] exp_l = {1, 1.5, 3,
+    3.5, 4, 7.5}
+    "Exponents of the gas-liquid boundary";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_sat_s
+    "Saturation pressure of gas-solid boundary";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_s_dT
+    "First-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+
+  Modelica.Units.SI.Pressure p_sat_l
+    "Saturation pressure of gas-liquid boundary";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_l_dT
+    "First-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  Real T_red_s = T_sat/T_trp
+    "Reduced temperature required for gas-solid boundary";
+  Real T_red_fl = 1 - T_sat/T_crit
+    "Reduced temperature required for gas-liquid boundary";
+
+  Real lambda(unit="1") = SorpLib.Numerics.smoothTransition(x=T_sat,
+    transitionPoint=T_trp, transitionLength=1, noDiff=3)
+    "Transiation factor";
+  Real dlambda_dT(unit="1/K") = SorpLib.Numerics.smoothTransition_der(x=T_sat,
+    transitionPoint=T_trp, transitionLength=1, noDiff=3, x_der=1)
+    "First-order derivative of transiation factor w.r.t. temperature";
+
+algorithm
+  //
+  // Calculate pressures
+  //
+  p_sat_s := p_trp * exp(coeff_s[1] - coeff_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] - coeff_s[2] * T_red_s ^ exp_s[2])
+    "Saturation pressure of gas-solid boundary";
+  p_sat_l := p_crit * exp(T_crit/T_sat *
+    (coeff_l[1] * T_red_fl ^ exp_l[1] +
+    coeff_l[2] * T_red_fl ^ exp_l[2] +
+    coeff_l[3] * T_red_fl ^ exp_l[3] +
+    coeff_l[4] * T_red_fl ^ exp_l[4] +
+    coeff_l[5] * T_red_fl ^ exp_l[5] +
+    coeff_l[6] * T_red_fl ^ exp_l[6]))
+    "Saturation pressure of gas-liquid boundary";
+
+  //
+  // Calculate first-order partial derivatives of pressures w.r.t. temperature
+  //
+  dp_sat_s_dT := -p_sat_s/T_sat *
+    (coeff_s[1] * exp_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] * exp_s[2] * T_red_s ^ exp_s[2])
+    "First-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+  dp_sat_l_dT := -p_sat_l/T_sat * (
+    log(p_sat_l/p_crit) +
+    coeff_l[1] +
+    coeff_l[2] * exp_l[2] * T_red_fl^(exp_l[2]-1) +
+    coeff_l[3] * exp_l[3] * T_red_fl^(exp_l[3]-1) +
+    coeff_l[4] * exp_l[4] * T_red_fl^(exp_l[4]-1) +
+    coeff_l[5] * exp_l[5] * T_red_fl^(exp_l[5]-1) +
+    coeff_l[6] * exp_l[6] * T_red_fl^(exp_l[6]-1))
+    "First-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  //
+  // Check for boundary
+  //
+  dp_sat_dT :=dlambda_dT*p_sat_s +
+    lambda*dp_sat_s_dT +
+    (-dlambda_dT)*p_sat_l +
+    (1-lambda)*dp_sat_l_dT
+    "First-order partial derivative of saturation pressure w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the first-order partial saturation pressure of water 
+with respect to temperature depending on the temperature. This functions covers 
+both, the solid-gas and the gas-liquid boundary. For details, please check the
+function
+<a href=\"Modelica://SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture.saturationPressureH2O_T\">SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture.saturationPressureH2O_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dsaturationPressureH2O_dT;
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/package.mo b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/package.mo
new file mode 100644
index 0000000..73f9a99
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/package.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.IdealGasMixtures.Interfaces;
+partial package PartialIdealGasMixture "Medium model of an ideal gas mixture based on NASA source"
+  extends Modelica.Media.IdealGases.Common.MixtureGasNasa(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5);
+
+  //
+  // New functions
+  //
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model extends the medium model of an ideal gas mixture provided
+in the Modelica Standard Library by some additional functions required
+in SorpLib. For details of the original medium model, check out the
+package
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa\">Modelica.Media.IdealGases.Common.MixtureGasNasa</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialIdealGasMixture;
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/package.order b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/package.order
new file mode 100644
index 0000000..3d7c373
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/package.order
@@ -0,0 +1,6 @@
+partialPressures
+specificEnthalpy_i_T
+specificEntropy_i_pTX
+saturationPressureH2O_T
+dsaturationPressureH2O_dT
+ddsaturationPressureH2O_dT_dT
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/partialPressures.mo b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/partialPressures.mo
new file mode 100644
index 0000000..fa9f8ee
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/partialPressures.mo
@@ -0,0 +1,48 @@
+within SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture;
+function partialPressures
+  "Returns partial pressures"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[nX] p_i
+    "Partial pressures"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction Y[nX]=
+    massToMoleFractions(X=state.X, MMX=MMX)
+    "Mole fractions";
+
+algorithm
+  p_i := Y .* state.p
+    "Partial pressures";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+  <p>
+  This function calculates the partial pressures as function of the state record.
+  </p>
+  </html>",
+          revisions="<html>
+  <ul>
+    <li>
+    November 24, 2023, by Mirko Engelpracht:<br/>
+    First implementation.
+    </li>
+  </ul>
+  </html>"));
+end partialPressures;
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/saturationPressureH2O_T.mo b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/saturationPressureH2O_T.mo
new file mode 100644
index 0000000..44db0a4
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/saturationPressureH2O_T.mo
@@ -0,0 +1,109 @@
+within SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture;
+function saturationPressureH2O_T
+  "Returns saturatation pressure of water as function of temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_sat
+    "Saturation temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Modelica.Units.SI.Pressure p_trp = 611.657
+    "Triple point pressure";
+  constant Modelica.Units.SI.Pressure p_crit = 22.064e6
+    "Critical pressure";
+
+  constant Modelica.Units.SI.Temperature T_trp = 273.16
+    "Triple point temperature";
+  constant Modelica.Units.SI.Temperature T_crit = 647.096
+    "Critical temperature";
+
+  constant Real[2] coeff_s = {-13.9281690, 34.7078238}
+    "Coefficients of the gas-solid boundary";
+  constant Real[6] coeff_l = {-7.85951783, 1.84408259, -11.7866497,
+    22.6807411, -15.9618719, 1.80122502}
+    "Coefficients of the gas-liquid boundary";
+
+  constant Real[2] exp_s = {-1.5, -1.25}
+    "Exponents of the gas-solid boundary";
+  constant Real[6] exp_l = {1, 1.5, 3,
+    3.5, 4, 7.5}
+    "Exponents of the gas-liquid boundary";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_sat_s
+    "Saturation pressure of gas-solid boundary";
+  Modelica.Units.SI.Pressure p_sat_l
+    "Saturation pressure of gas-liquid boundary";
+
+  Real T_red_s = T_sat/T_trp
+    "Reduced temperature required for gas-solid boundary";
+  Real T_red_fl = 1 - T_sat/T_crit
+    "Reduced temperature required for gas-liquid boundary";
+
+  Real lambda(unit="1") = SorpLib.Numerics.smoothTransition(x=T_sat,
+    transitionPoint=T_trp, transitionLength=1, noDiff=3)
+    "Transiation factor";
+
+algorithm
+  //
+  // Calculate pressures
+  //
+  p_sat_s := p_trp * exp(coeff_s[1] - coeff_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] - coeff_s[2] * T_red_s ^ exp_s[2])
+    "Saturation pressure of gas-solid boundary";
+  p_sat_l := p_crit * exp(T_crit/T_sat *
+    (coeff_l[1] * T_red_fl ^ exp_l[1] +
+    coeff_l[2] * T_red_fl ^ exp_l[2] +
+    coeff_l[3] * T_red_fl ^ exp_l[3] +
+    coeff_l[4] * T_red_fl ^ exp_l[4] +
+    coeff_l[5] * T_red_fl ^ exp_l[5] +
+    coeff_l[6] * T_red_fl ^ exp_l[6]))
+    "Saturation pressure of gas-liquid boundary";
+
+  //
+  // Check for boundary
+  //
+  p_sat :=lambda*p_sat_s + (1-lambda)*p_sat_l
+    "Saturation pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the saturation pressure of water depending on
+the temperature. This functions covers both, the solid-gas and the gas-
+liquid boundary.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wagner, W. and Pru&szlig;, A (2002). The IAPWS Formulation 1995 for the Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use, Journal of Physical and Chemical Reference Data, 31:387. DOI: https://doi.org/10.1063/1.1461829.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end saturationPressureH2O_T;
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/specificEnthalpy_i_T.mo b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/specificEnthalpy_i_T.mo
new file mode 100644
index 0000000..141a544
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/specificEnthalpy_i_T.mo
@@ -0,0 +1,56 @@
+within SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture;
+function specificEnthalpy_i_T
+  "Returns specific enthalpy of component i"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Integer ind_component
+    "Component index whose specific enthalpy is to be calculated"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean exclEnthForm=excludeEnthalpyOfFormation
+    "= true, enthalpy of formation Hf is not included in specific enthalpy h"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Media.Interfaces.Choices.ReferenceEnthalpy refChoice=
+    referenceChoice
+    "Choice of reference enthalpy"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.SpecificEnthalpy h_off = h_offset
+    "User definedreference enthalpy, if referenceChoice = UserDefined"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy of component ind_component"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  h := Modelica.Media.IdealGases.Common.Functions.h_T(
+    data[ind_component], T, exclEnthForm, refChoice, h_off)
+    "Specific enthalpy of component ind_component";
+
+  //
+  // Annotations
+  //
+  annotation(Inline=false,smoothOrder=2,
+    Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of component i.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificEnthalpy_i_T;
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/specificEntropy_i_pTX.mo b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/specificEntropy_i_pTX.mo
new file mode 100644
index 0000000..bbdb124
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/PartialIdealGasMixture/specificEntropy_i_pTX.mo
@@ -0,0 +1,71 @@
+within SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture;
+function specificEntropy_i_pTX
+  "Returns specific entropy of component i"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Integer ind_component
+    "Component index whose specific entropy is to be calculated"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions of mixture (full vector)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean exclEnthForm=excludeEnthalpyOfFormation
+    "= true, enthalpy of formation Hf is not included in specific enthalpy h"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Media.Interfaces.Choices.ReferenceEnthalpy refChoice=
+    referenceChoice
+    "Choice of reference enthalpy"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.SpecificEnthalpy h_off = h_offset
+    "User definedreference enthalpy, if referenceChoice = UserDefined"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy of component ind_component"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+    Modelica.Units.SI.MoleFraction[nX] Y = massToMoleFractions(X, data.MM)
+    "Molar fractions";
+
+algorithm
+  s := Modelica.Media.IdealGases.Common.Functions.s0_T(data[ind_component],
+    T) - Modelica.Constants.R/MMX[ind_component] * (if X[ind_component] <
+    Modelica.Constants.eps then Y[ind_component] else
+    Modelica.Math.log(Y[ind_component]*p / reference_p))
+    "Specific entropy of component ind_component";
+
+  //
+  // Annotations
+  //
+  annotation(Inline=false,smoothOrder=2,
+    Documentation(info="<html>
+<p>
+This function calculates the specific entropy of component i.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 24, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificEntropy_i_pTX;
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/package.mo b/SorpLib/Media/IdealGasMixtures/Interfaces/package.mo
new file mode 100644
index 0000000..47e9509
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.IdealGasMixtures;
+package Interfaces "Interfaces for models of ideal gas mixtures"
+extends Modelica.Icons.InterfacesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package provides definitions of basic interfaces for models
+of ideal gas mixtures.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Interfaces;
diff --git a/SorpLib/Media/IdealGasMixtures/Interfaces/package.order b/SorpLib/Media/IdealGasMixtures/Interfaces/package.order
new file mode 100644
index 0000000..a38ca7d
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Interfaces/package.order
@@ -0,0 +1 @@
+PartialIdealGasMixture
diff --git a/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2.mo b/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2.mo
new file mode 100644
index 0000000..37247cf
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2.mo
@@ -0,0 +1,211 @@
+within SorpLib.Media.IdealGasMixtures.Tester;
+model Test_DryAir_N2_O2 "Tester for dry air consisting of N2 and O2"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of paramters
+  //
+  replaceable package Medium = SorpLib.Media.IdealGasMixtures.DryAir_N2_O2
+    constrainedby Modelica.Media.IdealGases.Common.MixtureGasNasa
+    "Medium"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+  package MediumReference = Modelica.Media.Air.ReferenceAir.Air_pT
+    "Reference medium: Detailed dry air"
+    annotation (Dialog(tab="General",group="Models and Media"));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p(start=100, fixed=true)
+    "Pressure";
+  Modelica.Units.SI.Temperature T(start=253.15, fixed=true)
+    "Temperature";
+  Modelica.Units.SI.MassFraction[Medium.nX] X = Medium.reference_X
+    "Mass fractions";
+
+  Medium.BaseProperties medium_pTX
+    "Base properties calculated with pressure, temperature, and mass fractions";
+  MediumReference.BaseProperties mediumReference_pTX
+    "Base properties calculated with pressure, temperature, and mass fractions";
+
+  Modelica.Units.SI.Pressure[Medium.nX] p_i
+    "Partial pressures";
+
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+  Modelica.Units.SI.SpecificVolume vReference
+    "Specific volume";
+
+  Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy";
+  Modelica.Units.SI.SpecificEnthalpy h_1
+    "Specific enthalpy of component 1";
+  Modelica.Units.SI.SpecificEnthalpy h_2
+    "Specific enthalpy of component 2";
+  Modelica.Units.SI.SpecificEnthalpy hReference
+    "Specific enthalpy";
+
+  Modelica.Units.SI.SpecificInternalEnergy u
+    "Specific internal energy";
+  Modelica.Units.SI.SpecificInternalEnergy uReference
+    "Specific internal energy";
+
+  Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy";
+  Modelica.Units.SI.SpecificEntropy s_1
+    "Specific entropy of component 1";
+  Modelica.Units.SI.SpecificEntropy s_2
+    "Specific entropy of component 2";
+  Modelica.Units.SI.SpecificEntropy sReference
+    "Specific entropy";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity";
+  Modelica.Units.SI.SpecificHeatCapacity cpReference
+    "Specific heat capacity";
+
+  Modelica.Units.SI.RelativePressureCoefficient beta
+    "Isobaric expansion coefficient";
+  Modelica.Units.SI.RelativePressureCoefficient betaReference
+    "Isobaric expansion coefficient";
+
+  Modelica.Units.SI.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Units.SI.IsothermalCompressibility kappaReference
+    "Isothermal compressibility";
+
+  Modelica.Units.SI.Pressure p_sat_water
+    "Saturation pressure of water";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_water_dT
+    "First-order partial derivative of saturation pressure of water w.r.t. 
+    temperature";
+  SorpLib.Units.DerPressureByTemperatureTemperature ddp_sat_water_dT_dT
+    "Second-order partial derivative of saturation pressure of water w.r.t. 
+    temperature";
+
+  //
+  // Protected parameters
+  //
+protected
+  final parameter Modelica.Units.SI.SpecificEnthalpy dh_ref=
+    Medium.specificEnthalpy_pTX(p=1e5, T=273.15, X=Medium.reference_X) -
+    MediumReference.specificEnthalpy_pTX(p=1e5, T=273.15, X=MediumReference.reference_X)
+    "Difference of enthalpies to get offset of reference enthalpies";
+
+  final parameter Modelica.Units.SI.SpecificInternalEnergy du_ref=
+    (Medium.specificEnthalpy_pTX(p=1e5, T=273.15, X=Medium.reference_X) +
+    1e5 * Medium.density_pTX(p=1e5, T=273.15, X=Medium.reference_X)) -
+    (MediumReference.specificEnthalpy_pTX(p=1e5, T=273.15, X=MediumReference.reference_X) +
+    1e5 * MediumReference.density_pTX(p=1e5, T=273.15, X=MediumReference.reference_X))
+    "Difference of specific internal energies to get offset of reference internal
+    energies";
+
+  final parameter Modelica.Units.SI.SpecificEntropy ds_ref=
+    Medium.specificEntropy_pTX(p=1e5, T=273.15, X=Medium.reference_X) -
+    MediumReference.specificEntropy_pTX(p=1e5, T=273.15, X=MediumReference.reference_X)
+    "Difference of entropies to get offset of reference entropies";
+
+equation
+  //
+  // Change independent state variables
+  //
+  der(p) = (20e5 - 100) / 20
+    "Predescribed slope of pressure";
+  der(T) = (573.15 - 253.15) / 20
+    "Predescribed slope of temperature";
+
+  //
+  // Calculate state variables
+  //
+  medium_pTX.p = p
+    "Base properties calculated with pressure and temperature";
+  medium_pTX.T = T
+    "Base properties calculated with pressure and temperature";
+  medium_pTX.X = X
+    "Base properties calculated with pressure and temperature";
+
+  mediumReference_pTX.p = p
+    "Base properties calculated with pressure, temperature, and mass fractions";
+  mediumReference_pTX.T = T
+    "Base properties calculated with pressure, temperature, and mass fractions";
+
+  //
+  // Calculate further variables
+  //
+  p_i = Medium.partialPressures(state=medium_pTX.state)
+    "Partial pressures";
+
+  v = 1/medium_pTX.d
+    "Specific volume";
+  vReference = 1/mediumReference_pTX.d
+    "Specific volume";
+
+  h = medium_pTX.h
+    "Specific enthalpy";
+  h_1 = Medium.specificEnthalpy_i_T(ind_component=1, T=T)
+    "Specific enthalpy of component 1";
+  h_2 = Medium.specificEnthalpy_i_T(ind_component=2, T=T)
+    "Specific enthalpy of component 2";
+  hReference = mediumReference_pTX.h + dh_ref
+    "Specific enthalpy";
+
+  u = medium_pTX.u
+    "Specific internal energy";
+  uReference = mediumReference_pTX.u + du_ref
+    "Specific internal energy";
+
+  s = Medium.specificEntropy(state=medium_pTX.state)
+    "Specific entropy";
+  s_1 = Medium.specificEntropy_i_pTX(ind_component=1, p=p, T=T, X=X)
+    "Specific entropy of component 1";
+  s_2 = Medium.specificEntropy_i_pTX(ind_component=1, p=p, T=T, X=X)
+    "Specific entropy of component 2";
+  sReference = MediumReference.specificEntropy(state=mediumReference_pTX.state)
+    + ds_ref
+    "Specific entropy";
+
+  cp = Medium.specificHeatCapacityCp(state=medium_pTX.state)
+    "Specific heat capacity";
+  cpReference = MediumReference.specificHeatCapacityCp(state=mediumReference_pTX.state)
+    "Specific heat capacity";
+
+  beta = Medium.beta(state=medium_pTX.state)
+    "Isobaric expansion coefficient";
+  betaReference = MediumReference.beta(state=mediumReference_pTX.state)
+    "Isobaric expansion coefficient";
+
+  kappa = Medium.kappa(state=medium_pTX.state)
+    "Isothermal compressibility";
+  kappaReference = MediumReference.kappa(state=mediumReference_pTX.state)
+    "Isothermal compressibility";
+
+  p_sat_water=Medium.saturationPressureH2O_T(T_sat=T)
+    "Saturation pressure of water";
+  dp_sat_water_dT=Medium.dsaturationPressureH2O_dT(T_sat=T)
+    "First-order partial derivative of saturation pressure of water w.r.t. 
+    temperature";
+  ddp_sat_water_dT_dT=Medium.ddsaturationPressureH2O_dT_dT(T_sat=T)
+    "Second-order partial derivative of saturation pressure of water w.r.t. 
+    temperature";
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal gas mixture of
+N<sub>2</sub> and O<sub>2</sub>.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_DryAir_N2_O2;
diff --git a/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O.mo b/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O.mo
new file mode 100644
index 0000000..562ac2a
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.IdealGasMixtures.Tester;
+model Test_DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O
+  "Tester for dry air consisting of N2, O2, Ar, CO2, Ne, He, CH4, and H2O"
+  extends SorpLib.Media.IdealGasMixtures.Tester.Test_DryAir_N2_O2(
+    redeclare package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal gas mixture of
+N<sub>2</sub>, O<sub>2</sub>, Ar, CO<sub>2</sub>, Ne, He, CH<sub>4</sub>, and 
+H<sub>2</sub>0.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O;
diff --git a/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2_CO2_H2O.mo b/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2_CO2_H2O.mo
new file mode 100644
index 0000000..4878866
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Tester/Test_DryAir_N2_O2_CO2_H2O.mo
@@ -0,0 +1,28 @@
+within SorpLib.Media.IdealGasMixtures.Tester;
+model Test_DryAir_N2_O2_CO2_H2O
+  "Tester for dry air consisting of N2, O2, CO2, and H2O"
+  extends SorpLib.Media.IdealGasMixtures.Tester.Test_DryAir_N2_O2(
+    redeclare package Medium =
+      SorpLib.Media.IdealGasMixtures.DryAir_N2_O2_CO2_H2O);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal gas mixture of
+N<sub>2</sub>, O<sub>2</sub>, CO<sub>2</sub>, and H<sub>2</sub>O.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_DryAir_N2_O2_CO2_H2O;
diff --git a/SorpLib/Media/IdealGasMixtures/Tester/package.mo b/SorpLib/Media/IdealGasMixtures/Tester/package.mo
new file mode 100644
index 0000000..f6f09e4
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.IdealGasMixtures;
+package Tester "Package containing testers to test and varify models calculating fluid property data of ideal gas mixtures"
+  extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented fluid
+property models of ideal gas mixtures. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Media/IdealGasMixtures/Tester/package.order b/SorpLib/Media/IdealGasMixtures/Tester/package.order
new file mode 100644
index 0000000..47a949b
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/Tester/package.order
@@ -0,0 +1,3 @@
+Test_DryAir_N2_O2
+Test_DryAir_N2_O2_CO2_H2O
+Test_DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O
diff --git a/SorpLib/Media/IdealGasMixtures/package.mo b/SorpLib/Media/IdealGasMixtures/package.mo
new file mode 100644
index 0000000..77c4363
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/package.mo
@@ -0,0 +1,23 @@
+within SorpLib.Media;
+package IdealGasMixtures "Package containing medium models of ideal gas mixtures"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models of ideal gas mixtures. These models are based
+on the Modelica Standard Library but extended by new functions required in
+SorpLib. Note that the reference temperature must be 0 K and the reference 
+enthalpy and entropy must be 0 J/kg and 0 J/(Kg.K). Otherwise, absolute values 
+caloric and entropic properties may not be correctly calculated. For details 
+of the mixture models, check the documentation of the package 
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa\">Modelica.Media.IdealGases.Common.MixtureGasNasa</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IdealGasMixtures;
diff --git a/SorpLib/Media/IdealGasMixtures/package.order b/SorpLib/Media/IdealGasMixtures/package.order
new file mode 100644
index 0000000..9641cd9
--- /dev/null
+++ b/SorpLib/Media/IdealGasMixtures/package.order
@@ -0,0 +1,5 @@
+Interfaces
+DryAir_N2_O2
+DryAir_N2_O2_CO2_H2O
+DryAir_N2_O2_Ar_CO2_Ne_He_CH4_H2O
+Tester
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryAirMassFractions_dX.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryAirMassFractions_dX.mo
new file mode 100644
index 0000000..8628565
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryAirMassFractions_dX.mo
@@ -0,0 +1,58 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function ddryAirMassFractions_dX
+  "Partial derivatives of 'dry air'-based mass fractions w.r.t. 'moist air'-based mass fractions"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions based on moist air mass"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real[nX, nX] dx_dX(each unit="kg.kg/(kg.kg)")
+    "Partial derivatives of mass fractions given per dry air mass w.r.t. mass
+    fractions given per moist air mass: Rows are dry air mass and columns are
+    moist air mass"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  dx_dX :=zeros(nX, nX)
+    "Partial derivatives of mass fractions given per dry air mass w.r.t. mass
+    fractions given per moist air mass: Most elements are zero.";
+
+  dx_dX[nX, nX] := 1 / (X[nX] - 1)^2
+    "Partial derivatives of mass fractions given per dry air mass w.r.t. mass
+    fractions given per moist air mass: Water w.r.t. water.";
+
+  for ind in 1:nX-1 loop
+    dx_dX[ind, ind] := (1 + X[nX] / (1 - X[nX]))
+      "Partial derivatives of mass fractions given per dry air mass w.r.t. mass
+      fractions given per moist air mass: Diagonal.";
+    dx_dX[ind, nX] := X[ind]  / (X[nX] - 1)^2
+      "Partial derivatives of mass fractions given per dry air mass w.r.t. mass
+      fractions given per moist air mass: W.r.t. water.";
+
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivatives of mass fractions given per dry
+air mass with respect to mass fractions given per moist air mass.
+</p>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddryAirMassFractions_dX;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dT_pX.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dT_pX.mo
new file mode 100644
index 0000000..4d02e23
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dT_pX.mo
@@ -0,0 +1,70 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function ddryMassFractionSaturation_dT_pX
+  "Returns partial derivative of saturated wasser mass fraction per dry air mass w.r.t. temperature at constant pressure and mass fractions"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Real dx_sat_dT_pX(unit="kg/(kg.K)")
+    "Partial derivative of saturated wasser mass fraction per dry air mass 
+    w.r.t. temperature at constant pressure and mass fractions"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_sat=
+    saturationPressureH2O_T(T_sat = state.T)
+    "Saturation pressure";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_dT=
+    dsaturationPressureH2O_dT(T_sat = state.T)
+    "Partial derivative of saturation pressure w.r.t. temperature";
+
+algorithm
+  dx_sat_dT_pX := MMX[nX] / (state.Y[1:nX-1]./sum(state.Y[1:nX-1]) * MMX[1:nX-1]) *
+    (p_sat / max((state.p - p_sat)^2, Modelica.Constants.small) +
+    1 / max((state.p - p_sat), Modelica.Constants.small)) * dp_sat_dT
+    "Partial derivative of saturated wasser mass fraction per dry air mass 
+    w.r.t. temperature at constant pressure and mass fractions";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(p_sat <= state.p,
+      "Saturation pressure (" + String(p_sat) + " Pa) is greater than total " +
+      "pressure (" + String(state.p) + " Pa). Thus, the calculation of the " +
+      "saturation mass fraction is not sound!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the saturation mass fraction 
+of the condensing component (i.e., water) per dry air with respect to temperature
+at constant pressure and mass fractions as function of the state record. Note 
+that the saturation mass fraction can only be calculated if the partial pressure 
+of the condensing component is less than the pressure of the ideal gas-vapor 
+mixture.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddryMassFractionSaturation_dT_pX;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dX_pT.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dX_pT.mo
new file mode 100644
index 0000000..5e94b7d
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dX_pT.mo
@@ -0,0 +1,89 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function ddryMassFractionSaturation_dX_pT
+  "Returns partial derivatives of saturated wasser mass fraction per dry air mass w.r.t. mass fractions at constant pressure and temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Real[nX] dx_sat_dX_pT(each unit="kg.kg/(kg.kg)")
+    "Partial derivatives of saturated wasser mass fraction per dry air mass 
+    w.r.t. mass fractions given per moist air mass at constant pressure and 
+    temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MolarMass Y_dryAir=
+    sum(state.Y[1:nX-1])
+    "Sum of molar fractions of dry air components";
+  Modelica.Units.SI.MolarMass MM_dryAir=
+    state.Y[1:nX-1] ./ Y_dryAir * MMX[1:nX-1]
+    "Molar mass of dry air components";
+  Modelica.Units.SI.Pressure p_sat=
+    saturationPressureH2O_T(T_sat = state.T)
+    "Saturation pressure";
+
+  Real[nX-1] dMM_dryAir_dY=
+    MMX[1:nX-1] ./ Y_dryAir .- sum(MMX[1:nX-1] .* state.Y[1:nX-1] ./ Y_dryAir^2)
+    "Partial derivatives of molar mass of dry air components w.r.t. molar
+    fractions of dry air components";
+  Real[nX, nX] dY_dX(each unit="mol.kg/(mol.kg)")=
+    dmassToMoleFractions_dX(X=state.X)
+    "Partial derivatives of mole fractions given per moist air w.r.t mass 
+    fractions given per moist air mass: Rows are mole fractions and colums 
+    are mass fractions";
+  Real[nX] dMM_dryAir_dX=
+    {sum(dMM_dryAir_dY .* dY_dX[1:nX-1, ind]) for ind in 1:nX}
+    "Partial derivatives of molar mass of dry air components w.r.t. mass
+    fractions given per moist air mass";
+
+algorithm
+  dx_sat_dX_pT := (-MMX[nX] / MM_dryAir^2 *
+    p_sat / max((state.p - p_sat), Modelica.Constants.small)) .*
+    dMM_dryAir_dX
+    "Partial derivatives of saturated wasser mass fraction per dry air mass 
+    w.r.t. mass fractions given per moist air mass at constant pressure and 
+    temperature";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(p_sat <= state.p,
+      "Saturation pressure (" + String(p_sat) + " Pa) is greater than total " +
+      "pressure (" + String(state.p) + " Pa). Thus, the calculation of the " +
+      "saturation mass fraction is not sound!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivatives of the saturation mass fraction 
+of the condensing component (i.e., water) per dry air with respect to mass fractions
+given per moist air mass at constant pressure and temperature as function of the 
+state record. Note that the saturation mass fraction can only be calculated if 
+the partial pressure of the condensing component is less than the pressure of the 
+ideal gas-vapor mixture.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddryMassFractionSaturation_dX_pT;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dp_TX.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dp_TX.mo
new file mode 100644
index 0000000..9ff37a3
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddryMassFractionSaturation_dp_TX.mo
@@ -0,0 +1,66 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function ddryMassFractionSaturation_dp_TX
+  "Returns partial derivative of saturated wasser mass fraction per dry air mass w.r.t. pressure at constant temperature and mass fractions"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Real dx_sat_dp_TX(unit="kg/(kg.Pa)")
+    "Partial derivative of saturated wasser mass fraction per dry air mass 
+    w.r.t. pressure at constant temperature and mass fractions"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_sat=
+    saturationPressureH2O_T(T_sat = state.T)
+    "Saturation pressure";
+
+algorithm
+  dx_sat_dp_TX := -MMX[nX] / (state.Y[1:nX-1]./sum(state.Y[1:nX-1]) * MMX[1:nX-1]) *
+    p_sat / max((state.p - p_sat)^2, Modelica.Constants.small)
+    "Partial derivative of saturated wasser mass fraction per dry air mass 
+    w.r.t. pressure at constant temperature and mass fractions";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(p_sat <= state.p,
+      "Saturation pressure (" + String(p_sat) + " Pa) is greater than total " +
+      "pressure (" + String(state.p) + " Pa). Thus, the calculation of the " +
+      "saturation mass fraction is not sound!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the saturation mass fraction 
+of the condensing component (i.e., water) per dry air with respect to pressure
+at constant temperature and mass fractions as function of the state record. Note 
+that the saturation mass fraction can only be calculated if the partial pressure 
+of the condensing component is less than the pressure of the ideal gas-vapor 
+mixture.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddryMassFractionSaturation_dp_TX;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddsaturationPressureH2O_dT_dT.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddsaturationPressureH2O_dT_dT.mo
new file mode 100644
index 0000000..20b0fe0
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/ddsaturationPressureH2O_dT_dT.mo
@@ -0,0 +1,177 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function ddsaturationPressureH2O_dT_dT
+  "Returns second-order partial derivative of saturatation pressure of water w.r.t. temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_sat
+    "Saturation temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerPressureByTemperatureTemperature ddp_sat_dT_dT
+    "Second-order partial derivative of saturation pressure w.r.t. temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[2] coeff_s = {-13.9281690, 34.7078238}
+    "Coefficients of the gas-solid boundary";
+  constant Real[6] coeff_l = {-7.85951783, 1.84408259, -11.7866497,
+    22.6807411, -15.9618719, 1.80122502}
+    "Coefficients of the gas-liquid boundary";
+
+  constant Real[2] exp_s = {-1.5, -1.25}
+    "Exponents of the gas-solid boundary";
+  constant Real[6] exp_l = {1, 1.5, 3,
+    3.5, 4, 7.5}
+    "Exponents of the gas-liquid boundary";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_sat_s
+    "Saturation pressure of gas-solid boundary";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_s_dT
+    "First-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+  SorpLib.Units.DerPressureByTemperatureTemperature ddp_sat_s_dT_dT
+    "Second-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+
+  Modelica.Units.SI.Pressure p_sat_l
+    "Saturation pressure of gas-liquid boundary";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_l_dT
+    "First-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+  SorpLib.Units.DerPressureByTemperatureTemperature ddp_sat_l_dT_dT
+    "Second-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  Real T_red_s = T_sat/T_water_trp
+    "Reduced temperature required for gas-solid boundary";
+  Real T_red_fl = 1 - T_sat/T_water_crit
+    "Reduced temperature required for gas-liquid boundary";
+
+  Real lambda(unit="1") = SorpLib.Numerics.smoothTransition(
+    x=T_sat, transitionPoint=T_water_trp, transitionLength=1, noDiff=3)
+    "Transiation factor";
+  Real dlambda_dT(unit="1/K") = SorpLib.Numerics.smoothTransition_der(
+    x=T_sat, transitionPoint=T_water_trp, transitionLength=1, noDiff=3,
+    x_der=1)
+    "First-order derivative of transiation factor w.r.t. temperature";
+  Real ddlambda_dT_dT(unit="1/(K2)") = SorpLib.Numerics.smoothTransition_der2(
+    x=T_sat, transitionPoint=T_water_trp, transitionLength=1, noDiff=3,
+    x_der=1, x_der2=0)
+    "Second-order derivative of transiation factor w.r.t. temperature";
+
+  Real aux_s_1
+    "Auxiliary variable 1 of saturation pressure of gas-solid boundary";
+  Real aux_s_2
+    "Auxiliary variable 2 of saturation pressure of gas-solid boundary";
+
+  Real aux_l_1
+    "Auxiliary variable 1 of saturation pressure of gas-liquid boundary";
+  Real aux_l_2
+    "Auxiliary variable 2 of saturation pressure of gas-liquid boundary";
+
+algorithm
+  //
+  // Calculate pressures
+  //
+  p_sat_s := p_water_trp * exp(coeff_s[1] - coeff_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] - coeff_s[2] * T_red_s ^ exp_s[2])
+    "Saturation pressure of gas-solid boundary";
+  p_sat_l := p_water_crit * exp(T_water_crit/T_sat *
+    (coeff_l[1] * T_red_fl ^ exp_l[1] +
+    coeff_l[2] * T_red_fl ^ exp_l[2] +
+    coeff_l[3] * T_red_fl ^ exp_l[3] +
+    coeff_l[4] * T_red_fl ^ exp_l[4] +
+    coeff_l[5] * T_red_fl ^ exp_l[5] +
+    coeff_l[6] * T_red_fl ^ exp_l[6]))
+    "Saturation pressure of gas-liquid boundary";
+
+  //
+  // Calculate auxiliary variables
+  //
+  aux_s_1 := -p_sat_s/T_sat
+    "Auxiliary variable 1 of saturation pressure of gas-solid boundary";
+  aux_s_2 := (coeff_s[1] * exp_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] * exp_s[2] * T_red_s ^ exp_s[2])
+    "Auxiliary variable 2 of saturation pressure of gas-solid boundary";
+
+  aux_l_1 := -p_sat_l/T_sat
+    "Auxiliary variable 1 of saturation pressure of gas-liquid boundary";
+  aux_l_2 := log(p_sat_l/p_water_crit) + coeff_l[1] +
+    coeff_l[2] * exp_l[2] * T_red_fl^(exp_l[2]-1) +
+    coeff_l[3] * exp_l[3] * T_red_fl^(exp_l[3]-1) +
+    coeff_l[4] * exp_l[4] * T_red_fl^(exp_l[4]-1) +
+    coeff_l[5] * exp_l[5] * T_red_fl^(exp_l[5]-1) +
+    coeff_l[6] * exp_l[6] * T_red_fl^(exp_l[6]-1)
+    "Auxiliary variable 2 of saturation pressure of gas-liquid boundary";
+
+  //
+  // Calculate first-order partial derivatives of pressures w.r.t. temperature
+  //
+  dp_sat_s_dT := aux_s_1 * aux_s_2
+    "First-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+  dp_sat_l_dT := aux_l_1 * aux_l_2
+    "First-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  //
+  // Calculate second-order partial derivatives of pressures w.r.t. temperature
+  //
+  ddp_sat_s_dT_dT := (p_sat_s/T_sat^2 - dp_sat_s_dT/T_sat) * aux_s_2 +
+    aux_s_1/T_water_trp * (coeff_s[1] * exp_s[1]^2 * T_red_s ^ (exp_s[1]-1) +
+    coeff_s[2] * exp_s[2]^2 * T_red_s ^ (exp_s[2]-1))
+    "Second-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+  ddp_sat_l_dT_dT := (p_sat_l/T_sat^2 - dp_sat_l_dT/T_sat) * aux_l_2 +
+    aux_l_1 * (1/p_sat_l * dp_sat_l_dT + (-1/T_water_crit) *
+    (coeff_l[2] * exp_l[2] * (exp_l[2]-1) * T_red_fl^(exp_l[2]-2) +
+    coeff_l[3] * exp_l[3] * (exp_l[3]-1) * T_red_fl^(exp_l[3]-2) +
+    coeff_l[4] * exp_l[4] * (exp_l[4]-1) * T_red_fl^(exp_l[4]-2) +
+    coeff_l[5] * exp_l[5] * (exp_l[5]-1) * T_red_fl^(exp_l[5]-2) +
+    coeff_l[6] * exp_l[6] * (exp_l[6]-1) * T_red_fl^(exp_l[6]-2)))
+    "Second-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  //
+  // Check for boundary
+  //
+  ddp_sat_dT_dT :=ddlambda_dT_dT*p_sat_s +
+    2*dlambda_dT*dp_sat_s_dT +
+    lambda*ddp_sat_s_dT_dT +
+    (-ddlambda_dT_dT)*p_sat_l +
+    2*(-dlambda_dT)*dp_sat_l_dT +
+    (1-lambda)*ddp_sat_l_dT_dT
+    "Second-order partial derivative of saturation pressure w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the second-order partial saturation pressure of water 
+with respect to temperature depending on the temperature. This functions covers 
+both, the solid-gas and the gas-liquid boundary. For details, please check the
+function
+<a href=\"Modelica://SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture.saturationPressureH2O_T\">SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture.saturationPressureH2O_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddsaturationPressureH2O_dT_dT;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dT_pX.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dT_pX.mo
new file mode 100644
index 0000000..daaf137
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dT_pX.mo
@@ -0,0 +1,107 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dh_dT_pX
+  "Returns partial derivative of specific enthalpy w.r.t. temperature at constant pressure and mass fractions"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificHeatCapacity dh_dT_pX
+    "Partial derivative of specific enthalpy w.r.t. temperature at constant 
+    pressure and mass fractions"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+  Real dx_sat_dT_pX(unit="kg/(kg.K)")=
+    ddryMassFractionSaturation_dT_pX(state=state)
+    "Partial derivative of saturated wasser mass fraction per dry air mass 
+    w.r.t. temperature at constant pressure and mass fractions";
+
+algorithm
+  //
+  // Calculate partial derivative per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    dh_dT_pX := x[1:nX-1] / sum(x[1:nX-1]) *
+      {Modelica.Media.IdealGases.Common.Functions.cp_T(
+        data=data[i],
+        T=state.T) for i in 1:nX-1}
+      "Partial derivative equals partial derivative of unsaturated dry air without 
+      water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    dh_dT_pX := x[1:nX-1] / sum(x[1:nX-1]) *
+      {Modelica.Media.IdealGases.Common.Functions.cp_T(
+        data=data[i],
+        T=state.T) for i in 1:nX-1} +
+      x[nX] * specificHeatCapacityVapor(state=state)
+      "Partial derivative equals partial derivative of unsaturated dry air and water 
+      vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif state.T > T_water_trp then
+    dh_dT_pX := x[1:nX-1] / sum(x[1:nX-1]) *
+      {Modelica.Media.IdealGases.Common.Functions.cp_T(
+        data=data[i],
+        T=state.T) for i in 1:nX-1} +
+      enthalpyOfCondensingGas(T=state.T) * dx_sat_dT_pX +
+      x_sat * specificHeatCapacityVapor(state=state) +
+      (-1) * enthalpyOfLiquid(p=state.p, T=state.T) * dx_sat_dT_pX +
+      (x[nX]-x_sat) * specificHeatCapacityLiquid(state=state)
+      "Partial derivative equals partial derivative of saturated dry air, water
+      vapor, liquid water: Calculated applying the law of ideal gas mixtures.";
+
+  else
+    dh_dT_pX := x[1:nX-1] / sum(x[1:nX-1]) *
+      {Modelica.Media.IdealGases.Common.Functions.cp_T(
+        data=data[i],
+        T=state.T) for i in 1:nX-1} +
+      enthalpyOfCondensingGas(T=state.T) * dx_sat_dT_pX +
+      x_sat * specificHeatCapacityVapor(state=state) +
+      (-1) * enthalpyOfSolid(p=state.p, T=state.T) * dx_sat_dT_pX +
+      (x[nX]-x_sat) * specificHeatCapacitySolid(state=state)
+      "Partial derivative equals partial derivative of saturated dry air, water
+      vapor, solid water: Calculated applying the law of ideal gas mixtures.";
+
+  end if;
+
+  //
+  // Convert result
+  //
+  dh_dT_pX := dh_dT_pX / (1 + x[nX])
+    "Partial derivative per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy with
+respect to temperature at constant pressure and mass fractions as function of
+the state record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_dT_pX;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dX_pT.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dX_pT.mo
new file mode 100644
index 0000000..221242d
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dX_pT.mo
@@ -0,0 +1,154 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dh_dX_pT
+  "Returns partial derivative of specific enthalpy w.r.t. mass fractions at constant pressure and temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real[nX] dh_dX_pT(each unit="J.kg/(kg2)")
+    "Partial derivative of specific enthalpy w.r.t. mass fractions at constant 
+    pressure and temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+  Real[nX, nX] dx_dX(each unit="kg.kg/(kg.kg)")=
+    ddryAirMassFractions_dX(X=state.X)
+    "Partial derivatives of mass fractions given per dry air mass w.r.t. mass
+    fractions given per moist air mass: Rows are dry air mass and columns are
+    moist air mass";
+  Real[nX] dx_sat_dX_pT(each unit="kg.kg/(kg.kg)")=
+    ddryMassFractionSaturation_dX_pT(state=state)
+    "Partial derivatives of saturated wasser mass fraction per dry air mass 
+    w.r.t. mass fractions given per moist air mass at constant pressure and 
+    temperature";
+  Real[nX-1,nX-1] dx_dry_dx(each unit="kg.kg/(kg.kg)")
+    "Partial derivatives of mass fractions of dry air per dry air w.r.t. mass
+    fractions of dry air per dry air";
+
+  Modelica.Units.SI.SpecificEnthalpy[nX-1] h_dryAir
+    "Specific enthalpies of dry air components";
+  Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy per dry air mass";
+
+algorithm
+  //
+  // Calculate specific enthalpy and partial derivatives per dry air mass
+  //
+  for ind_x in 1:nX-1 loop
+    for ind_der in 1:nX-1 loop
+      if ind_x == ind_der then
+        dx_dry_dx[ind_x,ind_der] := 1/sum(x[1:nX-1]) - x[ind_x]/sum(x[1:nX-1])^2
+          "Partial derivatives of mass fractions of dry air per dry air w.r.t. 
+          mass fractions of dry air per dry air: Diagonal.";
+
+      else
+        dx_dry_dx[ind_x,ind_der] :=-x[ind_x]/sum(x[1:nX-1])^2
+          "Partial derivatives of mass fractions of dry air per dry air w.r.t. 
+          mass fractions of dry air per dry air: Other elements than diagonal.";
+
+      end if;
+    end for;
+  end for;
+
+  h_dryAir :={Modelica.Media.IdealGases.Common.Functions.h_T(
+    data=data[i],
+    T=state.T,
+    exclEnthForm=true,
+    refChoice=Modelica.Media.Interfaces.Choices.ReferenceEnthalpy.UserDefined,
+    h_off=h_dryAir_off) for i in 1:nX-1}
+    "Specific enthalpies of dry air components";
+
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    h := enthalpyOfNonCondensingGas(T=state.T, X=x)
+      "Specific enthalpy equals specific enthalpy of unsaturated dry air without 
+        water: Calculated applying the law of ideal gas mixtures.";
+    dh_dX_pT :=
+      {sum({sum(dx_dry_dx[1:nX-1,ind_x] .* h_dryAir) for ind_x in 1:nX-1} .*
+      dx_dX[1:nX-1,ind_X]) for ind_X in 1:nX}
+      "Partial derivative equals partial derivative of unsaturated dry air without 
+      water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    h := enthalpyOfNonCondensingGas(T=state.T, X=x) +
+      x[nX] * enthalpyOfCondensingGas(T=state.T)
+      "Specific enthalpy equals specific enthalpy of unsaturated dry air and water 
+        vapor: Calculated applying the law of ideal gas mixtures.";
+    dh_dX_pT :=
+      {sum({sum(dx_dry_dx[1:nX-1,ind_x] .* h_dryAir) for ind_x in 1:nX-1} .*
+      dx_dX[1:nX-1,ind_X]) for ind_X in 1:nX} .+
+      1 .* enthalpyOfCondensingGas(T=state.T) .* dx_dX[nX,1:nX]
+      "Partial derivative equals partial derivative of unsaturated dry air and water 
+      vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif state.T > T_water_trp then
+    h := enthalpyOfNonCondensingGas(T=state.T, X=x) +
+      x_sat * enthalpyOfCondensingGas(T=state.T) +
+      (x[nX]-x_sat) * enthalpyOfLiquid(p=state.p, T=state.T)
+      "Specific enthalpy equals specific enthalpy of saturated dry air, water
+        vapor, liquid water: Calculated applying the law of ideal gas mixtures.";
+    dh_dX_pT :=
+      {sum({sum(dx_dry_dx[1:nX-1,ind_x] .* h_dryAir) for ind_x in 1:nX-1} .*
+      dx_dX[1:nX-1,ind_X]) for ind_X in 1:nX} .+
+      1 .* enthalpyOfCondensingGas(T=state.T) .* dx_sat_dX_pT .+
+      (dx_dX[nX,1:nX] .- dx_sat_dX_pT) .* enthalpyOfLiquid(p=state.p, T=state.T)
+      "Partial derivative equals partial derivative of saturated dry air, water
+      vapor, liquid water: Calculated applying the law of ideal gas mixtures.";
+
+  else
+    h := enthalpyOfNonCondensingGas(T=state.T, X=x) +
+      x_sat * enthalpyOfCondensingGas(T=state.T) +
+      (x[nX]-x_sat) * enthalpyOfSolid(p=state.p, T=state.T)
+      "Specific enthalpy equals specific enthalpy of saturated dry air, water
+        vapor, solid water: Calculated applying the law of ideal gas mixtures.";
+    dh_dX_pT :=
+      {sum({sum(dx_dry_dx[1:nX-1,ind_x] .* h_dryAir) for ind_x in 1:nX-1} .*
+      dx_dX[1:nX-1,ind_X]) for ind_X in 1:nX} .+
+      1 .* enthalpyOfCondensingGas(T=state.T) .* dx_sat_dX_pT .+
+      (dx_dX[nX,1:nX] .- dx_sat_dX_pT) .* enthalpyOfSolid(p=state.p, T=state.T)
+      "Partial derivative equals partial derivative of saturated dry air, water
+      vapor, solid water: Calculated applying the law of ideal gas mixtures.";
+
+  end if;
+
+  //
+  // Convert result
+  //
+  dh_dX_pT := dh_dX_pT ./ (1 + x[nX]) .- h ./ (x[nX] + 1) ^2 .* dx_dX[nX,1:nX]
+    "Partial derivatives per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy with
+respect to mass fractions at constant pressure and temperature as function of
+the state record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_dX_pT;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dp_TX.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dp_TX.mo
new file mode 100644
index 0000000..26e92f0
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dh_dp_TX.mo
@@ -0,0 +1,90 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dh_dp_TX
+  "Returns partial derivative of specific enthalpy w.r.t. pressure at constant temperature and mass fractions"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerSpecificEnthalpyByPressure dh_dp_TX
+    "Partial derivative of specific enthalpy w.r.t. pressure at constant 
+    temperature and mass fractions"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+  Real dx_sat_dp_TX(unit="kg/(kg.Pa)")=
+    ddryMassFractionSaturation_dp_TX(state=state)
+    "Partial derivative of saturated wasser mass fraction per dry air mass 
+    w.r.t. pressure at constant temperature and mass fractions";
+
+algorithm
+  //
+  // Calculate partial derivative per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    dh_dp_TX := 0
+      "Partial derivative equals partial derivative of unsaturated dry air without 
+      water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    dh_dp_TX := 0
+      "Partial derivative equals partial derivative of unsaturated dry air and water 
+      vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif state.T > T_water_trp then
+    dh_dp_TX := enthalpyOfCondensingGas(T=state.T) * dx_sat_dp_TX +
+      (-1) * enthalpyOfLiquid(p=state.p, T=state.T) * dx_sat_dp_TX +
+      (x[nX]-x_sat) * v_water_liq
+      "Partial derivative equals partial derivative of saturated dry air, water
+      vapor, liquid water: Calculated applying the law of ideal gas mixtures.";
+
+  else
+    dh_dp_TX := enthalpyOfCondensingGas(T=state.T) * dx_sat_dp_TX +
+      (-1) * enthalpyOfSolid(p=state.p, T=state.T) * dx_sat_dp_TX +
+      (x[nX]-x_sat) * v_water_solid
+      "Partial derivative equals partial derivative of saturated dry air, water
+      vapor, solid water: Calculated applying the law of ideal gas mixtures.";
+
+  end if;
+
+  //
+  // Convert result
+  //
+  dh_dp_TX := dh_dp_TX / (1 + x[nX])
+    "Partial derivative per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy with
+respect to pressure at constant temperature and mass fractions as function of
+the state record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dh_dp_TX;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dmassToMoleFractions_dX.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dmassToMoleFractions_dX.mo
new file mode 100644
index 0000000..63a2a93
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dmassToMoleFractions_dX.mo
@@ -0,0 +1,62 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dmassToMoleFractions_dX
+  "Returns partial derivatives of mole fractions w.r.t mass fractions"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition  of inputs
+  //
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition  of outputs
+  //
+  output Real[nX, nX] dY_dX(each unit="mol.kg/(mol.kg)")
+    "Partial derivatives of mole fractions w.r.t mass fractions: Rows are mole
+    fractions and colums are mass fractions"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition  of variables
+  //
+protected
+  Modelica.Units.SI.MolarMass MM_mix = 1 / sum(X ./ MMX)
+    "Molar mass of mixture";
+
+algorithm
+  for ind_row in 1:nX loop
+    for ind_col in 1:nX loop
+      if ind_row == ind_col then
+        dY_dX[ind_row, ind_col] :=
+          MM_mix / MMX[ind_row] - X[ind_row] * MM_mix^2 / MMX[ind_row]^2
+          "Partial derivatives of mole fraction i w.r.t mass fraction i";
+
+      else
+        dY_dX[ind_row, ind_col] :=
+          -X[ind_row] * MM_mix^2 / (MMX[ind_row] * MMX[ind_col])
+          "Partial derivatives of mole fraction i w.r.t mass fraction j";
+
+      end if;
+    end for;
+  end for;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivatives of mole fractions with respect
+to mass fractions (i.e., rows = mole fractions; colums = mass fractions) as 
+function of mass fractions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dmassToMoleFractions_dX;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/drho_dX_ph.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/drho_dX_ph.mo
new file mode 100644
index 0000000..1e23953
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/drho_dX_ph.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function drho_dX_ph
+  "Returns partial derivative of density w.r.t. mass fractions at constant pressure and specific enthalpy"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real[nX] drho_dX_ph(each unit="kg.kg/(m3.kg)")
+    "Partial derivative of specific enthalpy w.r.t. mass fractions at constant 
+      pressure and temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+algorithm
+  drho_dX_ph := density_derX(state=state) .- density_derT_p(state=state) .*
+    dh_dX_pT(state=state) ./ dh_dT_pX(state=state)
+    "Partial derivative of specific enthalpy w.r.t. mass fractions at constant 
+      pressure and temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the density with resepct to
+mass fractions at constant pressure and specific enthalpy as function of the state 
+record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end drho_dX_ph;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryAirToMoistAirMassBasedProperties.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryAirToMoistAirMassBasedProperties.mo
new file mode 100644
index 0000000..eb6e78b
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryAirToMoistAirMassBasedProperties.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dryAirToMoistAirMassBasedProperties
+  "Converts 'dry air'-specific property to 'moist air'-specific property"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real z_dryAir
+    "Abitrary property given per dry air mass"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MassFraction x_water
+    "Mass fraction of water based on dry air mass"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real z_moistAir
+    "Abitrary property given per moist air mass"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  z_moistAir := z_dryAir / (1 + x_water)
+    "Abitrary property given per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function converts an abitrary property given per dry air mass so that it is
+given per moist air mass.
+</p>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dryAirToMoistAirMassBasedProperties;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryAirToMoistAirMassFractions.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryAirToMoistAirMassFractions.mo
new file mode 100644
index 0000000..2f0ba54
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryAirToMoistAirMassFractions.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dryAirToMoistAirMassFractions
+  "Convert mass fractions from 'dry air'-based to 'moist air'-based"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MassFraction[nX] x
+    "Mass fractions based on dry air mass"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions based on moist air mass"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  X :=cat(
+      1,
+      x[1:nX-1] ./ (1 + x[nX]),
+      {x[nX] / (1 + x[nX])})
+    "Mass fractions based on moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function converts mass fractions given per dry air mass to mass fractions
+given per moist air mass.
+</p>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dryAirToMoistAirMassFractions;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryMassFractionSaturation.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryMassFractionSaturation.mo
new file mode 100644
index 0000000..c09ae65
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dryMassFractionSaturation.mo
@@ -0,0 +1,62 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dryMassFractionSaturation
+  "Returns saturation mass fraction of condensing component (i.e., water) (per dry air mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Modelica.Units.SI.MassFraction x_sat
+    "Saturation mass fraction per dry air"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_sat=
+    saturationPressureH2O_T(T_sat = state.T)
+    "Saturation pressure";
+
+algorithm
+  x_sat := MMX[nX] / (state.Y[1:nX-1]./sum(state.Y[1:nX-1]) * MMX[1:nX-1]) *
+    p_sat / max((state.p - p_sat), Modelica.Constants.small)
+    "Saturation mass fraction per dry air";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(p_sat <= state.p,
+      "Saturation pressure (" + String(p_sat) + " Pa) is greater than total " +
+      "pressure (" + String(state.p) + " Pa). Thus, the calculation of the " +
+      "saturation mass fraction is not sound!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the saturation mass fraction of the condensing component
+(i.e., water) per dry air as function of the state record. Note that the saturation
+mass fraction can only be calculated if the partial pressure of the condensing
+component is less than the pressure of the ideal gas-vapor mixture.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dryMassFractionSaturation;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dsaturationPressureH2O_dT.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dsaturationPressureH2O_dT.mo
new file mode 100644
index 0000000..1f16381
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dsaturationPressureH2O_dT.mo
@@ -0,0 +1,127 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dsaturationPressureH2O_dT
+  "Returns partial derivative of saturatation pressure of water w.r.t. temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_sat
+    "Saturation temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Media.Common.DerPressureByTemperature dp_sat_dT
+    "First-order partial derivative of saturation pressure w.r.t. temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[2] coeff_s = {-13.9281690, 34.7078238}
+    "Coefficients of the gas-solid boundary";
+  constant Real[6] coeff_l = {-7.85951783, 1.84408259, -11.7866497,
+    22.6807411, -15.9618719, 1.80122502}
+    "Coefficients of the gas-liquid boundary";
+
+  constant Real[2] exp_s = {-1.5, -1.25}
+    "Exponents of the gas-solid boundary";
+  constant Real[6] exp_l = {1, 1.5, 3,
+    3.5, 4, 7.5}
+    "Exponents of the gas-liquid boundary";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_sat_s
+    "Saturation pressure of gas-solid boundary";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_s_dT
+    "First-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+
+  Modelica.Units.SI.Pressure p_sat_l
+    "Saturation pressure of gas-liquid boundary";
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_l_dT
+    "First-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  Real T_red_s = T_sat/T_water_trp
+    "Reduced temperature required for gas-solid boundary";
+  Real T_red_fl = 1 - T_sat/T_water_crit
+    "Reduced temperature required for gas-liquid boundary";
+
+  Real lambda(unit="1") = SorpLib.Numerics.smoothTransition(
+    x=T_sat, transitionPoint=T_water_trp, transitionLength=1, noDiff=3)
+    "Transiation factor";
+  Real dlambda_dT(unit="1/K") = SorpLib.Numerics.smoothTransition_der(
+    x=T_sat, transitionPoint=T_water_trp, transitionLength=1, noDiff=3,
+    x_der=1)
+    "First-order derivative of transiation factor w.r.t. temperature";
+
+algorithm
+  //
+  // Calculate pressures
+  //
+  p_sat_s := p_water_trp * exp(coeff_s[1] - coeff_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] - coeff_s[2] * T_red_s ^ exp_s[2])
+    "Saturation pressure of gas-solid boundary";
+  p_sat_l := p_water_crit * exp(T_water_crit/T_sat *
+    (coeff_l[1] * T_red_fl ^ exp_l[1] +
+    coeff_l[2] * T_red_fl ^ exp_l[2] +
+    coeff_l[3] * T_red_fl ^ exp_l[3] +
+    coeff_l[4] * T_red_fl ^ exp_l[4] +
+    coeff_l[5] * T_red_fl ^ exp_l[5] +
+    coeff_l[6] * T_red_fl ^ exp_l[6]))
+    "Saturation pressure of gas-liquid boundary";
+
+  //
+  // Calculate first-order partial derivatives of pressures w.r.t. temperature
+  //
+  dp_sat_s_dT := -p_sat_s/T_sat *
+    (coeff_s[1] * exp_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] * exp_s[2] * T_red_s ^ exp_s[2])
+    "First-order partial derivative of saturation pressure of gas-solid boundary
+    w.r.t. temperature";
+  dp_sat_l_dT := -p_sat_l/T_sat * (
+    log(p_sat_l/p_water_crit) +
+    coeff_l[1] +
+    coeff_l[2] * exp_l[2] * T_red_fl^(exp_l[2]-1) +
+    coeff_l[3] * exp_l[3] * T_red_fl^(exp_l[3]-1) +
+    coeff_l[4] * exp_l[4] * T_red_fl^(exp_l[4]-1) +
+    coeff_l[5] * exp_l[5] * T_red_fl^(exp_l[5]-1) +
+    coeff_l[6] * exp_l[6] * T_red_fl^(exp_l[6]-1))
+    "First-order partial derivative of saturation pressure of gas-liquid boundary
+    w.r.t. temperature";
+
+  //
+  // Check for boundary
+  //
+  dp_sat_dT :=dlambda_dT*p_sat_s +
+    lambda*dp_sat_s_dT +
+    (-dlambda_dT)*p_sat_l +
+    (1-lambda)*dp_sat_l_dT
+    "First-order partial derivative of saturation pressure w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the first-order partial saturation pressure of water 
+with respect to temperature depending on the temperature. This functions covers 
+both, the solid-gas and the gas-liquid boundary. For details, please check the
+function
+<a href=\"Modelica://SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture.saturationPressureH2O_T\">SorpLib.Media.IdealGasMixtures.Interfaces.PartialIdealGasMixture.saturationPressureH2O_T</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dsaturationPressureH2O_dT;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dT_pX.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dT_pX.mo
new file mode 100644
index 0000000..5823dae
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dT_pX.mo
@@ -0,0 +1,92 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dv_dT_pX
+  "Returns partial derivative of specific volume w.r.t. temperature at constant pressure and mass fractions"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerSpecificVolumeByTemperature dv_dT_pX
+    "Partial derivative of specific volume w.r.t. temperature at constant pressure
+    and mass fractions"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+  Real dx_sat_dT_pX(unit="kg/(kg.K)")=
+    ddryMassFractionSaturation_dT_pX(state=state)
+    "Partial derivative of saturated wasser mass fraction per dry air mass 
+    w.r.t. temperature at constant pressure and mass fractions";
+
+algorithm
+  //
+  // Calculate partial derivative per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    dv_dT_pX := sum(x[1:nX-1] ./ MMX[1:nX-1] .*  Modelica.Constants.R ./ state.p)
+      "Partial derivative equals partial derivative of unsaturated dry air without 
+      water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    dv_dT_pX := sum(x ./ MMX .* Modelica.Constants.R ./ state.p)
+      "Partial derivative equals partial derivative of unsaturated dry air and water 
+      vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif state.T > T_water_trp then
+    dv_dT_pX := sum(x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] ./ state.p) +
+      Modelica.Constants.R / MMX[nX] * state.T / state.p * dx_sat_dT_pX +
+      x_sat * Modelica.Constants.R / MMX[nX] / state.p +
+      (-1) * v_water_liq * dx_sat_dT_pX
+      "Partial derivative equals partial derivative of saturated dry air, water vapor,
+      and liquid water: Calculated applying the law of ideal gas  mixtures.";
+
+  else
+    dv_dT_pX := sum(x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] ./ state.p) +
+      Modelica.Constants.R / MMX[nX] * state.T / state.p * dx_sat_dT_pX +
+      x_sat * Modelica.Constants.R / MMX[nX] / state.p +
+      (-1) * v_water_solid * dx_sat_dT_pX
+      "Partial derivative equals partial derivative of saturated dry air, water vapor,
+      and solid water: Calculated applying the law of ideal gas  mixtures.";
+
+  end if;
+
+  //
+  // Convert result
+  //
+  dv_dT_pX := dv_dT_pX / (1 + x[nX])
+    "Partial derivative per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific volume with
+respect to temperature at constant pressure and mass fractions as function of
+the state record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dv_dT_pX;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dX_pT.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dX_pT.mo
new file mode 100644
index 0000000..2d9df04
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dX_pT.mo
@@ -0,0 +1,125 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dv_dX_pT
+  "Returns partial derivatives of specific volume w.r.t. mass fractions at constant pressure and temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real[nX] dv_dX_pT(each unit="m3/kg")
+    "Partial derivatives of specific volume w.r.t. mass fractions at constant 
+    pressure and temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+  Real[nX, nX] dx_dX(each unit="kg.kg/(kg.kg)")=
+    ddryAirMassFractions_dX(X=state.X)
+    "Partial derivatives of mass fractions given per dry air mass w.r.t. mass
+    fractions given per moist air mass: Rows are dry air mass and columns are
+    moist air mass";
+  Real[nX] dx_sat_dX_pT(each unit="kg.kg/(kg.kg)")=
+    ddryMassFractionSaturation_dX_pT(state=state)
+    "Partial derivatives of saturated wasser mass fraction per dry air mass 
+    w.r.t. mass fractions given per moist air mass at constant pressure and 
+    temperature";
+
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume per dry air mass";
+
+algorithm
+  //
+  // Calculate specific volume and partial derivatives per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    v := sum(x[1:nX-1] ./ MMX[1:nX-1] .* Modelica.Constants.R .*
+      state.T ./ state.p)
+      "Specific volume equals specific volume of unsaturated dry air without 
+      water: Calculated applying the law of ideal gas mixtures.";
+    dv_dX_pT := {sum(1 ./ MMX[1:nX-1] .* Modelica.Constants.R .*
+      state.T ./ state.p .* dx_dX[1:nX-1,ind]) for ind in 1:nX}
+      "Partial derivatives equal partial derivatives of unsaturated dry air 
+      without water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    v := sum(x ./ MMX .* Modelica.Constants.R  .*
+      state.T ./ state.p)
+      "Specific volume equals specific volume of unsaturated dry air and water 
+      vapor: Calculated applying the law of ideal gas mixtures.";
+    dv_dX_pT := {sum(1 ./ MMX .* Modelica.Constants.R  .*
+      state.T ./ state.p .* dx_dX[1:nX,ind]) for ind in 1:nX}
+      "Partial derivatives equal partial derivatives of unsaturated dry air and 
+      water vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif state.T > T_water_trp then
+    v := sum(x[1:nX-1] ./ MMX[1:nX-1] .* Modelica.Constants.R .*
+      state.T ./ state.p) +
+      x_sat * Modelica.Constants.R / MMX[nX] * state.T / state.p +
+      (x[nX] - x_sat) * v_water_liq
+      "Specific volume equals specific volume of saturated dry air, water vapor,
+      and liquid water: Calculated applying the law of ideal gas  mixtures.";
+    dv_dX_pT := {sum(1 ./ MMX[1:nX-1] .* Modelica.Constants.R .*
+      state.T ./ state.p .* dx_dX[1:nX-1,ind]) for ind in 1:nX} .+
+      1 .* Modelica.Constants.R ./ MMX[nX] .* state.T ./ state.p .*
+      dx_sat_dX_pT .+
+      (dx_dX[nX, 1:nX] - dx_sat_dX_pT) * v_water_liq
+      "Partial derivatives equal partial derivatives of saturated dry air, water 
+      vapor, and liquid water: Calculated applying the law of ideal gas mixtures.";
+
+  else
+    v := sum(x[1:nX-1] ./ MMX[1:nX-1] .* Modelica.Constants.R .*
+      state.T ./ state.p) +
+      x_sat * Modelica.Constants.R / MMX[nX] * state.T / state.p +
+      (x[nX] - x_sat) * v_water_solid
+      "Specific volume equals specific volume of saturated dry air, water vapor,
+      and solid water: Calculated applying the law of ideal gas  mixtures.";
+    dv_dX_pT := {sum(1 ./ MMX[1:nX-1] .* Modelica.Constants.R .*
+      state.T ./ state.p .* dx_dX[1:nX-1,ind]) for ind in 1:nX} .+
+      1 .* Modelica.Constants.R ./ MMX[nX] .* state.T ./ state.p .*
+      dx_sat_dX_pT .+
+      (dx_dX[nX, 1:nX] - dx_sat_dX_pT) * v_water_solid
+      "Partial derivatives equal partial derivatives of saturated dry air, water 
+      vapor, and solid water: Calculated applying the law of ideal gas  mixtures.";
+
+  end if;
+
+  //
+  // Convert result
+  //
+  dv_dX_pT := dv_dX_pT ./ (1 + x[nX]) .- v ./ (x[nX] + 1) ^2 .* dx_dX[nX,1:nX]
+    "Partial derivatives per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivatives of the specific volume with
+respect to mass fractions given per moist air mass at constant pressure and 
+temperature as function of the state record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dv_dX_pT;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dp_TX.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dp_TX.mo
new file mode 100644
index 0000000..8bb7fe3
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/dv_dp_TX.mo
@@ -0,0 +1,95 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function dv_dp_TX
+  "Returns partial derivative of specific volume w.r.t. pressure at constant temperature and mass fractions"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Units.DerSpecificVolumeByPressure dv_dp_TX
+    "Partial derivative of specific volume w.r.t. pressure at constant temperature
+    and mass fractions"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+  Real dx_sat_dp_TX(unit="kg/(kg.Pa)")=
+    ddryMassFractionSaturation_dp_TX(state=state)
+    "Partial derivative of saturated wasser mass fraction per dry air mass 
+    w.r.t. pressure at constant temperature and mass fractions";
+
+algorithm
+  //
+  // Calculate partial derivative per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    dv_dp_TX := sum(-x[1:nX-1] ./ MMX[1:nX-1] .*
+      Modelica.Constants.R .* state.T ./ state.p^2)
+      "Partial derivative equals partial derivative of unsaturated dry air without 
+      water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    dv_dp_TX := sum(-x ./ MMX .* Modelica.Constants.R  .* state.T ./ state.p^2)
+      "Partial derivative equals partial derivative of unsaturated dry air and water 
+      vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif state.T > T_water_trp then
+    dv_dp_TX := sum(-x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] .*
+      state.T ./ state.p^2) +
+      Modelica.Constants.R / MMX[nX] * state.T / state.p * dx_sat_dp_TX +
+      (-1) * x_sat * Modelica.Constants.R / MMX[nX] * state.T / state.p^2 +
+      (-1) * v_water_liq * dx_sat_dp_TX
+      "Partial derivative equals partial derivative of saturated dry air, water vapor,
+      and liquid water: Calculated applying the law of ideal gas  mixtures.";
+
+  else
+    dv_dp_TX := sum(-x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] .*
+      state.T ./ state.p^2) +
+      Modelica.Constants.R / MMX[nX] * state.T / state.p * dx_sat_dp_TX +
+      (-1) * x_sat * Modelica.Constants.R / MMX[nX] * state.T / state.p^2 +
+      (-1) * v_water_solid * dx_sat_dp_TX
+      "Partial derivative equals partial derivative of saturated dry air, water vapor,
+      and solid water: Calculated applying the law of ideal gas  mixtures.";
+
+  end if;
+
+  //
+  // Convert result
+  //
+  dv_dp_TX := dv_dp_TX / (1 + x[nX])
+    "Partial derivative per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific volume with
+respect to pressure at constant temperature and mass fractions as function of
+the state record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dv_dp_TX;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfCondensingComponent.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfCondensingComponent.mo
new file mode 100644
index 0000000..3be6c55
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfCondensingComponent.mo
@@ -0,0 +1,81 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function enthalpyOfCondensingComponent
+  "Returns specific enthalpy of condensing component (i.e., water) (per moist air mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy of condensing component (i.e., water) per moist air mass"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+algorithm
+  //
+  // Calculate specific enthalpy per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    h := 0
+      "Specific enthalpy equals zero because water is not within the mixture";
+
+  elseif x[nX] <= x_sat then
+    h := x[nX] * enthalpyOfCondensingGas(T=state.T)
+      "Specific enthalpy equals specific enthalpy of water vapor";
+
+  elseif state.T > T_water_trp then
+    h := x_sat * enthalpyOfCondensingGas(T=state.T) +
+      (x[nX]-x_sat) * enthalpyOfLiquid(p=state.p, T=state.T)
+      "Specific enthalpy equals specific enthalpy of water vapor and liquid 
+      water";
+
+  else
+    h := x_sat * enthalpyOfCondensingGas(T=state.T) +
+      (x[nX]-x_sat) * enthalpyOfSolid(p=state.p, T=state.T)
+      "Specific enthalpy equals specific enthalpy of water vapor and solid 
+      water";
+
+  end if;
+
+  //
+  // Convert specific enthalpy per dry air mass
+  //
+  h := h / (1 + x[nX])
+    "Specific enthalpy of condensing component (i.e., water) per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the condensing component (i.e.,
+water) per moist air mass according to the models of an ideal solid, ideal liquid, 
+and ideal gas.
+</p>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end enthalpyOfCondensingComponent;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfLiquidIce.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfLiquidIce.mo
new file mode 100644
index 0000000..7758f3e
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfLiquidIce.mo
@@ -0,0 +1,79 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function enthalpyOfLiquidIce
+  "Returns specific enthalpy of condensing component at solid or liquid state (i.e., ice or liquid water) (per moist air mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy of condensing component at solid or liquid state (i.e., 
+    ice or liquid water) per moist air mass"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+algorithm
+  //
+  // Calculate specific enthalpy per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    h := 0
+      "Specific enthalpy equals zero because water is not within the mixture";
+
+  elseif x[nX] <= x_sat then
+    h := 0
+      "Specific enthalpy equals zero because air is not saturated";
+
+  elseif state.T > T_water_trp then
+    h := (x[nX]-x_sat) * enthalpyOfLiquid(p=state.p, T=state.T)
+      "Specific enthalpy equals specific enthalpy of liquid water";
+
+  else
+    h := (x[nX]-x_sat) * enthalpyOfSolid(p=state.p, T=state.T)
+      "Specific enthalpy equals specific enthalpy of solid water";
+
+  end if;
+
+  //
+  // Convert specific enthalpy per dry air mass
+  //
+  h := h / (1 + x[nX])
+    "Specific enthalpy of condensing component at solid or liquid state per moist 
+    air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the condensing component at the
+solid or liquid state (i.e., ice or liquid water) per moist air mass according to 
+the models of an ideal solid or liquid.
+</p>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end enthalpyOfLiquidIce;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfNonCondensingComponents.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfNonCondensingComponents.mo
new file mode 100644
index 0000000..dda6d51
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfNonCondensingComponents.mo
@@ -0,0 +1,55 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function enthalpyOfNonCondensingComponents
+  "Returns specific enthalpy of non-condensing components (i.e., dry air) (per moist air mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy of non-condensing components (i.e., dry air)"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+algorithm
+  h := state.X[1:nX-1] * {Modelica.Media.IdealGases.Common.Functions.h_T(
+    data=data[i],
+    T=state.T,
+    exclEnthForm=true,
+    refChoice=Modelica.Media.Interfaces.Choices.ReferenceEnthalpy.UserDefined,
+    h_off=h_dryAir_off) for i in 1:nX-1}
+    "Specific enthalpy of dry air";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the non-condensing components
+(i.e., dry air) per moist air mass according to the model of an ideal gas mixture 
+as function of temperature and mass fractions. The specific enthalpy is calculated 
+using NASA Glenn Coefficients. For more details, check the function
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.h_TX\">Modelica.Media.IdealGases.Common.MixtureGasNasa.h_TX</a>.</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  McBride, B.J. and Zehe, M.J. and Gordon, S. (2002). NASA Glenn Coefficients for Calculating Thermodynamic Properties of Individual Species, Technical report, NASA/TP—2002-211556. URL: https://ntrs.nasa.gov/citations/20020085330.
+  </li>
+</ul>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end enthalpyOfNonCondensingComponents;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfSolid.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfSolid.mo
new file mode 100644
index 0000000..61be1c9
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfSolid.mo
@@ -0,0 +1,95 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function enthalpyOfSolid
+  "Returns specific enthalpy of solid water (per water mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy of solid water"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[7] coefficients=
+    {2.19406894387930e-11, -2.21186473219202e-8, 8.60754642146296e-6,
+    -1.57223901063024e-3, 1.24518779128263e-1, 5.27605328970081,
+    1.18325880591863e+1}
+    "Coefficients of polynomical function";
+  constant Real[7] exponents=
+    {6, 5, 4, 3, 2, 1, 0}
+    "Exponents of polynomical function";
+
+algorithm
+  h := h_water_ref - dh_fus_water_ref + v_water_solid * (p - p_water_ref) +
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+      T=T,
+      T_ref=T_water_trp,
+      z_ref=1,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature) -
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+      T=T_water_ref,
+      T_ref=T_water_trp,
+      z_ref=1,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Specific enthalpy of liquid water";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(50 <= T and T <= T_water_trp+1,
+      "Temperature (" + String(T) + " K) is not between 50 and 274.16 K. " +
+      "Calculation of specific enthalpy of ice may not be valid!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the condensing component's
+(i.e., water) solid phase per solid mass according to the model of an ideal solid 
+as function of pressure and temperature.  The specific heat capacity is calculated 
+as a polynomial fit to specific heat capacity data calculated with the reference 
+equation of state for ice. The data was calculated for fixed pressure 
+(p_water_trp = 611.657 Pa) and temperature varying from 50 K to 274.16 K. Note 
+that this function does not consider the actual water mass fraction. To calculate 
+the specific enthalpy of the solid water that is actually present, use the function
+<a href=\"Modelica://SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture.enthalpyOfLiquidIce\">SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture.enthalpyOfLiquidIce</a>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  The International Association for the Properties of Water and Steam (2009). Revised Release on the Equation of State 2006 for H2O Ice Ih. URL: https://iapws.org/relguide/Ice-2009.html.
+  </li>
+</ul>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end enthalpyOfSolid;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfVapor.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfVapor.mo
new file mode 100644
index 0000000..e0071e5
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/enthalpyOfVapor.mo
@@ -0,0 +1,75 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function enthalpyOfVapor
+  "Returns specific enthalpy of condensing component at gas state (i.e., water vapor) (per moist air mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy of condensing component at gas state (i.e., water vapor)
+    per moist air mass"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+algorithm
+  //
+  // Calculate specific enthalpy per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    h := 0
+      "Specific enthalpy equals zero because water is not within the mixture";
+
+  elseif x[nX] <= x_sat then
+    h := x[nX] * enthalpyOfCondensingGas(T=state.T)
+      "Specific enthalpy equals specific enthalpy of water vapor (unsaturated)";
+
+  else
+    h := x_sat * enthalpyOfCondensingGas(T=state.T)
+      "Specific enthalpy equals specific enthalpy of water vapor (saturated)";
+
+  end if;
+
+  //
+  // Convert specific enthalpy per dry air mass
+  //
+  h := h / (1 + x[nX])
+    "Specific enthalpy of condensing component at gas state (i.e., water vapor) 
+    per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the condensing component at the
+gas state (i.e., vaporous water) per moist air mass according to the model of an 
+ideal gas.
+</p>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end enthalpyOfVapor;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfCondensingGas.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfCondensingGas.mo
new file mode 100644
index 0000000..98ab1b2
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfCondensingGas.mo
@@ -0,0 +1,95 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function entropyOfCondensingGas
+  "Returns specific entropy of vaporous water (per water mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy of vaporous water"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[10] coefficients=
+    {7.03241022996521e-23, -4.12454440465976e-19, 1.05640534898709e-15,
+    -1.54797437245421e-12, 1.42577474111776e-9, -8.51385633913246e-7,
+    3.26064390458737e-4, -7.52464997116974e-2, 9.42339113729594,
+    1.36103845934352e+3}
+    "Coefficients of polynomical function";
+  constant Real[10] exponents=
+    {9, 8, 7, 6, 5, 4, 3, 2, 1, 0} .- 1
+    "Exponents of polynomical function";
+
+algorithm
+  s := s_water_ref + ds_vap_water_ref +
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+      T=T,
+      T_ref=T_water_crit,
+      z_ref=1,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature) -
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+      T=T_water_ref,
+      T_ref=T_water_crit,
+      z_ref=1,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature) -
+    Modelica.Constants.R / MMX[nX] * Modelica.Math.log(max(p,
+    Modelica.Constants.eps) / reference_p)
+    "Specific entropy of vaporous water";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(200 <= T and T <= 1000,
+      "Temperature (" + String(T) + " K) is not between 200 and 1000 K. " +
+      "Calculation of specific entropy of vapor may not be valid!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific entropy of the condensing component's
+(i.e., water) vapor phase per mass of water according to the model of an ideal 
+gas as function of pressue and temperature. The specific heat capacity is calculated 
+as a polynomial fit to specific heat capacity data calculated according to the NASA 
+Glenn Coefficients. The data was calculated for a temperature varying from 200 K 
+to 1000 K. Note that this function does not consider the actual water mass fraction. 
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  McBride, B.J. and Zehe, M.J. and Gordon, S. (2002). NASA Glenn Coefficients for Calculating Thermodynamic Properties of Individual Species, Technical report, NASA/TP—2002-211556. URL: https://ntrs.nasa.gov/citations/20020085330.
+  </li>
+</ul>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end entropyOfCondensingGas;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfLiquid.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfLiquid.mo
new file mode 100644
index 0000000..9262011
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfLiquid.mo
@@ -0,0 +1,91 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function entropyOfLiquid
+  "Returns specific entropy of liquid water (per water mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy of liquid water"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[10] coefficients=
+    {4.66348457415926e-19, -1.16579701193758e-15, 9.49925152355854e-13,
+    5.81553479401465e-11, -6.55387915784314e-7, 5.30868446475702e-4,
+    -2.18234813641286e-1, 5.13043718148301e1, -6.58121774333134e3,
+    3.63215816205503e5}
+    "Coefficients of polynomical function";
+  constant Real[10] exponents=
+    {9, 8, 7, 6, 5, 4, 3, 2, 1, 0} .- 1
+    "Exponents of polynomical function";
+
+algorithm
+  s := s_water_ref +
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+      T=T,
+      T_ref=T_water_crit,
+      z_ref=1,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature) -
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+      T=T_water_ref,
+      T_ref=T_water_crit,
+      z_ref=1,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Specific entropy of liquid water";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(T_water_trp-1 <= T and T <= 573.15,
+      "Temperature (" + String(T) + " K) is not between 272.16 and 573.15 K. " +
+      "Calculation of specific entropy of liquid may not be valid!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific entropy of the condensing component's
+(i.e., water) liquid phase per water mass according to the model of an ideal 
+liquid as function of pressure and temperature. The specific heat capacity is 
+calculated as a polynomial fit to specific heat capacity data calculated at 
+saturated liquid state with the reference equation of state for water. The data 
+was calculated for temperature varying from 273.16 K to 573.15 K. Note that this 
+function does not consider the actual water mass fraction.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  The International Association for the Properties of Water and Steam (2009). Revised Release on the Equation of State 2006 for H2O Ice Ih. URL: https://iapws.org/relguide/Ice-2009.html.
+  </li>
+</ul>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end entropyOfLiquid;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfNonCondensingGas.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfNonCondensingGas.mo
new file mode 100644
index 0000000..e68bae3
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfNonCondensingGas.mo
@@ -0,0 +1,64 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function entropyOfNonCondensingGas
+  "Returns specific entropy of non-condensing components (i.e., dry air) (per dry air mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Pressure[nX] p_i
+    "Partial pressures"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy of non-condensing components (i.e., dry air)"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+algorithm
+  s := X[1:nX-1] / sum(X[1:nX-1]) * {s_dryAir_off +
+    Modelica.Media.IdealGases.Common.Functions.s0_T(data=data[i], T=T) -
+    Modelica.Constants.R / MMX[i] * Modelica.Math.log(max(p_i[i],
+    Modelica.Constants.eps) / reference_p) for i in 1:nX-1}
+    "Specific entropy of non-condensing components (i.e., dry air)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific entropy of the non-condensing components
+(i.e., dry air) per moist air mass according to the model of an ideal gas mixture 
+as function of partial pressures, temperature, and mass fractions. The specific 
+entropy is calculated using NASA Glenn Coefficients. For more details, check the 
+functions
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.specificEntropy\">Modelica.Media.IdealGases.Common.MixtureGasNasa.specificEntropy</a>,
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.specificEntropyOfpTX\">Modelica.Media.IdealGases.Common.MixtureGasNasa.specificEntropyOfpTX</a>,
+and
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.s_TX\">Modelica.Media.IdealGases.Common.MixtureGasNasa.s_TX</a>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  McBride, B.J. and Zehe, M.J. and Gordon, S. (2002). NASA Glenn Coefficients for Calculating Thermodynamic Properties of Individual Species, Technical report, NASA/TP—2002-211556. URL: https://ntrs.nasa.gov/citations/20020085330.
+  </li>
+</ul>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end entropyOfNonCondensingGas;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfSolid.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfSolid.mo
new file mode 100644
index 0000000..971388a
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/entropyOfSolid.mo
@@ -0,0 +1,90 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function entropyOfSolid
+  "Returns specific entropy of solid water (per water mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy of solid water"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[7] coefficients=
+    {2.19406894387930e-11, -2.21186473219202e-8, 8.60754642146296e-6,
+    -1.57223901063024e-3, 1.24518779128263e-1, 5.27605328970081,
+    1.18325880591863e+1}
+    "Coefficients of polynomical function";
+  constant Real[7] exponents=
+    {6, 5, 4, 3, 2, 1, 0} .- 1
+    "Exponents of polynomical function";
+
+algorithm
+  s := s_water_ref - ds_fus_water_ref +
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+      T=T,
+      T_ref=T_water_crit,
+      z_ref=1,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature) -
+    SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+      T=T_water_ref,
+      T_ref=T_water_crit,
+      z_ref=1,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Specific entropy of solid water";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(50 <= T and T <= T_water_trp+1,
+      "Temperature (" + String(T) + " K) is not between 50 and 274.16 K. " +
+      "Calculation of specific entropy of ice may not be valid!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific entropy of the condensing component's
+(i.e., water) solid phase per solid mass according to the model of an ideal solid 
+as function of temperature.  The specific heat capacity is calculated as a 
+polynomial fit to specific heat capacity data calculated with the reference 
+equation of state for ice. The data was calculated for fixed pressure 
+(p_water_trp = 611.657 Pa) and temperature varying from 50 K to 274.16 K. Note 
+that this function does not consider the actual water mass fraction.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  The International Association for the Properties of Water and Steam (2009). Revised Release on the Equation of State 2006 for H2O Ice Ih. URL: https://iapws.org/relguide/Ice-2009.html.
+  </li>
+</ul>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end entropyOfSolid;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/massFractionSaturation.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/massFractionSaturation.mo
new file mode 100644
index 0000000..04ef20f
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/massFractionSaturation.mo
@@ -0,0 +1,49 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function massFractionSaturation
+  "Return saturation mass fraction of condensing component (i.e., water) (per saturated moist air mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Modelica.Units.SI.MassFraction X_sat
+    "Saturation mass fraction per saturated moist air"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  MassFraction x_sat = dryMassFractionSaturation(state=state)
+    "Saturation mass fraction per dry air";
+
+algorithm
+   X_sat :=x_sat / (1 + x_sat)
+    "Saturation mass fraction per saturated moist air";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the saturation mass fraction of the condensing component
+(i.e., water) per saturated moist air as function of the state record. Note that 
+the saturation mass fraction can only be calculated if the partial pressure of the 
+condensing component is less than the pressure of the ideal gas-vapor mixture.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end massFractionSaturation;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/massFractions_pTxDryPhi.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/massFractions_pTxDryPhi.mo
new file mode 100644
index 0000000..ffd41b3
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/massFractions_pTxDryPhi.mo
@@ -0,0 +1,89 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function massFractions_pTxDryPhi
+  "Returns mass fractions per moist air mass based on pressure, temperature, compoition of dry air, and relative humidity"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX-1] x
+    "Mass fractions of dry air components per dry air mass"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Real phi(min=0, max=1)
+    "Relative humidity"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions per moist air mass"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MoleFraction[nX-1] y=
+    massToMoleFractions(X=x, MMX=MMX)
+    "Mole fractions of dry air components per dry air amount of substances";
+  Modelica.Units.SI.Pressure p_sat=
+    saturationPressureH2O_T(T_sat = T)
+    "Saturation pressure";
+
+  Modelica.Units.SI.MassFraction x_water
+    "Water mass fraction per dry air mass";
+
+algorithm
+  x_water := MMX[nX] / (y * MMX[1:nX-1]) *
+    phi*p_sat / max((p - phi*p_sat), Modelica.Constants.small)
+    "Water mass fraction per dry air mass";
+
+  X :=cat(
+    1,
+    x ./ (1 + x_water),
+    {x_water} ./ (1 + x_water))
+    "Mass fractions per moist air mass";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(0 <= phi and phi <= 1,
+      "Relative humidity (" + String(phi) + " ) is not between 0 and 1. Thus, the" +
+      "calculation of the water mass fraction is not sound!",
+      level = AssertionLevel.warning);
+
+    assert(phi*p_sat <= p,
+      "Partial pressure of water (" + String(phi*p_sat) + " Pa ) is greater " +
+      "than the total pressure (" + String(p) + " Pa ) . Thus, the calculation " +
+      " of the water mass fraction is not sound!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the mass fractions per moist air mass based on the pressure,
+temperature, mass fractions of the dry air components per dry air mass, and relative 
+humidity. Note that this function only returns reasonable results for unsaturated
+air.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end massFractions_pTxDryPhi;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/moistAirToDryAirMassBasedProperties.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/moistAirToDryAirMassBasedProperties.mo
new file mode 100644
index 0000000..fe45fb8
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/moistAirToDryAirMassBasedProperties.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function moistAirToDryAirMassBasedProperties
+  "Converts 'moist air'-specific property to 'dry air'-specific property"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real z_moistAir
+    "Abitrary property given per moist air mass"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.MassFraction X_water
+    "Mass fraction of water based on moist air mass"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real z_dryAir
+    "Abitrary property given per dry air mass"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  z_dryAir := z_moistAir * (1 + X_water / (1 - X_water))
+    "Abitrary property given per dry air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function converts an abitrary property given per moist air mass so that it is
+given per dry air mass.
+</p>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end moistAirToDryAirMassBasedProperties;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/moistAirToDryAirMassFractions.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/moistAirToDryAirMassFractions.mo
new file mode 100644
index 0000000..e46843b
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/moistAirToDryAirMassFractions.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function moistAirToDryAirMassFractions
+  "Convert mass fractions from 'moist air'-based to 'dry air'-based"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions based on moist air mass"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.MassFraction[nX] x
+    "Mass fractions based on dry air mass"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  x :=cat(
+      1,
+      X[1:nX-1] .* (1 + X[nX] / (1 - X[nX])),
+      {X[nX] / (1 - X[nX])})
+    "Mass fractions based on dry air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function converts mass fractions given per moist air mass to mass fractions
+given per dry air mass.
+</p>
+
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end moistAirToDryAirMassFractions;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/package.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/package.mo
new file mode 100644
index 0000000..3fad5aa
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/package.mo
@@ -0,0 +1,1583 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces;
+partial package PartialIdealGasWaterVaporMixture "Medium model of an ideal gas-vapor mixture with water as condensing component based on NASA source "
+  extends Modelica.Media.Interfaces.PartialCondensingGases(
+    redeclare final record FluidConstants =
+      Modelica.Media.Interfaces.Types.IdealGas.FluidConstants,
+    final ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.pTX,
+    final singleState=false,
+    final reducedX=true,
+    final fixedX=false,
+    final reference_p=1e5,
+    final reference_T(min=0)=0);
+
+  //
+  // Definition of constants
+  //
+  constant Modelica.Media.IdealGases.Common.DataRecord[:] data
+    "Data records of ideal gas-vapor components. Note that water is the vapor
+    substance and must be the last data record.";
+  constant Modelica.Units.SI.MolarMass[nX] MMX=data[:].MM
+    "Molar masses of components";
+
+  constant Modelica.Units.SI.Pressure p_water_trp = 611.657
+   "Triple point pressure of water";
+  constant Modelica.Units.SI.Pressure p_water_crit = 22.064e6
+   "Critical pressure of water";
+
+  constant Modelica.Units.SI.Temperature T_water_trp = 273.16
+   "Triple point temperature of water";
+  constant Modelica.Units.SI.Temperature T_water_crit = 647.096
+   "Critical temperature of water";
+
+  constant Modelica.Units.SI.Density d_water_crit = 322
+    "Critical density of water";
+
+  constant Modelica.Units.SI.SpecificVolume v_water_liq = 1/1000
+    "Specific volume of condensing component (i.e., water) at liquid phase
+    assuming an ideal liquid";
+  constant Modelica.Units.SI.SpecificVolume v_water_solid = 1/918
+    "Specific volume of condensing component (i.e., water) at solid phase
+    assuming an ideal solid";
+
+  constant Modelica.Units.SI.Pressure p_water_ref = p_water_trp
+   "Reference pressure of water";
+  constant Modelica.Units.SI.Temperature T_water_ref = T_water_trp
+   "Reference temperature of water";
+  constant Modelica.Units.SI.SpecificEnthalpy h_water_ref = 0
+    "Reference specific enthalpy of water (at liquid state)";
+  constant Modelica.Units.SI.SpecificEnthalpy dh_vap_water_ref = 2500910
+    "Reference specific enthalpy of vaporization of water";
+  constant Modelica.Units.SI.SpecificEnthalpy dh_fus_water_ref = 333550
+    "Reference specific enthalpy of fusion of water";
+  constant Modelica.Units.SI.SpecificEntropy s_water_ref = 0
+    "Reference specific entropy of water (at liquid state)";
+  constant Modelica.Units.SI.SpecificEntropy ds_vap_water_ref=
+    dh_vap_water_ref / T_water_ref
+    "Reference specific entropy of vaporization of water";
+  constant Modelica.Units.SI.SpecificEntropy ds_fus_water_ref=
+    dh_fus_water_ref / T_water_ref
+    "Reference specific entropy of fusion of water";
+
+  constant Modelica.Units.SI.SpecificEnthalpy h_dryAir_off = 25097.2
+    "Specific enthalpy offset of ideal gas mixture of dry air components to
+    ensure that specific enthalpy of ideal dry air gas mixture is zero at
+    reference state of water and reference mass fractions";
+  constant Modelica.Units.SI.SpecificEntropy s_dryAir_off = -8239.74
+    "Specific enthalpy offset of ideal gas mixture of dry air components to
+    ensure that specific enthalpy of ideal dry air gas mixture is zero at
+    reference state of water and reference mass fractions";
+
+  constant Boolean print_warnings = false
+    "= true, if warnings indicating bounds of validity shall be printed";
+
+  //
+  // Redeclare functions regarding states
+  //
+  redeclare final record extends ThermodynamicState
+    "Thermodynamic state variables"
+    Modelica.Units.SI.MoleFraction[nX] Y
+      "Mole fractions (i.e., (component amount of substances)/(total amount of
+       substances) n_i/n)";
+  end ThermodynamicState;
+
+  redeclare replaceable model extends BaseProperties(
+    T(stateSelect=if preferredMediumStates then StateSelect.prefer else
+      StateSelect.default),
+    p(stateSelect=if preferredMediumStates then StateSelect.prefer else
+      StateSelect.default),
+    Xi(each stateSelect=if preferredMediumStates then StateSelect.prefer else
+      StateSelect.default),
+    final standardOrderComponents=true)
+    "Calculats base properties of the ideal gas-vapor mixture"
+
+    //
+    // Definition of variables
+    //
+    Modelica.Units.SI.MoleFraction[nX] Y
+      "Mole fractions of ideal gas vapor mixture";
+
+    Modelica.Units.SI.MassFraction[nX] x
+      "Mass fractions given per dry air mass";
+
+    Modelica.Units.SI.MassFraction X_sat
+      "Saturation mass fraction given per saturated moist air mass";
+    Modelica.Units.SI.MassFraction X_vapor
+      "Water vapor fraction given per moist air mass";
+    Modelica.Units.SI.MassFraction X_liquidIce
+      "Liquid or solid water fraction given per moist air mass";
+
+    Modelica.Units.SI.MassFraction x_sat
+      "Saturation mass fraction given per dry air mass";
+    Modelica.Units.SI.MassFraction x_vapor
+      "Water vapor fraction given per dry air mass";
+    Modelica.Units.SI.MassFraction x_liquidIce
+      "Liquid or solid water fraction given per dry air mass";
+
+    Real phi(min=0, max=1)
+      "Relative humidity";
+
+  equation
+    //
+    // Calculate mass fractions, mole fractions, and relative humidity
+    //
+    Y = massToMoleFractions(X=X, MMX=MMX)
+      "Mole fractions of ideal gas-vapor mixture";
+
+    x = moistAirToDryAirMassFractions(X=X)
+      "Mass fractions given per dry air mass";
+
+    X_sat = massFractionSaturation(state=state)
+      "Saturation mass fraction given per saturated moist air mass";
+    X_vapor = X[nX] - X_liquidIce
+      "Water vapor fraction given per moist air mass";
+    X_liquidIce = max(0.0, X[nX] - X_sat)
+      "Liquid or solid water fraction given per moist air mass";
+
+    x_sat = dryMassFractionSaturation(state=state)
+      "Saturation mass fraction given per dry air mass";
+    x_vapor = x[nX] - x_liquidIce
+      "Water vapor fraction given per dry air mass";
+    x_liquidIce = max(0.0, x[nX] - x_sat)
+      "Liquid or solid water fraction given per dry air mass";
+
+    phi = relativeHumidity(state=state)
+      "Relative humidity";
+
+    //
+    // Calculate state properties
+    //
+    d = rho_pTXY(p=p, T=T, X=X, Y=Y)
+      "Density";
+    h =specificEnthalpy_pTXY(
+        p=p,
+        T=T,
+        X=X,
+        Y=Y)
+      "Specific enthalpy per moist air mass";
+    u = h - p / d
+      "Specific internal energy per moist air mass";
+
+    state.p = p
+      "State record: Pressure";
+    state.T = T
+      "State record: Temperature";
+    state.X = X
+      "State record: Mass fractions";
+    state.Y = Y
+      "State record: Mole fractions";
+
+    //
+    // Calculate additional properties
+    //
+    MM = molarMass(state=state)
+      "Molar mass of the ideal gas-vapor mixture";
+    R_s = gasConstant(state=state)
+      "Specific ideal gas constant of the ideal gas-vapor mixture";
+
+      //
+      // Annotations
+      //
+      annotation (Documentation(info="<html>
+<p>
+This model calculates the base properties of an ideal gas-vapor mixture, including
+pressure p, temperature T, density d, specific enthalpy h, specific internal
+energy u, the specific ideal gas constant R_s, and the molar mass MM. Additionally,
+a state record is provided. Furthermore, this model calculates the relative humidity
+phi as well as the saturation mass fraction X/x_sat, water vapor mass fraction
+X/x_vapor, and water liquid/ice mass fraction X/x_liquidIce per moist air mass (X)
+and dry air mass (x). Note that preffered states are pressure, temperature, and
+mass fractions of dry air to avoid non-linear equations.
+</p>
+
+</html>",     revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end BaseProperties;
+
+  redeclare function extends setState_pTX
+    "Return thermodynamic state as function of pressure p, temperature T, and composition X"
+  algorithm
+    state := if size(X, 1) == nX then
+      ThermodynamicState(
+        p=p,
+        T=T,
+        X=X,
+        Y=massToMoleFractions(X=X, MMX=MMX)) else
+      ThermodynamicState(
+        p=p,
+        T=T,
+        X=cat(1, X, {1 - sum(X)}),
+        Y=massToMoleFractions(X=cat(1, X, {1 - sum(X)}), MMX=MMX))
+      "Thermodynamic state record";
+  end setState_pTX;
+
+  redeclare function extends setState_phX
+    "Return thermodynamic state as function of pressure p, specific enthalpy h, and composition X"
+  algorithm
+    state :=if size(X, 1) == nX then ThermodynamicState(
+        p=p,
+        T=temperature_phXY(
+          p=p,
+          h=h,
+          X=X,
+          Y=massToMoleFractions(X=X, MMX=MMX)),
+        X=X,
+        Y=massToMoleFractions(X=X, MMX=MMX)) else ThermodynamicState(
+        p=p,
+        T=temperature_phXY(
+          p=p,
+          h=h,
+          X=cat(
+            1,
+            X,
+            {1 - sum(X)}),
+          Y=massToMoleFractions(X=cat(
+            1,
+            X,
+            {1 - sum(X)}), MMX=MMX)),
+        X=cat(
+          1,
+          X,
+          {1 - sum(X)}),
+        Y=massToMoleFractions(X=cat(
+          1,
+          X,
+          {1 - sum(X)}), MMX=MMX))
+      "Thermodynamic state record";
+  end setState_phX;
+
+  redeclare function extends setState_psX
+    "Return thermodynamic state as function of pressure p, specific enthalpy h, and composition X"
+  algorithm
+    state :=if size(X, 1) == nX then ThermodynamicState(
+        p=p,
+        T=temperature_psXY(
+          p=p,
+          s=s,
+          X=X,
+          Y=massToMoleFractions(X=X, MMX=MMX)),
+        X=X,
+        Y=massToMoleFractions(X=X, MMX=MMX)) else ThermodynamicState(
+        p=p,
+        T=temperature_psXY(
+          p=p,
+          s=s,
+          X=cat(
+            1,
+            X,
+            {1 - sum(X)}),
+          Y=massToMoleFractions(X=cat(
+            1,
+            X,
+            {1 - sum(X)}), MMX=MMX)),
+        X=cat(
+          1,
+          X,
+          {1 - sum(X)}),
+        Y=massToMoleFractions(X=cat(
+          1,
+          X,
+          {1 - sum(X)}), MMX=MMX))
+      "Thermodynamic state record";
+  end setState_psX;
+
+  redeclare function extends setState_dTX
+    "Return thermodynamic state as function of density d, temperature T, and composition X"
+  algorithm
+    state :=if size(X, 1) == nX then ThermodynamicState(
+        p=pressure_dTXY(
+          d=d,
+          T=T,
+          X=X,
+          Y=massToMoleFractions(X=X, MMX=MMX)),
+        T=T,
+        X=X,
+        Y=massToMoleFractions(X=X, MMX=MMX)) else ThermodynamicState(
+        p=pressure_dTXY(
+          d=d,
+          T=T,
+          X=cat(
+            1,
+            X,
+            {1 - sum(X)}),
+          Y=massToMoleFractions(X=cat(
+            1,
+            X,
+            {1 - sum(X)}), MMX=MMX)),
+        T=T,
+        X=cat(
+          1,
+          X,
+          {1 - sum(X)}),
+        Y=massToMoleFractions(X=cat(
+          1,
+          X,
+          {1 - sum(X)}), MMX=MMX))
+      "Thermodynamic state record";
+  end setState_dTX;
+
+  redeclare function extends setSmoothState
+    "Return thermodynamic state so that it smoothly approximates: If x > 0, then state_a else state_b"
+  algorithm
+    state := ThermodynamicState(
+      p=Modelica.Media.Common.smoothStep(
+        x,
+        state_a.p,
+        state_b.p,
+        x_small),
+      T=Modelica.Media.Common.smoothStep(
+        x,
+        state_a.T,
+        state_b.T,
+        x_small),
+      X=Modelica.Media.Common.smoothStep(
+        x,
+        state_a.X,
+        state_b.X,
+        x_small),
+      Y=Modelica.Media.Common.smoothStep(
+        x,
+        state_a.Y,
+        state_b.Y,
+        x_small));
+  end setSmoothState;
+  //
+  // Redeclare functions regarding state properties
+  //
+  redeclare function extends pressure
+    "Returns pressure of the ideal gas-vapor mixture"
+  algorithm
+    p := state.p
+      "Pressure of ideal gas-vapor mixture";
+  end pressure;
+
+  redeclare function extends temperature
+    "Returns temperature of the ideal gas-vapor mixture"
+  algorithm
+    T := state.T
+      "Tempeerature of ideal gas-vapor mixture";
+  end temperature;
+
+  redeclare function extends density
+    "Returns density of the ideal gas-vapor mixture"
+  algorithm
+    d := rho_pTXY(p=state.p, T=state.T, X=state.X, Y=state.Y)
+      "Density of ideal gas-vapor mixture";
+  end density;
+
+  redeclare function extends specificEnthalpy
+    "Returns specific enthalpy of the ideal gas-vapor mixture"
+  algorithm
+    h :=specificEnthalpy_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y)
+      "Specific enthalpy of ideal gas-vapor mixture";
+  end specificEnthalpy;
+
+  redeclare function extends specificInternalEnergy
+    "Returns specific internal energy of the ideal gas-vapor mixture"
+  algorithm
+    u :=specificEnthalpy_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y) - state.p/rho_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y)
+      "Specific internal energy of ideal gas-vapor mixture";
+  end specificInternalEnergy;
+
+  redeclare function extends specificEntropy
+    "Returns specific entropy of the ideal gas-vapor mixture"
+  algorithm
+    s :=specificEntropy_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y)
+      "Specific entropy of ideal gas-vapor mixture";
+  end specificEntropy;
+
+  redeclare function extends specificGibbsEnergy
+    "Returns specific Gibbs energy of the ideal gas-vapor mixture"
+  algorithm
+    g :=specificEnthalpy_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y) - state.T*specificEntropy_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y)
+      "Specific Gibbs energy of ideal gas-vapor mixture";
+  end specificGibbsEnergy;
+
+  redeclare function extends specificHelmholtzEnergy
+    "Returns specific Helmholtz energy of the ideal gas-vapor mixture"
+  algorithm
+    f :=specificEnthalpy_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y) - state.p/rho_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y) - state.T*specificEntropy_pTXY(
+        p=state.p,
+        T=state.T,
+        X=state.X,
+        Y=state.Y)
+      "Specific Helmholtz energy of ideal gas-vapor mixture";
+  end specificHelmholtzEnergy;
+  //
+  // Redeclare functions regarding additional properties
+  //
+  redeclare function extends dynamicViscosity
+    "Returns dynamic viscosity"
+
+    //
+    // Definition of constants
+    //
+protected
+    constant Modelica.Units.SI.Temperature A_liq = 0.45047
+      "First constant of liquid water";
+    constant Modelica.Units.SI.Temperature B_liq = 1.39753
+      "Second constant of liquid water";
+    constant Modelica.Units.SI.Temperature C_liq = 613.181
+      "Third constant of liquid water";
+    constant Modelica.Units.SI.Temperature D_liq = 63.697
+      "fourth constant of liquid water";
+    constant Modelica.Media.Interfaces.Types.DynamicViscosity E_liq = 0.00006896
+      "Fivth constant of liquid water";
+
+    //
+    // Definition of variables
+    //
+    Modelica.Units.SI.MassFraction[nX] x=
+      moistAirToDryAirMassFractions(X=state.X)
+      "Mass fractions per dry air";
+    Modelica.Units.SI.MassFraction x_sat=
+      dryMassFractionSaturation(state=state)
+      "Saturation mass fraction of condensing component per dry air";
+
+    Modelica.Units.SI.Pressure[nX] p_i=
+      partialPressures(state=state)
+      "Partial pressures";
+
+    Modelica.Units.SI.SpecificVolume v_dryAirVapor
+      "Specific volume of dry air and water vapor per dry air mass";
+    Modelica.Units.SI.SpecificVolume v_liquidSolid
+      "Specific volume of liquid or solid water per dry air mass";
+
+    Modelica.Media.Interfaces.Types.DynamicViscosity[nX] eta_gasVapor
+      "Dynamic viscosities of components at gas or vapor state";
+    Modelica.Media.Interfaces.Types.DynamicViscosity eta_dryAirVapor
+      "Dynamic viscosity of dry air and water vapor";
+    Modelica.Media.Interfaces.Types.DynamicViscosity eta_liquidSolid
+      "Dynamic viscosity of water's liquid or solid phase";
+
+  algorithm
+    //
+    // Calculate dynamic viscosity of ideal gas-vapor mixture at gas state
+    //
+    for ind in 1:nX loop
+      eta_gasVapor[ind] :=
+        Modelica.Media.IdealGases.Common.Functions.dynamicViscosityLowPressure(
+          T=state.T,
+          Tc=fluidConstants[ind].criticalTemperature,
+          M=fluidConstants[ind].molarMass,
+          Vc=fluidConstants[ind].criticalMolarVolume,
+          w=fluidConstants[ind].acentricFactor,
+          mu=fluidConstants[ind].dipoleMoment)
+        "Dynamic viscosities of components at gas or vapor state";
+    end for;
+
+    eta_dryAirVapor := gasMixtureViscosity(
+        yi=p_i./state.p,
+        M=MMX,
+        eta=eta_gasVapor)
+      "Dynamic viscosity of dry air and water vapor";
+
+    //
+    // Calculate densities and dynamic viscosity of water at liquid or solid state
+    //
+    if x[nX] <= x_sat then
+      v_dryAirVapor :=
+        (sum(x ./ MMX .* Modelica.Constants.R .* state.T ./ state.p))
+        "Specific volume of dry air and water vapor per dry air mass";
+      v_liquidSolid :=0
+        "Specific volume of liquid or solid water per dry air mass";
+      eta_liquidSolid :=0
+        "Dynamic viscosity of water's liquid or solid phase";
+
+    elseif state.T > T_water_trp then
+      v_dryAirVapor :=
+        (sum(x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] .* state.T ./
+        state.p) +
+        x_sat * Modelica.Constants.R / MMX[nX] * state.T / state.p)
+        "Specific volume of dry air and water vapor per dry air mass";
+      v_liquidSolid :=
+        ((x[nX] - x_sat) * v_water_liq)
+        "Specific volume of liquid or solid water per dry air mass";
+      eta_liquidSolid :=
+        E_liq * Modelica.Math.exp(A_liq *
+        ((C_liq - state.T)/(state.T - D_liq)) ^ (1/3) + B_liq *
+        ((C_liq - state.T)/(state.T - D_liq)) ^ (4/3))
+        "Dynamic viscosity of water's liquid or solid phase";
+
+    else
+      /*
+    Note that the dynamic viscosity of solid water is neglected
+    */
+      v_dryAirVapor :=
+        (sum(x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] .* state.T ./
+        state.p) +
+        x_sat * Modelica.Constants.R / MMX[nX] * state.T / state.p)
+        "Specific volume of dry air and water vapor per dry air mass";
+      v_liquidSolid :=
+        ((x[nX] - x_sat) * v_water_solid) * 0
+        "Specific volume of liquid or solid water per dry air mass";
+      eta_liquidSolid := 1e14
+        "Dynamic viscosity of water's liquid or solid phase";
+
+    end if;
+
+    //
+    // Calculate density averaged dynamic viscosity
+    //
+    eta := v_dryAirVapor / (v_dryAirVapor + v_liquidSolid) * eta_dryAirVapor +
+      v_liquidSolid / (v_dryAirVapor + v_liquidSolid) * eta_liquidSolid
+      "Dynamic viscosity";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the dynamic viscosity of the ideal gas-vapor mixture as
+function of the state record. For the case of saturated dry air with liquid or
+solid water, the dynamic viscosity is calculated as average dynamic viscosity
+using the specific volumes of the different phases for averaging. Note that the
+dynamic viscosity of solid water is neglected. For the ideal gas-vapor mixture,
+this function applies a simplification of the kinetic theory (Chapman and Enskog 
+theory) neglecting the second-order effects. Details can be found in the orginal
+implementations:
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.dynamicViscosity\">Modelica.Media.IdealGases.Common.MixtureGasNasa.dynamicViscosity</a>
+and
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.gasMixtureViscosity\">Modelica.Media.IdealGases.Common.MixtureGasNasa.gasMixtureViscosity</a>. 
+For liquid water, a generalized function is applied according to the VDI Heat
+Atlas.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Kleiber, M. and Joh, R. and Span, R. (2002). D3 Properties of Pure Fluid Substances, In: VDI Heat Atlas, 2nd Edition. DOI: https://doi.org/10.1007/978-3-540-77877-6.
+  </li>
+</ul>
+
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end dynamicViscosity;
+
+  redeclare function extends thermalConductivity
+    "Returns thermal conductivity"
+    //
+    // Definition of constants
+    //
+protected
+    constant Modelica.Units.SI.ThermalConductivity A_liq = -2.4149
+      "First constant of liquid water";
+    constant Real B_liq(unit="W/(m.K2)") = 2.45165e-2
+      "Second constant of liquid water";
+    constant Real C_liq(unit="W/(m.K3)") = -0.73121e-4
+      "Third constant of liquid water";
+    constant Real D_liq(unit="W/(m.K4)") = 0.99492e-7
+      "fourth constant of liquid water";
+    constant Real E_liq(unit="W/(m.K5)") = -0.53730e-10
+      "Fivth constant of liquid water";
+
+    constant Modelica.Units.SI.ThermalConductivity A_solid = 2.60970865
+      "First constant of solid water";
+    constant Real B_solid(unit="W/(m.K2)") = 3.72962320e-2
+      "Second constant of solid water";
+    constant Real C_solid(unit="W/(m.K3)") = -2.63535950e-4
+      "Third constant of solid water";
+    constant Real D_solid(unit="W/(m.K4)") = 4.45674690e-7
+      "fourth constant of solid water";
+
+    //
+    // Definition of variables
+    //
+    Modelica.Units.SI.MassFraction[nX] x=
+      moistAirToDryAirMassFractions(X=state.X)
+      "Mass fractions per dry air";
+    Modelica.Units.SI.MassFraction x_sat=
+      dryMassFractionSaturation(state=state)
+      "Saturation mass fraction of condensing component per dry air";
+
+    Modelica.Units.SI.Pressure[nX] p_i=
+      partialPressures(state=state)
+      "Partial pressures";
+
+    Modelica.Units.SI.SpecificVolume v_dryAirVapor
+      "Specific volume of dry air and water vapor per dry air mass";
+    Modelica.Units.SI.SpecificVolume v_liquidSolid
+      "Specific volume of liquid or solid water per dry air mass";
+
+    Modelica.Units.SI.SpecificHeatCapacity[nX] cp_gasVapor
+      "Specific heat capacities of components at gas or vapor state";
+    Modelica.Units.SI.DynamicViscosity[nX] eta_gasVapor
+      "Dynamic viscosities of components at gas or vapor state";
+
+    Modelica.Units.SI.ThermalConductivity[nX] lambda_gasVapor
+      "Thermal conductivities of components at gas or vapor state";
+    Modelica.Units.SI.ThermalConductivity lambda_dryAirVapor
+      "Thermal conductivity of dry air and water vapor";
+    Modelica.Units.SI.ThermalConductivity lambda_liquidSolid
+      "Thermal conductivity of water's liquid or solid phase";
+
+  algorithm
+    //
+    // Calculate dynamic viscosity of ideal gas-vapor mixture at gas state
+    //
+    for ind in 1:nX loop
+      cp_gasVapor[ind] :=
+        Modelica.Media.IdealGases.Common.Functions.cp_T(
+          data=data[ind],
+          T=state.T)
+        "Specific heat capacities of components at gas or vapor state";
+
+      eta_gasVapor[ind] :=
+        Modelica.Media.IdealGases.Common.Functions.dynamicViscosityLowPressure(
+          T=state.T,
+          Tc=fluidConstants[ind].criticalTemperature,
+          M=fluidConstants[ind].molarMass,
+          Vc=fluidConstants[ind].criticalMolarVolume,
+          w=fluidConstants[ind].acentricFactor,
+          mu=fluidConstants[ind].dipoleMoment)
+        "Dynamic viscosities of components at gas or vapor state";
+
+      lambda_gasVapor[ind] :=
+       Modelica.Media.IdealGases.Common.Functions.thermalConductivityEstimate(
+          Cp=cp_gasVapor[ind],
+          eta=eta_gasVapor[ind],
+          method=1,
+          data=data[ind])
+        "Thermal conductivities of components at gas or vapor state";
+    end for;
+
+    lambda_dryAirVapor := lowPressureThermalConductivity(
+        y=p_i./state.p,
+        T=state.T,
+        Tc=fluidConstants[:].criticalTemperature,
+        Pc=fluidConstants[:].criticalPressure,
+        M=MMX,
+        lambda=lambda_gasVapor)
+      "Thermal conductivity of dry air and water vapor";
+
+    //
+    // Calculate densities and dynamic viscosity of water at liquid or solid state
+    //
+    if x[nX] <= x_sat then
+      v_dryAirVapor :=
+        (sum(x ./ MMX .* Modelica.Constants.R .* state.T ./ state.p))
+        "Specific volume of dry air and water vapor per dry air mass";
+      v_liquidSolid :=0
+        "Specific volume of liquid or solid water per dry air mass";
+      lambda_liquidSolid :=0
+        "Thermal conductivity of water's liquid or solid phase";
+
+    elseif state.T > T_water_trp then
+      v_dryAirVapor :=
+        (sum(x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] .* state.T ./
+        state.p) +
+        x_sat * Modelica.Constants.R / MMX[nX] * state.T / state.p)
+        "Specific volume of dry air and water vapor per dry air mass";
+      v_liquidSolid :=
+        ((x[nX] - x_sat) * v_water_liq)
+        "Specific volume of liquid or solid water per dry air mass";
+      lambda_liquidSolid :=
+        A_liq + B_liq * state.T + C_liq * state.T^2 +
+        D_liq * state.T^3 + E_liq * state.T^4
+        "Thermal conductivity of water's liquid or solid phase";
+
+    else
+      v_dryAirVapor :=
+        (sum(x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] .* state.T ./
+        state.p) +
+        x_sat * Modelica.Constants.R / MMX[nX] * state.T / state.p)
+        "Specific volume of dry air and water vapor per dry air mass";
+      v_liquidSolid :=
+        ((x[nX] - x_sat) * v_water_solid)
+        "Specific volume of liquid or solid water per dry air mass";
+      lambda_liquidSolid :=
+        A_solid + B_solid * state.T + C_solid * state.T^2 + D_solid * state.T^3
+        "Thermal conductivity of water's liquid or solid phase";
+
+    end if;
+
+    //
+    // Calculate density averaged dynamic viscosity
+    //
+    lambda := v_dryAirVapor / (v_dryAirVapor + v_liquidSolid) * lambda_dryAirVapor +
+      v_liquidSolid / (v_dryAirVapor + v_liquidSolid) * lambda_liquidSolid
+      "Thermal conductivity";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the thermal conductivity of the ideal gas-vapor mixture
+as function of the state record. For the case of saturated dry air with liquid or
+solid water, the thermal conductivity is calculated as average dynamic viscosity
+using the specific volumes of the different phases for averaging. For the ideal 
+gas-vapor mixture, this function applies the Masson and Saxena modification of the
+Wassiljewa Equation for the thermal conductivity for gas mixtures of n elements 
+at low pressure. Details can be found in the orginal implementations:
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.thermalConductivity\">Modelica.Media.IdealGases.Common.MixtureGasNasa.thermalConductivity</a>
+and
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.lowPressureThermalConductivity\">Modelica.Media.IdealGases.Common.MixtureGasNasa.lowPressureThermalConductivity</a>. 
+For liquid water, a generalized function is applied according to the VDI Heat
+Atlas. For solid water, a polynomial fit is applied using data from the
+Engineering Toolbox.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  The Engineering ToolBox (2004). Ice - Thermal Properties. URL: https://www.engineeringtoolbox.com/ice-thermal-properties-d_576.html [Accessed November 27, 2023].
+  </li>
+  <li>
+  Kleiber, M. and Joh, R. and Span, R. (2002). D3 Properties of Pure Fluid Substances, In: VDI Heat Atlas, 2nd Edition. DOI: https://doi.org/10.1007/978-3-540-77877-6.
+  </li>
+</ul>
+
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end thermalConductivity;
+
+  redeclare function extends specificHeatCapacityCp
+    "Returns specific heat capacity at constant pressure"
+  algorithm
+    cp := dh_dT_pX(state=state)
+      "Specific heat capacity at constant pressure";
+  end specificHeatCapacityCp;
+
+  redeclare function extends specificHeatCapacityCv
+    "Returns specific heat capacity at constant volume"
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.DerSpecificVolumeByPressure dv_dp_TX_=
+      dv_dp_TX(state=state)
+      "Partial derivative of specific volume w.r.t. pressure at constant 
+      temperature and mass fractions";
+    SorpLib.Units.DerSpecificVolumeByTemperature dv_dT_pX_=
+      dv_dT_pX(state=state)
+    "Partial derivative of specific volume w.r.t. temperature at constant pressure
+    and mass fractions";
+
+  algorithm
+    cv := dh_dT_pX(state=state) - state.p * dv_dT_pX_ -
+      dh_dp_TX(state=state) * dv_dT_pX_ / dv_dp_TX_ +
+      1 / density(state=state) * dv_dT_pX_ / dv_dp_TX_ +
+      state.p * dv_dT_pX_
+      "Specific heat capacity at constant volume";
+  end specificHeatCapacityCv;
+
+  redeclare function extends isentropicExponent
+    "Returns isentropic exponent that is only sound for unsaturated air"
+  algorithm
+    gamma := specificHeatCapacityCp(state=state) /
+      specificHeatCapacityCv(state=state)
+      "Isentropic exponent";
+  end isentropicExponent;
+
+  redeclare function extends isentropicEnthalpy
+    "Returns isentropic enthalpy"
+  algorithm
+    h_is := specificEnthalpy_pTXY(
+      p=p_downstream,
+      T=temperature_psXY(
+        p=p_downstream,
+        s=specificEntropy(state=refState),
+        X=refState.Y,
+        Y=refState.Y),
+      X=refState.X,
+      Y=refState.Y)
+      "Isentropic enthalpy";
+  end isentropicEnthalpy;
+
+  redeclare function extends velocityOfSound
+    "Return veolicity of sound"
+  algorithm
+    a := sqrt(1 / (-density(state=state)^2 * (dv_dp_TX(state=state) +
+      dv_dT_pX(state=state)^2 * state.T  / specificHeatCapacityCp(state=state))))
+      "Velocity of sound";
+  end velocityOfSound;
+
+  redeclare function extends isobaricExpansionCoefficient
+    "Returns isobaric expansion coefficient"
+  algorithm
+    beta := density(state=state) * dv_dT_pX(state=state)
+      "Isobaric expansion coefficient";
+  end isobaricExpansionCoefficient;
+
+  redeclare function extends isothermalCompressibility
+    "Returns isothermal compressibility"
+  algorithm
+    kappa := -density(state=state) * dv_dp_TX(state=state)
+      "Isothermal compressibility";
+  end isothermalCompressibility;
+
+  redeclare function extends density_derp_h
+    "Returns partial derivative of density w.r.t. pressure at constant specific enthalpy and mass fractions"
+  algorithm
+    ddph := density_derp_T(state=state) - density_derT_p(state=state) *
+      dh_dp_TX(state=state) / dh_dT_pX(state=state)
+      "Partial derivative of density w.r.t. pressure at constant specific  
+      enthalpy and mass fractions";
+  end density_derp_h;
+
+  redeclare function extends density_derh_p
+    "Returns partial derivative of density w.r.t. specific enthalpy at constant pressure and mass fractions"
+  algorithm
+    ddhp := density_derT_p(state=state) / dh_dT_pX(state=state)
+      "Partial derivative of density w.r.t. specific enthalpy at constant  
+      pressure and mass fractions";
+  end density_derh_p;
+
+  redeclare function extends density_derp_T
+    "Returns partial derivative of density w.r.t. pressure at constant temperature and mass fractions"
+  algorithm
+    ddpT := -rho_pTXY(p=state.p, T=state.T, X=state.X, Y=state.Y)^2 *
+      dv_dp_TX(state=state)
+      "Partial derivative of density w.r.t. pressure at constant temperature 
+      and mass fractions";
+  end density_derp_T;
+
+  redeclare function extends density_derT_p
+    "Returns partial derivative of density w.r.t. temperature at constant pressure and mass fractions"
+  algorithm
+    ddTp := -rho_pTXY(p=state.p, T=state.T, X=state.X, Y=state.Y)^2 *
+      dv_dT_pX(state=state)
+      "Partial derivative of density w.r.t. temperature at constant pressure 
+      and mass fractions";
+  end density_derT_p;
+
+  redeclare function extends density_derX
+    "Returns partial derivatives of density w.r.t. mass fractions at constant pressure and temperature"
+  algorithm
+    dddX := -rho_pTXY(p=state.p, T=state.T, X=state.X, Y=state.Y)^2 .*
+      dv_dX_pT(state=state)
+      "Partial derivative of density w.r.t. mass fractions at constant pressure 
+    and temperature";
+  end density_derX;
+
+  redeclare function extends molarMass
+    "Returns molar mass of the ideal gas-vapor mixture"
+  algorithm
+    MM := state.Y * MMX
+      "Molar mass of the ideal gas-vapor mixture";
+  end molarMass;
+
+  redeclare function extends gasConstant
+    "Returns specific ideal gas constant of the ideal gas-vapor mixture"
+  algorithm
+    if (state.X[nX] / (1 - state.X[nX])) >
+      dryMassFractionSaturation(state=state) then
+      R_s := Modelica.Constants.R /
+        sum(partialPressures(state=state) ./ state.p .* MMX)
+        "Specific ideal gas constant for saturated gas-vapor mixture ";
+
+    else
+      R_s := Modelica.Constants.R * sum(state.X ./ MMX)
+        "Specific ideal gas constant for unsaturated gas-vapor mixture ";
+
+    end if;
+  end gasConstant;
+
+  redeclare function extends enthalpyOfNonCondensingGas
+    "Returns specific enthalpy of non-condensing components (i.e., dry air) (per dry air mass)"
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.MassFraction[:] X
+      "Vector of mass fractions"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+  algorithm
+    h := X[1:nX-1] / sum(X[1:nX-1]) *
+      {Modelica.Media.IdealGases.Common.Functions.h_T(
+        data=data[i],
+        T=T,
+        exclEnthForm=true,
+        refChoice=Modelica.Media.Interfaces.Choices.ReferenceEnthalpy.UserDefined,
+        h_off=h_dryAir_off) for i in 1:nX-1}
+      "Specific enthalpy of dry air";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the non-condensing components
+(i.e., dry air) per dry air mass according to the model of an ideal gas mixture 
+as function of temperature and mass fractions. The specific enthalpy is calculated 
+using NASA Glenn Coefficients. For more details, check the function
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.h_TX\">Modelica.Media.IdealGases.Common.MixtureGasNasa.h_TX</a>.
+Note that this function does assume that no water is present. To calculate the 
+specific enthalpy of the non-condensing components that are actually present, 
+use the function
+<a href=\"Modelica://SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture.enthalpyOfNonCondensingComponents\">SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture.enthalpyOfNonCondensingComponents</a>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  McBride, B.J. and Zehe, M.J. and Gordon, S. (2002). NASA Glenn Coefficients for Calculating Thermodynamic Properties of Individual Species, Technical report, NASA/TP—2002-211556. URL: https://ntrs.nasa.gov/citations/20020085330.
+  </li>
+</ul>
+
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end enthalpyOfNonCondensingGas;
+
+  redeclare function extends enthalpyOfGas(
+    T=state.T,
+    X=state.X)
+    "Returns specific enthalpy of non-condensing components (i.e., dry air) and vaporous water (per moist air mass)"
+
+    //
+    // Definition of inputs
+    //
+    input ThermodynamicState state
+      "Thermodynamic state record"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.MassFraction[nX] x=
+      moistAirToDryAirMassFractions(X=state.X)
+      "Mass fractions per dry air";
+    Modelica.Units.SI.MassFraction x_sat=
+      dryMassFractionSaturation(state=state)
+      "Saturation mass fraction of condensing component per dry air";
+
+  algorithm
+    //
+    // Calculate specific enthalpy per dry air mass
+    //
+    if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+      h := enthalpyOfNonCondensingGas(T=state.T, X=x)
+        "Specific enthalpy equals specific enthalpy of unsaturated dry air without 
+        water: Calculated applying the law of ideal gas mixtures.";
+
+    elseif x[nX] <= x_sat then
+      h := enthalpyOfNonCondensingGas(T=state.T, X=x) +
+        x[nX] * enthalpyOfCondensingGas(T=state.T)
+        "Specific enthalpy equals specific enthalpy of unsaturated dry air and water 
+        vapor: Calculated applying the law of ideal gas mixtures.";
+
+    else
+      h := enthalpyOfNonCondensingGas(T=state.T, X=x) +
+        x_sat * enthalpyOfCondensingGas(T=state.T)
+        "Specific enthalpy equals specific enthalpy of saturated dry air and water
+        vapor: Calculated applying the law of ideal gas mixtures.";
+
+    end if;
+
+    //
+    // Convert specific enthalpy per dry air mass
+    //
+    h := h / (1 + x[nX])
+      "Specific enthalpy per moist air mass";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the non-condensing components
+(i.e., dry air) and vaporous water (i.e., vapor) per moist air mass according to 
+the model of an ideal gas-vapor mixture as function of temperature and mass 
+fractions.
+</p>
+
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end enthalpyOfGas;
+  //
+  // Redeclare functions regarding condensing component
+  //
+  redeclare function extends saturationPressure
+    "Returns saturation pressure of condensing fluid (i.e., water)"
+  algorithm
+    psat := saturationPressureH2O_T(Tsat)
+      "Saturation pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+      InlineAfterIndexReduction=false,
+      LateInline=true,
+      inverse(Tsat=saturationTemperature(p_sat=psat)));
+  end saturationPressure;
+
+  redeclare function extends enthalpyOfVaporization
+    "Returns specific enthalpy of vaporization of water (per water mass)"
+
+    //
+    // Definition of constants
+    //
+protected
+    constant Real[7] coefficients_liq=
+      {1, 1.99274064, 1.09965342, -0.510839303,
+      -1.75493479, -45.5170352, -6.74694450e5}
+      "Coefficients of saturated liquid density";
+    constant Real[6] coefficients_vap=
+      {-2.03150240, -2.68302940, -5.38626492, -17.2991605,
+      -44.7586581, -63.9201063}
+      "Coefficients of saturated vapor density";
+
+    constant Real[7] exponents_liq=
+      {0, 1/3, 2/3, 5/3, 16/3, 43/3, 110/3}
+      "Exponents of saturated liquid density";
+    constant Real[6] exponents_vap=
+      {2/6, 4/6, 8/6, 18/6, 37/6, 71/6}
+      "Exponents of saturated vapor density";
+
+    //
+    // Definition of variables
+    //
+    Modelica.Media.Common.DerPressureByTemperature dp_sat_dT=
+      dsaturationPressureH2O_dT(T_sat=T)
+      "First-order partial derivative of saturation pressure w.r.t. temperature";
+
+    Modelica.Units.SI.Density rho_sat_liq=
+      SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+        T=T,
+        T_ref=T_water_crit,
+        z_ref=d_water_crit,
+        coefficients=coefficients_liq,
+        exponents=exponents_liq,
+        approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionReducedTemperature)
+      "Density of saturated liquid";
+    Modelica.Units.SI.Density rho_sat_vap=
+      SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+        T=T,
+        T_ref=T_water_crit,
+        z_ref=d_water_crit,
+        coefficients=coefficients_vap,
+        exponents=exponents_vap,
+        approach=SorpLib.Choices.GeneralizedFunctionApproach.ExponentialFunctionReducedTemperature)
+      "Density of saturated vapor";
+
+  algorithm
+    r0 := (T/rho_sat_vap - T/rho_sat_liq) * dp_sat_dT
+      "Specific enthalpy of vaporization of water";
+
+    //
+    // Assertations
+    //
+    if print_warnings then
+      assert(T_water_trp <= T and T <= T_water_crit,
+        "Temperature (" + String(T) + " K) is not between 273.16 and 647.096 K. " +
+        "Calculation of specific enthalpy of vaporization is not possible!",
+        level = AssertionLevel.warning);
+    end if;
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of vaporization of the condensing 
+component (i.e., water) per water mass as function of the temperature.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wagner, W. and Pru&szlig;, A (2002). The IAPWS Formulation 1995 for the Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use, Journal of Physical and Chemical Reference Data, 31:387. DOI: https://doi.org/10.1063/1.1461829.
+  </li>
+</ul>
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end enthalpyOfVaporization;
+
+  redeclare function extends enthalpyOfLiquid
+    "Returns enthalpy of liquid water (per water mass)"
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Pressure p
+      "Pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of constants
+    //
+protected
+    constant Real[10] coefficients=
+      {4.66348457415926e-19, -1.16579701193758e-15, 9.49925152355854e-13,
+      5.81553479401465e-11, -6.55387915784314e-7, 5.30868446475702e-4,
+      -2.18234813641286e-1, 5.13043718148301e1, -6.58121774333134e3,
+      3.63215816205503e5}
+      "Coefficients of polynomical function";
+    constant Real[10] exponents=
+      {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
+      "Exponents of polynomical function";
+
+  algorithm
+    h := h_water_ref + v_water_liq * (p - p_water_ref) +
+      SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+        T=T,
+        T_ref=573.15,
+        z_ref=1,
+        coefficients=coefficients,
+        exponents=exponents,
+        approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature) -
+      SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+        T=T_water_ref,
+        T_ref=573.15,
+        z_ref=1,
+        coefficients=coefficients,
+        exponents=exponents,
+        approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+      "Specific enthalpy of liquid water";
+
+    //
+    // Assertations
+    //
+    if print_warnings then
+      assert(T_water_trp-1 <= T and T <= 573.15,
+        "Temperature (" + String(T) + " K) is not between 272.16 and 573.15 K. " +
+        "Calculation of specific enthalpy of liquid may not be valid!",
+        level = AssertionLevel.warning);
+    end if;
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the condensing component's
+(i.e., water) liquid phase per water mass according to the model of an ideal 
+liquid as function of pressure and temperature. The specific heat capacity is 
+calculated as a polynomial fit to specific heat capacity data calculated at 
+saturated liquid state with the reference equation of state for water. The data 
+was calculated for temperature varying from 273.16 K to 573.15 K. Note that this 
+function does not consider the actual water mass fraction. To calculate the 
+specific enthalpy of the liquid water that is actually present, use the function
+<a href=\"Modelica://SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture.enthalpyOfLiquidIce\">SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture.enthalpyOfLiquidIce</a>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  McBride, B.J. and Zehe, M.J. and Gordon, S. (2002). NASA Glenn Coefficients for Calculating Thermodynamic Properties of Individual Species, Technical report, NASA/TP—2002-211556. URL: https://ntrs.nasa.gov/citations/20020085330.
+  </li>
+</ul>
+
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end enthalpyOfLiquid;
+
+  redeclare function extends enthalpyOfCondensingGas
+    "Returns enthalpy of vaporous water (per water mass)"
+
+    //
+    // Definition of constants
+    //
+protected
+    constant Real[10] coefficients=
+      {7.03241022996521e-23, -4.12454440465976e-19, 1.05640534898709e-15,
+      -1.54797437245421e-12, 1.42577474111776e-9, -8.51385633913246e-7,
+      3.26064390458737e-4, -7.52464997116974e-2, 9.42339113729594,
+      1.36103845934352e+3}
+      "Coefficients of polynomical function";
+    constant Real[10] exponents=
+      {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
+      "Exponents of polynomical function";
+
+  algorithm
+    h := h_water_ref + dh_vap_water_ref +
+      SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+        T=T,
+        T_ref=T_water_crit,
+        z_ref=1,
+        coefficients=coefficients,
+        exponents=exponents,
+        approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature) -
+      SorpLib.Media.Functions.Utilities.intGeneralizedFunction_dT(
+        T=T_water_ref,
+        T_ref=T_water_crit,
+        z_ref=1,
+        coefficients=coefficients,
+        exponents=exponents,
+        approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+      "Specific enthalpy of vaporous water";
+
+    //
+    // Assertations
+    //
+    if print_warnings then
+      assert(200 <= T and T <= 1000,
+        "Temperature (" + String(T) + " K) is not between 200 and 1000 K. " +
+        "Calculation of specific enthalpy of vapor may not be valid!",
+        level = AssertionLevel.warning);
+    end if;
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the condensing component's
+(i.e., water) vapor phase per mass of water according to the model of an ideal 
+gas as function of temperature. The specific heat capacity is calculated as a 
+polynomial fit to specific heat capacity data calculated according to the NASA 
+Glenn Coefficients. The data was calculated for a temperature varying from 200 K 
+to 1000 K. Note that this function does not consider the actual water mass fraction. 
+To calculate the specific enthalpy of the vaporous water that is actually present, 
+use the function
+<a href=\"Modelica://SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture.enthalpyOfVapor\">SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture.enthalpyOfVapor</a>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  McBride, B.J. and Zehe, M.J. and Gordon, S. (2002). NASA Glenn Coefficients for Calculating Thermodynamic Properties of Individual Species, Technical report, NASA/TP—2002-211556. URL: https://ntrs.nasa.gov/citations/20020085330.
+  </li>
+</ul>
+
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end enthalpyOfCondensingGas;
+  //
+  // Add new functions
+  //  
+  function saturationTemperature
+    "Returns saturation temperature of condensing fluid (i.e., water)"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Pressure p_sat
+      "Saturation pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.Temperature T_sat
+      "Saturation temperature"
+      annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+    //
+    // Definition of protected funtions
+    //
+protected
+    function p_sat_T_sat
+      "Function used to solve non-linear equation 0 = p_sat(T_sat) - p_sat"
+      extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+      //
+      // Definition of inputs
+      //
+      input Modelica.Units.SI.Pressure p_sat
+        "Saturation pressure";
+
+    algorithm
+      y :=saturationPressureH2O_T(T_sat=u) - p_sat
+        "Zero point problem";
+    end p_sat_T_sat;
+
+  algorithm
+    T_sat := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+      f = function p_sat_T_sat(p_sat=p_sat),
+      u_min = 50,
+      u_max = T_water_crit-1,
+      tolerance = 100*Modelica.Constants.eps)
+      "Saturation temperature";
+
+    //
+    // Annotations
+    //
+    annotation (Inline=false,
+      InlineAfterIndexReduction=false,
+      LateInline=true,
+      inverse(p_sat=saturationPressure(Tsat=T_sat)),
+      Documentation(info="<html>
+<p>
+This function calculates the vapor temperature as function of the vapor pesssure
+by solving a non-linear equation via the very efficient function
+<a href=\"Modelica://Modelica.Math.Nonlinear.solveOneNonlinearEquation\">Modelica.Math.Nonlinear.solveOneNonlinearEquation</a>.
+</p>
+</html>",   revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end saturationTemperature;
+
+protected 
+  function gasMixtureViscosity
+    "Returns viscosities of gas mixtures (at low pressures according to the Wilke method)"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.MoleFraction[nX] yi
+      "Mole fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.MolarMass[nX] M
+      "Mole masses"
+    annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.DynamicViscosity[nX] eta
+      "Pure component viscosities"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.DynamicViscosity etam
+      "Viscosity of the mixture"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+    //
+    // Definition of variables
+    //
+protected
+    Real fi[nX,nX];
+
+  algorithm
+    for i in 1:nX loop
+      //
+      // Check if calculation is possible
+      //
+      assert(fluidConstants[i].hasDipoleMoment,"Dipole moment for " +
+        fluidConstants[i].chemicalFormula +
+        " not known. Can not compute viscosity.");
+      assert(fluidConstants[i].hasCriticalData, "Critical data for " +
+        fluidConstants[i].chemicalFormula +
+        " not known. Can not compute viscosity.");
+
+      //
+      // Calculate viscosity
+      //
+      for j in 1:nX loop
+        if i==1 then
+          fi[i,j] := (1 + (eta[i]/eta[j])^(1/2)*(M[j]/M[i])^(1/4))^2/
+            (8*(1 + M[i]/M[j]))^(1/2);
+        elseif j<i then
+            fi[i,j] := eta[i]/eta[j]*M[j]/M[i]*fi[j,i];
+          else
+            fi[i,j] := (1 + (eta[i]/eta[j])^(1/2)*(M[j]/M[i])^(1/4))^2/
+            (8*(1 + M[i]/M[j]))^(1/2);
+        end if;
+      end for;
+    end for;
+
+    etam := sum(yi[i]*eta[i]/sum(yi[j]*fi[i,j] for j in 1:nX) for i in 1:nX);
+
+    //
+    // Annotations
+    //
+    annotation (smoothOrder=2, Documentation(info="<html>  
+<p>
+Simplification of the kinetic theory (Chapman and Enskog theory) approach 
+neglecting the second-order effects. This function is a copy of function 
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.gasMixtureViscosity\">Modelica.Media.IdealGases.Common.MixtureGasNasa.gasMixtureViscosity</a>, 
+to be able to use this function within the curent media model.
+</p>  
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end gasMixtureViscosity;
+
+  function lowPressureThermalConductivity
+    "Returns thermal conductivity (at low pressure according to the Mason and Saxena modification)"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.MoleFraction[nX] y
+      "Mole fraction of the components in the gas mixture"
+    annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T
+      "Temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature[nX] Tc
+      "Critical temperatures"
+    annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.AbsolutePressure[nX] Pc
+      "Critical pressures"
+    annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.MolarMass[nX] M
+      "Molecular weights"
+    annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.ThermalConductivity[nX] lambda
+      "Thermal conductivities of the pure gases"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.ThermalConductivity lambdam
+      "Thermal conductivity of the gas mixture"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+    //
+    // Definition of constants
+    //
+protected
+    constant Real epsilon = 1.0
+      "Numerical constant near unity";
+
+    //
+    // Definition of variables
+    //
+    Modelica.Units.SI.MolarMass[nX] gamma;
+    Real[nX] Tr
+      "Reduced temperature";
+    Real[nX,nX] A
+      "Mason and Saxena Modification";
+
+  algorithm
+    for i in 1:nX loop
+      gamma[i] := 210*(Tc[i]*M[i]^3/Pc[i]^4)^(1/6);
+      Tr[i] := T/Tc[i];
+
+    end for;
+
+    for i in 1:nX loop
+      for j in 1:nX loop
+        A[i,j] := epsilon*(1 + (gamma[j]*(Modelica.Math.exp(0.0464*Tr[i]) -
+          Modelica.Math.exp(-0.2412*Tr[i])) /
+          (gamma[i]*(Modelica.Math.exp(0.0464*Tr[j]) -
+          Modelica.Math.exp(-0.2412*Tr[j])))) ^
+          (1/2)*(M[i]/M[j])^(1/4))^2/(8*(1 + M[i]/M[j]))^(1/2);
+      end for;
+    end for;
+
+    lambdam :=
+      sum(y[i]*lambda[i]/(sum(y[j]*A[i,j] for j in 1:nX)) for i in 1:nX);
+
+    //
+    // Annotations
+    //
+    annotation (smoothOrder=2, Documentation(info="<html>  
+<p>
+This function applies the Masson and Saxena modification of the Wassiljewa 
+Equation for the thermal conductivity for gas mixtures of n elements at low 
+pressure. This function is a copy of function 
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa.lowPressureThermalConductivity\">Modelica.Media.IdealGases.Common.MixtureGasNasa.lowPressureThermalConductivity</a>, 
+to be able to use this function within the curent media model.
+</p>  
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end lowPressureThermalConductivity;
+  //
+  // Annotations
+  //    
+  annotation (Documentation(info="<html>
+<p>
+This model extends the medium model of an ideal gas-vapor mixture provided
+in the Modelica Standard Library by additional functions needed in SorpLib.
+Furthermore, the media model is modified so that it can describe an ideal gas 
+mixture with any number of non-condensing components and one ideal condensing 
+component. The condensing component is water and must always be the last component
+when defining a medium model. The properties of the ideal gas mixture of the 
+non-condensing components are calculated according to the media model
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa\">Modelica.Media.IdealGases.Common.MixtureGasNasa</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialIdealGasWaterVaporMixture;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/package.order b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/package.order
new file mode 100644
index 0000000..aa4d172
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/package.order
@@ -0,0 +1,104 @@
+data
+MMX
+p_water_trp
+p_water_crit
+T_water_trp
+T_water_crit
+d_water_crit
+v_water_liq
+v_water_solid
+p_water_ref
+T_water_ref
+h_water_ref
+dh_vap_water_ref
+dh_fus_water_ref
+s_water_ref
+ds_vap_water_ref
+ds_fus_water_ref
+h_dryAir_off
+s_dryAir_off
+print_warnings
+ThermodynamicState
+BaseProperties
+setState_pTX
+setState_phX
+setState_psX
+setState_dTX
+setSmoothState
+pressure
+temperature
+density
+specificEnthalpy
+specificInternalEnergy
+specificEntropy
+specificGibbsEnergy
+specificHelmholtzEnergy
+dynamicViscosity
+thermalConductivity
+specificHeatCapacityCp
+specificHeatCapacityCv
+isentropicExponent
+isentropicEnthalpy
+velocityOfSound
+isobaricExpansionCoefficient
+isothermalCompressibility
+density_derp_h
+density_derh_p
+density_derp_T
+density_derT_p
+density_derX
+molarMass
+gasConstant
+enthalpyOfNonCondensingGas
+enthalpyOfGas
+saturationPressure
+enthalpyOfVaporization
+enthalpyOfLiquid
+enthalpyOfCondensingGas
+rho_pTXY
+specificEnthalpy_pTXY
+specificEntropy_pTXY
+pressure_dTXY
+temperature_phXY
+temperature_psXY
+massFractions_pTxDryPhi
+partialPressures
+enthalpyOfNonCondensingComponents
+entropyOfNonCondensingGas
+specificEnthalpy_i
+specificEntropy_i
+dmassToMoleFractions_dX
+dv_dp_TX
+dv_dT_pX
+dv_dX_pT
+dh_dp_TX
+dh_dT_pX
+dh_dX_pT
+drho_dX_ph
+saturationTemperature
+saturationPressureH2O_T
+dsaturationPressureH2O_dT
+ddsaturationPressureH2O_dT_dT
+relativeHumidity
+massFractionSaturation
+dryMassFractionSaturation
+ddryMassFractionSaturation_dp_TX
+ddryMassFractionSaturation_dT_pX
+ddryMassFractionSaturation_dX_pT
+specificHeatCapacitySolid
+specificHeatCapacityLiquid
+specificHeatCapacityVapor
+enthalpyOfSolid
+enthalpyOfCondensingComponent
+enthalpyOfVapor
+enthalpyOfLiquidIce
+entropyOfSolid
+entropyOfLiquid
+entropyOfCondensingGas
+moistAirToDryAirMassFractions
+dryAirToMoistAirMassFractions
+moistAirToDryAirMassBasedProperties
+dryAirToMoistAirMassBasedProperties
+ddryAirMassFractions_dX
+gasMixtureViscosity
+lowPressureThermalConductivity
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/partialPressures.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/partialPressures.mo
new file mode 100644
index 0000000..3da7827
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/partialPressures.mo
@@ -0,0 +1,71 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function partialPressures
+  "Returns partial pressures"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure[nX] p_i
+    "Partial pressures"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_sat=
+    saturationPressure(Tsat=state.T)
+    "Saturation pressure of condensing fluid (i.e., water)";
+  Modelica.Units.SI.Pressure p_dryAir
+    "Partial pressure of dry air (i.e., without condensing component)";
+
+  Modelica.Units.SI.SpecificVolume v_dryAir
+    "Specific volume of dry air (i.e., without condensing component) related
+      to mass of moist air";
+
+algorithm
+  if (state.X[nX] / (1 - state.X[nX])) >
+    dryMassFractionSaturation(state=state) then
+    p_dryAir :=state.p - p_sat
+      "Partial pressure of dry air (i.e., without partial pressure of water)";
+    v_dryAir := sum(state.X[1:nX-1] ./ MMX[1:nX-1]) .* Modelica.Constants.R .*
+      state.T ./ p_dryAir
+      "Specific volume of dry air (i.e., without condensing component) related
+        to mass of moist air";
+
+    p_i[1:nX-1] := state.X[1:nX-1] ./ MMX[1:nX-1] .* Modelica.Constants.R .*
+      state.T ./ v_dryAir
+      "Partial pressures of non-condensing components";
+    p_i[nX] := p_sat
+      "Partial pressures of condensing component";
+
+  else
+    p_i := state.Y .* state.p
+      "Partial pressures";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial pressures as function of the state record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end partialPressures;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/pressure_dTXY.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/pressure_dTXY.mo
new file mode 100644
index 0000000..8380d89
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/pressure_dTXY.mo
@@ -0,0 +1,79 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function pressure_dTXY
+  "Returns pressure as inverse of function rho_pTXY"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Density d
+    "Density"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[nX] Y
+    "Mole fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of protected funtions
+  //
+protected
+  function rho_pTXY_inverse
+    "Function used to solve non-linear equation 0 = d(p,T,X,Y) - d"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Density d
+      "Density";
+    input Modelica.Units.SI.Temperature T
+      "Pressure";
+    input Modelica.Units.SI.MassFraction[nX] X
+      "Mass fractions";
+    input Modelica.Units.SI.MoleFraction[nX] Y
+      "Mole fractions";
+
+  algorithm
+    y :=rho_pTXY(p=u, T=T, X=X, Y=Y) - d
+      "Zero point problem";
+  end rho_pTXY_inverse;
+
+algorithm
+  p := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+    f = function rho_pTXY_inverse(d=d, T=T, X=X, Y=Y),
+    u_min = 1e-6,
+    u_max = 100*10e5,
+    tolerance = 100*Modelica.Constants.eps)
+    "Pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false, InlineAfterIndexReduction=false, LateInline=true,
+inverse(d=rho_pTXY(p=p, T=T, X=X, Y=Y)),Documentation(info="<html>
+<p>
+This function calculates the pressure of the ideal gas-vapor mixture as function
+of density, temperature, mass fractions, and mole fractions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end pressure_dTXY;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/relativeHumidity.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/relativeHumidity.mo
new file mode 100644
index 0000000..e5d6fae
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/relativeHumidity.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function relativeHumidity
+  "Returns relative humidity"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real phi(min=0, max=1)
+     "Relative humidity"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+algorithm
+  phi := if (state.X[nX] / (1 - state.X[nX])) >
+    dryMassFractionSaturation(state=state) then 1 else
+    state.Y[nX] * state.p / saturationPressure(Tsat=state.T)
+    "Relative humidity";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the relative humidity as function of the state record.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end relativeHumidity;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/rho_pTXY.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/rho_pTXY.mo
new file mode 100644
index 0000000..46f94b6
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/rho_pTXY.mo
@@ -0,0 +1,96 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function rho_pTXY
+  "Returns density of the ideal gas-vapor mixture"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[nX] Y
+    "Mole fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Density rho
+    "Density"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=ThermodynamicState(p=p, T=T, X=X, Y=Y))
+    "Saturation mass fraction of condensing component per dry air";
+
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume per dry air mass";
+
+algorithm
+  //
+  // Calculate specific volume per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    v := sum(x[1:nX-1] ./ MMX[1:nX-1] .* Modelica.Constants.R .* T ./ p)
+      "Specific volume equals specific volume of unsaturated dry air without 
+        water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    v := sum(x ./ MMX .* Modelica.Constants.R  .* T ./ p)
+      "Specific volume equals specific volume of unsaturated dry air and water 
+        vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif T > T_water_trp then
+    v := sum(x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] .* T ./ p) +
+      x_sat * Modelica.Constants.R / MMX[nX] * T / p +
+      (x[nX] - x_sat) * v_water_liq
+      "Specific volume equals specific volume of saturated dry air, water vapor,
+        and liquid water: Calculated applying the law of ideal gas  mixtures.";
+
+  else
+    v := sum(x[1:nX-1] .* Modelica.Constants.R ./ MMX[1:nX-1] .* T ./ p) +
+      x_sat * Modelica.Constants.R / MMX[nX] * T / p +
+      (x[nX] - x_sat) * v_water_solid
+      "Specific volume equals specific volume of saturated dry air, water vapor,
+        and solid water: Calculated applying the law of ideal gas  mixtures.";
+
+  end if;
+
+  //
+  // Convert specific volume to density
+  //
+  rho := 1 / (v / (1 + x[nX]))
+    "Density of ideal gas-vapor mixture";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false, InlineAfterIndexReduction=false, LateInline=true,
+inverse(p=pressure_dTXY(d=rho, T=T, X=X, Y=Y)), Documentation(info="<html>
+<p>
+This function calculates the density of the ideal gas-vapor mixture as function
+of pressure, temperature, mass fractions, and mole fractions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end rho_pTXY;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/saturationPressureH2O_T.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/saturationPressureH2O_T.mo
new file mode 100644
index 0000000..72d9d84
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/saturationPressureH2O_T.mo
@@ -0,0 +1,99 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function saturationPressureH2O_T
+  "Returns saturatation pressure of water"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_sat
+    "Saturation temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[2] coeff_s = {-13.9281690, 34.7078238}
+    "Coefficients of the gas-solid boundary";
+  constant Real[6] coeff_l = {-7.85951783, 1.84408259, -11.7866497,
+    22.6807411, -15.9618719, 1.80122502}
+    "Coefficients of the gas-liquid boundary";
+
+  constant Real[2] exp_s = {-1.5, -1.25}
+    "Exponents of the gas-solid boundary";
+  constant Real[6] exp_l = {1, 1.5, 3,
+    3.5, 4, 7.5}
+    "Exponents of the gas-liquid boundary";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_sat_s
+    "Saturation pressure of gas-solid boundary";
+  Modelica.Units.SI.Pressure p_sat_l
+    "Saturation pressure of gas-liquid boundary";
+
+  Real T_red_s = T_sat/T_water_trp
+    "Reduced temperature required for gas-solid boundary";
+  Real T_red_fl = 1 - T_sat/T_water_crit
+    "Reduced temperature required for gas-liquid boundary";
+
+  Real lambda(unit="1") = SorpLib.Numerics.smoothTransition(
+    x=T_sat, transitionPoint=T_water_trp, transitionLength=1, noDiff=3)
+    "Transition factor";
+
+algorithm
+  //
+  // Calculate pressures
+  //
+  p_sat_s := p_water_trp * exp(coeff_s[1] - coeff_s[1] * T_red_s ^ exp_s[1] +
+    coeff_s[2] - coeff_s[2] * T_red_s ^ exp_s[2])
+    "Saturation pressure of gas-solid boundary";
+  p_sat_l := p_water_crit * exp(T_water_crit/T_sat *
+    (coeff_l[1] * T_red_fl ^ exp_l[1] +
+    coeff_l[2] * T_red_fl ^ exp_l[2] +
+    coeff_l[3] * T_red_fl ^ exp_l[3] +
+    coeff_l[4] * T_red_fl ^ exp_l[4] +
+    coeff_l[5] * T_red_fl ^ exp_l[5] +
+    coeff_l[6] * T_red_fl ^ exp_l[6]))
+    "Saturation pressure of gas-liquid boundary";
+
+  //
+  // Check for boundary
+  //
+  p_sat :=lambda*p_sat_s + (1-lambda)*p_sat_l
+    "Saturation pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the saturation pressure of water depending on
+the temperature. This functions covers both, the solid-gas and the gas-
+liquid boundary.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wagner, W. and Pru&szlig;, A (2002). The IAPWS Formulation 1995 for the Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use, Journal of Physical and Chemical Reference Data, 31:387. DOI: https://doi.org/10.1063/1.1461829.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end saturationPressureH2O_T;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEnthalpy_i.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEnthalpy_i.mo
new file mode 100644
index 0000000..6885777
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEnthalpy_i.mo
@@ -0,0 +1,84 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function specificEnthalpy_i
+  "Returns specific enthalpy of component i per component mass"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Integer ind_component
+    "Component index whose specific enthalpy is to be calculated"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy of component ind_component"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+algorithm
+  if ind_component <> nX then
+    h := Modelica.Media.IdealGases.Common.Functions.h_T(
+      data=data[ind_component],
+      T=state.T,
+      exclEnthForm=true,
+      refChoice=Modelica.Media.Interfaces.Choices.ReferenceEnthalpy.UserDefined,
+      h_off=h_dryAir_off)
+      "Specific enthalpy equals specific enthalpy of dry air component";
+
+  elseif Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    h := 0
+      "Specific enthalpy equals specific enthalpy of water but water is not
+      within the ideal gas-vapor mixture";
+
+  elseif x[nX] <= x_sat then
+    h := enthalpyOfCondensingGas(T=state.T)
+      "Specific enthalpy equals specific enthalpy of water: Unsaturated dry
+      air";
+
+  elseif state.T > T_water_trp then
+    h := x_sat/x[nX] * enthalpyOfCondensingGas(T=state.T) +
+      (x[nX]-x_sat)/x[nX] * enthalpyOfLiquid(p=state.p, T=state.T)
+      "Specific enthalpy equals specific enthalpy of water: Saturated dry
+      air with liquid water";
+
+  else
+    h := x_sat/x[nX] * enthalpyOfCondensingGas(T=state.T) +
+      (x[nX]-x_sat)/x[nX] * enthalpyOfSolid(p=state.p, T=state.T)
+      "Specific enthalpy equals specific enthalpy of water: Saturated dry
+      air with solid water";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation(Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of component i per component mass.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificEnthalpy_i;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEnthalpy_pTXY.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEnthalpy_pTXY.mo
new file mode 100644
index 0000000..893ceb7
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEnthalpy_pTXY.mo
@@ -0,0 +1,94 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function specificEnthalpy_pTXY
+  "Returns specific enthalpy of the ideal gas-vapor mixture"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[nX] Y
+    "Mole fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=ThermodynamicState(p=p, T=T, X=X, Y=Y))
+    "Saturation mass fraction of condensing component per dry air";
+
+algorithm
+  //
+  // Calculate specific enthalpy per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    h := enthalpyOfNonCondensingGas(T=T, X=x)
+      "Specific enthalpy equals specific enthalpy of unsaturated dry air without 
+        water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    h := enthalpyOfNonCondensingGas(T=T, X=x) +
+      x[nX] * enthalpyOfCondensingGas(T=T)
+      "Specific enthalpy equals specific enthalpy of unsaturated dry air and water 
+        vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif T > T_water_trp then
+    h := enthalpyOfNonCondensingGas(T=T, X=x) +
+      x_sat * enthalpyOfCondensingGas(T=T) +
+      (x[nX]-x_sat) * enthalpyOfLiquid(p=p, T=T)
+      "Specific enthalpy equals specific enthalpy of saturated dry air, water
+        vapor, liquid water: Calculated applying the law of ideal gas mixtures.";
+
+  else
+    h := enthalpyOfNonCondensingGas(T=T, X=x) +
+      x_sat * enthalpyOfCondensingGas(T=T) +
+      (x[nX]-x_sat) * enthalpyOfSolid(p=p, T=T)
+      "Specific enthalpy equals specific enthalpy of saturated dry air, water
+        vapor, solid water: Calculated applying the law of ideal gas mixtures.";
+
+  end if;
+
+  //
+  // Convert specific enthalpy per dry air mass
+  //
+  h := h / (1 + x[nX])
+    "Specific enthalpy per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false, InlineAfterIndexReduction=false, LateInline=true,
+inverse(T=temperature_phXY(p=p, h=h, X=X, Y=Y)),Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy of the ideal gas-vapor mixture as 
+function of pressure, temperature, mass fractions, and mole fractions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificEnthalpy_pTXY;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEntropy_i.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEntropy_i.mo
new file mode 100644
index 0000000..7a5c0cc
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEntropy_i.mo
@@ -0,0 +1,86 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function specificEntropy_i
+  "Returns specific entropy of component i per componentmass"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Integer ind_component
+    "Component index whose specific entropy is to be calculated"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy of component ind_component"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=state.X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=state)
+    "Saturation mass fraction of condensing component per dry air";
+
+  Modelica.Units.SI.Pressure[nX] p_i=
+    partialPressures(state=state)
+    "Partial pressures";
+
+algorithm
+  if ind_component <> nX then
+    s := s_dryAir_off + Modelica.Media.IdealGases.Common.Functions.s0_T(
+      data=data[ind_component], T=state.T) - Modelica.Constants.R /
+      MMX[ind_component] * Modelica.Math.log(max(p_i[ind_component],
+      Modelica.Constants.eps) / reference_p)
+      "Specific entropy equals specific entropy of dry air component";
+
+  elseif Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    s := 0
+      "Specific entropy equals specific entropy of water but water is not
+      within the ideal gas-vapor mixture";
+
+  elseif x[nX] <= x_sat then
+    s := entropyOfCondensingGas(T=state.T, p=p_i[nX])
+      "Specific entropy equals specific entropy of water: Unsaturated dry
+      air";
+
+  elseif state.T > T_water_trp then
+    s := x_sat/x[nX] * entropyOfCondensingGas(T=state.T, p=p_i[nX]) +
+      (x[nX]-x_sat)/x[nX] * entropyOfLiquid(T=state.T)
+      "Specific entropy equals specific entropy of water: Saturated dry
+      air with liquid water";
+
+  else
+    s := x_sat/x[nX] * entropyOfCondensingGas(T=state.T, p=p_i[nX]) +
+      (x[nX]-x_sat)/x[nX] * entropyOfSolid(T=state.T)
+      "Specific entropy equals specific entropy of water: Saturated dry
+      air with solid water";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation(Documentation(info="<html>
+<p>
+This function calculates the specific entropy of component i per component mass.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificEntropy_i;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEntropy_pTXY.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEntropy_pTXY.mo
new file mode 100644
index 0000000..a04590c
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificEntropy_pTXY.mo
@@ -0,0 +1,98 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function specificEntropy_pTXY
+  "Returns specific entropy of the ideal gas-vapor mixture"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Temperature T
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[nX] Y
+    "Mole fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.MassFraction[nX] x=
+    moistAirToDryAirMassFractions(X=X)
+    "Mass fractions per dry air";
+  Modelica.Units.SI.MassFraction x_sat=
+    dryMassFractionSaturation(state=ThermodynamicState(p=p, T=T, X=X, Y=Y))
+    "Saturation mass fraction of condensing component per dry air";
+
+  Modelica.Units.SI.Pressure[nX] p_i=
+    partialPressures(state=ThermodynamicState(p=p, T=T, X=X, Y=Y))
+    "Partial pressures";
+
+algorithm
+  //
+  // Calculate specific enthalpy per dry air mass
+  //
+  if Modelica.Math.isEqual(s1=x[nX], s2=0, eps=100*Modelica.Constants.eps) then
+    s := entropyOfNonCondensingGas(T=T, X=x, p_i=p_i)
+      "Specific entropy equals specific entropy of unsaturated dry air without 
+      water: Calculated applying the law of ideal gas mixtures.";
+
+  elseif x[nX] <= x_sat then
+    s := entropyOfNonCondensingGas(T=T, X=x, p_i=p_i) +
+      x[nX] * entropyOfCondensingGas(T=T, p=p_i[nX])
+      "Specific entropy equals specific entropy of unsaturated dry air and water 
+      vapor: Calculated applying the law of ideal gas mixtures.";
+
+  elseif T > T_water_trp then
+    s := entropyOfNonCondensingGas(T=T, X=x, p_i=p_i) +
+      x_sat * entropyOfCondensingGas(T=T, p=p_i[nX]) +
+      (x[nX]-x_sat) * entropyOfLiquid(T=T)
+      "Specific entropy equals specific entropy of saturated dry air, water
+      vapor, liquid water: Calculated applying the law of ideal gas mixtures.";
+
+  else
+    s := entropyOfNonCondensingGas(T=T, X=x, p_i=p_i) +
+      x_sat * entropyOfCondensingGas(T=T, p=p_i[nX]) +
+      (x[nX]-x_sat) * entropyOfSolid(T=T)
+      "Specific entropy equals specific entropy of saturated dry air, water
+      vapor, solid water: Calculated applying the law of ideal gas mixtures.";
+
+  end if;
+
+  //
+  // Convert specific enthalpy per dry air mass
+  //
+  s := s / (1 + x[nX])
+    "Specific entropy per moist air mass";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false, InlineAfterIndexReduction=false, LateInline=true,
+  inverse(T=temperature_psXY(p=p, s=s, X=X, Y=Y)), Documentation(info="<html>
+<p>
+This function calculates the specific entropy of the ideal gas-vapor mixture as 
+function of pressure, temperature, mass fractions, and mole fractions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificEntropy_pTXY;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacityLiquid.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacityLiquid.mo
new file mode 100644
index 0000000..0a816ad
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacityLiquid.mo
@@ -0,0 +1,80 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function specificHeatCapacityLiquid
+  "Returns specific heat capacity c of condensing component's liquid phase (per water mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Modelica.Units.SI.SpecificHeatCapacity c
+    "Specific heat capacity of liquid"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[10] coefficients=
+    {4.66348457415926e-19, -1.16579701193758e-15, 9.49925152355854e-13,
+    5.81553479401465e-11, -6.55387915784314e-7, 5.30868446475702e-4,
+    -2.18234813641286e-1, 5.13043718148301e1, -6.58121774333134e3,
+    3.63215816205503e5}
+    "Coefficients of polynomical function";
+  constant Real[10] exponents=
+    {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
+    "Exponents of polynomical function";
+
+algorithm
+  c := SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=state.T,
+    T_ref=573.15,
+    z_ref=1,
+    coefficients=coefficients,
+    exponents=exponents,
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Specific heat capacity of liquid";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(T_water_trp-1 <= state.T and state.T <= 573.15,
+      "Temperature (" + String(state.T) + " K) is not between 272.16 and 573.15 K. " +
+      "Calculation of specific heat capacity of liquid may not be valid!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the condensing component
+(i.e., water) at its liquid phase as function of the state record. The specific 
+heat capacity is calculated as a polynomial fit to specific heat capacity data 
+calculated at saturated liquid state with the reference equation of state for 
+water. The data was calculated for temperature varying from 273.16 K to 573.15 K.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wagner, W. and Pru&szlig;, A (2002). The IAPWS Formulation 1995 for the Thermodynamic Properties of Ordinary Water Substance for General and Scientific Use, Journal of Physical and Chemical Reference Data, 31:387. DOI: https://doi.org/10.1063/1.1461829.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificHeatCapacityLiquid;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacitySolid.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacitySolid.mo
new file mode 100644
index 0000000..1cacbc2
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacitySolid.mo
@@ -0,0 +1,80 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function specificHeatCapacitySolid
+  "Returns specific heat capacity c of condensing component's solid phase (i.e., ice) (per water mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Modelica.Units.SI.SpecificHeatCapacity c
+    "Specific heat capacity of ice"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[7] coefficients=
+    {2.19406894387930e-11, -2.21186473219202e-8, 8.60754642146296e-6,
+    -1.57223901063024e-3, 1.24518779128263e-1, 5.27605328970081,
+    1.18325880591863e+1}
+    "Coefficients of polynomical function";
+  constant Real[7] exponents=
+    {6, 5, 4, 3, 2, 1, 0}
+    "Exponents of polynomical function";
+
+algorithm
+  c := SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=state.T,
+    T_ref=T_water_trp,
+    z_ref=1,
+    coefficients=coefficients,
+    exponents=exponents,
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Specific heat capacity of ice";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(50 <= state.T and state.T <= T_water_trp+1,
+      "Temperature (" + String( state.T) + " K) is not between 50 and 274.16 K. " +
+      "Calculation of specific heat capacity of ice may not be valid!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the condensing component
+(i.e., water) at its solid phase (i.e., ice) as function of the state record. The
+specific heat capacity is calculated as a polynomial fit to specific heat capacity
+data calculated with the reference equation of state for ice. The data was calculated
+for fixed pressure (p_water_trp = 611.657 Pa) and temperature varying from 50 K
+to 274.16 K.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  The International Association for the Properties of Water and Steam (2009). Revised Release on the Equation of State 2006 for H2O Ice Ih. URL: https://iapws.org/relguide/Ice-2009.html.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificHeatCapacitySolid;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacityVapor.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacityVapor.mo
new file mode 100644
index 0000000..d3d5caf
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/specificHeatCapacityVapor.mo
@@ -0,0 +1,80 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function specificHeatCapacityVapor
+  "Returns specific heat capacity cp of condensing component's ideal gas phase (i.e., vapor) (per water mass)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Deifnition of inputs
+  //
+  input ThermodynamicState state
+    "Thermodynamic state record"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Deifnition of outputs
+  //
+  output Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity of vapor"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+protected
+  constant Real[10] coefficients=
+    {7.03241022996521e-23, -4.12454440465976e-19, 1.05640534898709e-15,
+    -1.54797437245421e-12, 1.42577474111776e-9, -8.51385633913246e-7,
+    3.26064390458737e-4, -7.52464997116974e-2, 9.42339113729594,
+    1.36103845934352e+3}
+    "Coefficients of polynomical function";
+  constant Real[10] exponents=
+    {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
+    "Exponents of polynomical function";
+
+algorithm
+  cp := SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+    T=state.T,
+    T_ref=T_water_crit,
+    z_ref=1,
+    coefficients=coefficients,
+    exponents=exponents,
+    approach=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature)
+    "Specific heat capacity of vapor";
+
+  //
+  // Assertations
+  //
+  if print_warnings then
+    assert(200 <= state.T and state.T <= 1000,
+      "Temperature (" + String(state.T) + " K) is not between 200 and 1000 K. " +
+      "Calculation of specific heat capacity of vapor may not be valid!",
+      level = AssertionLevel.warning);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific heat capacity of the condensing component
+(i.e., water) at its ideal gas phase (i.e., vapor) as function of the state record.
+The specific heat capacity is calculated as a polynomial fit to specific heat capacity
+data calculated according to the NASA Glenn Coefficients. The data was calculated
+for a temperature varying from 200 K to 1000 K.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  McBride, B.J. and Zehe, M.J. and Gordon, S. (2002). NASA Glenn Coefficients for Calculating Thermodynamic Properties of Individual Species, Technical report, NASA/TP—2002-211556. URL: https://ntrs.nasa.gov/citations/20020085330.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end specificHeatCapacityVapor;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/temperature_phXY.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/temperature_phXY.mo
new file mode 100644
index 0000000..7d7dd22
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/temperature_phXY.mo
@@ -0,0 +1,83 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function temperature_phXY
+  "Returns temperature as inverse of function h_pTXY"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[nX] Y
+    "Mole fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of protected funtions
+  //
+protected
+  function h_pTXY_inverse
+    "Function used to solve non-linear equation 0 = h(p,T,X,Y) - h"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Pressure p
+      "Pressure";
+    input Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy";
+    input Modelica.Units.SI.MassFraction[nX] X
+      "Mass fractions";
+    input Modelica.Units.SI.MoleFraction[nX] Y
+      "Mole fractions";
+
+  algorithm
+    y :=specificEnthalpy_pTXY(
+        p=p,
+        T=u,
+        X=X,
+        Y=Y) - h
+      "Zero point problem";
+  end h_pTXY_inverse;
+
+algorithm
+  T := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+    f = function h_pTXY_inverse(p=p, h=h, X=X, Y=Y),
+    u_min = 200,
+    u_max = 573.15,
+    tolerance = 1e-6)
+    "Temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false, InlineAfterIndexReduction=false, LateInline=true,
+  inverse(h=specificEnthalpy_pTXY(p=p, T=T, X=X, Y=Y)), Documentation(info="<html>
+<p>
+This function calculates the temperature of the ideal gas-vapor mixture as function
+of pressure, specific enthalpy, mass fractions, and mole fractions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end temperature_phXY;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/temperature_psXY.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/temperature_psXY.mo
new file mode 100644
index 0000000..73b2c90
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/PartialIdealGasWaterVaporMixture/temperature_psXY.mo
@@ -0,0 +1,83 @@
+within SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture;
+function temperature_psXY
+  "Returns temperature as inverse of function s_pTXY"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MassFraction[nX] X
+    "Mass fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.MoleFraction[nX] Y
+    "Mole fractions"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General",group="Outputs", enable=false));
+
+  //
+  // Definition of protected funtions
+  //
+protected
+  function s_pTXY_inverse
+    "Function used to solve non-linear equation 0 = s(p,T,X,Y) - s"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Pressure p
+      "Pressure";
+    input Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy";
+    input Modelica.Units.SI.MassFraction[nX] X
+      "Mass fractions";
+    input Modelica.Units.SI.MoleFraction[nX] Y
+      "Mole fractions";
+
+  algorithm
+    y :=specificEntropy_pTXY(
+        p=p,
+        T=u,
+        X=X,
+        Y=Y) - s
+      "Zero point problem";
+  end s_pTXY_inverse;
+
+algorithm
+  T := Modelica.Math.Nonlinear.solveOneNonlinearEquation(
+    f = function s_pTXY_inverse(p=p, s=s, X=X, Y=Y),
+    u_min = 200,
+    u_max = 573.15,
+    tolerance = 1e-6)
+    "Temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false, InlineAfterIndexReduction=false, LateInline=true,
+  inverse(s=specificEntropy_pTXY(p=p, T=T, X=X, Y=Y)), Documentation(info="<html>
+<p>
+This function calculates the temperature of the ideal gas-vapor mixture as function
+of pressure, specific entropy, mass fractions, and mole fractions.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 27, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end temperature_psXY;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/package.mo b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/package.mo
new file mode 100644
index 0000000..7af3bfd
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.IdealGasVaporMixtures;
+package Interfaces "Interfaces for models of ideal gas-vapor mixtures"
+extends Modelica.Icons.InterfacesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package provides definitions of basic interfaces for models
+of ideal gas-vapor mixtures.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Interfaces;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Interfaces/package.order b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/package.order
new file mode 100644
index 0000000..d3770d9
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Interfaces/package.order
@@ -0,0 +1 @@
+PartialIdealGasWaterVaporMixture
diff --git a/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_Ar_H2O/package.mo b/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_Ar_H2O/package.mo
new file mode 100644
index 0000000..0f25eb8
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_Ar_H2O/package.mo
@@ -0,0 +1,38 @@
+within SorpLib.Media.IdealGasVaporMixtures;
+package MoistAir_N2_O2_Ar_H2O "SorpLib: Simple moist air consisting of N2, O2, Ar, and H2O"
+  extends
+    SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture(
+    mediumName="MoistAir_N2_O2_Ar_H2O",
+    data={Modelica.Media.IdealGases.Common.SingleGasesData.N2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.O2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.Ar,
+          Modelica.Media.IdealGases.Common.SingleGasesData.H2O},
+    fluidConstants={Modelica.Media.IdealGases.Common.FluidData.N2,
+                    Modelica.Media.IdealGases.Common.FluidData.O2,
+                    Modelica.Media.IdealGases.Common.FluidData.Ar,
+                    Modelica.Media.IdealGases.Common.FluidData.H2O},
+    substanceNames={"Nitrogen",
+                    "Oxygen",
+                    "Argon",
+                    "Water"},
+    final reference_X={0.7552/0.9994,0.2313/0.9994,0.0129/0.9994,1e-5},
+    h_dryAir_off = 25097.2,
+    s_dryAir_off = -8239.74);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the fluid property of moist air modeled as ideal gas-vapor
+mixture of N<sub>2</sub>, O<sub>2</sub>, Ar, and H<sub>2</sub>0.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 28, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MoistAir_N2_O2_Ar_H2O;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_Ar_H2O/package.order b/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_Ar_H2O/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_CO2_H2O/package.mo b/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_CO2_H2O/package.mo
new file mode 100644
index 0000000..750a376
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_CO2_H2O/package.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.IdealGasVaporMixtures;
+package MoistAir_N2_O2_CO2_H2O "SorpLib: Simple moist air consisting of N2, O2, CO2, and H2O"
+  extends SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture(
+    mediumName="MoistAir_N2_O2_CO2_H2O",
+    data={Modelica.Media.IdealGases.Common.SingleGasesData.N2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.O2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.CO2,
+          Modelica.Media.IdealGases.Common.SingleGasesData.H2O},
+    fluidConstants={Modelica.Media.IdealGases.Common.FluidData.N2,
+                    Modelica.Media.IdealGases.Common.FluidData.O2,
+                    Modelica.Media.IdealGases.Common.FluidData.CO2,
+                    Modelica.Media.IdealGases.Common.FluidData.H2O},
+    substanceNames={"Nitrogen",
+                    "Oxygen",
+                    "Carbondioxide",
+                    "Water"},
+    final reference_X={0.7650,0.2344,5.90e-4,1e-5},
+    h_dryAir_off = 25252.5,
+    s_dryAir_off = -10137.3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the fluid property of moist air modeled as ideal gas-vapor
+mixture of N<sub>2</sub>, O<sub>2</sub>, CO<sub>2</sub>, and H<sub>2</sub>0.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 28, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MoistAir_N2_O2_CO2_H2O;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_CO2_H2O/package.order b/SorpLib/Media/IdealGasVaporMixtures/MoistAir_N2_O2_CO2_H2O/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Tester/Test_MoistAir_N2_O2_Ar_H2O.mo b/SorpLib/Media/IdealGasVaporMixtures/Tester/Test_MoistAir_N2_O2_Ar_H2O.mo
new file mode 100644
index 0000000..c4d6479
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Tester/Test_MoistAir_N2_O2_Ar_H2O.mo
@@ -0,0 +1,1023 @@
+within SorpLib.Media.IdealGasVaporMixtures.Tester;
+model Test_MoistAir_N2_O2_Ar_H2O
+  "Tester for moist air consisting of N2, O2, Ar, and H2O"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of paramters
+  //
+  replaceable package Medium =
+    SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_Ar_H2O(s_dryAir_off=-6625)
+    constrainedby
+    SorpLib.Media.IdealGasVaporMixtures.Interfaces.PartialIdealGasWaterVaporMixture
+    "Medium"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+  package MediumMoistAir =
+    Modelica.Media.Air.MoistAir(reference_X={1e-5,1-1e-5})
+    "Ideal moist air"
+    annotation (Dialog(tab="General",group="Models and Media"));
+  package MediumReferenceMoistAir =
+    Modelica.Media.Air.ReferenceMoistAir(reference_X={1e-5,1-1e-5})
+    "Reference moist air"
+    annotation (Dialog(tab="General",group="Models and Media"));
+
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="Numerics", group="Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="Numerics", group="Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real dX = 1e-6
+    "Mass fraction difference used to calculate partial derivatives numerically"
+    annotation (Dialog(tab="Numerics", group="Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables regarding state properties
+  //
+  Modelica.Units.SI.Pressure p(start=150, fixed=true)
+    "Pressure";
+  Modelica.Units.SI.Pressure p_solid(start=5, fixed=true)
+    "Pressure used to check solid properties";
+  Modelica.Units.SI.Pressure p_liquid(start=612, fixed=true)
+    "Pressure used to check liquid properties";
+  Modelica.Units.SI.Pressure p_vapor(start=150, fixed=true)
+    "Pressure used to check vaporous properties";
+
+  Modelica.Units.SI.Temperature T(start=223.15, fixed=true)
+    "Temperature";
+  Modelica.Units.SI.Temperature T_solid(start=50, fixed=true)
+    "Temperature used to check solid properties";
+  Modelica.Units.SI.Temperature T_liquid(start=273.16, fixed=true)
+    "Temperature used to check liquid properties";
+  Modelica.Units.SI.Temperature T_vapor(start=200, fixed=true)
+    "Temperature used to check vapor properties";
+
+  Modelica.Units.SI.MassFraction[Medium.nX] X
+    "Mass fractions";
+  Modelica.Units.SI.MassFraction[MediumMoistAir.nX] X_MoistAir
+    "Mass fractions";
+  Modelica.Units.SI.MassFraction[MediumReferenceMoistAir.nX] X_ReferenceMoistAir
+    "Mass fractions";
+
+  Modelica.Units.SI.MassFraction[Medium.nX] x
+    "Mass fractions per dry air mass";
+  Modelica.Units.SI.MassFraction[Medium.nX] X_from_x
+    "Mass fractions per moist air mass calculated from x";
+  Modelica.Units.SI.MassFraction[Medium.nX] X_from_xDryAirPhi
+    "Mass fractions per moist air mass calculated from x of dry air components 
+    and phi";
+
+  Medium.ThermodynamicState state_pTX
+    "State properties calculated with pressure, temperature, and composition";
+  Medium.ThermodynamicState state_phX
+    "State properties calculated with pressure, specific enthalpy, and composition";
+  Medium.ThermodynamicState state_psX
+    "State properties calculated with pressure, specific entropy, and composition";
+  Medium.ThermodynamicState state_dTX
+    "State properties calculated with density, temperature, and composition";
+
+  Medium.BaseProperties medium_pTX
+    "State properties";
+  MediumMoistAir.BaseProperties mediumMoistAir_pTX
+    "Base properties calculated with pressure, temperature, and mass fractions";
+  MediumReferenceMoistAir.BaseProperties mediumReferenceMoistAir_pTX
+    "Base properties calculated with pressure, temperature, and mass fractions";
+
+  Modelica.Units.SI.MassFraction x_sat
+    "Saturation uptake per unit of dry air";
+  Modelica.Units.SI.MassFraction x_sat_MoistAir
+    "Saturation uptake per unit of dry air";
+  Modelica.Units.SI.MassFraction x_sat_ReferenceMoistAir
+    "Saturation uptake per unit of dry air";
+
+  Modelica.Units.SI.MassFraction X_sat
+    "Saturation uptake per unit of moist air";
+  Modelica.Units.SI.MassFraction X_sat_MoistAir
+    "Saturation uptake per unit of moist air";
+  Modelica.Units.SI.MassFraction X_sat_ReferenceMoistAir
+    "Saturation uptake per unit of moist air";
+
+  Modelica.Units.SI.SpecificEnthalpy h_1
+    "Specific enthalpy of component 1";
+  Modelica.Units.SI.SpecificEnthalpy h_last
+    "Specific enthalpy of last component";
+
+  Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy";
+  Modelica.Units.SI.SpecificEntropy s_1
+    "Specific entropy of component 1";
+  Modelica.Units.SI.SpecificEntropy s_last
+    "Specific entropy of last component";
+  Modelica.Units.SI.SpecificEntropy s_MoistAir
+    "Specific entropy";
+  Modelica.Units.SI.SpecificEntropy s_ReferenceMoistAir
+    "Specific entropy";
+
+  //
+  // Definition of variables regarding additional properties
+  //
+  Modelica.Units.SI.Pressure[Medium.nX] p_i
+    "Partial pressures";
+  Modelica.Units.SI.Pressure p_water_ReferenceMoistAir
+    "Partial pressure of water";
+
+  Modelica.Media.Interfaces.Types.DynamicViscosity eta
+    "Dynamic viscosity";
+  Modelica.Media.Interfaces.Types.DynamicViscosity eta_MoistAir
+    "Dynamic viscosity";
+  Modelica.Media.Interfaces.Types.DynamicViscosity eta_ReferenceMoistAir
+    "Dynamic viscosity";
+
+  Modelica.Media.Interfaces.Types.ThermalConductivity lambda
+    "Thermal conductivity";
+  Modelica.Media.Interfaces.Types.ThermalConductivity lambda_MoistAir
+    "Thermal conductivity";
+  Modelica.Media.Interfaces.Types.ThermalConductivity lambda_ReferenceMoistAir
+    "Thermal conductivity";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity";
+  Modelica.Units.SI.SpecificHeatCapacity cp_MoistAir
+    "Specific heat capacity";
+  Modelica.Units.SI.SpecificHeatCapacity cp_ReferenceMoistAir
+    "Specific heat capacity";
+
+  Modelica.Units.SI.SpecificHeatCapacity cv
+    "Specific heat capacity";
+  Modelica.Units.SI.SpecificHeatCapacity cv_MoistAir
+    "Specific heat capacity";
+  Modelica.Units.SI.SpecificHeatCapacity cv_ReferenceMoistAir
+    "Specific heat capacity";
+
+  Modelica.Media.Interfaces.Types.IsentropicExponent gamma
+    "Isentropic coefficient";
+  Modelica.Media.Interfaces.Types.IsentropicExponent gamma_MoistAir
+    "Isentropic coefficient";
+  Modelica.Media.Interfaces.Types.IsentropicExponent gamma_ReferenceMoistAir
+    "Isentropic coefficient";
+
+  Modelica.Units.SI.SpecificEnthalpy h_is
+    "Isentropic specific enthalpy";
+  Modelica.Units.SI.SpecificEnthalpy h_is_MoistAir
+    "Isentropic specific enthalpy";
+  Modelica.Units.SI.SpecificEnthalpy h_is_ReferenceMoistAir
+    "Isentropic specific enthalpy";
+
+  Modelica.Media.Interfaces.Types.VelocityOfSound w_is
+    "Velocity of sound";
+  Modelica.Media.Interfaces.Types.VelocityOfSound w_is_MoistAir
+    "Velocity of sound";
+  Modelica.Media.Interfaces.Types.VelocityOfSound w_is_ReferenceMoistAir
+    "Velocity of sound";
+
+  Modelica.Units.SI.RelativePressureCoefficient beta
+    "Isobaric expansion coefficient";
+  Modelica.Units.SI.RelativePressureCoefficient beta_MoistAir
+    "Isobaric expansion coefficient";
+
+  Modelica.Units.SI.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+  Modelica.Units.SI.IsothermalCompressibility kappa_MoistAir
+    "Isothermal compressibility";
+
+  Modelica.Units.SI.SpecificEnthalpy h_dryAir
+    "Specific enthalpy of non-condensing components calculated for T_vapor";
+  Modelica.Units.SI.SpecificEnthalpy h_dryAir_MoistAir
+    "Specific enthalpy of liquid water calculated for T_vapor";
+  Modelica.Units.SI.SpecificEnthalpy h_dryAir_ReferenceMoistAir
+    "Specific enthalpy of non-condensing components calculated for T_vapor and 
+    p_vapor";
+
+  Modelica.Units.SI.SpecificEnthalpy h_dryAirVapor
+    "Specific enthalpy of non-condensing components and vapor";
+  Modelica.Units.SI.SpecificEnthalpy h_dryAirVapor_MoistAir
+    "Specific enthalpy of non-condensing components and vapor";
+  Modelica.Units.SI.SpecificEnthalpy h_dryAirVapor_ReferenceMoistAir
+    "Specific enthalpy of non-condensing components and vapor";
+
+  //
+  // Definition of variables regarding partial derivatives
+  //
+  SorpLib.Units.DerSpecificVolumeByPressure dv_dp_TX
+    "Partial derivative of specific volume w.r.t. pressure at constant
+    temperature and mass fractions";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_dp_TX_num
+    "Partial derivative of specific volume w.r.t. pressure at constant
+    temperature and mass fractions calculated numerically";
+
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_dT_pX
+    "Partial derivative of specific volume w.r.t. temperature  at constant
+    pressure and mass fractions";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_dT_pX_num
+    "Partial derivative of specific volume w.r.t. temperature  at constant
+    pressure and mass fractions calculated numerically";
+
+  Real[Medium.nX] dv_dX_pT(each unit="m3/kg")
+    "Partial derivatives of specific volume w.r.t. mass fractions  at constant
+    pressure and temperature";
+  Real[Medium.nX] dv_dX_pT_num(each unit="m3/kg")
+    "Partial derivatives of specific volume w.r.t. mass fractions  at constant
+    pressure and temperature calculated numerically";
+
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_dp_TX
+    "Partial derivative of specific enthalpy w.r.t. pressure at constant
+    temperature and mass fractions";
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_dp_TX_num
+    "Partial derivative of specific enthalpy w.r.t. pressure at constant
+    temperature and mass fractions calculated numerically";
+
+  Modelica.Units.SI.SpecificHeatCapacity dh_dT_pX
+    "Partial derivative of specific enthalpy w.r.t. temperature at constant
+    pressure and mass fractions";
+  Modelica.Units.SI.SpecificHeatCapacity dh_dT_pX_num
+    "Partial derivative of specific enthalpy w.r.t. temperature at constant
+    pressure and mass fractions calculated numerically";
+
+  Real[Medium.nX] dh_dX_pT(each unit="J/kg")
+    "Partial derivative of specific enthalpy w.r.t. mass fractions at constant
+    pressure and temperature";
+  Real[Medium.nX] dh_dX_pT_num(each unit="J/kg")
+    "Partial derivative of specific enthalpy w.r.t. mass fractions at constant
+    pressure and temperature calculated numerically";
+
+  Modelica.Media.Interfaces.Types.DerDensityByPressure drho_dp_hX
+    "Partial derivative of density w.r.t. pressure at constant specific enthalpy
+    and mass fractions";
+  Modelica.Media.Interfaces.Types.DerDensityByPressure drho_dp_hX_MoistAir
+    "Partial derivative of density w.r.t. pressure at constant specific enthalpy
+    and mass fractions";
+
+  Modelica.Media.Interfaces.Types.DerDensityByEnthalpy drho_dh_pX
+    "Partial derivative of density w.r.t. specific enthalpy at constant pressure
+    and mass fractions";
+  Modelica.Media.Interfaces.Types.DerDensityByEnthalpy drho_dh_pX_MoistAir
+    "Partial derivative of density w.r.t. specific enthalpy at constant pressure
+    and mass fractions";
+
+  Real[Medium.nX] drho_dX_ph(each unit="kg.kg/(m3.kg)")
+    "Partial derivative of density w.r.t. mass fractions at constant pressure
+    and specific enthalpy";
+  Real[Medium.nX] drho_dX_ph_num(each unit="kg.kg/(m3.kg)")
+    "Partial derivative of density w.r.t. mass fractions at constant pressure
+    and specific enthalpy calculated numerically";
+
+  Modelica.Media.Interfaces.Types.DerDensityByPressure drho_dp_TX
+    "Partial derivative of density w.r.t. pressure at constant temperature and
+    mass fractions";
+  Modelica.Media.Interfaces.Types.DerDensityByPressure drho_dp_TX_MoistAir
+    "Partial derivative of density w.r.t. pressure at constant temperature and
+    mass fractions";
+
+  Modelica.Media.Interfaces.Types.DerDensityByTemperature drho_dT_pX
+    "Partial derivative of density w.r.t. pressure at constant temperature and
+    mass fractions";
+  Modelica.Media.Interfaces.Types.DerDensityByTemperature drho_dT_pX_MoistAir
+    "Partial derivative of density w.r.t. pressure at constant temperature and
+    mass fractions";
+
+  Real[Medium.nX] drho_dX_pT(each unit="kg.kg/(m3.kg)")
+    "Partial derivative of density w.r.t. mass fractions at constant pressure
+    and temperature";
+  Real[Medium.nX] drho_dX_pT_num(each unit="kg.kg/(m3.kg)")
+    "Partial derivative of density w.r.t. mass fractions at constant pressure
+    and temperature calculated numerically";
+
+  //
+  // Definition of variables regarding condensing component
+  //
+  Modelica.Units.SI.Pressure p_sat
+    "Saturation pressure of water";
+  Modelica.Units.SI.Pressure p_sat_MoistAir
+    "Saturation pressure of water";
+  Modelica.Units.SI.Pressure p_sat_ReferenceMoistAir
+    "Saturation pressure of water";
+
+  Modelica.Units.SI.Temperature T_sat_p_sat
+    "Saturation temperature of water at saturation pressure of water";
+
+  Modelica.Units.SI.SpecificHeatCapacity c_solid
+    "Specific heat capacity of ice calculated fot T_solid";
+  Modelica.Units.SI.SpecificHeatCapacity c_liquid
+    "Specific heat capacity of ice calculated fot T_liquid";
+  Modelica.Units.SI.SpecificHeatCapacity cp_vapor
+    "Specific heat capacity of vapor calculated for T_vapor";
+
+  Modelica.Units.SI.SpecificEnthalpy dh_vap
+    "Specific enthalpy of vaporization calculated for T_liquid";
+  Modelica.Units.SI.SpecificEnthalpy dh_vap_MoistAir
+    "Specific enthalpy of vaporization calculated for T_liquid";
+  Modelica.Units.SI.SpecificEnthalpy dh_vap_ReferenceMoistAir
+    "Specific enthalpy of vaporization calculated for T_liquid and p_liquid";
+
+  Modelica.Units.SI.SpecificEnthalpy h_solid
+    "Specific enthalpy of solid water calculated for T_solid and p_solid";
+  Modelica.Units.SI.SpecificEnthalpy h_solid_MoistAir
+    "Specific enthalpy of solid water calculated for T_solid";
+  Modelica.Units.SI.SpecificEnthalpy h_solid_ReferenceMoistAir
+    "Specific enthalpy of solid water calculated for T_solid and p_solid";
+
+  Modelica.Units.SI.SpecificEnthalpy h_liquid
+    "Specific enthalpy of liquid water calculated for T_liquid and p_liquid";
+  Modelica.Units.SI.SpecificEnthalpy h_liquid_MoistAir
+    "Specific enthalpy of liquid water calculated for T_liquid";
+  Modelica.Units.SI.SpecificEnthalpy h_liquid_ReferenceMoistAir
+    "Specific enthalpy of liquid water calculated for T_liquid and p_liquid";
+
+  Modelica.Units.SI.SpecificEnthalpy h_vapor
+    "Specific enthalpy of vaporous water calculated for T_vapor";
+  Modelica.Units.SI.SpecificEnthalpy h_vapor_MoistAir
+    "Specific enthalpy of vaporous water calculated for T_vapor";
+  Modelica.Units.SI.SpecificEnthalpy h_vapor_ReferenceMoistAir
+    "Specific enthalpy of vaporous water calculated for T_vapor and p_vapor";
+
+  Modelica.Units.SI.SpecificEnthalpy h_water
+    "Specific enthalpy of whole water";
+  Modelica.Units.SI.SpecificEnthalpy h_solidLiquid_water
+    "Specific enthalpy of solid or liquid water";
+  Modelica.Units.SI.SpecificEnthalpy h_vapor_water
+    "Specific enthalpy of vaporous water";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.MassFraction X_water
+    "Mass fraction of water";
+  Modelica.Units.SI.MassFraction X_dryAir
+    "Mass fraction of dry air (i.e., without water)";
+
+  Medium.ThermodynamicState state_pdp
+    "Thermodynamic state: p + dp";
+  Medium.ThermodynamicState state_mdp
+    "Thermodynamic state: p - dp";
+
+  Medium.ThermodynamicState state_pdT
+    "Thermodynamic state: T + dT";
+  Medium.ThermodynamicState state_mdT
+    "Thermodynamic state: T - dT";
+
+  //
+  // Definitio of parameters correcting reference states
+  //
+  parameter Modelica.Units.SI.SpecificEnthalpy dh_MoistAir=
+    Medium.specificEnthalpy(
+      state=Medium.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X=Medium.reference_X,
+        Y=Medium.massToMoleFractions(X=Medium.reference_X, MMX=Medium.MMX))) -
+    MediumMoistAir.specificEnthalpy(
+      state=MediumMoistAir.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X={Medium.reference_X[Medium.nX],1-Medium.reference_X[Medium.nX]}))
+    "Difference of reference points: Ideal gas-vapor mixture";
+  parameter Modelica.Units.SI.SpecificEnthalpy dh_ReferenceMoistAir=
+    Medium.specificEnthalpy(
+      state=Medium.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X=Medium.reference_X,
+        Y=Medium.massToMoleFractions(X=Medium.reference_X, MMX=Medium.MMX))) -
+    MediumReferenceMoistAir.specificEnthalpy(
+      state=MediumReferenceMoistAir.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X={Medium.reference_X[Medium.nX],1-Medium.reference_X[Medium.nX]}))
+    "Difference of reference points: Ideal gas-vapor mixture";
+
+  parameter Modelica.Units.SI.SpecificEntropy ds_MoistAir=
+    Medium.specificEntropy(
+      state=Medium.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X=Medium.reference_X,
+        Y=Medium.massToMoleFractions(X=Medium.reference_X, MMX=Medium.MMX))) -
+    MediumMoistAir.specificEntropy(
+      state=MediumMoistAir.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X={Medium.reference_X[Medium.nX],1-Medium.reference_X[Medium.nX]}))
+    "Difference of reference points: Ideal gas-vapor mixture";
+  parameter Modelica.Units.SI.SpecificEntropy ds_ReferenceMoistAir=
+    Medium.specificEntropy(
+      state=Medium.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X=Medium.reference_X,
+        Y=Medium.massToMoleFractions(X=Medium.reference_X, MMX=Medium.MMX))) -
+    MediumReferenceMoistAir.specificEntropy(
+      state=MediumReferenceMoistAir.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X={Medium.reference_X[Medium.nX],1-Medium.reference_X[Medium.nX]}))
+    "Difference of reference points: Ideal gas-vapor mixture";
+
+  parameter Modelica.Units.SI.SpecificEnthalpy dh_dryAir_MoistAir=
+    Medium.enthalpyOfNonCondensingGas(
+      T=Medium.T_water_ref,
+      X=Medium.reference_X) -
+    MediumMoistAir.enthalpyOfNonCondensingGas(
+      T=Medium.T_water_ref)
+    "Difference of reference points: Ideal gas mixture of dry gas";
+  parameter Modelica.Units.SI.SpecificEnthalpy dh_dryAir_ReferenceMoistAir=
+    Medium.enthalpyOfNonCondensingGas(
+      T=Medium.T_water_ref,
+      X=Medium.reference_X) -
+    MediumReferenceMoistAir.enthalpyOfNonCondensingGas(
+      state=MediumReferenceMoistAir.ThermodynamicState(
+        p=Medium.p_water_ref,
+        T=Medium.T_water_ref,
+        X={Medium.reference_X[Medium.nX],1-Medium.reference_X[Medium.nX]}))
+    "Difference of reference points: Ideal gas mixture of dry gas";
+
+equation
+  //
+  // Change independent state variables
+  //
+  der(p) = (90e5 - 150) / 20
+    "Predescribed slope of pressure";
+  der(p_solid) = (90e5 - 5) / 20
+    "Predescribed slope of pressure used to check solid properties";
+  der(p_liquid) = (90e5 - 612) / 20
+    "Predescribed slope of pressure used to check liquid properties";
+  der(p_vapor) = (90e5 - 150) / 20
+    "Predescribed slope of pressure used to check vaporous properties";
+
+  der(T) = (563.15 - 223.15) / 20
+    "Predescribed slope of temperature";
+  der(T_solid) = (273.16 - 50) / 20
+    "Predescribed slope of temperature used to check solid properties";
+  der(T_liquid) = (573.15 - 273.16) / 20
+    "Predescribed slope of temperature used to check liquid properties";
+  der(T_vapor) = (1000 - 200) / 20
+    "Predescribed slope of temperature used to check vapor properties";
+
+  X_water = 0.5 + 0.5 * Modelica.Math.sin(2*Modelica.Constants.pi * 1/5 * time)
+    "Mass fraction of water";
+  X_dryAir = 1 - X_water
+    "Mass fraction of dry air (i.e., without water)";
+
+  X = cat(
+    1,
+    Medium.reference_X[1:end-1] ./ sum(Medium.reference_X[1:end-1]) * X_dryAir,
+    {X_water})
+    "Mass fractions";
+  X_MoistAir =  {X_water, X_dryAir}
+    "Mass fractions";
+  X_ReferenceMoistAir = {X_water, X_dryAir}
+    "Mass fractions";
+
+  x = Medium.moistAirToDryAirMassFractions(X=X)
+    "Mass fractions per dry air mass";
+  X_from_x = Medium.dryAirToMoistAirMassFractions(x=x)
+    "Mass fractions per moist air mass calculated from x";
+  X_from_xDryAirPhi =
+    Medium.massFractions_pTxDryPhi(p=p, T=T, x=x[1:end-1], phi=medium_pTX.phi)
+    "Mass fractions per moist air mass calculated from x of dry air components 
+    and phi";
+
+  //
+  // Calculate state variables
+  //
+  state_pdp = Medium.setState_pTX(p=p+dp, T=T, X=X)
+    "Thermodynamic state: p + dp";
+  state_mdp = Medium.setState_pTX(p=p-dp, T=T, X=X)
+    "Thermodynamic state: p - dp";
+
+  state_pdT = Medium.setState_pTX(p=p, T=T+dT, X=X)
+    "Thermodynamic state: T + dT";
+  state_mdT = Medium.setState_pTX(p=p, T=T-dT, X=X)
+    "Thermodynamic state: T - dT";
+
+  state_pTX = Medium.setState_pTX(p=p, T=T, X=X)
+    "State properties calculated with pressure, temperature, and composition";
+  state_phX = Medium.setState_phX(p=p, h=medium_pTX.h, X=X)
+    "State properties calculated with pressure, specific enthalpy, and composition";
+  state_psX = Medium.setState_psX(p=p, s=s, X=X)
+    "State properties calculated with pressure, specific entropy, and composition";
+  state_dTX = Medium.setState_dTX(d=medium_pTX.d, T=T, X=X)
+    "State properties calculated with density, temperature, and composition";
+
+  medium_pTX.p = p
+    "Base properties calculated with pressure and temperature";
+  medium_pTX.T = T
+    "Base properties calculated with pressure and temperature";
+  medium_pTX.X[1:end-1] = X[1:end-1]
+    "Base properties calculated with pressure and temperature";
+
+  mediumMoistAir_pTX.p = p
+    "Base properties calculated with pressure and temperature";
+  mediumMoistAir_pTX.T = T
+    "Base properties calculated with pressure and temperature";
+  mediumMoistAir_pTX.X[1] = X_MoistAir[1]
+    "Base properties calculated with pressure and temperature";
+
+  mediumReferenceMoistAir_pTX.p = p
+    "Base properties calculated with pressure and temperature";
+  mediumReferenceMoistAir_pTX.T = T
+    "Base properties calculated with pressure and temperature";
+  mediumReferenceMoistAir_pTX.X[1] = X_ReferenceMoistAir[1]
+    "Base properties calculated with pressure and temperature";
+
+  x_sat =
+    Medium.dryMassFractionSaturation(state=medium_pTX.state)
+    "Saturation uptake per unit of dry air";
+  x_sat_MoistAir =
+    MediumMoistAir.xsaturation(state=mediumMoistAir_pTX.state)
+    "Saturation uptake per unit of dry air";
+  x_sat_ReferenceMoistAir=
+    MediumReferenceMoistAir.xsaturation(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Saturation uptake per unit of dry air";
+
+  X_sat =
+    Medium.massFractionSaturation(state=medium_pTX.state)
+    "Saturation uptake per unit of moist air";
+  X_sat_MoistAir =
+    MediumMoistAir.Xsaturation(state=mediumMoistAir_pTX.state)
+    "Saturation uptake per unit of moist air";
+  X_sat_ReferenceMoistAir=
+    MediumReferenceMoistAir.Xsaturation(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Saturation uptake per unit of moist air";
+
+  h_1 =
+    Medium.specificEnthalpy_i(ind_component=1, state=medium_pTX.state)
+    "Specific enthalpy of component 1";
+  h_last =
+    Medium.specificEnthalpy_i(ind_component=Medium.nX, state=medium_pTX.state)
+    "Specific enthalpy of last component";
+
+  s =
+    Medium.specificEntropy(state=medium_pTX.state)
+    "Specific entropy";
+  s_1 =
+    Medium.specificEntropy_i(ind_component=1, state=medium_pTX.state)
+    "Specific entropy of component 1";
+  s_last =
+    Medium.specificEntropy_i(ind_component=Medium.nX, state=medium_pTX.state)
+    "Specific entropy of last component";
+  s_MoistAir =
+    MediumMoistAir.specificEntropy(state=mediumMoistAir_pTX.state) +
+    ds_MoistAir
+    "Specific entropy";
+  s_ReferenceMoistAir =
+    MediumReferenceMoistAir.specificEntropy(
+      state=mediumReferenceMoistAir_pTX.state) +
+    ds_ReferenceMoistAir
+    "Specific entropy";
+
+  //
+  // Calculate further properties
+  //
+  p_i = Medium.partialPressures(state=medium_pTX.state)
+    "Partial pressures";
+  p_water_ReferenceMoistAir = MediumReferenceMoistAir.Utilities.pd_pTX(
+    p=mediumReferenceMoistAir_pTX.state.p,
+    T=mediumReferenceMoistAir_pTX.state.T,
+    X=mediumReferenceMoistAir_pTX.state.X)
+    "Partial pressure of water";
+
+  eta =
+    Medium.dynamicViscosity(state=medium_pTX.state)
+    "Dynamic viscosity";
+  eta_MoistAir =
+    MediumMoistAir.dynamicViscosity(state=mediumMoistAir_pTX.state)
+    "Dynamic viscosity";
+  eta_ReferenceMoistAir =
+    MediumReferenceMoistAir.dynamicViscosity(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Dynamic viscosity";
+
+  lambda =
+    Medium.thermalConductivity(state=medium_pTX.state)
+    "Thermal conductivity";
+  lambda_MoistAir =
+    MediumMoistAir.thermalConductivity(state=mediumMoistAir_pTX.state)
+    "Thermal conductivity";
+  lambda_ReferenceMoistAir =
+    MediumReferenceMoistAir.thermalConductivity(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Thermal conductivity";
+
+  cp =
+    Medium.specificHeatCapacityCp(state=medium_pTX.state)
+    "Specific heat capacity";
+  cp_MoistAir =
+    MediumMoistAir.specificHeatCapacityCp(state=mediumMoistAir_pTX.state)
+    "Specific heat capacity";
+  cp_ReferenceMoistAir =
+    MediumReferenceMoistAir.specificHeatCapacityCp(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Specific heat capacity";
+
+  cv =
+    Medium.specificHeatCapacityCv(state=medium_pTX.state)
+    "Specific heat capacity";
+  cv_MoistAir =
+    MediumMoistAir.specificHeatCapacityCv(state=mediumMoistAir_pTX.state)
+    "Specific heat capacity";
+  cv_ReferenceMoistAir =
+    MediumReferenceMoistAir.specificHeatCapacityCv(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Specific heat capacity";
+
+  gamma =
+    Medium.isentropicExponent(state=medium_pTX.state)
+    "Isentropic coefficient";
+  gamma_MoistAir=
+    MediumMoistAir.isentropicExponent(state=mediumMoistAir_pTX.state)
+    "Isentropic coefficient";
+  gamma_ReferenceMoistAir=
+    MediumReferenceMoistAir.isentropicExponent(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Isentropic coefficient";
+
+  h_is =
+    Medium.isentropicEnthalpy(
+      p_downstream=p, refState=medium_pTX.state)
+    "Isentropic specific enthalpy";
+  h_is_MoistAir =
+    MediumMoistAir.isentropicEnthalpy(
+      p_downstream=p, refState=mediumMoistAir_pTX.state) +
+    dh_MoistAir
+    "Isentropic specific enthalpy";
+  h_is_ReferenceMoistAir =
+    MediumReferenceMoistAir.isentropicEnthalpy(
+      p_downstream=p, refState=mediumReferenceMoistAir_pTX.state)+
+    dh_ReferenceMoistAir
+    "Isentropic specific enthalpy";
+
+  w_is =
+    Medium.velocityOfSound(
+      state=medium_pTX.state)
+    "Velocity of sound";
+  w_is_MoistAir =
+    MediumMoistAir.velocityOfSound(
+      state=mediumMoistAir_pTX.state)
+    "Velocity of sound";
+  w_is_ReferenceMoistAir =
+    MediumReferenceMoistAir.velocityOfSound(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Velocity of sound";
+
+  beta =
+    Medium.beta(state=medium_pTX.state)
+    "Isobaric expansion coefficient";
+  beta_MoistAir =
+    MediumMoistAir.beta(state=mediumMoistAir_pTX.state)
+    "Isobaric expansion coefficient";
+
+  kappa =
+    Medium.kappa(state=medium_pTX.state)
+    "Isothermal compressibility";
+  kappa_MoistAir =
+    MediumMoistAir.kappa(state=mediumMoistAir_pTX.state)
+    "Isothermal compressibility";
+
+  h_dryAir =
+    Medium.enthalpyOfNonCondensingGas(
+      T=T_vapor,
+      X=X)
+    "Specific enthalpy of non-condensing components calculated for T_vapor";
+  h_dryAir_MoistAir =
+    MediumMoistAir.enthalpyOfNonCondensingGas(T=T_vapor) +
+    dh_dryAir_MoistAir
+    "Specific enthalpy of liquid water calculated for T_vapor";
+  h_dryAir_ReferenceMoistAir =
+    MediumReferenceMoistAir.enthalpyOfNonCondensingGas(
+      state=MediumReferenceMoistAir.ThermodynamicState(
+        p=p_vapor,
+        T=T_vapor,
+        X=X_ReferenceMoistAir)) +
+    dh_dryAir_ReferenceMoistAir
+    "Specific enthalpy of non-condensing components calculated for T_vapor and 
+    p_vapor";
+
+  h_dryAirVapor =
+    Medium.enthalpyOfGas(state=medium_pTX.state)
+    "Specific enthalpy of non-condensing components and vapor";
+  h_dryAirVapor_MoistAir =
+    MediumMoistAir.enthalpyOfGas(
+      T=T,
+      X=X_MoistAir) +
+    dh_MoistAir
+    "Specific enthalpy of non-condensing components and vapor";
+  h_dryAirVapor_ReferenceMoistAir =
+    MediumReferenceMoistAir.enthalpyOfGas(
+      state=mediumReferenceMoistAir_pTX.state) /
+    (1 + X_ReferenceMoistAir[1] / (1 - X_ReferenceMoistAir[1])) +
+    dh_ReferenceMoistAir
+    "Specific enthalpy of non-condensing components and vapor";
+
+  //
+  // Calculate partial derivatives
+  //
+  dv_dp_TX = Medium.dv_dp_TX(state=medium_pTX.state)
+    "Partial derivative of specific volume w.r.t. pressure at constant
+    temperature and mass fractions";
+  dv_dp_TX_num = -1/medium_pTX.d^2 *
+    ((Medium.density(state=state_pdp) -
+    Medium.density(state=state_mdp)) / (2*dp))
+    "Partial derivative of specific volume w.r.t. pressure at constant
+    temperature and mass fractions calculated numerically";
+
+  dv_dT_pX = Medium.dv_dT_pX(state=medium_pTX.state)
+    "Partial derivative of specific volume w.r.t. temperature  at constant
+    pressure and mass fractions";
+  dv_dT_pX_num = -1/medium_pTX.d^2 *
+    ((Medium.density(state=state_pdT) -
+    Medium.density(state=state_mdT)) / (2*dT))
+    "Partial derivative of specific volume w.r.t. temperature  at constant
+    pressure and mass fractions calculated numerically";
+
+  dv_dX_pT = Medium.dv_dX_pT(state=medium_pTX.state)
+    "Partial derivatives of specific volume w.r.t. mass fractions at constant
+    pressure and temperature";
+  for ind in 1:Medium.nX loop
+    dv_dX_pT_num[ind] = -1/medium_pTX.d^2 *
+      ((Medium.density(
+        state=Medium.setState_pTX(
+          p=p,
+          T=T,
+          X=cat(1,
+            X[1:ind-1],
+            {X[ind] + dX},
+            X[ind+1:Medium.nX]))) -
+      Medium.density(
+        state=Medium.setState_pTX(
+          p=p,
+          T=T,
+          X=cat(1,
+            X[1:ind-1],
+            {X[ind] - dX},
+            X[ind+1:Medium.nX])))) / (2*dX))
+    "Partial derivatives of specific volume w.r.t. mass fractions  at constant
+    pressure and temperature calculated numerically";
+  end for;
+
+  dh_dp_TX = Medium.dh_dp_TX(state=medium_pTX.state)
+    "Partial derivative of specific enthalpy w.r.t. pressure at constant
+    temperature and mass fractions";
+  dh_dp_TX_num = (Medium.specificEnthalpy(state=state_pdp) -
+    Medium.specificEnthalpy(state=state_mdp)) / (2*dp)
+    "Partial derivative of specific enthalpy w.r.t. pressure at constant
+    temperature and mass fractions calculated numerically";
+
+  dh_dT_pX = Medium.dh_dT_pX(state=medium_pTX.state)
+    "Partial derivative of specific enthalpy w.r.t. temperature at constant
+    pressure and mass fractions";
+  dh_dT_pX_num = (Medium.specificEnthalpy(state=state_pdT) -
+    Medium.specificEnthalpy(state=state_mdT)) / (2*dT)
+    "Partial derivative of specific enthalpy w.r.t. temperature at constant
+    pressure and mass fractions calculated numerically";
+
+  dh_dX_pT = Medium.dh_dX_pT(state=medium_pTX.state)
+  "Partial derivative of specific enthalpy w.r.t. mass fractions at constant
+  pressure and temperature";
+  for ind in 1:Medium.nX loop
+    dh_dX_pT_num[ind] =
+      (Medium.specificEnthalpy(
+        state=Medium.setState_pTX(
+          p=p,
+          T=T,
+          X=cat(1,
+            X[1:ind-1],
+            {X[ind] + dX},
+            X[ind+1:Medium.nX]))) -
+      Medium.specificEnthalpy(
+        state=Medium.setState_pTX(
+          p=p,
+          T=T,
+          X=cat(1,
+            X[1:ind-1],
+            {X[ind] - dX},
+            X[ind+1:Medium.nX]))))/ (2*dX)
+    "Partial derivative of specific enthalpy w.r.t. mass fractions at constant
+    pressure and temperature calculated numerically";
+  end for;
+
+  drho_dp_hX =
+    Medium.density_derp_h(state=medium_pTX.state)
+    "Partial derivative of density w.r.t. pressure at constant specific enthalpy
+    and mass fractions";
+  drho_dp_hX_MoistAir =
+    MediumMoistAir.density_derp_h(state=mediumMoistAir_pTX.state)
+    "Partial derivative of density w.r.t. pressure at constant specific enthalpy
+    and mass fractions";
+
+  drho_dh_pX =
+    Medium.density_derh_p(state=medium_pTX.state)
+    "Partial derivative of density w.r.t. specific enthalpy at constant pressure
+    and mass fractions";
+  drho_dh_pX_MoistAir =
+    MediumMoistAir.density_derh_p(state=mediumMoistAir_pTX.state)
+    "Partial derivative of density w.r.t. specific enthalpy at constant pressure
+    and mass fractions";
+
+  drho_dX_ph = Medium.drho_dX_ph(state=medium_pTX.state)
+    "Partial derivative of density w.r.t. mass fractions at constant pressure
+    and specific enthalpy";
+  for ind in 1:Medium.nX loop
+    drho_dX_ph_num[ind] =
+      ((Medium.density(
+        state=Medium.setState_phX(
+          p=p,
+          h=medium_pTX.h,
+          X=cat(1,
+            X[1:ind-1],
+            {X[ind] + dX},
+            X[ind+1:Medium.nX]))) -
+      Medium.density(
+        state=Medium.setState_phX(
+          p=p,
+          h=medium_pTX.h,
+          X=cat(1,
+            X[1:ind-1],
+            {X[ind] - dX},
+            X[ind+1:Medium.nX])))) / (2*dX))
+      "Partial derivative of density w.r.t. mass fractions at constant pressure
+      and specific enthalpy calculated numerically";
+  end for;
+
+  drho_dp_TX =
+    Medium.density_derp_T(state=medium_pTX.state)
+    "Partial derivative of density w.r.t. pressure at constant temperature and
+    mass fractions";
+  drho_dp_TX_MoistAir =
+    MediumMoistAir.density_derp_T(state=mediumMoistAir_pTX.state)
+    "Partial derivative of density w.r.t. pressure at constant temperature and
+    mass fractions";
+
+  drho_dT_pX =
+    Medium.density_derT_p(state=medium_pTX.state)
+    "Partial derivative of density w.r.t. pressure at constant temperature and
+    mass fractions";
+  drho_dT_pX_MoistAir=
+    MediumMoistAir.density_derT_p(state=mediumMoistAir_pTX.state)
+    "Partial derivative of density w.r.t. pressure at constant temperature and
+    mass fractions";
+
+  drho_dX_pT =
+    Medium.density_derX(state=medium_pTX.state)
+    "Partial derivative of density w.r.t. mass fractions at constant pressure
+    and temperature";
+  for ind in 1:Medium.nX loop
+    drho_dX_pT_num[ind] =
+      ((Medium.density(
+        state=Medium.setState_pTX(
+          p=p,
+          T=T,
+          X=cat(1,
+            X[1:ind-1],
+            {X[ind] + dX},
+            X[ind+1:Medium.nX]))) -
+      Medium.density(
+        state=Medium.setState_pTX(
+          p=p,
+          T=T,
+          X=cat(1,
+            X[1:ind-1],
+            {X[ind] - dX},
+            X[ind+1:Medium.nX])))) / (2*dX))
+    "Partial derivatives of density w.r.t. mass fractions at constant
+    pressure and temperature calculated numerically";
+  end for;
+
+  //
+  // Calculate properties regarding condensing component
+  //
+  p_sat =
+    Medium.saturationPressure(Tsat=T)
+    "Saturation pressure of water";
+  p_sat_MoistAir =
+    MediumMoistAir.saturationPressure(Tsat=T)
+    "Saturation pressure of water";
+  p_sat_ReferenceMoistAir=
+    MediumReferenceMoistAir.saturationPressure(
+      state=mediumReferenceMoistAir_pTX.state)
+    "Saturation pressure of water";
+
+  T_sat_p_sat =
+    Medium.saturationTemperature(p_sat=p_sat)
+    "Saturation temperature of water at saturation pressure of water";
+
+  c_solid =
+    Medium.specificHeatCapacitySolid(state=Medium.ThermodynamicState(
+      p=p_solid,
+      T=T_solid,
+      X=medium_pTX.state.X,
+      Y=medium_pTX.state.Y))
+    "Specific heat capacity of solid calculated for T_solid and p_solid";
+  c_liquid =
+    Medium.specificHeatCapacityLiquid(state=Medium.ThermodynamicState(
+      p=p_liquid,
+      T=T_liquid,
+      X=medium_pTX.state.X,
+      Y=medium_pTX.state.Y))
+    "Specific heat capacity of liquid calculated for T_liquid and p_liquid";
+  cp_vapor =
+    Medium.specificHeatCapacityVapor(state=Medium.ThermodynamicState(
+      p=p_vapor,
+      T=T_vapor,
+      X=medium_pTX.state.X,
+      Y=medium_pTX.state.Y))
+    "Specific heat capacity of vapor calculated for T_vapor and p_vapor";
+
+  dh_vap =
+    Medium.enthalpyOfVaporization(T=T_liquid)
+    "Specific enthalpy of vaporization calculated for T_liquid";
+  dh_vap_MoistAir =
+    MediumMoistAir.enthalpyOfVaporization(T=T_liquid)
+    "Specific enthalpy of vaporization calculated for T_liquid";
+  dh_vap_ReferenceMoistAir=
+    MediumReferenceMoistAir.enthalpyOfVaporization(
+      state=MediumReferenceMoistAir.ThermodynamicState(
+        p=p_liquid,
+        T=T_liquid,
+        X=X_ReferenceMoistAir))
+    "Specific enthalpy of vaporization calculated for T_liquid and p_liquid";
+
+  h_solid =
+    Medium.enthalpyOfSolid(
+      p=p_solid,
+      T=T_solid)
+    "Specific enthalpy of solid water calculated for T_solid and p_solid";
+  h_solid_MoistAir =
+    MediumMoistAir.enthalpyOfWater(T=T_solid)
+    "Specific enthalpy of solid water calculated for T_solid";
+  h_solid_ReferenceMoistAir =
+    MediumReferenceMoistAir.Utilities.Ice09_Utilities.h_pT(
+      p=p_solid,
+      T=T_solid)
+    "Specific enthalpy of solid water calculated for T_solid and p_solid";
+
+  h_liquid =
+    Medium.enthalpyOfLiquid(
+      p=p_liquid,
+      T=T_liquid)
+    "Specific enthalpy of liquid water calculated for T_liquid and p_liquid";
+  h_liquid_MoistAir =
+    MediumMoistAir.enthalpyOfWater(T=T_liquid)
+    "Specific enthalpy of liquid water calculated for T_liquid";
+  h_liquid_ReferenceMoistAir=
+    Modelica.Media.Water.IF97_Utilities.h_pT(
+      p=p_liquid,
+      T=T_liquid,
+      region=1)
+    "Specific enthalpy of liquid water calculated for T_liquid and p_liquid";
+
+  h_vapor =
+    Medium.enthalpyOfCondensingGas(T=T_vapor)
+    "Specific enthalpy of vaporous water calculated for T_vapor";
+  h_vapor_MoistAir =
+    MediumMoistAir.enthalpyOfCondensingGas(T=T_vapor)
+    "Specific enthalpy of vaporous water calculated for T_vapor";
+  h_vapor_ReferenceMoistAir=
+    MediumReferenceMoistAir.enthalpyOfCondensingGas(
+      state=MediumReferenceMoistAir.ThermodynamicState(
+        p=p_vapor,
+        T=T_vapor,
+        X=X_ReferenceMoistAir)) /
+    (X_ReferenceMoistAir[1] / (1 - X_ReferenceMoistAir[1]))
+    "Specific enthalpy of vaporous water calculated for T_vapor and p_vapor";
+
+  h_water =
+    Medium.enthalpyOfCondensingComponent(state=medium_pTX.state)
+    "Specific enthalpy of whole water";
+  h_solidLiquid_water =
+    Medium.enthalpyOfLiquidIce(state=medium_pTX.state)
+    "Specific enthalpy of solid or liquid water";
+  h_vapor_water =
+    Medium.enthalpyOfVapor(state=medium_pTX.state)
+    "Specific enthalpy of vaporous water";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal gas-vapor mixture
+of N<sub>2</sub>, O<sub>2</sub>, Ar, and H<sub>2</sub>O.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 28, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_MoistAir_N2_O2_Ar_H2O;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Tester/Test_MoistAir_N2_O2_CO2_H2O.mo b/SorpLib/Media/IdealGasVaporMixtures/Tester/Test_MoistAir_N2_O2_CO2_H2O.mo
new file mode 100644
index 0000000..031ab1c
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Tester/Test_MoistAir_N2_O2_CO2_H2O.mo
@@ -0,0 +1,28 @@
+within SorpLib.Media.IdealGasVaporMixtures.Tester;
+model Test_MoistAir_N2_O2_CO2_H2O
+  "Tester for moist air consisting of N2, O2, CO2, and H2O"
+  extends SorpLib.Media.IdealGasVaporMixtures.Tester.Test_MoistAir_N2_O2_Ar_H2O(
+    redeclare package Medium =
+      SorpLib.Media.IdealGasVaporMixtures.MoistAir_N2_O2_CO2_H2O(s_dryAir_off=-6625));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal gas-vapor mixture
+of N<sub>2</sub>, O<sub>2</sub>, CO<sub>2</sub>, and H<sub>2</sub>O.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 28, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_MoistAir_N2_O2_CO2_H2O;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Tester/package.mo b/SorpLib/Media/IdealGasVaporMixtures/Tester/package.mo
new file mode 100644
index 0000000..cde30da
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.IdealGasVaporMixtures;
+package Tester "Package containing testers to test and varify models calculating fluid property data of ideal gas mixtures"
+  extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented fluid
+property models of ideal gas-vapor mixtures. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/Tester/package.order b/SorpLib/Media/IdealGasVaporMixtures/Tester/package.order
new file mode 100644
index 0000000..cea5a47
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/Tester/package.order
@@ -0,0 +1,2 @@
+Test_MoistAir_N2_O2_Ar_H2O
+Test_MoistAir_N2_O2_CO2_H2O
diff --git a/SorpLib/Media/IdealGasVaporMixtures/package.mo b/SorpLib/Media/IdealGasVaporMixtures/package.mo
new file mode 100644
index 0000000..69100d1
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media;
+package IdealGasVaporMixtures "Package containing medium models of ideal gas-vapor mixtures"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models of ideal gas-vapor mixtures. These models are based
+on the Modelica Standard Library but extended by new functions required in
+SorpLib. Note that the reference temperature must be 0 K and the reference 
+enthalpy and entropy must be 0 J/kg and 0 J/(Kg.K) for functions taken for the
+Modelica Standard Library (i.e., mixture properties calculated using the medium
+package
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.MixtureGasNasa\">Modelica.Media.IdealGases.Common.MixtureGasNasa</a>).
+Otherwise, absolute values caloric and entropic properties may not be correctly 
+calculated.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IdealGasVaporMixtures;
diff --git a/SorpLib/Media/IdealGasVaporMixtures/package.order b/SorpLib/Media/IdealGasVaporMixtures/package.order
new file mode 100644
index 0000000..73e1adb
--- /dev/null
+++ b/SorpLib/Media/IdealGasVaporMixtures/package.order
@@ -0,0 +1,4 @@
+Interfaces
+MoistAir_N2_O2_Ar_H2O
+MoistAir_N2_O2_CO2_H2O
+Tester
diff --git a/SorpLib/Media/IdealGases/Ar/package.mo b/SorpLib/Media/IdealGases/Ar/package.mo
new file mode 100644
index 0000000..5ac2307
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Ar/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media.IdealGases;
+package Ar "SorpLib: Ideal gas Ar from NASA Glenn coefficients"
+  extends Modelica.Media.IdealGases.SingleGases.Ar(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5,
+    final reference_X=fill(1/nX, nX));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This medium model calculates fluid property data of Ar. For details,
+check the package
+<a href=\"Modelica://Modelica.Media.IdealGases.SingleGases.Ar\">Modelica.Media.IdealGases.SingleGases.Ar</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Ar;
diff --git a/SorpLib/Media/IdealGases/Ar/package.order b/SorpLib/Media/IdealGases/Ar/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGases/CH4/package.mo b/SorpLib/Media/IdealGases/CH4/package.mo
new file mode 100644
index 0000000..708b99a
--- /dev/null
+++ b/SorpLib/Media/IdealGases/CH4/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media.IdealGases;
+package CH4 "SorpLib: Ideal gas CH4 from NASA Glenn coefficients"
+  extends Modelica.Media.IdealGases.SingleGases.CH4(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5,
+    final reference_X=fill(1/nX, nX));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This medium model calculates fluid property data of CH<sub>4</sub>. For details,
+check the package
+<a href=\"Modelica://Modelica.Media.IdealGases.SingleGases.CH4\">Modelica.Media.IdealGases.SingleGases.CH4</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CH4;
diff --git a/SorpLib/Media/IdealGases/CH4/package.order b/SorpLib/Media/IdealGases/CH4/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGases/CO2/package.mo b/SorpLib/Media/IdealGases/CO2/package.mo
new file mode 100644
index 0000000..e89f37f
--- /dev/null
+++ b/SorpLib/Media/IdealGases/CO2/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media.IdealGases;
+package CO2 "SorpLib: Ideal gas CO2 from NASA Glenn coefficients"
+  extends Modelica.Media.IdealGases.SingleGases.CO2(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5,
+    final reference_X=fill(1/nX, nX));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This medium model calculates fluid property data of CO<sub>2</sub>. For details,
+check the package
+<a href=\"Modelica://Modelica.Media.IdealGases.SingleGases.CO2\">Modelica.Media.IdealGases.SingleGases.CO2</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CO2;
diff --git a/SorpLib/Media/IdealGases/CO2/package.order b/SorpLib/Media/IdealGases/CO2/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGases/H2O/package.mo b/SorpLib/Media/IdealGases/H2O/package.mo
new file mode 100644
index 0000000..c938d9b
--- /dev/null
+++ b/SorpLib/Media/IdealGases/H2O/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media.IdealGases;
+package H2O "SorpLib: Ideal gas H2O from NASA Glenn coefficients"
+  extends Modelica.Media.IdealGases.SingleGases.H2O(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5,
+    final reference_X=fill(1/nX, nX));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This medium model calculates fluid property data of H<sub>2</sub>O. For details,
+check the package
+<a href=\"Modelica://Modelica.Media.IdealGases.SingleGases.H2O\">Modelica.Media.IdealGases.SingleGases.H2O</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end H2O;
diff --git a/SorpLib/Media/IdealGases/H2O/package.order b/SorpLib/Media/IdealGases/H2O/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGases/He/package.mo b/SorpLib/Media/IdealGases/He/package.mo
new file mode 100644
index 0000000..e6e8132
--- /dev/null
+++ b/SorpLib/Media/IdealGases/He/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media.IdealGases;
+package He "SorpLib: Ideal gas He from NASA Glenn coefficients"
+  extends Modelica.Media.IdealGases.SingleGases.He(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5,
+    final reference_X=fill(1/nX, nX));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This medium model calculates fluid property data of He. For details,
+check the package
+<a href=\"Modelica://Modelica.Media.IdealGases.SingleGases.He\">Modelica.Media.IdealGases.SingleGases.He</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end He;
diff --git a/SorpLib/Media/IdealGases/He/package.order b/SorpLib/Media/IdealGases/He/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGases/N2/package.mo b/SorpLib/Media/IdealGases/N2/package.mo
new file mode 100644
index 0000000..cfd6d0a
--- /dev/null
+++ b/SorpLib/Media/IdealGases/N2/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media.IdealGases;
+package N2 "SorpLib: Ideal gas N2 from NASA Glenn coefficients"
+  extends Modelica.Media.IdealGases.SingleGases.N2(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5,
+    final reference_X=fill(1/nX, nX));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This medium model calculates fluid property data of N<sub>2</sub>. For details,
+check the package
+<a href=\"Modelica://Modelica.Media.IdealGases.SingleGases.N2\">Modelica.Media.IdealGases.SingleGases.N2</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end N2;
diff --git a/SorpLib/Media/IdealGases/N2/package.order b/SorpLib/Media/IdealGases/N2/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGases/Ne/package.mo b/SorpLib/Media/IdealGases/Ne/package.mo
new file mode 100644
index 0000000..f9782af
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Ne/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media.IdealGases;
+package Ne "SorpLib: Ideal gas Ne from NASA Glenn coefficients"
+  extends Modelica.Media.IdealGases.SingleGases.Ne(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5,
+    final reference_X=fill(1/nX, nX));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This medium model calculates fluid property data of Ne. For details,
+check the package
+<a href=\"Modelica://Modelica.Media.IdealGases.SingleGases.Ne\">Modelica.Media.IdealGases.SingleGases.Ne</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Ne;
diff --git a/SorpLib/Media/IdealGases/Ne/package.order b/SorpLib/Media/IdealGases/Ne/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGases/O2/package.mo b/SorpLib/Media/IdealGases/O2/package.mo
new file mode 100644
index 0000000..a5a1cfd
--- /dev/null
+++ b/SorpLib/Media/IdealGases/O2/package.mo
@@ -0,0 +1,25 @@
+within SorpLib.Media.IdealGases;
+package O2 "SorpLib: Ideal gas O2 from NASA Glenn coefficients"
+  extends Modelica.Media.IdealGases.SingleGases.O2(
+    final reference_T(min=0) = 0,
+    final reference_p = 1e5,
+    final reference_X=fill(1/nX, nX));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This medium model calculates fluid property data of O<sub>2</sub>. For details,
+check the package
+<a href=\"Modelica://Modelica.Media.IdealGases.SingleGases.O2\">Modelica.Media.IdealGases.SingleGases.O2</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end O2;
diff --git a/SorpLib/Media/IdealGases/O2/package.order b/SorpLib/Media/IdealGases/O2/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/IdealGases/Tester/Test_Ar.mo b/SorpLib/Media/IdealGases/Tester/Test_Ar.mo
new file mode 100644
index 0000000..4a37d5a
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/Test_Ar.mo
@@ -0,0 +1,90 @@
+within SorpLib.Media.IdealGases.Tester;
+model Test_Ar "Tester for ideal gas Ar"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of paramters
+  //
+  replaceable package Medium = SorpLib.Media.IdealGases.Ar
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p(start=100, fixed=true)
+    "Pressure";
+  Modelica.Units.SI.Temperature T(start=253.15, fixed=true)
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+  Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy";
+
+  Medium.BaseProperties medium_pT
+    "Base properties calculated with pressure and temperature";
+
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity";
+  Modelica.Units.SI.RelativePressureCoefficient beta
+    "Isobaric expansion coefficient";
+  Modelica.Units.SI.IsothermalCompressibility kappa
+    "Isothermal compressibility";
+
+
+equation
+  //
+  // Change independent state variables
+  //
+  der(p) = (20e5 - 100) / 20
+    "Predescribed slope of pressure";
+  der(T) = (573.15 - 253.15) / 20
+    "Predescribed slope of temperature";
+
+  //
+  // Calculate state variables
+  //
+  medium_pT.p = p
+    "Base properties calculated with pressure and temperature";
+  medium_pT.T = T
+    "Base properties calculated with pressure and temperature";
+
+  //
+  // Calculate further variables
+  //
+  v = 1/medium_pT.d
+    "Specific volume";
+  s = Medium.specificEntropy(state=medium_pT.state)
+    "Specific entropy";
+
+  cp = Medium.specificHeatCapacityCp(state=medium_pT.state)
+    "Specific heat capacity";
+  beta = Medium.beta(state=medium_pT.state)
+    "Isobaric expansion coefficient";
+  kappa = Medium.kappa(state=medium_pT.state)
+    "Isothermal compressibility";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal
+gas Ar.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_Ar;
diff --git a/SorpLib/Media/IdealGases/Tester/Test_CH4.mo b/SorpLib/Media/IdealGases/Tester/Test_CH4.mo
new file mode 100644
index 0000000..682323b
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/Test_CH4.mo
@@ -0,0 +1,26 @@
+within SorpLib.Media.IdealGases.Tester;
+model Test_CH4 "Tester for ideal gas CH4"
+  extends SorpLib.Media.IdealGases.Tester.Test_Ar(
+     redeclare package Medium = SorpLib.Media.IdealGases.CH4);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal
+gas CH<sub>4</sub>.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_CH4;
diff --git a/SorpLib/Media/IdealGases/Tester/Test_CO2.mo b/SorpLib/Media/IdealGases/Tester/Test_CO2.mo
new file mode 100644
index 0000000..db48d0f
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/Test_CO2.mo
@@ -0,0 +1,26 @@
+within SorpLib.Media.IdealGases.Tester;
+model Test_CO2 "Tester for ideal gas CO2"
+  extends SorpLib.Media.IdealGases.Tester.Test_Ar(
+     redeclare package Medium = SorpLib.Media.IdealGases.CO2);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal
+gas CO<sub>2</sub>.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_CO2;
diff --git a/SorpLib/Media/IdealGases/Tester/Test_H2O.mo b/SorpLib/Media/IdealGases/Tester/Test_H2O.mo
new file mode 100644
index 0000000..f4abbf5
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/Test_H2O.mo
@@ -0,0 +1,26 @@
+within SorpLib.Media.IdealGases.Tester;
+model Test_H2O "Tester for ideal gas H2O"
+  extends SorpLib.Media.IdealGases.Tester.Test_Ar(
+     redeclare package Medium = SorpLib.Media.IdealGases.H2O);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal
+gas H<sub>2</sub>O.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_H2O;
diff --git a/SorpLib/Media/IdealGases/Tester/Test_He.mo b/SorpLib/Media/IdealGases/Tester/Test_He.mo
new file mode 100644
index 0000000..e88e334
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/Test_He.mo
@@ -0,0 +1,26 @@
+within SorpLib.Media.IdealGases.Tester;
+model Test_He "Tester for ideal gas He"
+  extends SorpLib.Media.IdealGases.Tester.Test_Ar(
+     redeclare package Medium = SorpLib.Media.IdealGases.He);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal
+gas He.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_He;
diff --git a/SorpLib/Media/IdealGases/Tester/Test_N2.mo b/SorpLib/Media/IdealGases/Tester/Test_N2.mo
new file mode 100644
index 0000000..b95a295
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/Test_N2.mo
@@ -0,0 +1,26 @@
+within SorpLib.Media.IdealGases.Tester;
+model Test_N2 "Tester for ideal gas N2"
+  extends SorpLib.Media.IdealGases.Tester.Test_Ar(
+     redeclare package Medium = SorpLib.Media.IdealGases.N2);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal
+gas N<sub>2</sub>.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_N2;
diff --git a/SorpLib/Media/IdealGases/Tester/Test_Ne.mo b/SorpLib/Media/IdealGases/Tester/Test_Ne.mo
new file mode 100644
index 0000000..eab1014
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/Test_Ne.mo
@@ -0,0 +1,26 @@
+within SorpLib.Media.IdealGases.Tester;
+model Test_Ne "Tester for ideal gas Ne"
+  extends SorpLib.Media.IdealGases.Tester.Test_Ar(
+     redeclare package Medium = SorpLib.Media.IdealGases.Ne);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal
+gas Ne.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_Ne;
diff --git a/SorpLib/Media/IdealGases/Tester/Test_O2.mo b/SorpLib/Media/IdealGases/Tester/Test_O2.mo
new file mode 100644
index 0000000..c995230
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/Test_O2.mo
@@ -0,0 +1,26 @@
+within SorpLib.Media.IdealGases.Tester;
+model Test_O2 "Tester for ideal gas O2"
+  extends SorpLib.Media.IdealGases.Tester.Test_Ar(
+     redeclare package Medium = SorpLib.Media.IdealGases.O2);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StopTime=20, Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model checks the fluid property calculation of the ideal
+gas O<sub>2</sub>.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_O2;
diff --git a/SorpLib/Media/IdealGases/Tester/package.mo b/SorpLib/Media/IdealGases/Tester/package.mo
new file mode 100644
index 0000000..725830b
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.IdealGases;
+package Tester "Package containing testers to test and varify models calculating fluid property data of ideal gases"
+  extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented fluid
+property models of ideal gases. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Media/IdealGases/Tester/package.order b/SorpLib/Media/IdealGases/Tester/package.order
new file mode 100644
index 0000000..1dc8d76
--- /dev/null
+++ b/SorpLib/Media/IdealGases/Tester/package.order
@@ -0,0 +1,8 @@
+Test_Ar
+Test_CO2
+Test_CH4
+Test_H2O
+Test_He
+Test_N2
+Test_Ne
+Test_O2
diff --git a/SorpLib/Media/IdealGases/package.mo b/SorpLib/Media/IdealGases/package.mo
new file mode 100644
index 0000000..fabcf48
--- /dev/null
+++ b/SorpLib/Media/IdealGases/package.mo
@@ -0,0 +1,24 @@
+within SorpLib.Media;
+package IdealGases "Package containing medium models of ideal gases"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models of ideal gases. These models are based on the 
+Modelica Standard Library. Note that the reference temperature must be 0 K
+and the reference enthalpy and entropy must be 0 J/kg and 0 J/(Kg.K). Otherwise,
+absolute values caloric and entropic properties may not be correctly calculated.
+Hence, existing models of ideal gases are implemented in this package again, but
+their reference points are correctly set. For details of the ideal gas models, 
+check the documentation of the package 
+<a href=\"Modelica://Modelica.Media.IdealGases.Common.SingleGasNasa\">Modelica.Media.IdealGases.Common.SingleGasNasa</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IdealGases;
diff --git a/SorpLib/Media/IdealGases/package.order b/SorpLib/Media/IdealGases/package.order
new file mode 100644
index 0000000..1e80c1d
--- /dev/null
+++ b/SorpLib/Media/IdealGases/package.order
@@ -0,0 +1,9 @@
+Ar
+CO2
+CH4
+H2O
+He
+N2
+Ne
+O2
+Tester
diff --git a/SorpLib/Media/Solids/BaseClasses/PartialSolid.mo b/SorpLib/Media/Solids/BaseClasses/PartialSolid.mo
new file mode 100644
index 0000000..45ccecd
--- /dev/null
+++ b/SorpLib/Media/Solids/BaseClasses/PartialSolid.mo
@@ -0,0 +1,844 @@
+within SorpLib.Media.Solids.BaseClasses;
+partial model PartialSolid
+  "Base model for solids"
+  extends Modelica.Icons.MaterialProperty;
+
+  //
+  // Definition of parameters regarding calculation setup
+  //
+  parameter Boolean calcCaloricProperties = false
+    "= true, if caloric properties are calculated (i.e., h and u)"
+    annotation (Dialog(tab="General", group="General"),
+                choices(checkBox=true),
+                Evaluate= true);
+  parameter Boolean calcEntropicProperties = false
+    "= true, if caloric properties are calculated (i.e., s, g and a)"
+    annotation (Dialog(tab="General", group="General",
+                enable = calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate= true);
+
+  //
+  // Definition of parameters regarding the specific volume
+  //
+  parameter SorpLib.Choices.SpecificVolumeSolid approach_v=
+    SorpLib.Choices.SpecificVolumeSolid.Constant
+    "Calculation approach for the specific volume"
+    annotation (Dialog(tab="Specific Volume", group="General"), Evaluate=false);
+
+  parameter Modelica.Units.SI.SpecificVolume v_constant= 1/7919
+    "Constant specific volume"
+    annotation (Dialog(tab="Specific Volume", group="Constant",
+                enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  parameter SorpLib.Choices.GeneralizedFunctionApproach approach_v_function=
+      SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Generalized function used to calculate the specific volume" annotation (
+      Dialog(
+      tab="Specific Volume",
+      group="Generalized Function",
+      enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+      Evaluate=true);
+  parameter Modelica.Units.SI.Temperature T_ref_v = 293.15
+    "Reference temperature for the specific volume"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real v_ref = 1
+    "Reference fluid property data for the specific volume"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_v[:]={v_constant}
+    "Coefficients of generalized function for the specific volume"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real exponents_v[size(coefficients_v,1)]={0}
+    "Exponents of generalized function for the specific volume"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+
+  parameter SorpLib.Choices.InterpolationApproach approach_v_interpolation=
+      SorpLib.Choices.InterpolationApproach.Linear
+    "Interpolation approach used to calculate the specific volume" annotation (
+      Dialog(
+      tab="Specific Volume",
+      group="Interpolation",
+      enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+      Evaluate=false);
+  parameter Real abscissa_v[:]={0, 1000}
+    "Known abscissa values for the specific volume"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real ordinate_v[size(abscissa_v,1)]={v_constant, v_constant}
+    "Known ordinate values for the specific volume"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=(approach_v == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  final parameter Real coefficients_cubicSplines_v[size(abscissa_v,1),4]=
+    SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients(
+    abscissa=abscissa_v,
+    ordinate=ordinate_v)
+    "Coefficient a to d for cubic polynomials for the specific volume"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=false),
+                HideResult=true,
+                Evaluate= true);
+
+  //
+  // Definition of parameters regarding the specific heat capacity
+  //
+  parameter SorpLib.Choices.SpecificHeatCapacitySolid approach_c=
+    SorpLib.Choices.SpecificHeatCapacitySolid.Constant
+    "Calculation approach for the specific heat capacity" annotation (Dialog(
+        tab="Specific Heat Capacity", group="General"), Evaluate=false);
+
+  parameter Modelica.Units.SI.SpecificHeatCapacity c_constant= 472
+    "Constant specific heat capacity"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Constant",
+                enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  parameter SorpLib.Choices.GeneralizedFunctionApproach approach_c_function=
+      SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Generalized function used to calculate the specific heat capacity"
+    annotation (Dialog(
+      tab="Specific Heat Capacity",
+      group="Generalized Function",
+      enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+      Evaluate=true);
+  parameter Modelica.Units.SI.Temperature T_ref_c = 293.15
+    "Reference temperature for the specific heat capacity"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real c_ref = 1
+    "Reference fluid property data for the specific heat capacity"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_c[:]= {c_constant}
+    "Coefficients of generalized function for the specific heat capacity"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real exponents_c[size(coefficients_c,1)] = {0}
+    "Exponents of generalized function for the specific heat capacity"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+
+  parameter SorpLib.Choices.InterpolationApproach approach_c_interpolation=
+      SorpLib.Choices.InterpolationApproach.Linear
+    "Interpolation approach used to calculate the specific heat capacity"
+    annotation (Dialog(
+      tab="Specific Heat Capacity",
+      group="Interpolation",
+      enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+      Evaluate=false);
+  parameter Real abscissa_c[:]={0, 1000}
+    "Known abscissa values for the specific heat capacity"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real ordinate_c[size(abscissa_c,1)]= {c_constant, c_constant}
+    "Known ordinate values for the specific heat capacity"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=(approach_c == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  final parameter Real coefficients_cubicSplines_c[size(abscissa_c,1),4]=
+    SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients(
+    abscissa=abscissa_c,
+    ordinate=ordinate_c)
+    "Coefficient a to d for cubic polynomials for the specific heat capacity"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=false),
+                HideResult=true,
+                Evaluate= true);
+
+  //
+  // Definition of parameters regarding the thermal conductivity
+  //
+  parameter SorpLib.Choices.ThermalConductivitySolid approach_lambda=
+    SorpLib.Choices.ThermalConductivitySolid.Constant
+    "Calculation approach for the thermal conductivity" annotation (Dialog(tab=
+          "Thermal Conductivity", group="General"), Evaluate=false);
+
+  parameter Modelica.Units.SI.ThermalConductivity lambda_constant= 14.8
+    "Constant thermal conductivity"
+    annotation (Dialog(tab="Thermal Conductivity", group="Constant",
+                enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  parameter SorpLib.Choices.GeneralizedFunctionApproach approach_lambda_function=
+    SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Generalized function used to calculate the thermal conductivity"
+    annotation (Dialog(
+      tab="Thermal Conductivity",
+      group="Generalized Function",
+      enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+      Evaluate=true);
+  parameter Modelica.Units.SI.Temperature T_ref_lambda = 293.15
+    "Reference temperature for the thermal conductivity"
+    annotation (Dialog(tab="Thermal Conductivity", group="Generalized Function",
+                enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real lambda_ref = 1
+    "Reference fluid property data for the thermal conductivity"
+    annotation (Dialog(tab="Thermal Conductivity", group="Generalized Function",
+                enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_lambda[:]={lambda_constant}
+    "Coefficients of generalized function for the thermal conductivity"
+    annotation (Dialog(tab="Thermal Conductivity", group="Generalized Function",
+                enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real exponents_lambda[size(coefficients_lambda,1)]={0}
+    "Exponents of generalized function for the thermal conductivity"
+    annotation (Dialog(tab="Thermal Conductivity", group="Generalized Function",
+                enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+
+  parameter SorpLib.Choices.InterpolationApproach approach_lambda_interpolation=
+     SorpLib.Choices.InterpolationApproach.Linear
+    "Interpolation approach used to calculate the thermal conductivity"
+    annotation (Dialog(
+      tab="Thermal Conductivity",
+      group="Interpolation",
+      enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+      Evaluate=false);
+  parameter Real abscissa_lambda[:]={0, 1000}
+    "Known abscissa values for the thermal conductivity"
+    annotation (Dialog(tab="Thermal Conductivity", group="Interpolation",
+                enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real ordinate_lambda[size(abscissa_lambda,1)]= {lambda_constant, lambda_constant}
+    "Known ordinate values for the thermal conductivity"
+    annotation (Dialog(tab="Thermal Conductivity", group="Interpolation",
+                enable=(approach_lambda == SorpLib.Choices.SpecificVolumeSolid.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  final parameter Real coefficients_cubicSplines_lambda[size(abscissa_lambda,1),4]=
+    SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients(
+    abscissa=abscissa_lambda,
+    ordinate=ordinate_lambda)
+    "Coefficient a to d for cubic polynomials for the thermal conductivity"
+    annotation (Dialog(tab="Thermal Conductivity", group="Interpolation",
+                enable=false),
+                HideResult=true,
+                Evaluate= true);
+
+  //
+  // Definition of parameters regarding advanced options
+  //
+  parameter Modelica.Units.SI.Pressure p_ref = 1e5
+    "Reference pressure for caloric and entropic calculations"
+    annotation (Dialog(tab="Advanced", group="Reference State",
+                enable=calcCaloricProperties or calcEntropicProperties),
+                Evaluate= true);
+  parameter Modelica.Units.SI.Temperature T_ref = 298.15
+    "Reference temperature for caloric and entropic calculations"
+    annotation (Dialog(tab="Advanced", group="Reference State",
+                enable=calcCaloricProperties or calcEntropicProperties),
+                Evaluate= true);
+
+  parameter Modelica.Units.SI.SpecificEnthalpy h_ref = 0
+    "Specific enthalpy at reference state"
+    annotation (Dialog(tab="Advanced", group="Reference State",
+                enable=calcCaloricProperties or calcEntropicProperties),
+                Evaluate= true);
+  parameter Modelica.Units.SI.SpecificEntropy s_ref = 0
+    "Specific entropy at reference state"
+    annotation (Dialog(tab="Advanced", group="Reference State",
+                enable=calcEntropicProperties),
+                Evaluate= true);
+
+  parameter Real tolerance_int_h = 1e-6
+    "Integration tolerance when calculating the specific enthalpy numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics",
+                enable=calcCaloricProperties),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real tolerance_int_s = 1e-6
+    "Integration tolerance when calculating the specific entropy numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics",
+                enable=calcEntropicProperties),
+                HideResult=true,
+                Evaluate= true);
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Pressure p
+    "Pressure of solid"
+    annotation (Dialog(tab="General", group="Inputs",
+                enable=false));
+  input Modelica.Units.SI.Temperature T
+    "Temperature of solid"
+    annotation (Dialog(tab="General", group="Inputs",
+                enable=false));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Media.Solids.Records.StateVariables state_variables
+    "Thermodynamic state variables"
+    annotation (Dialog(tab="General", group="Outputs",
+                enable=false));
+  output SorpLib.Media.Solids.Records.AdditionalVariables additional_variables
+    "Additional variables"
+    annotation (Dialog(tab="General", group="Outputs",
+                enable=false));
+
+  //
+  // Definition of functions describing integrands
+  //
+protected
+  function int_c_dT_generalizedFunction
+    "Integrand required for calculating the specific enthalpy using the generalized
+    function"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Modelica.Units.SI.Temperature T_ref
+      "Reference temperature for fluid property data";
+    input Real z_ref
+      "Reference fluid property data";
+    input Real coefficients[:]
+      "Coefficients of generalized function";
+    input Real exponents[size(coefficients,1)]
+      "Exponents of generalized function";
+    input SorpLib.Choices.GeneralizedFunctionApproach approach
+      "Function approach";
+  algorithm
+    y := SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+      T=u,
+      T_ref=T_ref,
+      z_ref=z_ref,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=approach)
+      "Integrand required for calculating the specific enthalpy using the generalized
+      function";
+  end int_c_dT_generalizedFunction;
+
+  function int_c_div_T_dT_generalizedFunction
+    "Integrand required for calculating the specific entropy using the generalized
+    function"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Modelica.Units.SI.Temperature T_ref
+      "Reference temperature for fluid property data";
+    input Real z_ref
+      "Reference fluid property data";
+    input Real coefficients[:]
+      "Coefficients of generalized function";
+    input Real exponents[size(coefficients,1)]
+      "Exponents of generalized function";
+    input SorpLib.Choices.GeneralizedFunctionApproach approach
+      "Function approach";
+  algorithm
+    y := SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+      T=u,
+      T_ref=T_ref,
+      z_ref=z_ref,
+      coefficients=coefficients,
+      exponents=exponents,
+      approach=approach) / u
+      "Integrand required for calculating the specific entropy using the generalized
+      function";
+  end int_c_div_T_dT_generalizedFunction;
+
+  function int_c_dT_linearInterpolation
+    "Integrand required for calculating the specific enthalpy using linear 
+    interpolation"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Real abscissa[:]
+      "Known abscissa values";
+    input Real ordinate[size(abscissa,1)]
+      "Known ordinate values";
+  algorithm
+    y := SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+      T=u,
+      abscissa=abscissa,
+      ordinate=ordinate)
+      "Integrand required for calculating the specific enthalpy using linear 
+      interpolation";
+  end int_c_dT_linearInterpolation;
+
+  function int_c_div_T_dT_linearInterpolation
+    "Integrand required for calculating the specific entropy using linear 
+    interpolation"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Real abscissa[:]
+      "Known abscissa values";
+    input Real ordinate[size(abscissa,1)]
+      "Known ordinate values";
+  algorithm
+    y := SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+      T=u,
+      abscissa=abscissa,
+      ordinate=ordinate) / u
+      "Integrand required for calculating the specific entropy using linear 
+      interpolation";
+  end int_c_div_T_dT_linearInterpolation;
+
+  function int_c_dT_cubicSplineInterpolation
+    "Integrand required for calculating the specific enthalpy using cubic spline 
+    interpolation"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Real abscissa[:]
+      "Known abscissa values";
+    input Real ordinate[size(abscissa,1)]
+      "Known ordinate values";
+    input Real coefficients[size(abscissa,1),4]
+      "Coefficient a to d for cubic polynomials";
+  algorithm
+    y := SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+      T=u,
+      abscissa=abscissa,
+      ordinate=ordinate,
+      coefficients=coefficients)
+      "Integrand required for calculating the specific enthalpy using cubic spline 
+      interpolation";
+  end int_c_dT_cubicSplineInterpolation;
+
+  function int_c_div_T_dT_cubicSplineInterpolation
+    "Integrand required for calculating the specific entropy using cubic spline 
+    interpolation"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+    input Real abscissa[:]
+      "Known abscissa values";
+    input Real ordinate[size(abscissa,1)]
+      "Known ordinate values";
+    input Real coefficients[size(abscissa,1),4]
+      "Coefficient a to d for cubic polynomials";
+  algorithm
+    y := SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+      T=u,
+      abscissa=abscissa,
+      ordinate=ordinate,
+      coefficients=coefficients) / u
+      "Integrand required for calculating the specific entropy using cubic spline 
+      interpolation";
+  end int_c_div_T_dT_cubicSplineInterpolation;
+
+equation
+  //
+  // Pass input data
+  //
+  state_variables.p = p
+    "Pressure";
+  state_variables.T = T
+    "Pressure";
+
+  //
+  // Calculate the density
+  //
+  if approach_v == SorpLib.Choices.SpecificVolumeSolid.Constant then
+    state_variables.v = v_constant
+      "Specific volume of solid";
+
+  elseif approach_v == SorpLib.Choices.SpecificVolumeSolid.GeneralizedFunction then
+    state_variables.v = SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+      T=T,
+      T_ref=T_ref_v,
+      z_ref=v_ref,
+      coefficients=coefficients_v,
+      exponents=exponents_v,
+      approach=approach_v_function)
+      "Specific volume of solid";
+
+  else
+    if approach_v_interpolation == SorpLib.Choices.InterpolationApproach.Linear then
+      state_variables.v = SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+        T=T,
+        abscissa=abscissa_v,
+        ordinate=ordinate_v)
+        "Specific volume of solid";
+
+    else
+      state_variables.v = SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+        T=T,
+        abscissa=abscissa_v,
+        ordinate=ordinate_v,
+        coefficients=coefficients_cubicSplines_v)
+        "Specific volume of solid";
+
+    end if;
+  end if;
+
+  //
+  // Calculate the specific heat capacity
+  //
+  if approach_c == SorpLib.Choices.SpecificHeatCapacitySolid.Constant then
+    additional_variables.c = c_constant
+      "Specific heat capacitiy of solid";
+
+  elseif approach_c == SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction then
+    additional_variables.c = SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+      T=T,
+      T_ref=T_ref_c,
+      z_ref=c_ref,
+      coefficients=coefficients_c,
+      exponents=exponents_c,
+      approach=approach_c_function)
+      "Specific heat capacitiy of solid";
+
+  else
+    if approach_c_interpolation == SorpLib.Choices.InterpolationApproach.Linear then
+      additional_variables.c = SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+        T=T,
+        abscissa=abscissa_c,
+        ordinate=ordinate_c)
+        "Specific heat capacitiy of solid";
+
+    else
+      additional_variables.c = SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+        T=T,
+        abscissa=abscissa_c,
+        ordinate=ordinate_c,
+        coefficients=coefficients_cubicSplines_c)
+        "Specific heat capacitiy of solid";
+
+    end if;
+  end if;
+
+  //
+  // Calculate the thermal conductivity
+  //
+  if approach_lambda == SorpLib.Choices.ThermalConductivitySolid.Constant then
+    additional_variables.lambda = lambda_constant
+      "Thermal conductivity of solid";
+
+  elseif approach_lambda == SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction then
+    additional_variables.lambda = SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+      T=T,
+      T_ref=T_ref_lambda,
+      z_ref=lambda_ref,
+      coefficients=coefficients_lambda,
+      exponents=exponents_lambda,
+      approach=approach_lambda_function)
+      "Thermal conductivity of solid";
+
+  else
+    if approach_lambda_interpolation == SorpLib.Choices.InterpolationApproach.Linear then
+      additional_variables.lambda = SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+        T=T,
+        abscissa=abscissa_lambda,
+        ordinate=ordinate_lambda)
+        "Thermal conductivity of solid";
+
+    else
+      additional_variables.lambda = SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+        T=T,
+        abscissa=abscissa_lambda,
+        ordinate=ordinate_lambda,
+        coefficients=coefficients_cubicSplines_lambda)
+        "Thermal conductivity of solid";
+
+    end if;
+  end if;
+
+  //
+  // Calculate caloric and entropic properties
+  //
+  if calcCaloricProperties then
+    //
+    // Specific enthalpy: An analytical integral does not always exist or
+    // numerical integration is faster
+    //
+    if approach_c == SorpLib.Choices.SpecificHeatCapacitySolid.Constant then
+      state_variables.h = h_ref + additional_variables.c * (T - T_ref) +
+        state_variables.v * (p - p_ref)
+        "Specific enthalpy of solid";
+
+    elseif approach_c == SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction then
+      state_variables.h = h_ref + state_variables.v * (p - p_ref) +
+        Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function int_c_dT_generalizedFunction(
+            T_ref=T_ref_c,
+            z_ref=c_ref,
+            coefficients=coefficients_c,
+            exponents=exponents_c,
+            approach=approach_c_function),
+          a=T_ref,
+          b=T,
+          tolerance=tolerance_int_h)
+        "Specific enthalpy of solid";
+
+    else
+      if approach_c_interpolation == SorpLib.Choices.InterpolationApproach.Linear then
+        state_variables.h = h_ref + state_variables.v * (p - p_ref) +
+          Modelica.Math.Nonlinear.quadratureLobatto(
+            f=function int_c_dT_linearInterpolation(
+              abscissa=abscissa_c,
+              ordinate=ordinate_c),
+            a=T_ref,
+            b=T,
+            tolerance=tolerance_int_h)
+          "Specific enthalpy of solid";
+
+      else
+        state_variables.h = h_ref + state_variables.v * (p - p_ref) +
+          Modelica.Math.Nonlinear.quadratureLobatto(
+            f=function int_c_dT_cubicSplineInterpolation(
+              abscissa=abscissa_c,
+              ordinate=ordinate_c,
+              coefficients=coefficients_cubicSplines_c),
+            a=T_ref,
+            b=T,
+            tolerance=tolerance_int_h)
+          "Specific enthalpy of solid";
+
+      end if;
+    end if;
+
+    state_variables.u = state_variables.h - p * state_variables.v
+      "Specific internal energy of solid";
+
+  else
+    state_variables.h = 0
+      "Specific enthalpy of solid";
+    state_variables.u = 0
+      "Specific internal energy of solid";
+
+  end if;
+
+  //
+  // Calculate entropic properties
+  //
+  if calcCaloricProperties and calcEntropicProperties then
+    //
+    // Specific entropy: An analytical integral does not always exist or
+    // numerical integration is faster
+    //
+    if approach_c == SorpLib.Choices.SpecificHeatCapacitySolid.Constant then
+      state_variables.s = s_ref +
+        additional_variables.c * (log(abs(T)) - log(abs(T_ref)))
+        "Specific entropy of solid";
+
+    elseif approach_c == SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction then
+      state_variables.s = s_ref +
+        Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function int_c_div_T_dT_generalizedFunction(
+            T_ref=T_ref_c,
+            z_ref=c_ref,
+            coefficients=coefficients_c,
+            exponents=exponents_c,
+            approach=approach_c_function),
+          a=T_ref,
+          b=T,
+          tolerance=tolerance_int_s)
+        "Specific entropy of solid";
+
+    else
+      if approach_c_interpolation == SorpLib.Choices.InterpolationApproach.Linear then
+        state_variables.s = s_ref +
+          Modelica.Math.Nonlinear.quadratureLobatto(
+            f=function int_c_div_T_dT_linearInterpolation(
+              abscissa=abscissa_c,
+              ordinate=ordinate_c),
+            a=T_ref,
+            b=T,
+            tolerance=tolerance_int_s)
+          "Specific entropy of solid";
+
+      else
+        state_variables.s = s_ref +
+          Modelica.Math.Nonlinear.quadratureLobatto(
+            f=function int_c_div_T_dT_cubicSplineInterpolation(
+              abscissa=abscissa_c,
+              ordinate=ordinate_c,
+              coefficients=coefficients_cubicSplines_c),
+            a=T_ref,
+            b=T,
+            tolerance=tolerance_int_s)
+          "Specific entropy of solid";
+
+      end if;
+    end if;
+
+    state_variables.g = state_variables.h - T * state_variables.s
+      "Specific free enthalpy (i.e., Gibbs free energy) of solid";
+    state_variables.a = state_variables.u - T * state_variables.s
+      "Specific free energy (i.e., Helmholts free energy) of solid";
+
+  else
+    state_variables.s = 0
+      "Specific entropy of solid";
+    state_variables.g = 0
+      "Specific free enthalpy (i.e., Gibbs free energy) of solid";
+    state_variables.a = 0
+      "Specific free energy (i.e., Helmholts free energy) of solid";
+
+  end if;
+
+  //
+  // Assertations
+  //
+  if calcCaloricProperties or calcEntropicProperties then
+    if not approach_v == SorpLib.Choices.SpecificVolumeSolid.Constant then
+      Modelica.Utilities.Streams.print("Warning: The specific volume is not " +
+        "constant. The caloric model equations assume an incompressible " +
+        "solid. Thus, the thermodynamic calculation is not consistent.");
+    end if;
+  end if;
+
+  if calcEntropicProperties then
+    if not approach_v == SorpLib.Choices.SpecificVolumeSolid.Constant then
+      Modelica.Utilities.Streams.print("Warning: The specific volume is not " +
+        "constant. The caloric model equations assume an incompressible " +
+        "solid. Thus, the thermodynamic calculation is not consistent.");
+    end if;
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the base model for calculating thermodynamic properties of solids, 
+such as sorbents or metals and metal alloys. In the model, fundamental thermodynamic 
+properties can be calculated:
+</p>
+<ol>
+  <li>
+  Thermal state variables: <i>p</i>, <i>T</i>, and <i>&rho;</i>.
+  </li>
+  <li>
+  Caloric state variables: <i>h</i> and <i>u</i>.
+  </li>
+  <li>
+  Entropic state variables: <i>s</i>, <i>g</i>, and <i>a</i>.
+  </li>
+</ol>
+<p>
+Moreover, the model allows to calculate the specific heat capacity <i>c</i> and thermal 
+conductivity <i>&lambda;</i>. Models that inherit properties from this partial models have 
+to selected the correct calculation for the thermodynamic properties and to specify 
+solid-specific parameters.
+</p>
+
+<h4>Implemented calculation approaches for the thermodyanmic properties <i>h</i> and <i>s</i></h4>
+<p>
+The calculation methods assume an ideal solid:
+</p>
+<pre>
+    h = h<sub>ref</sub>(p<sub>ref</sub>, T<sub>ref</sub>) + &int;_T<sub>ref</sub>^T [c] dT + v * (p - p<sub>ref</sub>);
+</pre>
+<pre>
+    s = s<sub>ref</sub>(T<sub>ref</sub>) + &int;_T<sub>ref</sub>^T [c / T] dT
+</pre>
+<p>
+Herein, <i>h<sub>ref</sub></i> and <i>s<sub>ref</sub></i> are the specific enthalpy and
+entropy at reference pressure <i>p<sub>ref</sub></i> and temperature <i>T<sub>ref</sub></i>.
+</p>
+
+<h4>Implemented calculation approaches for the thermodyanmic properties <i>&rho;</i>, <i>c</i>, and <i>&lambda;</i></h4>
+<p>
+Three calculation approaches can be selected for each thermodynamic property:
+</p>
+<ol>
+  <li>
+  Constant value.
+  </li>
+  <li>
+  Generalized function.
+  </li>
+  <li>
+  Interpolation.
+  </li>
+</ol>
+
+<h4>Options regarding the generalized function</h4>
+<p>
+The
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.generalizedFunction_T\">generalized function</a>
+comprises four function types often used for fluid property data calculation:
+</p>
+<ol>
+  <li>
+  For <i>approach = PolynomialFunction_Temperature</i>:
+  <br>
+  <pre>z = z<sub>ref</sub> * &sum;<sub>i</sub> a<sub>i</sub> * T ^ (b<sub>i</sub>);</pre>
+  <br>
+  </li>
+  <li>
+  For <i>approach = PolynomialFunction_ReducedTemperature</i>:
+  <br>
+  <pre>z = z<sub>ref</sub> * &sum;<sub>i</sub> a<sub>i</sub> * (1 - T / T<sub>ref</sub>) ^ (b<sub>i</sub>);</pre>
+  <br>
+  </li>
+  <li>
+  For <i>approach = ExponentialFunction_Temperature</i>:
+  <br>
+  <pre>z = z<sub>ref</sub> * <strong>exp</strong>(&sum;<sub>i</sub> a<sub>i</sub> * T ^ (b<sub>i</sub>));</pre>
+  <br>
+  </li>
+  <li>
+  For <i>approach = ExponentialFunction_ReducedTemperature</i>:
+  <br>
+  <pre>z = z<sub>ref</sub> * <strong>exp</strong>(&sum;<sub>i</sub> a<sub>i</sub> * (1 - T / T<sub>ref</sub>) ^ (b<sub>i</sub>));</pre>
+  <br>
+  </li>
+</ol>
+<p>
+Herein, <i>z<sub>ref</sub></i> is either a pre-factor for approaches that use the 
+temperature or the fluid property at reference temperature <i>T<sub>ref</sub></i> 
+for approaches that use the reduced temperature. The vectors <i>a</i> and <i>b</i>
+contain the coefficents and exponents for each summand of the sum.
+</p>
+
+<h4>Options regarding interpolation</h4>
+<p>
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.linearInterpolation_T\">Linear</a>
+or 
+<a href=\"Modelica://SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T\">cubic spline interpolation</a>
+can be selected.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Currently, the thermodynamic properties <i>&rho;</i>, <i>c</i>, and <i>&lambda;</i> do only depend on the temperature and not on the pressrure.
+  </li>
+  <li>
+  When calculating caloric and entropic state properties, the desnity is assumed to be constant (i.e., incompressible solid).
+  </li>
+</ul>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+  <li>
+  January 25, 2021, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialSolid;
diff --git a/SorpLib/Media/Solids/BaseClasses/PartialTest.mo b/SorpLib/Media/Solids/BaseClasses/PartialTest.mo
new file mode 100644
index 0000000..8abac46
--- /dev/null
+++ b/SorpLib/Media/Solids/BaseClasses/PartialTest.mo
@@ -0,0 +1,133 @@
+within SorpLib.Media.Solids.BaseClasses;
+partial model PartialTest
+  "Base model for testers of describing isobaric expansion coefficients of the adsorpt phase for pure component adsorption"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Pressure p_start = 1000
+    "Start value of pressure"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_start = 273.15
+    "Start value of temperature"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real p_der(unit="Pa/s") = (1e5-1000)/20
+    "Prescriped sloped of pressure to test solid model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real T_der(unit="K/s") = 500/20
+    "Prescriped sloped of temperature to test solid model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+
+  replaceable model Solid =
+    SorpLib.Media.Solids.BaseClasses.PartialSolid
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Solid model"
+    annotation (Dialog(tab="General",group="Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p(start=p_start, fixed=true)
+    "Pressure";
+  Modelica.Units.SI.Temperature T(start=T_start, fixed=true)
+    "Temperature";
+
+  //
+  // Instantiation of models
+  //
+  Solid solid_constant(
+    calcCaloricProperties=true,
+    calcEntropicProperties=true,
+    final approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+    final approach_v_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Constant,
+    final approach_c_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final approach_lambda=SorpLib.Choices.ThermalConductivitySolid.Constant,
+    final approach_lambda_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final p=p,
+    final T=T) "Solid: Consant properties"
+    annotation (Placement(transformation(extent={{-80,-10},{-60,10}})));
+
+  Solid solid_generalizedFunction(
+    calcCaloricProperties=true,
+    calcEntropicProperties=true,
+    approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+    final approach_v_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+    final approach_c_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final approach_lambda=SorpLib.Choices.ThermalConductivitySolid.GeneralizedFunction,
+    final approach_lambda_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final p=p,
+    final T=T) "Solid: Generalized function"
+    annotation (Placement(transformation(extent={{-40,-10},{-20,10}})));
+
+  Solid solid_linearInterpolation(
+    calcCaloricProperties=true,
+    calcEntropicProperties=true,
+    approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+    final approach_v_interpolation=SorpLib.Choices.InterpolationApproach.Linear,
+    final approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Interpolation,
+    final approach_c_interpolation=SorpLib.Choices.InterpolationApproach.Linear,
+    final approach_lambda=SorpLib.Choices.ThermalConductivitySolid.Interpolation,
+    final approach_lambda_interpolation=SorpLib.Choices.InterpolationApproach.Linear,
+    final p=p,
+    final T=T) "Solid: Linear interpolation"
+    annotation (Placement(transformation(extent={{20,-10},{40,10}})));
+
+  Solid solid_cubicSplineInterpolation(
+    calcCaloricProperties=true,
+    calcEntropicProperties=true,
+    approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+    final approach_v_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Interpolation,
+    final approach_c_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final approach_lambda=SorpLib.Choices.ThermalConductivitySolid.Interpolation,
+    final approach_lambda_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final p=p,
+    final T=T) "Solid: Cubic spline interpolation"
+    annotation (Placement(transformation(extent={{60,-10},{80,10}})));
+
+equation
+  //
+  // Calculation of properties
+  //
+  der(p) = p_der
+    "Predecsriped slope of p to demonstrate the solid model";
+  der(T) = T_der
+    "Predecsriped slope of T to demonstrate the solid model";
+
+  //
+  // Annotations
+  //
+  annotation (
+    Icon(coordinateSystem(preserveAspectRatio=false)),
+    Diagram(coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the basic model for all testers of solid models. This partial 
+model defines all relevant parameters, variables, and models to test the solid models.
+<br/><br/>
+Models that inherit properties from this partial model have to redeclare the model
+'Solid' and to define the test setup.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialTest;
diff --git a/SorpLib/Media/Solids/BaseClasses/package.mo b/SorpLib/Media/Solids/BaseClasses/package.mo
new file mode 100644
index 0000000..5f852b4
--- /dev/null
+++ b/SorpLib/Media/Solids/BaseClasses/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.Solids;
+package BaseClasses "Base classes used to build new solid models"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial functions and models. These partial functions and models
+contain fundamental definitions for calculating thermodynamic properties of solids.
+The content of this package is only of interest when adding new functions to the library.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Media/Solids/BaseClasses/package.order b/SorpLib/Media/Solids/BaseClasses/package.order
new file mode 100644
index 0000000..f267fa6
--- /dev/null
+++ b/SorpLib/Media/Solids/BaseClasses/package.order
@@ -0,0 +1,2 @@
+PartialSolid
+PartialTest
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Aluminium.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Aluminium.mo
new file mode 100644
index 0000000..8b9d158
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Aluminium.mo
@@ -0,0 +1,75 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys;
+model Aluminium "Model of aluminium"
+  extends BaseClasses.PartialSolid(
+    approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+    final v_constant=1/2700,
+    final approach_v_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_v=273.15,
+    final v_ref=1,
+    final coefficients_v={2.40565103604828e-17,-3.18909783349765e-14,
+        3.05844815369395e-11,9.82750318802462e-09,0.000365560992186206},
+    final exponents_v={4,3,2,1,0},
+    approach_v_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_v={1.721428571,98.86428571,201.7214286,298.8642857,
+        398.8642857,501.7214286,601.7214286,696.0071429,793.15,901.7214286,
+        930.2928571},
+    final ordinate_v={0.000365578,0.000366803,0.000368566,0.000370705,
+        0.000372868,0.000375608,0.000378763,0.000382543,0.000386204,0.000391529,
+        0.000393539},
+    approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Interpolation,
+    final c_constant=837,
+    final approach_c_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_c=273.15,
+    final c_ref=1,
+    final coefficients_c={4.27500975902274e-12,-1.57466005351826e-08,
+        2.29069115958695e-05,-0.0160371796818545,5.75972719368390,
+        110.779863838808},
+    final exponents_c={5,4,3,2,1,0},
+    approach_c_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_c={264.1864146,306.7634454,351.5813725,409.8446779,
+        474.8306723,566.707423,667.5477591,739.2564426,799.7606443,846.8194678,
+        889.3964986},
+    final ordinate_c={864.2857143,901.9305019,931.8532819,958.8803089,
+        984.9420849,1020.656371,1063.127413,1099.80695,1133.590734,1162.548263,
+        1189.57529},
+    approach_lambda=SorpLib.Choices.ThermalConductivitySolid.Interpolation,
+    final lambda_constant=236,
+    final approach_lambda_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_lambda=273.15,
+    final lambda_ref=1,
+    final coefficients_lambda={5.93000570062670e-13,-1.92890156664459e-09,
+        2.59002630981166e-06,-0.00184669307956919,0.642940781600963,
+        154.914872094860},
+    final exponents_lambda={5,4,3,2,1,0},
+    approach_lambda_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_lambda={275.2664021,298.5468254,351.4568783,400.134127,
+        501.7214286,603.3087302,700.6632275,800.134127,899.6050265,933.4674603},
+    final ordinate_lambda={235.8518519,236.8888889,238.962963,240,236.3703704,
+        231.1851852,224.962963,217.7037037,209.9259259,208.3703704});
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model describes aluminium.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Neubronner, M. and Bodmer, T. and H&uuml;bner, C. and Kempa, P.B. and Tsotsas, E. and Eschner, A. and Kasparek, G. and Ochs, F. and M&uuml;ller-Steinhagen, H. and Werner, H. and Spitzner M. (2010). D6 Properties of Solids and Solid Materials. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_26.
+  </li>
+  <li>
+  Foteinopoulos, P. and Papacharalampopoulos, A. and Stavropoulos, P. (2018). On thermal modeling of Additive Manufacturing processes. CIRP Journal of Manufacturing Science and Technology, 20: 66-83. DOI: https://doi.org/10.1016/j.cirpj.2017.09.007.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Aluminium;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Copper.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Copper.mo
new file mode 100644
index 0000000..d5e61e5
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Copper.mo
@@ -0,0 +1,67 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys;
+model Copper "Model of copper"
+  extends BaseClasses.PartialSolid(
+    approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+    final v_constant=1/8960,
+    final approach_v_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_v=273.15,
+    final v_ref=1,
+    final coefficients_v={1.60881016976082e-22,-5.53823537743382e-19,
+        7.14670930357768e-16,-4.34191656855154e-13,1.31448861732992e-10,-1.36958086403092e-08,
+        0.000111423194172002},
+    final exponents_v={6,5,4,3,2,1,0},
+    approach_v_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_v={100,150,200,250,300,400,600,800,1000,1200},
+    final ordinate_v={0.000111,0.00011121,0.000111445,0.000111719,0.000111982,
+        0.000112562,0.000113804,0.000115714,0.000116713,0.000118231},
+    approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Interpolation,
+    final c_constant=381,
+    final approach_c_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_c=273.15,
+    final c_ref=1,
+    final coefficients_c={-8.07419641469257e-15,3.50215406143622e-11,-5.94904387124967e-08,
+        5.02166294598675e-05,-0.0221269700391500,4.96530568724046,-65.8705951309113},
+    final exponents_c={6,5,4,3,2,1,0},
+    approach_c_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_c={100,150,200,250,300,400,600,800,1000,1200},
+    final ordinate_c={254,323,357,377,386,396,431,448,446,480},
+    approach_lambda=SorpLib.Choices.ThermalConductivitySolid.Interpolation,
+    final lambda_constant=401,
+    final approach_lambda_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_lambda=273.15,
+    final lambda_ref=1,
+    final coefficients_lambda={1.94540420564950e-15,-8.18944543476065e-12,
+        1.37969889556392e-08,-1.18885525980176e-05,0.00552526968168941,-1.38362953925209,
+        545.964729052232},
+    final exponents_lambda={6,5,4,3,2,1,0},
+    approach_lambda_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_lambda={100,150,200,250,300,400,600,800,1000,1200},
+    final ordinate_lambda={480,429,413,406,401,393,379,366,352,339});
+
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model describes copper.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Neubronner, M. and Bodmer, T. and H&uuml;bner, C. and Kempa, P.B. and Tsotsas, E. and Eschner, A. and Kasparek, G. and Ochs, F. and M&uuml;ller-Steinhagen, H. and Werner, H. and Spitzner M. (2010). D6 Properties of Solids and Solid Materials. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_26.
+  </li>
+  <li>
+  The Engineering ToolBox (2023). Copper - Density, Specific Heat and Thermal Conductivity vs. Temperature. URL: https://www.engineeringtoolbox.com/copper-density-specific-heat-thermal-conductivity-vs-temperature-d_2223.html.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Copper;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/StainlessSteel_X5CrNi18_10.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/StainlessSteel_X5CrNi18_10.mo
new file mode 100644
index 0000000..5d19fca
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/StainlessSteel_X5CrNi18_10.mo
@@ -0,0 +1,76 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys;
+model StainlessSteel_X5CrNi18_10
+  "Model of stainless steel (X5CrNi18-10, 1.4301)"
+  extends BaseClasses.PartialSolid(
+    approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+    final v_constant=1/7919,
+    final approach_v_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_v=293.15,
+    final v_ref=1,
+    final coefficients_v={1.417e-12,5.53e-09,0.0001245},
+    final exponents_v={2,1,0},
+    approach_v_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_v={173.15,223.15,273.15,293.15,323.15,373.15,423.15,473.15,
+        523.15,573.15,623.15,673.15,723.15,773.15,823.15,873.15,923.15,973.15,
+        1023.15,1073.15,1123.15,1173.15,1223.15,1273.15},
+    final ordinate_v={0.000125597,0.000125865,0.000126151,0.000126279,
+        0.00012647,0.000126791,0.000127113,0.000127453,0.000127796,0.000128172,
+        0.000128535,0.000128899,0.000129266,0.000129651,0.000130056,0.000130446,
+        0.000130839,0.000131268,0.000131683,0.0001321,0.000132538,0.000132961,
+        0.000133422,0.000133851},
+    approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Interpolation,
+    final c_constant=472,
+    final approach_c_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_c=293.15,
+    final c_ref=1,
+    final coefficients_c={9.25930531486607e-23,-6.29809836854451e-19,
+        1.82815391249959e-15,-2.95540224203995e-12,2.91605553475977e-09,-1.81312388707961e-06,
+        0.000709566941044524,-0.169563319957511,23.0970795857625,-957.595934830084},
+    final exponents_c={9,8,7,6,5,4,3,2,1,0},
+    approach_c_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_c={173.15,223.15,273.15,293.15,323.15,373.15,423.15,473.15,
+        523.15,573.15,623.15,673.15,723.15,773.15,823.15,873.15,923.15,973.15,
+        1023.15,1073.15,1123.15,1173.15,1223.15,1273.15},
+    final ordinate_c={394,437,463,472,484,501,518,525,527,532,544,555,567,582,
+        595,604,608,610,610,609,610,615,625,641},
+    approach_lambda=SorpLib.Choices.ThermalConductivitySolid.Interpolation,
+    final lambda_constant=14.8,
+    final approach_lambda_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_lambda=293.15,
+    final lambda_ref=1,
+    final coefficients_lambda={-1.08698661001520e-11,3.55842498641231e-08,-4.21979972731494e-05,
+        0.0355381893207769,7.17648049527021},
+    final exponents_lambda={4,3,2,1,0},
+    approach_lambda_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_lambda={173.15,223.15,273.15,293.15,323.15,373.15,423.15,
+        473.15,523.15,573.15,623.15,673.15,723.15,773.15,823.15,873.15,923.15,
+        973.15,1023.15,1073.15,1123.15,1173.15,1223.15,1273.15},
+    final ordinate_lambda={12.2,13.4,14.4,14.8,15.4,16.2,17,17.8,18.5,19.2,19.9,
+        20.6,21.3,22,22.7,23.4,24.2,24.8,25.6,26.2,27,27.6,28.3,29});
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model describes the stainless steel 'X5CrNi18-10' (i.e., 1.4301).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Neubronner, M. and Bodmer, T. and H&uuml;bner, C. and Kempa, P.B. and Tsotsas, E. and Eschner, A. and Kasparek, G. and Ochs, F. and M&uuml;ller-Steinhagen, H. and Werner, H. and Spitzner M. (2010). D6 Properties of Solids and Solid Materials. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_26.
+  </li>
+  <li>
+  Richter, F. (2011). The Physical Properties of Steels. „The 100 Steels Programme“. Part I: Tables and Figures. URL: https://www.tugraz.at/fileadmin/user_upload/Institute/IEP/Thermophysics_Group/Files/Staehle-Richter.pdf. 
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end StainlessSteel_X5CrNi18_10;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Steel_35_8.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Steel_35_8.mo
new file mode 100644
index 0000000..9e1aae7
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Steel_35_8.mo
@@ -0,0 +1,72 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys;
+model Steel_35_8 "Model of steel (St 35.8, 1.0305)"
+  extends BaseClasses.PartialSolid(
+    approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+    final v_constant=1/7849,
+    final approach_v_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_v=293.15,
+    final v_ref=1,
+    final coefficients_v={-9.24794524189667e-16,3.38530633048595e-12,
+        2.82381898383647e-09,0.000126309572458865},
+    final exponents_v={3,2,1,0},
+    approach_v_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_v={173.15,223.15,273.15,293.15,323.15,373.15,423.15,473.15,
+        523.15,573.15,623.15,673.15,723.15,773.15,823.15,873.15,923.15},
+    final ordinate_v={0.000126904,0.000127097,0.000127307,0.000127405,
+        0.000127551,0.000127779,0.000128041,0.000128304,0.000128584,0.000128866,
+        0.000129149,0.000129467,0.000129769,0.00013009,0.000130412,0.000130736,
+        0.000131079},
+    approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Interpolation,
+    final c_constant=461,
+    final approach_c_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_c=293.15,
+    final c_ref=1,
+    final coefficients_c={1.53498822513122e-21,-7.10858683567692e-18,
+        1.42358708364266e-14,-1.61700732871324e-11,1.14838006710273e-08,-5.29608834276069e-06,
+        0.00159217501494625,-0.303448556797988,34.1990283010557,-1370.20964231408},
+    final exponents_c={9,8,7,6,5,4,3,2,1,0},
+    approach_c_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_c={173.15,223.15,273.15,293.15,323.15,373.15,423.15,473.15,
+        523.15,573.15,623.15,673.15,723.15,773.15,823.15,873.15,923.15},
+    final ordinate_c={371,419,451,461,475,496,515,533,550,568,589,611,639,677,
+        724,778,880},
+    approach_lambda=SorpLib.Choices.ThermalConductivitySolid.Interpolation,
+    final lambda_constant=47,
+    final approach_lambda_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final T_ref_lambda=293.15,
+    final lambda_ref=1,
+    final coefficients_lambda={-3.94094761029167e-13,1.07417893817399e-09,-9.96940386382202e-07,
+        0.000294011493296933,0.0194428803212433,34.2898469544763},
+    final exponents_lambda={5,4,3,2,1,0},
+    approach_lambda_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_lambda={173.15,223.15,273.15,293.15,323.15,373.15,423.15,
+        473.15,523.15,573.15,623.15,673.15,723.15,773.15,823.15,873.15,923.15},
+    final ordinate_lambda={42.2,45.1,46.6,47,47.9,48.8,49.1,48.2,47.2,45.7,44.3,
+        42.6,40.8,39.3,37.7,35.9,34.4});
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model describes the steel 'St 35.8' (i.e., 1.0305).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Neubronner, M. and Bodmer, T. and H&uuml;bner, C. and Kempa, P.B. and Tsotsas, E. and Eschner, A. and Kasparek, G. and Ochs, F. and M&uuml;ller-Steinhagen, H. and Werner, H. and Spitzner M. (2010). D6 Properties of Solids and Solid Materials. In: VDI Heat Atlas. VDI-Buch. Springer, Berlin, Heidelberg. DOI: https://doi.org/10.1007/978-3-540-77877-6_26.
+  </li>
+  <li>
+  Richter, F. (2011). The Physical Properties of Steels. „The 100 Steels Programme“. Part I: Tables and Figures. URL: https://www.tugraz.at/fileadmin/user_upload/Institute/IEP/Thermophysics_Group/Files/Staehle-Richter.pdf. 
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Steel_35_8;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Aluminium.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Aluminium.mo
new file mode 100644
index 0000000..f675f25
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Aluminium.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys.Testers;
+model Test_Aluminium "Tester for the model 'Aluminium'"
+  extends SorpLib.Media.Solids.BaseClasses.PartialTest(redeclare final model
+      Solid = SorpLib.Media.Solids.MetalsAndMetalAlloys.Aluminium);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'Aluminium' model. The main 
+approaches for calculating thermodynamic property data are demonstrated: 
+Constant values, generic functions, and interpolation.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_Aluminium;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Copper.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Copper.mo
new file mode 100644
index 0000000..29c242b
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Copper.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys.Testers;
+model Test_Copper "Tester for the model 'Copper'"
+  extends SorpLib.Media.Solids.BaseClasses.PartialTest(redeclare final model
+      Solid = SorpLib.Media.Solids.MetalsAndMetalAlloys.Copper);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'Copper' model. The main 
+approaches for calculating thermodynamic property data are demonstrated: 
+Constant values, generic functions, and interpolation.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_Copper;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_StainlessSteel_X5CrNi18_10.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_StainlessSteel_X5CrNi18_10.mo
new file mode 100644
index 0000000..99bf9fb
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_StainlessSteel_X5CrNi18_10.mo
@@ -0,0 +1,31 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys.Testers;
+model Test_StainlessSteel_X5CrNi18_10
+  "Tester for the model 'StainlessSteel_X5CrNi18_10'"
+  extends SorpLib.Media.Solids.BaseClasses.PartialTest(redeclare final model
+      Solid =
+        SorpLib.Media.Solids.MetalsAndMetalAlloys.StainlessSteel_X5CrNi18_10);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'StainlessSteel_X5CrNi18_10' model. The main 
+approaches for calculating thermodynamic property data are demonstrated: 
+Constant values, generic functions, and interpolation.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_StainlessSteel_X5CrNi18_10;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Steel_35_8.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Steel_35_8.mo
new file mode 100644
index 0000000..05c96f6
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/Test_Steel_35_8.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys.Testers;
+model Test_Steel_35_8 "Tester for the model 'Steel_35_8'"
+  extends SorpLib.Media.Solids.BaseClasses.PartialTest(redeclare final model
+      Solid = SorpLib.Media.Solids.MetalsAndMetalAlloys.Steel_35_8);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'Steel_35_8' model. The main 
+approaches for calculating thermodynamic property data are demonstrated: 
+Constant values, generic functions, and interpolation.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_Steel_35_8;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/package.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/package.mo
new file mode 100644
index 0000000..909a8c0
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.Solids.MetalsAndMetalAlloys;
+package Testers "Models to test and varify sorbent models"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all models of metals and metal
+alloys. The test models check the implementation and demonstrate the models' 
+general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/package.order b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/package.order
new file mode 100644
index 0000000..1eb11d2
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/Testers/package.order
@@ -0,0 +1,4 @@
+Test_Aluminium
+Test_Copper
+Test_Steel_35_8
+Test_StainlessSteel_X5CrNi18_10
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/package.mo b/SorpLib/Media/Solids/MetalsAndMetalAlloys/package.mo
new file mode 100644
index 0000000..48be767
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Solids;
+package MetalsAndMetalAlloys "Parametrized models of metals and metal alloys"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrized solid models describing metals and metal alloys.
+The models already implemented can be found in the package content. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end MetalsAndMetalAlloys;
diff --git a/SorpLib/Media/Solids/MetalsAndMetalAlloys/package.order b/SorpLib/Media/Solids/MetalsAndMetalAlloys/package.order
new file mode 100644
index 0000000..29a016e
--- /dev/null
+++ b/SorpLib/Media/Solids/MetalsAndMetalAlloys/package.order
@@ -0,0 +1,5 @@
+Aluminium
+Copper
+Steel_35_8
+StainlessSteel_X5CrNi18_10
+Testers
diff --git a/SorpLib/Media/Solids/Records/AdditionalVariables.mo b/SorpLib/Media/Solids/Records/AdditionalVariables.mo
new file mode 100644
index 0000000..2e92e94
--- /dev/null
+++ b/SorpLib/Media/Solids/Records/AdditionalVariables.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.Solids.Records;
+record AdditionalVariables
+  "This record contains additional thermodynamic variables"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of paramters
+  //
+  Modelica.Units.SI.SpecificHeatCapacity c
+    "Specific heat capacitiy";
+  Modelica.Units.SI.ThermalConductivity lambda
+    "Thermal conductivity";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains additional thermodynamic variables.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdditionalVariables;
diff --git a/SorpLib/Media/Solids/Records/StateVariables.mo b/SorpLib/Media/Solids/Records/StateVariables.mo
new file mode 100644
index 0000000..b045021
--- /dev/null
+++ b/SorpLib/Media/Solids/Records/StateVariables.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.Solids.Records;
+record StateVariables
+  "This record contains thermodynamic state variables"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p
+    "Pressure";
+  Modelica.Units.SI.Temperature T
+    "Temperature";
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume";
+  Modelica.Units.SI.SpecificEnthalpy h
+    "Specific enthalpy";
+  Modelica.Units.SI.SpecificInternalEnergy u
+    "Specific internal energy";
+  Modelica.Units.SI.SpecificEntropy s
+    "Specific entropy";
+  Modelica.Units.SI.SpecificGibbsFreeEnergy  g
+    "Specific free enthalpy (i.e., Gibbs free energy)";
+  Modelica.Units.SI.SpecificHelmholtzFreeEnergy  a
+    "Specific free energy (i.e., Helmholts free energy)";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains thermodynamic state variables.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end StateVariables;
diff --git a/SorpLib/Media/Solids/Records/package.mo b/SorpLib/Media/Solids/Records/package.mo
new file mode 100644
index 0000000..91e1bf5
--- /dev/null
+++ b/SorpLib/Media/Solids/Records/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Solids;
+package Records "Package containing records"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records. These records are used to cluster 
+variables and tidy up the model output.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Media/Solids/Records/package.order b/SorpLib/Media/Solids/Records/package.order
new file mode 100644
index 0000000..de27307
--- /dev/null
+++ b/SorpLib/Media/Solids/Records/package.order
@@ -0,0 +1,2 @@
+StateVariables
+AdditionalVariables
diff --git a/SorpLib/Media/Solids/Sorbents/GenericSorbent.mo b/SorpLib/Media/Solids/Sorbents/GenericSorbent.mo
new file mode 100644
index 0000000..0393743
--- /dev/null
+++ b/SorpLib/Media/Solids/Sorbents/GenericSorbent.mo
@@ -0,0 +1,38 @@
+within SorpLib.Media.Solids.Sorbents;
+model GenericSorbent "Model of a generic solid sorbent"
+  extends BaseClasses.PartialSolid(
+    v_constant=1/2200,
+    coefficients_v = {v_constant},
+    exponents_v = {0},
+    abscissa_v = {0, 1000},
+    ordinate_v = {v_constant, v_constant},
+    c_constant=1000,
+    coefficients_c = {c_constant},
+    exponents_c = {0},
+    abscissa_c = {0, 1000},
+    ordinate_c = {c_constant, c_constant},
+    lambda_constant=0.12,
+    coefficients_lambda = {lambda_constant},
+    exponents_lambda = {0},
+    abscissa_lambda = {0, 1000},
+    ordinate_lambda = {lambda_constant, lambda_constant});
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model can be used a generic sorbent model. This model is useful if the exact 
+thermodynamic properties as a function of temperature are not known or if individual 
+parameters are determined during parameter estimation. Note that the density 
+describes the true particle density.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end GenericSorbent;
diff --git a/SorpLib/Media/Solids/Sorbents/RDSilicaGel.mo b/SorpLib/Media/Solids/Sorbents/RDSilicaGel.mo
new file mode 100644
index 0000000..eba8fb2
--- /dev/null
+++ b/SorpLib/Media/Solids/Sorbents/RDSilicaGel.mo
@@ -0,0 +1,56 @@
+within SorpLib.Media.Solids.Sorbents;
+model RDSilicaGel
+  "Model of a regular density silica gel (e.g., silica gel 123)"
+  extends BaseClasses.PartialSolid(
+    v_constant=1/725,
+    coefficients_v={v_constant},
+    exponents_v={0},
+    abscissa_v={0,1000},
+    ordinate_v={v_constant,v_constant},
+    approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.GeneralizedFunction,
+    final approach_c_function=SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature,
+    final c_constant=934,
+    final T_ref_c=293.15,
+    final c_ref=1,
+    final coefficients_c={655.814203422836,1.21401945870847,-7816005.43610635},
+    final exponents_c={0,1,-2},
+    approach_c_interpolation=SorpLib.Choices.InterpolationApproach.CubicSplines,
+    final abscissa_c={303.15,308.15,313.15,318.15,323.15,328.15,333.15,338.15,
+        343.15,348.15,353.15,358.15,363.15,368.15,373.15},
+    final ordinate_c={934,951,958,966,974,982,990,997,1006,1013,1020,1029,1037,
+        1045,1055},
+    lambda_constant=0.12,
+    coefficients_lambda={lambda_constant},
+    exponents_lambda={0},
+    abscissa_lambda={0,1000},
+    ordinate_lambda={lambda_constant,lambda_constant});
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model describes regular density silica gel, such as silica gel 123. The properties
+density and thermal conductivity are fixed to values given by Schawe (1999). The specific
+heat capacity is temperature dependt according to measurements by Islam et al. (2020). Note
+that the density describes the true particle density.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe, D. (1999). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD Thesis, Stuttgart.
+  </li>
+  <li>
+  Islam, M.A. and Pal, A. and Saha, B.B. (2020). Experimental study on thermophysical and porous properties of silica gels, International Journal of Refrigeration, 110:277–28. DOI https://doi.org/10.1016/j.ijrefrig.2019.10.027.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end RDSilicaGel;
diff --git a/SorpLib/Media/Solids/Sorbents/Testers/Test_GenericSorbent.mo b/SorpLib/Media/Solids/Sorbents/Testers/Test_GenericSorbent.mo
new file mode 100644
index 0000000..f362fd3
--- /dev/null
+++ b/SorpLib/Media/Solids/Sorbents/Testers/Test_GenericSorbent.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.Solids.Sorbents.Testers;
+model Test_GenericSorbent "Tester for the model 'GenericSorbent'"
+  extends SorpLib.Media.Solids.BaseClasses.PartialTest(
+    redeclare final model Solid = SorpLib.Media.Solids.Sorbents.GenericSorbent);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'GenericSorbent' model. The main 
+approaches for calculating thermodynamic property data are demonstrated: 
+Constant values, generic functions, and interpolation.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_GenericSorbent;
diff --git a/SorpLib/Media/Solids/Sorbents/Testers/Test_RDSilicaGel.mo b/SorpLib/Media/Solids/Sorbents/Testers/Test_RDSilicaGel.mo
new file mode 100644
index 0000000..0faf6be
--- /dev/null
+++ b/SorpLib/Media/Solids/Sorbents/Testers/Test_RDSilicaGel.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.Solids.Sorbents.Testers;
+model Test_RDSilicaGel "Tester for the model 'RDSilicaGel'"
+  extends SorpLib.Media.Solids.BaseClasses.PartialTest(
+    redeclare final model Solid = SorpLib.Media.Solids.Sorbents.RDSilicaGel);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'RDSilicaGel' model. The main 
+approaches for calculating thermodynamic property data are demonstrated: 
+Constant values, generic functions, and interpolation.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_RDSilicaGel;
diff --git a/SorpLib/Media/Solids/Sorbents/Testers/package.mo b/SorpLib/Media/Solids/Sorbents/Testers/package.mo
new file mode 100644
index 0000000..fd53900
--- /dev/null
+++ b/SorpLib/Media/Solids/Sorbents/Testers/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Solids.Sorbents;
+package Testers "Models to test and varify sorbent models"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all sorbent models. The test 
+models check the implementation and demonstrate the models' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/Solids/Sorbents/Testers/package.order b/SorpLib/Media/Solids/Sorbents/Testers/package.order
new file mode 100644
index 0000000..07fd1e1
--- /dev/null
+++ b/SorpLib/Media/Solids/Sorbents/Testers/package.order
@@ -0,0 +1,2 @@
+Test_GenericSorbent
+Test_RDSilicaGel
diff --git a/SorpLib/Media/Solids/Sorbents/package.mo b/SorpLib/Media/Solids/Sorbents/package.mo
new file mode 100644
index 0000000..e131aad
--- /dev/null
+++ b/SorpLib/Media/Solids/Sorbents/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.Solids;
+package Sorbents "Parametrized sorbent models"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrized solid models describing sorbents. The sorbent models 
+already implemented can be found in the package content. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Sorbents;
diff --git a/SorpLib/Media/Solids/Sorbents/package.order b/SorpLib/Media/Solids/Sorbents/package.order
new file mode 100644
index 0000000..56fbd6f
--- /dev/null
+++ b/SorpLib/Media/Solids/Sorbents/package.order
@@ -0,0 +1,3 @@
+GenericSorbent
+RDSilicaGel
+Testers
diff --git a/SorpLib/Media/Solids/package.mo b/SorpLib/Media/Solids/package.mo
new file mode 100644
index 0000000..027f8ef
--- /dev/null
+++ b/SorpLib/Media/Solids/package.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media;
+package Solids "Models to calcualte fluid property data of solids"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models calculating thermodynamic properties of solids, such as
+sorbents or metals and metal alloys. Independent state variables are the pressure and
+temperature. In the models, fundamental thermodynamic properties can be calculated:
+</p>
+<ol>
+  <li>
+  Thermal state variables: <i>p</i>, <i>T</i>, and <i>&rho;</i>.
+  </li>
+  <li>
+  Caloric state variables: <i>h</i> and <i>u</i>.
+  </li>
+  <li>
+  Entropic state variables: <i>s</i>, <i>g</i>, and <i>a</i>.
+  </li>
+</ol>
+<p>
+Moreover, the model allow to calculate the specific heat capacity <i>c</i> and thermal 
+conductivity <i>&lambda;</i>.
+</p>
+
+<h4>How to add new solid models</h4>
+<p>
+To add a new solid model, duplicate an existing solid model in the correct package. Then,
+parametrize the model and write the documentation, including references for the thermodynamic
+properties.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Solids;
diff --git a/SorpLib/Media/Solids/package.order b/SorpLib/Media/Solids/package.order
new file mode 100644
index 0000000..9f92561
--- /dev/null
+++ b/SorpLib/Media/Solids/package.order
@@ -0,0 +1,4 @@
+BaseClasses
+Records
+Sorbents
+MetalsAndMetalAlloys
diff --git a/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureCharts.mo b/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureCharts.mo
new file mode 100644
index 0000000..01fdfea
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureCharts.mo
@@ -0,0 +1,251 @@
+within SorpLib.Media.WorkingPairs.BaseClasses;
+partial model PartialPureCharts
+  "Base model that creates an isotherm chart of a pure component working pair"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter SorpLib.Choices.DiagramTypePureComponentWorkingPair diagramType=
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms
+    "Diagram type: Isotherms, isosters, or isobars"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Choices.ChangingConstantVariableOfDiagram isoLineType=
+    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual
+    "Changing type of iso-lines: Manual, linearly distributed, or logarithmically
+    distributed"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Integer no_isoLines = 10
+    "Number of isotherm or isobars"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.Pressure p_adsorpt_min = 1000
+    "Minimal pressure for diagram of isotherms or isobars"
+    annotation (Dialog(tab="General", group="Setup Pressure",
+                enable=
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms or
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars and
+                  isoLineType<>
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual))),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Pressure p_adsorpt_max = 1e5
+    "Maximal pressure for diagram of isotherms or isobars"
+    annotation (Dialog(tab="General", group="Setup Pressure",
+                enable=
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms or
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars and
+                  isoLineType<>
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual))),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Pressure[no_isoLines] p_adsorpt_const=
+    linspace(p_adsorpt_min, p_adsorpt_max, no_isoLines)
+    "Constant pressures when using isobars"
+    annotation (Dialog(tab="General", group="Setup Pressure",
+                enable=
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars and
+                  isoLineType==
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual)),
+                Evaluate=false,
+                HideResult=false);
+
+  parameter Modelica.Units.SI.Temperature T_adsorpt_min = 283.15
+    "Minimal temperature for diagram of isosters or isotherms"
+    annotation (Dialog(tab="General", group="Setup Temperature",
+                enable=
+                  (diagramType<>
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms or
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms and
+                  isoLineType<>
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual))),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_max = 373.15
+    "Maximal temperature for diagram of isosters or isotherms"
+    annotation (Dialog(tab="General", group="Setup Temperature",
+                enable=
+                  (diagramType<>
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms or
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms and
+                  isoLineType<>
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual))),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature[no_isoLines] T_adsorpt_const=
+    linspace(T_adsorpt_min, T_adsorpt_max, no_isoLines)
+    "Constant temperatures when using isotherms"
+    annotation (Dialog(tab="General", group="Setup Temperature",
+                enable=
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms and
+                  isoLineType==
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual)),
+                Evaluate=false,
+                HideResult=false);
+
+  parameter SorpLib.Units.Uptake x_adsorpt_min = 0.05
+    "Minimal uptake for diagram of isosters"
+    annotation (Dialog(tab="General", group="Setup Uptake",
+                enable=
+                  diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters and
+                  isoLineType<>
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual),
+                Evaluate=false,
+                HideResult=false);
+  parameter SorpLib.Units.Uptake x_adsorpt_max = 0.2
+    "Maximal uptake for diagram of isosters"
+    annotation (Dialog(tab="General", group="Setup Uptake",
+                enable=
+                  diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters and
+                  isoLineType<>
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual),
+                Evaluate=false,
+                HideResult=false);
+  parameter SorpLib.Units.Uptake[no_isoLines] x_adsorpt_const=
+    linspace(x_adsorpt_min, x_adsorpt_max, no_isoLines)
+    "Constant uptake when using isosters"
+    annotation (Dialog(tab="General", group="Setup Uptake",
+                enable=
+                  (diagramType==
+                    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters and
+                  isoLineType==
+                    SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual)),
+                Evaluate=false,
+                HideResult=false);
+
+  //
+  // Definition of parameters describing packages and models
+  //
+  replaceable model PureWorkingPairModel =
+    SorpLib.Media.WorkingPairs.PureComponents.CO2.ActivatedCarbon_Toth_DantasEtAl2011_Gas
+    constrainedby
+    SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs(
+      final stateVariables=stateVariables,
+      final calcCaloricProperties=true,
+      final calcEntropicProperties=true,
+      final calcDerivativesIsotherm=true,
+      final calcDerivativesMassEnergyBalance=true,
+      final calcDerivativesEntropyBalance=true)
+    "Pure working pair model"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Instanziation of models
+  //
+  PureWorkingPairModel[no_isoLines] pureWorkingPair(
+    final p_adsorpt=p_adsorpt,
+    final x_adsorpt=x_adsorpt,
+    final T_adsorpt=T_adsorpt)
+    "Thermodynamic properties and partial derivatives of a pure working pair";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure[no_isoLines] p_adsorpt
+    "Pressure";
+  Modelica.Units.SI.Temperature[no_isoLines] T_adsorpt
+    "Temperature";
+  SorpLib.Units.Uptake[no_isoLines] x_adsorpt
+    "Uptake";
+
+  //
+  // Definition of final parameters
+  //
+protected
+  final parameter Choices.IndependentVariablesPureComponentWorkingPair stateVariables=
+    if diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters then
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT else
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT
+    "Independent state variables of the working pair model";
+
+  //
+  // Definition of protected variables
+  //
+  Modelica.Units.SI.Pressure[no_isoLines] p_adsorpt_const_
+    "Constant pressures";
+  Modelica.Units.SI.Temperature[no_isoLines] T_adsorpt_const_
+    "Constant temperatures";
+  SorpLib.Units.Uptake[no_isoLines] x_adsorpt_const_
+    "Constant uptakes";
+
+equation
+  //
+  // Calculate constant variables
+  //
+  if isoLineType==SorpLib.Choices.ChangingConstantVariableOfDiagram.Manual then
+    p_adsorpt_const_=p_adsorpt_const
+      "Constant pressures";
+    T_adsorpt_const_=T_adsorpt_const
+      "Constant temperatures";
+    x_adsorpt_const_=x_adsorpt_const
+      "Constant uptakes";
+
+  elseif isoLineType==SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace then
+    p_adsorpt_const_=linspace(p_adsorpt_min, p_adsorpt_max, no_isoLines)
+      "Constant pressures";
+    T_adsorpt_const_=linspace(T_adsorpt_min, T_adsorpt_max, no_isoLines)
+      "Constant temperatures";
+    x_adsorpt_const_=linspace(x_adsorpt_min, x_adsorpt_max, no_isoLines)
+      "Constant uptakes";
+
+  else
+    p_adsorpt_const_=
+      {exp(log(p_adsorpt_min) + (log(p_adsorpt_max) - log(p_adsorpt_min)) *
+      (i - 1) / (no_isoLines - 1)) for i in 1:no_isoLines}
+      "Constant pressures";
+    T_adsorpt_const_=
+      {exp(log(T_adsorpt_min) + (log(T_adsorpt_max) - log(T_adsorpt_min)) *
+      (i - 1) / (no_isoLines - 1)) for i in 1:no_isoLines}
+      "Constant temperatures";
+    x_adsorpt_const_=
+      {exp(log(x_adsorpt_min) + (log(x_adsorpt_max) - log(x_adsorpt_min)) *
+      (i - 1) / (no_isoLines - 1)) for i in 1:no_isoLines}
+      "Constant uptakes";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the basic model for all models creating fluid propertey diagrams
+for working pair models describing adsorption of pure components.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the working pair
+model <i>PureWorkingPairModel</i> and the test setup. Furthermore, equations must be
+added to calculate the inputs <i>p_adsorpt</i>, <i>T_adsorpt</i>, and <i>x_adsorpt</i>
+depending on the diagram type (i.e., just two inputs are needed in each case).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureCharts;
diff --git a/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureTest.mo b/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureTest.mo
new file mode 100644
index 0000000..2aeaf08
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureTest.mo
@@ -0,0 +1,143 @@
+within SorpLib.Media.WorkingPairs.BaseClasses;
+partial model PartialPureTest
+  "Base model for all testers of pure working pair models"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters describing the test setup
+  //
+  parameter Modelica.Units.SI.Pressure p_adsorpt_start = 700
+    "Start value of pressure"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter SorpLib.Units.Uptake x_adsorpt_start = 0.10
+    "Start value of uptake"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_start = 303.15
+    "Start value of temperature"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+
+  parameter Real p_adsorpt_der(unit="Pa/s") = (0.4e5-700)/20
+    "Prescriped sloped of pressure to test working pair model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real x_adsorpt_der(unit="kg/(kg.s)") = 0.15/20
+    "Prescriped sloped of uptake to test working pair model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+  parameter Real T_adsorpt_der(unit="K/s") = 70/20
+    "Prescriped sloped of temperature to working pair model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=false,
+                HideResult=false);
+
+  parameter Choices.IndependentVariablesPureComponentWorkingPair stateVariables=
+     SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT
+    "Independent state variables of the working pair model"
+    annotation (Dialog(tab="General", group="Test setup"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters describing packages and models
+  //
+  replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.CO2.ActivatedCarbon_Toth_DantasEtAl2011_Gas
+    constrainedby
+    SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs(
+      final stateVariables=stateVariables,
+      final p_adsorpt=p_adsorpt,
+      final x_adsorpt=x_adsorpt,
+      final T_adsorpt=T_adsorpt,
+      calcAdsorptAdsorbateState=false,
+      approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron,
+      x_adsorpt_lb=1e-2)
+    "Pure working pair model"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Instanziation of models
+  //
+  PureWorkingPairModel pureWorkingPair
+    "Thermodynamic properties and partial derivatives of a pure working pair";
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure";
+  Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature";
+  SorpLib.Units.Uptake x_adsorpt
+    "Uptake";
+  SorpLib.Units.MolarUptake x_adsorpt_m=
+    x_adsorpt / pureWorkingPair.medium_adsorpt.M_adsorpt
+    "Molar uptake";
+
+initial equation
+  //
+  // Definition of start values
+  //
+  if stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+    p_adsorpt = p_adsorpt_start
+    "Pressure";
+    T_adsorpt = T_adsorpt_start
+      "Temperature";
+
+  else
+    x_adsorpt = x_adsorpt_start
+      "Uptake";
+    T_adsorpt = T_adsorpt_start
+      "Temperature";
+
+  end if;
+
+equation
+  //
+  // Definition of slopes
+  //
+  if stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT then
+    der(p_adsorpt) = p_adsorpt_der
+      "Predecsriped slope of p_adsorpt";
+    der(T_adsorpt) = T_adsorpt_der
+      "Predescriped slope of T_adsorpt";
+  else
+    der(x_adsorpt) = x_adsorpt_der
+      "Predecsriped slope of x_adsorpt";
+    der(T_adsorpt) = T_adsorpt_der
+      "Predescriped slope of T_adsorpt";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial model is the basic model for all testers of working pair models describing
+adsorption of pure components.
+<br/><br/>
+Models that inherit properties from this partial model have to specify the working pair
+model <i>PureWorkingPairModel</i> and the test setup.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureTest;
diff --git a/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureWorkingPairs.mo b/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureWorkingPairs.mo
new file mode 100644
index 0000000..82b89ef
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/BaseClasses/PartialPureWorkingPairs.mo
@@ -0,0 +1,1463 @@
+within SorpLib.Media.WorkingPairs.BaseClasses;
+partial model PartialPureWorkingPairs
+  "Base model for pure component working pairs"
+  extends Modelica.Icons.MaterialProperty;
+
+  //
+  // Definition of parameters regarding the working pair and medium
+  //
+  replaceable package WorkingPair =
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization
+    constrainedby
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization(
+      redeclare final model Sorbent = Sorbent)
+    "Parametrized working pair model"
+    annotation (Dialog(tab = "General", group = "Working Pair and Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable model Sorbent =
+    SorpLib.Media.Solids.Sorbents.RDSilicaGel
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid(
+      final calcCaloricProperties=calcCaloricProperties,
+      final calcEntropicProperties=calcEntropicProperties,
+      final p=p_adsorpt_,
+      final T=T_adsorpt,
+      final approach_v=SorpLib.Choices.SpecificVolumeSolid.Constant,
+      final p_ref=p_sorbent_ref,
+      final T_ref=T_sorbent_ref,
+      final h_ref=h_sorbent_ref,
+      final s_ref=s_sorbent_ref,
+      final tolerance_int_h=tolerance_sorbent_int_h,
+      final tolerance_int_s=tolerance_sorbent_int_s)
+    "Calculates the thermodynamic properties of the sorbent"
+    annotation (Dialog(tab = "General", group = "Working Pair and Medium"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of parameters regarding the calculation approach
+  //
+  parameter SorpLib.Choices.IndependentVariablesPureComponentWorkingPair
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT
+    "Independent state variables of the working pair model"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choicesAllMatching=true,
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean calcCaloricProperties = true
+    "= true, if caloric properties are calculated (i.e., h, u, h_ads, and cp)"
+    annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcEntropicProperties = true
+    "= true, if caloric properties are calculated (i.e., s, g, a, and s_ads)"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean calcAdsorptAdsorbateState = false
+    "= true, if state properties of average adsorpt phase and adosrbate phase are
+    calculated (i.e., requires numerical integration)"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean calcDerivativesIsotherm = true
+    "= true, if partial derivatives of isotherms required for mass, energy, and
+    entropy balance of working paur volumes are calculated"
+    annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcDerivativesMassEnergyBalance = true
+    "= true, if partial derivatives required for mass and energy balance of
+    working pair volumes are calculated"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = calcDerivativesIsotherm and calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcDerivativesEntropyBalance = true
+    "= true, if partial derivatives required for entropy balance of working
+    pair volumes are calculated"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = calcDerivativesIsotherm and
+                  calcDerivativesMassEnergyBalance and calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean adsorptiveAtDewPoint = false
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = WorkingPair.twoPhaseAdsorptive),
+                Evaluate=true,
+                choices(checkBox=true));
+
+  //
+  // Definition of parameters regarding sorption enthalpy
+  //
+  parameter SorpLib.Choices.SorptionEnthalpy approachSorptionEnthalpy=
+    SorpLib.Choices.SorptionEnthalpy.Constant
+    "Calculation approach for the sorption enthalpy"
+    annotation (Dialog(tab="Sorption Enthalpy", group="General"),
+                Evaluate=false,
+                choicesAllMatching=true);
+
+  parameter Modelica.Units.SI.SpecificEnthalpy h_ads_constant= 2750e3
+    "Constant specific enthalpy of adsorption"
+    annotation (Dialog(tab="Sorption Enthalpy", group="Constant",
+                enable=(approachSorptionEnthalpy ==
+                  SorpLib.Choices.SorptionEnthalpy.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  //
+  // Definition of parameters regarding adsorpt phase's specific heat capacity
+  //
+  parameter SorpLib.Choices.SpecificHeatCapacityAdsorpt
+    approachSpecificHeatCapacity=
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.Constant
+    "Calculation approach for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="General"),
+                Evaluate=false,
+                choicesAllMatching=true);
+
+  parameter Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt_constant= 4e3
+    "Constant specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Constant",
+                enable=(approachSpecificHeatCapacity ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  parameter SorpLib.Choices.GeneralizedFunctionApproach cp_adsorpt_function=
+      SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Generalized function used to calculate the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity",
+                group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                Evaluate=true);
+  parameter Modelica.Units.SI.Temperature T_ref_cp_adsorpt = 293.15
+    "Reference temperature for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt_ref = 1
+    "Reference fluid property data for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_cp_adsorpt[:]={cp_adsorpt_constant}
+    "Coefficients of generalized function for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real exponents_cp_adsorpt[size(coefficients_cp_adsorpt,1)]={0}
+    "Exponents of generalized function for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+
+  parameter SorpLib.Choices.InterpolationApproach cp_adsorpt_interpolation=
+      SorpLib.Choices.InterpolationApproach.Linear
+    "Interpolation approach used to calculate the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity",
+                group="Interpolation",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                Evaluate=false);
+  parameter Real abscissa_cp_adsorpt[:]={0, 1000}
+    "Known abscissa values for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real ordinate_cp_adsorpt[size(abscissa_cp_adsorpt,1)]=
+    {cp_adsorpt_constant, cp_adsorpt_constant}
+    "Known ordinate values for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificHeatCapacityAdsorpt.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  final parameter Real coefficients_cubicSplines_cp_adsorpt[size(abscissa_cp_adsorpt,1),4]=
+    SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients(
+    abscissa=abscissa_cp_adsorpt,
+    ordinate=ordinate_cp_adsorpt)
+    "Coefficient a to d for cubic polynomials for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=false),
+                HideResult=true,
+                Evaluate= true);
+
+  //
+  // Definition of parameters regarding adsorpt phase's specific volume
+  //
+  parameter Boolean neglectSpecifcVolume = false
+    "= true, if specific volume of the adsorpt is neglected (i.e., v_adsorpt = 0
+    -> u_adsorpt = h_adsorpt and g_adsorpt = a_adsorpt)"
+    annotation (Dialog(tab = "Specific Volume", group = "General"),
+                choices(checkBox=true),
+                Evaluate= false);
+  parameter SorpLib.Choices.SpecificVolumeAdsorpt approachSpecificVolume=
+      SorpLib.Choices.SpecificVolumeAdsorpt.Constant
+    "Calculation approach for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="General",
+                enable=not neglectSpecifcVolume),
+                Evaluate=false,
+                choicesAllMatching=true);
+
+  parameter Modelica.Units.SI.SpecificVolume v_adsorpt_constant= 1e-3
+    "Constant specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Constant",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  parameter SorpLib.Choices.GeneralizedFunctionApproach v_adsorpt_function=
+      SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Generalized function used to calculate the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                Evaluate=true);
+  parameter Modelica.Units.SI.Temperature T_ref_v_adsorpt = 293.15
+    "Reference temperature for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Modelica.Units.SI.SpecificVolume v_adsorpt_ref = 1
+    "Reference fluid property data for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_v_adsorpt[:]={v_adsorpt_constant}
+    "Coefficients of generalized function for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real exponents_v_adsorpt[size(coefficients_v_adsorpt,1)]={0}
+    "Exponents of generalized function for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+
+  parameter SorpLib.Choices.InterpolationApproach v_adsorpt_interpolation=
+      SorpLib.Choices.InterpolationApproach.Linear
+    "Interpolation approach used to calculate the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume",group="Interpolation",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                Evaluate=false);
+  parameter Real abscissa_v_adsorpt[:]={0, 1000}
+    "Known abscissa values for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real ordinate_v_adsorpt[size(abscissa_v_adsorpt,1)]=
+    {v_adsorpt_constant, v_adsorpt_constant}
+    "Known ordinate values for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  final parameter Real coefficients_cubicSplines_v_adsorpt[size(abscissa_v_adsorpt,1),4]=
+    SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients(
+    abscissa=abscissa_v_adsorpt,
+    ordinate=ordinate_v_adsorpt)
+    "Coefficient a to d for cubic polynomials for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=false),
+                HideResult=true,
+                Evaluate= true);
+
+  //
+  // Definition of parameters regarding advanced options
+  //
+  parameter Boolean avoidEvents = false
+    "= true, if events are avoided using the noEvent()-operator"
+    annotation (Dialog(tab = "Advanced", group = "General"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean limitLowerPressure = false
+    "= true, if pressure p_adsorpt is limited to p_adsorpt_min"
+    annotation (Dialog(tab = "Advanced", group = "Limiter"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean limitLowerPressureAdsorptive = false
+    "= true, if pressure p_adsorpt is limited to p_adsorpt_min only for property
+    calculation (i.e., properties of the adsorptive)"
+    annotation (Dialog(tab = "Advanced", group = "Limiter",
+                enable=not limitLowerPressure),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Pressure p_adsorpt_min = 615
+    "Lower limit for the pressure p_adsorpt"
+    annotation (Dialog(tab = "Advanced", group = "Limiter",
+                enable=limitLowerPressure or limitLowerPressureAdsorptive),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.Pressure p_adsorpt_lb_start = 1e3
+    "Lower bound if function p_adsorpt(x_adsorpt, T_adsorpt) is calculated numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Inverses"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Pressure p_adsorpt_ub_start = 1e4
+    "Upper bound if function p_adsorpt(x_adsorpt, T_adsorpt) is calculated numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Inverses"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_p_adsorpt = 100*Modelica.Constants.eps
+    "Tolerance if function p_adsorpt(x_adsorpt, T_adsorpt) is calculated numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Inverses"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used when calculating partial derivatives numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used when calculating partial derivatives numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Units.Uptake dx = 1e-3
+    "Uptake difference used when calculating partial derivatives numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Real tolerance_sorbent_int_h = 1e-2
+    "Integration tolerance when calculating the specific enthalpy of the sorbent
+    numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcCaloricProperties),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_sorbent_int_s = 1e-2
+    "Integration tolerance when calculating the specific entropy of the sorbent
+    numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcEntropicProperties),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_adsorpt_int_h = 1e-2
+    "Integration tolerance when calculating the specific average enthalpy of the
+    adsorpt numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcAdsorptAdsorbateState and calcCaloricProperties),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_adsorpt_int_s = 1e-2
+    "Integration tolerance when calculating the specific average entropy of the
+    adsorpt numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcAdsorptAdsorbateState and calcEntropicProperties),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_adsorpt_int_cp = 1e-2
+    "Integration tolerance when calculating the specific heat capacity of the
+    adsorpt numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcCaloricProperties and (
+                  approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan or
+                  approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificHeatCapacityAdsorpt.SchwambergerSchmidt)),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Units.Uptake x_adsorpt_lb = 0
+    "Lower limit for integral when calculating the specific heat capacity of the
+    adsorpt or uptake-averaged porperties of the adsorpt numerically (i.e., 
+    should be zero)"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcCaloricProperties and (
+                  calcAdsorptAdsorbateState or
+                  approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan or
+                  approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificHeatCapacityAdsorpt.SchwambergerSchmidt)),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.Pressure p_sorbent_ref = 1e5
+    "Reference pressure for caloric and entropic calculations (i.e., per mass 
+    sorbent)"
+    annotation (Dialog(tab="Advanced", group="Reference State - Sorbent",
+                enable=calcCaloricProperties or calcEntropicProperties),
+                Evaluate=true);
+  parameter Modelica.Units.SI.Temperature T_sorbent_ref =  298.15
+    "Reference temperature for caloric and entropic calculations (i.e., per mass 
+    sorbent)"
+    annotation (Dialog(tab="Advanced", group="Reference State - Sorbent",
+                enable=calcCaloricProperties or calcEntropicProperties),
+                Evaluate=true);
+  parameter Modelica.Units.SI.SpecificEnthalpy h_sorbent_ref=
+    WorkingPair.MediumSpecificFunctions.h_pT(
+      p=p_sorbent_ref,
+      T=T_sorbent_ref,
+      p_lb=p_adsorpt_min,
+      h_ref=0,
+      p_ref=p_sorbent_ref,
+      T_ref=T_sorbent_ref)
+    "Specific enthalpy of adsorptive at reference state (i.e., per mass sorbent)"
+    annotation (Dialog(tab="Advanced", group="Reference State - Sorbent",
+                enable=calcCaloricProperties or calcEntropicProperties),
+                Evaluate=true);
+  parameter Modelica.Units.SI.SpecificEntropy s_sorbent_ref=
+    WorkingPair.MediumSpecificFunctions.s_pT(
+      p=p_sorbent_ref,
+      T=T_sorbent_ref,
+      p_lb=p_adsorpt_min,
+      s_ref=0,
+      p_ref=p_sorbent_ref,
+      T_ref=T_sorbent_ref)
+    "Specific entropy of adsorptive at reference state (i.e., per mass sorbent)"
+    annotation (Dialog(tab="Advanced", group="Reference State - Sorbent",
+                enable=calcEntropicProperties),
+                Evaluate=true);
+
+  //
+  // Definition of inputs
+  //
+  input SorpLib.Units.Uptake x_adsorpt
+    "Equilibrium uptake"
+    annotation (Dialog(tab = "General", group = "Inputs",
+                enable=false));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature"
+    annotation (Dialog(tab = "General", group = "Inputs",
+                enable=false));
+
+  //
+  // Definition of outputs
+  //
+  output Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure"
+    annotation (Dialog(tab = "General", group = "Outputs", enable = false));
+
+  output SorpLib.Media.WorkingPairs.Records.StateVariables state_sorbent
+    "State properties of the sorbent (i.e., per sorbent mass)"
+    annotation (Dialog(tab = "General", group = "Outputs", enable = false));
+  output SorpLib.Media.WorkingPairs.Records.StateVariables state_lastAdsorbedMolecule
+    "State properties of the last adsorbed molecule (i.e., per adsorptive/adsorpt 
+    mass)"
+    annotation (Dialog(tab = "General", group = "Outputs", enable = false));
+  output SorpLib.Media.WorkingPairs.Records.StateVariables state_averageAdsorpt
+    "State properties of the uptake-averaged adsorpt (i.e., per adsorptive/
+    adsorpt mass)"
+    annotation (Dialog(tab = "General", group = "Outputs", enable = false));
+  output SorpLib.Media.WorkingPairs.Records.StateVariables state_averageAdsorbate
+    "State properties of the adsorbate (i.e., per sorbent mass)"
+    annotation (Dialog(tab = "General", group = "Outputs", enable = false));
+  output SorpLib.Media.WorkingPairs.Records.StateVariables state_adsorptive
+    "State properties of the vapor/gas (i.e., per adsorptive/adsorpt mass)"
+    annotation (Dialog(tab = "General", group = "Outputs", enable = false));
+
+  output SorpLib.Media.WorkingPairs.Records.DerivativesPureIsothermModel
+    derivatives_isotherm "Partial derivatives of the isotherm model"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+  output SorpLib.Media.WorkingPairs.Records.DerivativesPureMassEnergyBalances
+    derivatives_massEnergy
+    "Partial derivatives regarding mass and energy balances"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+  output SorpLib.Media.WorkingPairs.Records.DerivativesPureEntropyBalance
+    derivatives_entropy "Partial derivatives regarding entropy balances"
+    annotation (Dialog(
+      tab="General",
+      group="Outputs",
+      enable=false));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.SpecificEnthalpy h_ads(displayUnit="kJ/kg")
+    "Specific enthalpy of adsorption";
+  Modelica.Units.SI.SpecificEntropy s_ads(displayUnit="kJ/(kg.K)")
+    "Specific entropy of adsorption";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt
+    "Specific heat capacity of the adsorpt";
+
+  //
+  // Instantiation of models
+  //
+  WorkingPair.Sorbent medium_sorbent
+    "State properties of the sorbent";
+
+  WorkingPair.AdsorptProperties medium_adsorpt(
+    final stateVariables=stateVariables,
+    final calcCaloricProperties=calcCaloricProperties,
+    final calcEntropicProperties=calcEntropicProperties,
+    final calcAdsorptAdsorbateState=calcAdsorptAdsorbateState,
+    final calcDerivativesIsotherm=calcDerivativesIsotherm,
+    final calcDerivativesMassEnergyBalance=calcDerivativesMassEnergyBalance,
+    final calcDerivativesEntropyBalance=calcDerivativesEntropyBalance,
+    final adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+    final c=isothermCoefficients.c,
+    final dc_dT_adsorpt=isothermCoefficients.dc_dT,
+    final ddc_dT_adsorpt_dT_adsorpt=isothermCoefficients.ddc_dT_dT,
+    final p_adsorpt=p_adsorpt_,
+    final T_adsorpt=T_adsorpt,
+    final x_adsorpt=x_adsorpt,
+    final properties_adsorptive=medium_adsorptive.properties,
+    final approachSorptionEnthalpy=approachSorptionEnthalpy,
+    final h_ads_constant=h_ads_constant,
+    final approachSpecificHeatCapacity = approachSpecificHeatCapacity,
+    final cp_adsorpt_constant = cp_adsorpt_constant,
+    final cp_adsorpt_function = cp_adsorpt_function,
+    final T_ref_cp_adsorpt = T_ref_cp_adsorpt,
+    final cp_adsorpt_ref = cp_adsorpt_ref,
+    final coefficients_cp_adsorpt = coefficients_cp_adsorpt,
+    final exponents_cp_adsorpt = exponents_cp_adsorpt,
+    final cp_adsorpt_interpolation = cp_adsorpt_interpolation,
+    final abscissa_cp_adsorpt = abscissa_cp_adsorpt,
+    final ordinate_cp_adsorpt = ordinate_cp_adsorpt,
+    final coefficients_cubicSplines_cp_adsorpt = coefficients_cubicSplines_cp_adsorpt,
+    final neglectSpecifcVolume=neglectSpecifcVolume,
+    final approachSpecificVolume=approachSpecificVolume,
+    final v_adsorpt_constant=v_adsorpt_constant,
+    final v_adsorpt_function=v_adsorpt_function,
+    final T_ref_v_adsorpt=T_ref_v_adsorpt,
+    final v_adsorpt_ref=v_adsorpt_ref,
+    final coefficients_v_adsorpt=coefficients_v_adsorpt,
+    final exponents_v_adsorpt=exponents_v_adsorpt,
+    final v_adsorpt_interpolation=v_adsorpt_interpolation,
+    final abscissa_v_adsorpt=abscissa_v_adsorpt,
+    final ordinate_v_adsorpt=ordinate_v_adsorpt,
+    final coefficients_cubicSplines_v_adsorpt=coefficients_cubicSplines_v_adsorpt,
+    final p_adsorpt_min=p_adsorpt_min,
+    final dp=dp,
+    final dT=dT,
+    final tolerance_adsorpt_int_h=tolerance_adsorpt_int_h,
+    final tolerance_adsorpt_int_s=tolerance_adsorpt_int_s,
+    final tolerance_adsorpt_int_cp=tolerance_adsorpt_int_cp,
+    final x_adsorpt_lb=x_adsorpt_lb)
+    "Properties of the adsorptive required for calculation: These properties are
+    calculated at once to save computational costs";
+
+  WorkingPair.MediumSpecificFunctions.AdsorptiveProperties medium_adsorptive(
+    final calcCaloricProperties=calcCaloricProperties,
+    final calcEntropicProperties=calcEntropicProperties,
+    final calcAdsorptAdsorbateState=calcAdsorptAdsorbateState,
+    final calcDerivativesIsotherm=calcDerivativesIsotherm,
+    final calcDerivativesMassEnergyBalance=calcDerivativesMassEnergyBalance,
+    final calcDerivativesEntropyBalance=calcDerivativesEntropyBalance,
+    final adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+    final neglectSpecifcVolume=neglectSpecifcVolume,
+    final approachSpecificVolume=approachSpecificVolume,
+    final approachSpecificHeatCapacity=approachSpecificHeatCapacity,
+    final approachSorptionEnthalpy=approachSorptionEnthalpy,
+    final dp=dp,
+    final dT=dT,
+    final p=if limitLowerPressure then p_adsorpt_ elseif
+      limitLowerPressureAdsorptive then max(p_adsorpt_min, p_adsorpt_) else
+      p_adsorpt_,
+    final T=T_adsorpt)
+    "Properties of the adsorptive required for calculation: These properties are
+    calculated at once to save computational costs";
+
+  WorkingPair.IsothermCoefficients isothermCoefficients(
+    final T_adsorpt=T_adsorpt,
+    final dT=dT)
+    "Temperature-dependent isotherm coefficients";
+
+  //
+  // Booleans indicating which variables msut be calculated
+  //
+protected
+  parameter Boolean require_derivativesMassEnergyBalances_pT=
+    (calcCaloricProperties and calcDerivativesIsotherm and
+    calcDerivativesMassEnergyBalance)
+    "= true, if partial derivatives of mass and energy balances w.r.t. pressure 
+    and temperature are required";
+  parameter Boolean require_derivativesMassEnergyBalances_xT=
+    (require_derivativesMassEnergyBalances_pT and stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT)
+    "= true, if partial derivatives of mass and energy balances w.r.t. uptake 
+    and temperature are required";
+
+  parameter Boolean require_derivativesEntropyBalances_pT=
+    (require_derivativesMassEnergyBalances_pT and calcDerivativesEntropyBalance)
+    "= true, if partial derivatives of the entropy balance w.r.t. pressure and
+    temperature are required";
+  parameter Boolean require_derivativesEntropyBalances_xT=
+    (require_derivativesEntropyBalances_pT and stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT)
+    "= true, if partial derivatives of the entropy balance w.r.t. uptake and
+    temperature are required";
+
+  //
+  // Auxillary variables
+  //
+  Modelica.Units.SI.Pressure p_adsorpt_
+    "Equilibrium pressure that might be limited";
+
+equation
+  //
+  // Pass state properties of the sorbent (per sorbent mass)
+  //
+  state_sorbent = medium_sorbent.state_variables
+    "State properties of the sorbent (i.e., per sorbent mass)";
+
+  //
+  // Calculate thermal state properties of the last adsorbed molecule
+  // (per adsorptive/adsorpt mass)
+  //
+  if stateVariables ==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT then
+    p_adsorpt_ = if limitLowerPressure then
+      max(p_adsorpt_min, WorkingPair.IsothermModel.p_xT(
+        x_adsorpt=x_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=isothermCoefficients.c,
+        p_adsorpt_lb_start=p_adsorpt_lb_start,
+        p_adsorpt_ub_start=p_adsorpt_ub_start,
+        tolerance=tolerance_p_adsorpt)) else
+      WorkingPair.IsothermModel.p_xT(
+        x_adsorpt=x_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=isothermCoefficients.c,
+        p_adsorpt_lb_start=p_adsorpt_lb_start,
+        p_adsorpt_ub_start=p_adsorpt_ub_start,
+        tolerance=tolerance_p_adsorpt)
+      "Equilibrium pressure that might be limited";
+
+    p_adsorpt = p_adsorpt_
+      "Equilibrium pressure";
+
+  else
+    p_adsorpt_ = if limitLowerPressure
+      then max(p_adsorpt_min, p_adsorpt) else p_adsorpt
+      "Equilibrium pressure that might be limited";
+
+    x_adsorpt = WorkingPair.IsothermModel.x_pT(
+      p_adsorpt= p_adsorpt_,
+      T_adsorpt=T_adsorpt,
+      c=isothermCoefficients.c,
+      p_adsorpt_lb_start=p_adsorpt_lb_start,
+      p_adsorpt_ub_start=p_adsorpt_ub_start,
+      tolerance=tolerance_p_adsorpt)
+      "Equilibrium uptake";
+
+  end if;
+
+  state_lastAdsorbedMolecule.p = p_adsorpt_
+    "Equilibrium pressure";
+  state_lastAdsorbedMolecule.T = T_adsorpt
+    "Equilibrium temperautre";
+
+  state_lastAdsorbedMolecule.v = if neglectSpecifcVolume then 0 else
+      medium_adsorpt.properties.v
+      "Specific volume of the adsorpt";
+
+  //
+  // Calculate caloric state properties of the last adsorbed molecule
+  // (per adsorptive/adsorpt mass)
+  //
+  state_lastAdsorbedMolecule.h =
+    if not calcCaloricProperties then 0 else
+    medium_adsorptive.properties.state.h - h_ads
+    "Specific enthalpy of the adsorpt";
+  state_lastAdsorbedMolecule.u =
+    if not calcCaloricProperties then 0 else
+    state_lastAdsorbedMolecule.h - state_lastAdsorbedMolecule.p *
+    state_lastAdsorbedMolecule.v
+    "Specific internal energy of the adsorpt";
+
+  //
+  // Calculate entropic state properties of the last adsorbed molecule
+  // (per adsorptive/adsorpt mass)
+  //
+  state_lastAdsorbedMolecule.s =
+    if not (calcCaloricProperties and calcEntropicProperties) then 0 else
+    medium_adsorptive.properties.state.s - s_ads
+    "Specific entropy of the adsorpt";
+  state_lastAdsorbedMolecule.g =
+    if not (calcCaloricProperties and calcEntropicProperties) then 0 else
+    state_lastAdsorbedMolecule.h - T_adsorpt * state_lastAdsorbedMolecule.s
+    "Free enthalpy (i.e., Gibbs free energy) of the adsorpt";
+  state_lastAdsorbedMolecule.a =
+    if not (calcCaloricProperties and calcEntropicProperties) then 0 else
+    state_lastAdsorbedMolecule.u - T_adsorpt * state_lastAdsorbedMolecule.s
+    "Free energy (i.e., Helmholts free energy) of the adsorpt";
+
+  //
+  // Pass state properties of the uptake-averaged adsorpt
+  // (per adsorptive/adsorpt mass)
+  //
+  state_averageAdsorpt.p = medium_adsorpt.properties.state.p
+    "Equilibrium pressure";
+  state_averageAdsorpt.T = medium_adsorpt.properties.state.T
+    "Equilibrium temperature";
+  state_averageAdsorpt.v = medium_adsorpt.properties.state.v
+    "Uptake-averaged specific volume of the adsorpt";
+
+  state_averageAdsorpt.h = medium_adsorpt.properties.state.h
+    "Uptake-averaged specific enthalpy of the adsorpt";
+  state_averageAdsorpt.u = medium_adsorpt.properties.state.u
+    "Uptake-averaged specific internal energy of the adsorpt";
+
+  state_averageAdsorpt.s = medium_adsorpt.properties.state.s
+    "Uptake-averaged specific entropy of the adsorpt";
+  state_averageAdsorpt.g = medium_adsorpt.properties.state.g
+    "Uptake-averaged specific free enthalpy (i.e., Gibbs free energy) of the 
+    adsorpt";
+  state_averageAdsorpt.a = medium_adsorpt.properties.state.a
+    "Uptake-averaged specific free energy (i.e., Helmholts free energy) of the 
+    adsorpt";
+
+  //
+  // Pass state properties of the uptake-averaged adsorbate (per sorbent mass)
+  //
+  state_averageAdsorbate.p = if not calcAdsorptAdsorbateState then 0 else
+    state_averageAdsorpt.p
+    "Equilibrium pressure";
+  state_averageAdsorbate.T = if not calcAdsorptAdsorbateState then 0 else
+    state_averageAdsorpt.T
+    "Equilibrium temperature";
+  state_averageAdsorbate.v = if not calcAdsorptAdsorbateState then 0 else
+    state_sorbent.v + x_adsorpt * state_averageAdsorpt.v
+    "Uptake-averaged specific volume of the adsorbate";
+
+  state_averageAdsorbate.h = if not calcAdsorptAdsorbateState then 0 else
+    state_sorbent.h + x_adsorpt * state_averageAdsorpt.h
+    "Uptake-averaged specific enthalpy of the adsorbate";
+  state_averageAdsorbate.u = if not calcAdsorptAdsorbateState then 0 else
+    state_sorbent.u + x_adsorpt * state_averageAdsorpt.u
+    "Uptake-averaged specific internal energy of the adsorbate";
+
+  state_averageAdsorbate.s = if not calcAdsorptAdsorbateState then 0 else
+    state_sorbent.s + x_adsorpt * state_averageAdsorpt.s
+    "Uptake-averaged specific entropy of the adsorbate";
+  state_averageAdsorbate.g = if not calcAdsorptAdsorbateState then 0 else
+    state_sorbent.g + x_adsorpt * state_averageAdsorpt.g
+    "Uptake-averaged specific free enthalpy (i.e., Gibbs free energy) of the 
+     adsorbate";
+  state_averageAdsorbate.a = if not calcAdsorptAdsorbateState then 0 else
+    state_sorbent.a + x_adsorpt * state_averageAdsorpt.a
+    "Uptake-averaged specific free energy (i.e., Helmholts free energy) of the 
+     adsorbate";
+
+  //
+  // Pass state properties of the adsorptive (per adsorptive/adsorpt mass)
+  //
+  state_adsorptive = medium_adsorptive.properties.state
+    "State properties of the adsorptive at vapor/gas phase";
+
+  //
+  // Pass and calculate additional properties
+  //
+  h_ads = medium_adsorpt.properties.h_ads
+    "Specific enthalpy of adsorption";
+  s_ads =
+    if not (calcCaloricProperties and calcEntropicProperties) then 0 else
+    h_ads / T_adsorpt
+    "Specific entropy of adsorption";
+
+  cp_adsorpt = medium_adsorpt.properties.cp
+    "Specific heat capacity of the adsorpt";
+
+  //
+  // Pass partial derivatives of the isotherm model
+  //
+  derivatives_isotherm.dx_dp_T =
+    medium_adsorpt.properties.derivatives_isotherm.dx_dp_T
+    "Partial derivative of the uptake w.r.t. pressure at constant temperature";
+  derivatives_isotherm.dx_dT_p =
+    medium_adsorpt.properties.derivatives_isotherm.dx_dT_p
+    "Partial derivative of the uptake w.r.t. temperature at constant pressure";
+
+  derivatives_isotherm.dp_dx_T =
+    medium_adsorpt.properties.derivatives_isotherm.dp_dx_T
+    "Partial derivative of the uptake w.r.t. uptake at constant temperature";
+  derivatives_isotherm.dp_dT_x =
+    medium_adsorpt.properties.derivatives_isotherm.dp_dT_x
+    "Partial derivative of the uptake w.r.t. temperature at constant uptake";
+
+  //
+  // Pass and calculate partial derivatives regarding the mass and energy balance
+  //
+  derivatives_massEnergy.dv_sorbent_dp_T =
+    if not require_derivativesMassEnergyBalances_pT then 0 else 0
+    "Partial derivative of the specific volume of the sorbent w.r.t. pressure at 
+    constant temperature (i.e., ideal solid: v_solid = const.)";
+  derivatives_massEnergy.dv_sorbent_dT_p =
+    if not require_derivativesMassEnergyBalances_pT then 0 else 0
+    "Partial derivative of the specific volume of the sorbent w.r.t. temperature 
+    at constant pressure (i.e., ideal solid: v_solid = const.";
+  derivatives_massEnergy.dv_sorbent_dx_T =
+    if not require_derivativesMassEnergyBalances_xT then 0 else
+    derivatives_massEnergy.dv_sorbent_dp_T * derivatives_isotherm.dp_dx_T
+    "Partial derivative of the specific volume of the sorbent w.r.t. uptake at 
+    constant temperature";
+  derivatives_massEnergy.dv_sorbent_dT_x =
+    if not require_derivativesMassEnergyBalances_xT then 0 else
+    derivatives_massEnergy.dv_sorbent_dT_p +
+    derivatives_massEnergy.dv_sorbent_dp_T * derivatives_isotherm.dp_dT_x
+    "Partial derivative of the specific volume of the sorbent w.r.t. temperature 
+    at constant uptake";
+
+  derivatives_massEnergy.dh_sorbent_dp_T =
+    if not require_derivativesMassEnergyBalances_pT then 0 else
+    state_sorbent.v
+    "Partial derivative of the specific enthalpy of the sorbent w.r.t. pressure
+    at constant temperature (i.e., beta_sorbent = 0)";
+  derivatives_massEnergy.dh_sorbent_dT_p =
+    if not require_derivativesMassEnergyBalances_pT then 0 else
+    medium_sorbent.additional_variables.c
+    "Partial derivative of the specific enthalpy of the sorbent w.r.t. temperature
+    at constant pressure";
+  derivatives_massEnergy.dh_sorbent_dx_T =
+    if not require_derivativesMassEnergyBalances_xT then 0 else
+    derivatives_massEnergy.dh_sorbent_dp_T * derivatives_isotherm.dp_dx_T
+    "Partial derivative of the specific enthalpy of the sorbent w.r.t. uptake
+    at constant temperature";
+  derivatives_massEnergy.dh_sorbent_dT_x =
+    if not require_derivativesMassEnergyBalances_xT then 0 else
+    derivatives_massEnergy.dh_sorbent_dT_p +
+    derivatives_massEnergy.dh_sorbent_dp_T * derivatives_isotherm.dp_dT_x
+    "Partial derivative of the specific enthalpy of the sorbent w.r.t. temperature
+    at constant uptake";
+
+  derivatives_massEnergy.dxv_avg_adsorpt_dp_T =
+    if not require_derivativesMassEnergyBalances_pT then 0 else
+    medium_adsorpt.properties.dxv_avg_dp_T
+    "Partial derivative of the uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. pressure at constant temperature";
+  derivatives_massEnergy.dxv_avg_adsorpt_dT_p =
+    if not require_derivativesMassEnergyBalances_pT then 0 else
+    medium_adsorpt.properties.dxv_avg_dT_p
+    "Partial derivative of the uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. temperature at constant pressure";
+  derivatives_massEnergy.dxv_avg_adsorpt_dx_T =
+    if not require_derivativesMassEnergyBalances_xT then 0 else
+    derivatives_massEnergy.dxv_avg_adsorpt_dp_T * derivatives_isotherm.dp_dx_T
+    "Partial derivative of the uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. uptake at constant temperature";
+  derivatives_massEnergy.dxv_avg_adsorpt_dT_x =
+    if not require_derivativesMassEnergyBalances_xT then 0 else
+    derivatives_massEnergy.dxv_avg_adsorpt_dT_p +
+    derivatives_massEnergy.dxv_avg_adsorpt_dp_T * derivatives_isotherm.dp_dT_x
+    "Partial derivative of the uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. temperature at constant uptake";
+
+  derivatives_massEnergy.dxh_avg_adsorpt_dp_T =
+    if not require_derivativesMassEnergyBalances_pT then 0 else
+    medium_adsorpt.properties.dxh_avg_dp_T
+    "Partial derivative of the uptake-averaged specific enthalpy of the adsorpt 
+    times the uptake w.r.t. pressure at constant temperature";
+  derivatives_massEnergy.dxh_avg_adsorpt_dT_p =
+    if not require_derivativesMassEnergyBalances_pT then 0 else
+    medium_adsorpt.properties.dxh_avg_dT_p
+    "Partial derivative of the uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. temperature at constant pressure";
+  derivatives_massEnergy.dxh_avg_adsorpt_dx_T =
+    if not require_derivativesMassEnergyBalances_xT then 0 else
+    medium_adsorpt.properties.dxh_avg_dx_T
+    "Partial derivative of the uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. uptake at constant temperature";
+  derivatives_massEnergy.dxh_avg_adsorpt_dT_x =
+    if not require_derivativesMassEnergyBalances_xT then 0 else
+    medium_adsorpt.properties.dxh_avg_dT_x
+    "Partial derivative of the uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. temperature at constant uptake";
+
+  //
+  // Pass and calculate partial derivatives regarding the entropy balance
+  //
+  derivatives_entropy.ds_sorbent_dp_T =
+    if not require_derivativesEntropyBalances_pT then 0 else 0
+    "Partial derivative of the specific entropy of the sorbent w.r.t. pressure
+    at constant temperature (i.e., ideal solid: v_solid = const.)";
+  derivatives_entropy.ds_sorbent_dT_p =
+    if not require_derivativesEntropyBalances_pT then 0 else
+    medium_sorbent.additional_variables.c / T_adsorpt
+    "Partial derivative of the specific entropy of the sorbent w.r.t. temperature
+    at constant pressure";
+  derivatives_entropy.ds_sorbent_dx_T =
+    if not require_derivativesEntropyBalances_xT then 0 else
+    derivatives_entropy.ds_sorbent_dp_T * derivatives_isotherm.dp_dx_T
+    "Partial derivative of the specific entropy of the sorbent w.r.t. uptake
+    at constant temperature";
+  derivatives_entropy.ds_sorbent_dT_x =
+    if not require_derivativesEntropyBalances_xT then 0 else
+    derivatives_entropy.ds_sorbent_dT_p +
+    derivatives_entropy.ds_sorbent_dp_T * derivatives_isotherm.dp_dT_x
+    "Partial derivative of the specific entropy of the sorbent w.r.t. temperature
+    at constant uptake";
+
+  derivatives_entropy.dxs_avg_adsorpt_dp_T =
+    if not require_derivativesEntropyBalances_pT then 0 else
+    medium_adsorpt.properties.dxs_avg_dp_T
+    "Partial derivative of the uptake-averaged specific entropy of the adsorpt
+    times the uptake w.r.t. pressure at constant temperature";
+  derivatives_entropy.dxs_avg_adsorpt_dT_p =
+    if not require_derivativesEntropyBalances_pT then 0 else
+    medium_adsorpt.properties.dxs_avg_dT_p
+    "Partial derivative of the uptake-averaged specific entropy of the adsorpt
+    times the uptake w.r.t. temperature at constant pressure";
+  derivatives_entropy.dxs_avg_adsorpt_dx_T =
+    if not require_derivativesEntropyBalances_xT then 0 else
+    medium_adsorpt.properties.dxs_avg_dx_T
+    "Partial derivative of the uptake-averaged specific entropy of the adsorpt
+    times the uptake w.r.t. uptake at constant temperature";
+  derivatives_entropy.dxs_avg_adsorpt_dT_x =
+    if not require_derivativesEntropyBalances_xT then 0 else
+    medium_adsorpt.properties.dxs_avg_dT_x
+    "Partial derivative of the uptake-averaged specific entropy of the adsorpt 
+    times the uptake w.r.t. temperature at constant uptake";
+
+  //
+  // Assertations
+  //
+  if adsorptiveAtDewPoint then
+    assert(WorkingPair.twoPhaseAdsorptive,
+      "Selected adsorptive medium model does not have a two-phase regime. " +
+      "Cannot calculate state properties of dew point at T_adsorpt.",
+      level = AssertionLevel.error);
+  end if;
+
+  if approachSpecificVolume ==
+    SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve then
+    assert(WorkingPair.twoPhaseAdsorptive,
+      "Selected adsorptive medium model does not have a two-phase regime. " +
+      "Cannot calculate specific volume of the adsorpt at the bubble point.",
+      level = AssertionLevel.error);
+  end if;
+
+  if approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve then
+    assert(WorkingPair.twoPhaseAdsorptive,
+      "Selected adsorptive medium model does not have a two-phase regime. " +
+      "Cannot calculate specific heat capacity of the adsorpt at the bubble point.",
+      level = AssertionLevel.error);
+  end if;
+
+  if approachSorptionEnthalpy == SorpLib.Choices.SorptionEnthalpy.Dubinin then
+    assert(WorkingPair.modelOfDubinin,
+      "You cannot calculate the specific enthaly of adsorption using the model " +
+      "of Dubinin if the isotherm model is not the model of Dubinin.",
+      level = AssertionLevel.error);
+
+    assert(WorkingPair.twoPhaseAdsorptive,
+      "Selected adsorptive medium model does not have a two-phase regime. " +
+      "Cannot calculate specific enthalpy of adsorption according to Dubinin.",
+      level = AssertionLevel.error);
+  end if;
+
+  if calcAdsorptAdsorbateState then
+    assert(calcCaloricProperties,
+      "You cannot calculate uptake-averaged adsorpt and adsorbate properties if " +
+      "you do not calculate at least caloric properties.",
+      level = AssertionLevel.error);
+  end if;
+
+  if calcEntropicProperties then
+    assert(calcCaloricProperties,
+      "You cannot calculate entropic properties if you do not calculate caloric " +
+      "properties.",
+      level = AssertionLevel.error);
+  end if;
+
+  if calcDerivativesEntropyBalance then
+    assert(calcCaloricProperties,
+      "You cannot calculate partial derivatives for the mass and energy balances " +
+      "if you do not calculate caloric properties.",
+      level = AssertionLevel.error);
+
+    assert(calcDerivativesIsotherm,
+      "You cannot calculate partial derivatives for the mass and energy balances " +
+      "if you do not calculate partial derivatives of the isotherm models.",
+      level = AssertionLevel.error);
+  end if;
+
+  if calcDerivativesEntropyBalance then
+    assert(calcCaloricProperties,
+      "You cannot calculate partial derivatives for the entropy balance if you " +
+      "do not calculate caloric properties.",
+      level = AssertionLevel.error);
+
+    assert(calcDerivativesIsotherm,
+      "You cannot calculate partial derivatives for the entropy balance if you " +
+      "do not calculate partial derivatives of the isotherm models.",
+      level = AssertionLevel.error);
+
+    assert(calcDerivativesMassEnergyBalance,
+      "You cannot calculate partial derivatives for the entropy balance if you " +
+      "do not calculate partial derivatives of the mass and energy balances.",
+      level = AssertionLevel.error);
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the thermodynamic properties of a working pair. 
+Specifically, the properties of the sorbent, the adsorpt (i.e. only 
+the adsorbed molecules), the adsorbate (i.e. sorbent and adsorpt) and 
+the adsorptive (i.e. gas/vapor phase) are calculated. Depending on 
+the model settings, only common state variables such as pressure, 
+temperature, loading, and specific enthalpy are calculated. Note that 
+adsorption is very heterogeous, so the adsorpt phase is not homogenous. 
+Therefore, macroscopic averaging can be applied using the loading for 
+averaging. As this averaging requires solving integrals numerically, it
+should only be done if required. In addition to the phase properties, 
+partial derivatives can also be calculated, which are required for 
+dynamic mass, energy, and entropy balances in a working pair volume.
+</p>
+
+<h4>Main equations for the last adsorbed molecule</h4>
+<p>
+The adsorption equilibrium is calculated via an isotherm model, thus 
+connecting the uptake, pressure, and temperature:
+</p>
+<pre>
+    x<sub>adsorpt</sub>(p<sub>adsorpt</sub>, T<sub>adsorpt</sub>);
+</pre>
+<p>
+For details on available isotherm models, check the package
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEquilibria\">SorpLib.Media.Functions.SorptionEquilibria</a>.
+</p>
+
+<p>
+The specific average enthalpy of the last adsorbed molecule
+<i>h<sub>adsorpt</sub></i> is calculated as
+</p>
+<pre>
+    h<sub>adsorpt</sub> = h<sub>adsorptive</sub> - &Delta;h<sub>ads</sub>;
+</pre>
+<p>
+and the specific entropy of the last adsorpbed molecule 
+<i>s<sub>adsorpt</sub></i> is calculated as
+</p>
+<pre>
+    s<sub>adsorpt</sub> = s<sub>adsorptive</sub> - &Delta;h<sub>ads</sub> / T<sub>adsorpt</sub>;
+</pre>
+<p>
+Herein, <i>h<sub>adsorptive</sub></i>/<i>s<sub>adsorptive</sub></i> is 
+the specific enthalpy/entropy of the adsorptive and <i>&Delta;h<sub>ads</sub></i> 
+is the specific enthalpy of adsorption. For the specific enthalpy of 
+adsorption, different calculation approaches are implemented. For details, 
+check the package
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies\">SorpLib.Media.Functions.SorptionEnthalpies</a>.
+</p>
+
+<p>
+Knowing the specific enthalpy of the adsorpt, the specific internal 
+energy ofthe last adsorbed molecule <i>u<sub>adsorpt</sub></i> is 
+calculated as
+</p>
+<pre>
+    u<sub>adsorpt</sub> = h<sub>adsorpt</sub> - p<sub>adsorpt</sub> * v<sub>adsorpt</sub>;
+</pre>
+<p>
+Herein, <i>v<sub>adsorpt</sub></i> is the specific volume of the 
+adsorpt, which can be calculated using different approaches. For 
+details, check the enumeration
+<a href=\"Modelica://SorpLib.Choices.SpecificVolumeAdsorpt\">SorpLib.Choices.SpecificVolumeAdsorpt</a>.
+</p>
+
+<h4>Main equations for the uptake-averaged adsorpt (i.e., macroscopic properties)</h4>
+<p>
+The adsorption phenomenon is very heterogeneous, so the adsorpt 
+phase is typically not homogeneous. Therefore, macroscopic 
+averaging is performed using the loading <i>x<sub>adsorpt</sub></i> 
+to obtain average, homogeneous fluid properties
+<i><SPAN STYLE=\"text-decoration:overline\">z</SPAN><sub>adsorpt</sub></i>:
+</p>
+<pre>
+    <SPAN STYLE=\"text-decoration:overline\">z</SPAN><sub>adsorpt</sub> = 1/x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:underline\">z</SPAN><sub>adsorpt</sub> = 1/x<sub>adsorpt</sub> * &int;_0^x<sub>adsorpt</sub> [z(x',T<sub>adsorpt</sub>)] dx';
+</pre>
+<p>
+Herein, loading <i>x<sub>adsorpt</sub></i> and temperature <i>T<sub>adsorpt</sub></i> 
+are assumed to independent state properties. This averaging must be 
+performed for all fluid quantities except for pressure <i>p<sub>adsorpt</sub></i> 
+(mechanical equilibrium), temperature <i>T<sub>adsorpt</sub></i> (thermal 
+equilibrium), and, consequently, loading <i>x<sub>adsorpt</sub></i>. 
+Since the specific volume of the adsorpt phase <i>v<sub>adsorpt</sub></i> 
+depends only on temperature (see assumptions), it already is a macroscopic
+property and no averaging is necessary.
+</p>
+
+<h4>Main equations for uptake-averaged adsorbate</h4>
+Sstate properties <i>z</i> of the adsorbate are calculated as
+</p>
+<pre>
+    z<sub>adsorbate</sub> = z<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">z</SPAN><sub>adsorpt</sub>;
+</pre>
+<p>
+and, thus, are given per unit sorbent mass.
+</p>
+
+<h4>Main equations for partial derivatives required for mass, energy, and entropy balances</h4>
+<p>
+Transient governing equations are used in finite volume models under 
+<a href=\"Modelica://SorpLib.Basics.Volumes.Adsorbates.\">SorpLib.Basics.Volumes.Adsorbates</a>.
+This requires partial differential equations, which have to be calculated 
+partially for the uptake-averaged properties. The required partial 
+derivatives vary with the selected independent differential states, which 
+can be either pressure <i>p<sub>adsorpt</sub></i> and temperature 
+<i>T<sub>adsorpt</sub></i> or loading <i>x<sub>adsorpt</sub></i> and 
+temperature <i>T<sub>adsorpt</sub></i>.
+</p>
+
+<p>
+For all conservation equations, partial derivatives of the isotherm 
+model are provided to switch between the independent differential states:
+</p>
+<ul>
+  <li>
+  <i>(&part;x/&part;p)<sub>T</sub></i>: 
+  Partial derivative of the loading w.r.t. to pressure at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;x/&part;T)<sub>p</sub></i>: 
+  Partial derivative of the loading w.r.t. to temperature at 
+  constant pressure.
+  </li>
+  <li>
+  <i>(&part;p/&part;x)<sub>T</sub> = 1 / (&part;x/&part;p)<sub>T</sub></i>: 
+  Partial derivative of the pressure w.r.t. to loading at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;p/&part;T)<sub>x</sub> = -(&part;x/&part;T)<sub>p</sub> / (&part;x/&part;p)<sub>T</sub></i>: 
+  Partial derivative of the pressure w.r.t. to temperature at 
+  constant loading.
+  </li>
+</ul>
+
+<p>
+The specific volume of the sorbent <i>v<sub>sor</sub></i> is constant 
+(see assumptions), so the mass of the sorbent <i>m<sub>sor</sub></i> 
+does not change with the properties of the substance. The mass balance 
+of the adsorpt is expressed directly in terms of the loading 
+<i>x<sub>adsorpt</sub></i>, so no partial derivatives of the density 
+are required either.
+</p>
+
+<p>
+The energy balance of an adsorbate volume can be derived from the 
+definition of the internal energy of the adsorbate volume 
+<i>U<sub>adsorbate</sub></i>:
+</p>
+<pre>
+    U<sub>adsorbate</sub> = m<sub>sor</sub> * u<sub>sor</sub> + m<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub> = m<sub>sor</sub> * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>];
+</pre>
+<p>
+Thus, the total differential of the  internal energy of the adsorbate 
+volume <i>dU<sub>adsorbate</sub></i> is:
+</p>
+<pre>
+    dU<sub>adsorbate</sub> = dm<sub>sor</sub> * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [du<sub>sor</sub> + d(x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>)] = dm<sub>sor</sub> * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [du<sub>sor</sub> + d<SPAN STYLE=\"text-decoration:underline\">u</SPAN><sub>adsorpt</sub>];
+</pre>
+<p>
+The total differential <i>dU<sub>adsorbate</sub></i> can be further 
+simplified if the definition of the specific internal energy 
+<i>u = h - p * v</i> is used and then the macroscopic quantities of 
+the adsorpt (pressure <i>p = p<sub>adsorpt</sub></i>, temperature 
+<i>T = T<sub>adsorpt</sub></i>, and specific volume <i>v<sub>adsorpt</sub></i>) 
+are taken into account:
+</p>
+<pre>
+    dU<sub>adsorbate</sub> = dm<sub>sor</sub> * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [dh<sub>sor</sub> - p * dv<sub>sor</sub> - v<sub>sor</sub> * dp + d<SPAN STYLE=\"text-decoration:underline\">h</SPAN><sub>adsorpt</sub> - d(x<sub>adsorpt</sub> * v<sub>adsorpt</sub> * p)] = dm<sub>sor</sub> * [u<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">u</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [dh<sub>sor</sub> - p * dv<sub>sor</sub> - v<sub>sor</sub> * dp + d<SPAN STYLE=\"text-decoration:underline\">h</SPAN><sub>adsorpt</sub> - d(x<sub>adsorpt</sub> * v<sub>adsorpt</sub>) * p - x<sub>adsorpt</sub> * v<sub>adsorpt</sub> * dp];
+</pre>
+
+<p>
+Thus, the following partial derivatives are provided for the sorbent:
+</p>
+<ul>
+  <li>
+  <i>(&part;h<sub>sor</sub>/&part;p)<sub>T</sub> = v<sub>sor</sub> * (1 - T * &beta;<sub>sor</sub>)</i>: 
+  Partial derivative of the specific enthaly w.r.t. to pressure at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;h<sub>sor</sub>/&part;T)<sub>p</sub> = c<sub>sor</sub></i>: 
+  Partial derivative of the specific enthaly w.r.t. to temperature at 
+  constant pressure.
+  </li>
+  <li>
+  <i>(&part;h<sub>sor</sub>/&part;x)<sub>T</sub></i>: 
+  Partial derivative of the specific enthaly w.r.t. to loading at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;h<sub>sor</sub>/&part;T)<sub>x</sub></i>: 
+  Partial derivative of the specific enthaly w.r.t. to temperature at 
+  constant loading.
+  </li>
+  <li>
+  <i>(&part;v<sub>sor</sub>/&part;p)<sub>T</sub> = 0</i>: 
+  Partial derivative of the specific volume w.r.t. to pressure at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;v<sub>sor</sub>/&part;T)<sub>p</sub> = 0</i>: 
+  Partial derivative of the specific volume w.r.t. to temperature at 
+  constant pressure.
+  </li>
+  <li>
+  <i>(&part;v<sub>sor</sub>/&part;x)<sub>T</sub> = 0</i>: 
+  Partial derivative of the specific volume w.r.t. to loading at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;v<sub>sor</sub>/&part;T)<sub>x</sub> = 0</i>: 
+  Partial derivative of the specific volume w.r.t. to temperature at 
+  constant loading.
+  </li>
+</ul>
+<p>
+Accordingly, the following partial derivatives are provided for the 
+adsorpt:
+</p>
+<ul>
+  <li>
+  <i>(&part;<SPAN STYLE=\"text-decoration:underline\">h</SPAN><sub>adsorpt</sub>/&part;p)<sub>T</sub></i>: 
+  Partial derivative of the specific enthaly w.r.t. to pressure at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;<SPAN STYLE=\"text-decoration:underline\">h</SPAN><sub>adsorpt</sub>/&part;T)<sub>p</sub></i>: 
+  Partial derivative of the specific enthaly w.r.t. to temperature at 
+  constant pressure.
+  </li>
+  <li>
+  <i>(&part;<SPAN STYLE=\"text-decoration:underline\">h</SPAN><sub>adsorpt</sub>/&part;x)<sub>T</sub> = h<sub>adsorpt</sub></i>: 
+  Partial derivative of the specific enthaly w.r.t. to loading at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;<SPAN STYLE=\"text-decoration:underline\">h</SPAN><sub>adsorpt</sub>/&part;T)<sub>x</sub> = c<sub>adsorpt</sub> * x<sub>adsorpt</sub></i>: 
+  Partial derivative of the specific enthaly w.r.t. to temperature at 
+  constant loading. It was assumed that the specific heat capacity is 
+  either independent of the loading or directly corresponds to the 
+  uptake-averaged specific heat capacity (see assumptions).
+  </li>
+  <li>
+  <i>(&part;(x<sub>adsorpt</sub> * v<sub>adsorpt</sub>)/&part;p)<sub>T</sub> = x<sub>adsorpt</sub> * (&part;(v<sub>adsorpt</sub>)/&part;p)<sub>T</sub> + (&part;(x<sub>adsorpt</sub>)/&part;p)<sub>T</sub> * v<sub>adsorpt</sub></i>: 
+  Partial derivative of the product of specific volume and uptake w.r.t. 
+  to pressure at constant temperature.
+  </li>
+  <li>
+  <i>(&part;(x<sub>adsorpt</sub> * v<sub>adsorpt</sub>)/&part;T)<sub>p</sub> = x<sub>adsorpt</sub> * (&part;(v<sub>adsorpt</sub>)/&part;T)<sub>p</sub> + (&part;(x<sub>adsorpt</sub>)/&part;T)<sub>p</sub> * v<sub>adsorpt</sub></i></i>:  
+  Partial derivative of the product of specific volume and uptake w.r.t. 
+  to temperature at constant pressure.
+  </li>
+  <li>
+  <i>(&part;v(x<sub>adsorpt</sub> * v<sub>adsorpt</sub>)&part;x)<sub>T</sub></i>:  
+  Partial derivative of the product of specific volume and uptake w.r.t. 
+  to loading at constant temperature.
+  </li>
+  <li>
+  <i>(&part;(x<sub>adsorpt</sub> * v<sub>adsorpt</sub>)/&part;T)<sub>x</sub></i>:  
+  Partial derivative of the product of specific volume and uptake w.r.t. 
+  to temperature at constant loading.
+  </li>
+</ul>
+
+<p>
+The partial derivatives required for the entropy balance can be 
+determined in the same way as for the energy balance. The total 
+entropy of the adsorbate volume <i>S<sub>adsorbate</sub></i> is:
+</p>
+<pre>
+    S<sub>adsorbate</sub> = m<sub>sor</sub> * [s<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">s</SPAN><sub>adsorpt</sub>];
+</pre>
+<p>
+Thus, when applying all assumptions, the total differential of the 
+entropy of the adsorbate volume <i>dS<sub>adsorbate</sub></i> is:
+</p>
+<pre>
+    dS<sub>adsorbate</sub> = dm<sub>sor</sub> * [s<sub>sor</sub> + x<sub>adsorpt</sub> * <SPAN STYLE=\"text-decoration:overline\">s</SPAN><sub>adsorpt</sub>] + m<sub>sor</sub> * [ds<sub>sor</sub> + d<SPAN STYLE=\"text-decoration:underline\">s</SPAN><sub>adsorpt</sub>];
+</pre>
+<p>
+Consequently, the following partial derivatives are provided for the 
+sorbent and adsorpt:
+</p>
+<ul>
+  <li>
+  <i>(&part;s<sub>sor</sub>/&part;p)<sub>T</sub> = v<sub>sor</sub> * &beta;<sub>sor</sub></i>: 
+  Partial derivative of the specific entropy w.r.t. to pressure at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;s<sub>sor</sub>/&part;T)<sub>p</sub> = c<sub>sor</sub> / T</i>: 
+  Partial derivative of the specific entropy w.r.t. to temperature at 
+  constant pressure.
+  </li>
+  <li>
+  <i>(&part;s<sub>sor</sub>/&part;x)<sub>T</sub></i>: 
+  Partial derivative of the specific entropy w.r.t. to loading at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;s<sub>sor</sub>/&part;T)<sub>x</sub></i>: 
+  Partial derivative of the specific entropy w.r.t. to temperature at 
+  constant loading.
+  </li>
+  <li>
+  <i>(&part;<SPAN STYLE=\"text-decoration:underline\">s</SPAN><sub>adsorpt</sub>/&part;p)<sub>T</sub></i>: 
+  Partial derivative of the specific entropy w.r.t. to pressure at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;<SPAN STYLE=\"text-decoration:underline\">s</SPAN><sub>adsorpt</sub>/&part;T)<sub>p</sub></i>: 
+  Partial derivative of the specific entropy w.r.t. to temperature at 
+  constant pressure.
+  </li>
+  <li>
+  <i>(&part;<SPAN STYLE=\"text-decoration:underline\">s</SPAN><sub>adsorpt</sub>/&part;x)<sub>T</sub> = s<sub>adsorpt</sub></i>: 
+  Partial derivative of the specific entropy w.r.t. to loading at 
+  constant temperature.
+  </li>
+  <li>
+  <i>(&part;<SPAN STYLE=\"text-decoration:underline\">s</SPAN><sub>adsorpt</sub>/&part;T)<sub>x</sub> = c<sub>adsorpt</sub> / T * x<sub>adsorpt</sub></i>: 
+  Partial derivative of the specific entropy w.r.t. to temperature at 
+  constant loading. It was assumed that the specific heat capacity is 
+  either independent of the loading or directly corresponds to the 
+  uptake-averaged specific heat capacity (see assumptions).
+  </li>
+  <li>
+</ul>
+
+<p>
+Partial derivatives that are not fully specified can be calculated 
+using the fundamental laws of analysis and the specified partial 
+derivatives as well as the partial derivatives of the isotherm model.
+</p>
+
+<h4>Assumptions and limitations</h4>
+<ul>
+  <li>
+  Adsorption equilibrium with all adsorptive beeing adsorbed and in adsorpt
+  phase (i.e., chemical equilibrium).
+  </li>
+  <li>
+  The sorbent and adsorpt have the same pressure (i.e., mechanical equilibrium).
+  </li>
+  <li>
+  The sorbent and adsorpt have the same temperature (i.e., thermal equilibrium).
+  </li>
+  <li>
+  Specific volume of the adsorpt may only depend on the temperature and is thus
+  a macroscopic property without averaging.
+  </li>
+  <li>
+  Specific heat capacity of the adsorpt may only depend on the temperature or is
+  assumed to already be an uptake-averaged specific heat capacity.
+  </li>
+  <li>
+  Ideal and inert sorbent with constant specific volume.
+  </li>
+</ul>
+
+<h4>Typical use</h4>
+<p>
+This model is mainly used to calculate thermodynamic properties of an adsorbate 
+volume.
+</p>
+
+<h4>Important parameters and options</h4>
+<ul>
+  <li>
+  All parameters of the calculation setup: Define which variables are calculated.
+  </li>
+  <li>
+  <i>adsorptiveAtDewPoint = true</i>: Assume thermodynamic state of the adsorptive
+  to correspond to the dew point at given temperature.
+  </li>
+  <li>
+  <i>neglectSpecifcVolume = true</i>: Neglect the specific volume of the adsorpt.
+  This options can significantly simplify the calculation procedure and is often
+  a good assumption.
+  </li>
+  <li>
+  <i>approachSpecificVolume</i>: Choose the calculation approach for the specific
+  volume of the adsorpt.
+  </li>
+  <li>
+  <i>approachSpecificHeatCapacity</i>: Choose the calculation approach for the 
+  specific heat capacity of the adsorpt.
+  </li>
+  <li>
+  <i>approachSorptionEnthalpy</i>: Choose the calculation approach for the 
+  specific enthalpy of adsorption.
+  </li>
+</ul>
+
+<h4>Dynamics</h4>
+<p>
+Dynamic states are either the pressure and temperature or the uptake and
+temperature. To change the dynamic states, use the parameter <i>stateVariables</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  Major adaptations and extensions (e.g. partial derivatives for mass,
+  energy, and entropy balances or properties of the sorbent).
+  </li>
+  <li>
+  December 14, 2020, by Mirko Engelpracht:<br/>
+  Major reivisions (e.g., object-oriented approach, functionaliy) due 
+  to restructuring of the library.
+  </li>
+  <li>
+  November 17, 2017, by Uwe Bau:<br/> 
+  Tidy up implementation and enhance documentation for publication of 
+  library.
+  </li>
+</ul>
+</html>"));
+end PartialPureWorkingPairs;
diff --git a/SorpLib/Media/WorkingPairs/BaseClasses/Partial_ddz_dT_dT.mo b/SorpLib/Media/WorkingPairs/BaseClasses/Partial_ddz_dT_dT.mo
new file mode 100644
index 0000000..5bc5ab2
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/BaseClasses/Partial_ddz_dT_dT.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.WorkingPairs.BaseClasses;
+partial function Partial_ddz_dT_dT
+  "Base function for calculating the second-order partial derivative of coefficients w.r.t. temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real ddz_dT_dT
+    "Second-order partial derivative of coefficient w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for calculating the second-order 
+partial derivative of a coefficient with respect to temperature as function of 
+temperature.
+<br/><br/>
+This partial function defines the temperature <i>T</i> as input and the second-
+order partial derivative of the coefficient with respect to temperature <i>ddz_dT_dT</i>
+as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_ddz_dT_dT;
diff --git a/SorpLib/Media/WorkingPairs/BaseClasses/Partial_dz_dT.mo b/SorpLib/Media/WorkingPairs/BaseClasses/Partial_dz_dT.mo
new file mode 100644
index 0000000..73d6c18
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/BaseClasses/Partial_dz_dT.mo
@@ -0,0 +1,42 @@
+within SorpLib.Media.WorkingPairs.BaseClasses;
+partial function Partial_dz_dT
+  "Base function for calculating the partial derivative of coefficients w.r.t. temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real dz_dT
+    "Partial derivative of coefficient w.r.t. temperature"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for calculating the partial derivative 
+of a coefficient with respect to temperature as function of temperature.
+<br/><br/>
+This partial function defines the temperature <i>T</i> as input and the partial
+derivative of the coefficient with respect to temperature <i>dz_dT</i> as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_dz_dT;
diff --git a/SorpLib/Media/WorkingPairs/BaseClasses/Partial_z_T.mo b/SorpLib/Media/WorkingPairs/BaseClasses/Partial_z_T.mo
new file mode 100644
index 0000000..694301f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/BaseClasses/Partial_z_T.mo
@@ -0,0 +1,42 @@
+within SorpLib.Media.WorkingPairs.BaseClasses;
+partial function Partial_z_T
+  "Base function for calculating a coefficient as function of temperature"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real z
+    "Coefficient"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial function is the basic function for calculating a coefficient as 
+function of temperature.
+<br/><br/>
+This partial function defines the temperature <i>T</i> as input and the abitrary
+coefficient <i>c</i> as output.
+<br/><br/>
+Functions that inherit properties from this partial function may have to add
+furhter inputs, outputs, and the function algorithm.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Partial_z_T;
diff --git a/SorpLib/Media/WorkingPairs/BaseClasses/package.mo b/SorpLib/Media/WorkingPairs/BaseClasses/package.mo
new file mode 100644
index 0000000..5578536
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/BaseClasses/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Media.WorkingPairs;
+package BaseClasses "Base classes used to build new working pair models"
+  extends Modelica.Icons.BasesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains partial basic functions and models. These partial functions
+and models contain fundamental definitions of all working pair models and corresponding
+test models, covering pure and multi-component adsorption. The content of this package 
+is only of interest when adding new working pair models to the library.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end BaseClasses;
diff --git a/SorpLib/Media/WorkingPairs/BaseClasses/package.order b/SorpLib/Media/WorkingPairs/BaseClasses/package.order
new file mode 100644
index 0000000..1bcf8b2
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/BaseClasses/package.order
@@ -0,0 +1,6 @@
+Partial_z_T
+Partial_dz_dT
+Partial_ddz_dT_dT
+PartialPureWorkingPairs
+PartialPureTest
+PartialPureCharts
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairDubinin.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairDubinin.mo
new file mode 100644
index 0000000..7119852
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairDubinin.mo
@@ -0,0 +1,250 @@
+within SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents;
+model ChartWorkingPairDubinin
+  "Model that creates a fluid property diagram of a pure component working pair using the MSL for fluid property data calculation of a real fluid with a two-phase regime"
+  extends SorpLib.Media.WorkingPairs.BaseClasses.PartialPureCharts(
+    redeclare replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+      constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+        redeclare package Medium=Medium));
+
+  //
+  // Definition of replaceable medium
+  //
+  replaceable package WorkingPair =
+    SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017
+    constrainedby
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+      redeclare final package MediumSpecificFunctions =
+        SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+        ( redeclare final package Medium = Medium))
+    "Parametrized working pair model"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Pressure p_adsorpt_lowerLimit = 612
+    "Lower limit for the pressure to calculate fluod property data"
+    annotation (Dialog(tab = "Advanced", group = "Limiter"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_lowerLimit = 273.17
+    "Lower limit for the temperature to calculate fluod property data"
+    annotation (Dialog(tab = "Advanced", group = "Limiter"),
+                Evaluate=true,
+                HideResult=true);
+  final parameter Modelica.Units.SI.Pressure p_sat_T_adsorpt_lowerLimit=
+    if diagramType<>
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters then 0 else
+    Medium.saturationPressure(T=T_adsorpt_lowerLimit)
+    "Saturation pressure at T_adsorpt_lowerLimit"
+    annotation (Dialog(tab = "Advanced", group = "Limiter"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  SorpLib.Units.Uptake x_sat_isotherms
+    "Saturation uptake as function of changing pressure (i.e., required for 
+    diagram of isotherms)";
+  Modelica.Units.SI.Pressure p_sat_isosters
+    "Saturation pressure as function of changing temperature (i.e., required for
+    diagram of isosteres)";
+  SorpLib.Units.Uptake x_sat_isobars
+    "Saturation uptake as function of changing temperature (i.e., required for 
+    diagram of isobars)";
+
+  Real x_axis_isotherm
+    "X-axis for isotherm diagram: Pressure p_adsorpt";
+  Real x_axis_isosters
+    "X-axis for isosters diagram: Negative reciproce temperature -1/T_adsorpt";
+  Real x_axis_isobars
+    "X-axis for isobars diagram: Temperature T_adsorpt";
+
+  //
+  // Definition of protected variables
+  //
+protected
+  Modelica.Units.SI.Pressure
+    p_adsorpt_(start=max(p_adsorpt_min, p_adsorpt_lowerLimit), fixed=true)
+    "Changing pressure";
+  Modelica.Units.SI.Temperature
+    T_adsorpt_(start=max(T_adsorpt_min, T_adsorpt_lowerLimit), fixed=true)
+    "Changing temperature";
+
+  Modelica.Units.SI.Pressure p_sat_T_adsorpt
+    "Saturation pressure as function of changing temperature (i.e., required
+    for diagram of isosteres or isobars)";
+  Modelica.Units.SI.Temperature T_sat_p_adsorpt
+    "Saturation temperature as function of changing pressure (i.e., required
+    for diagram of isotherms)";
+
+  SorpLib.Units.Uptake x_sat_T_adsorpt_lowerLimit
+    "Saturation uptake at p_sat(T_adsorpt_lowerLimit) and T_adsorpt_lowerLimit";
+  SorpLib.Units.Uptake x_sat_T_adsorpt
+    "Saturation uptake at p_sat(T_adsorpt) and T_adsorpt";
+
+  //
+  // Instantiation of final models
+  //
+  WorkingPair.IsothermCoefficients isothermCoefficients(
+    final T_adsorpt=if diagramType==
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then
+    T_sat_p_adsorpt else T_adsorpt_)
+    "Temperature-dependent isotherm coefficients";
+
+equation
+  //
+  // Calculate upper limits for different diagrams types
+  //
+  T_sat_p_adsorpt = if diagramType<>
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then 0 else
+    Medium.saturationTemperature(p=p_adsorpt_)
+    "Saturation pressure as function of changing temperature (i.e., required
+    for diagram of isotherms)";
+  p_sat_T_adsorpt = if diagramType==
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then 0 else
+    Medium.saturationPressure(T=T_adsorpt_)
+    "Saturation pressure as function of changing temperature (i.e., required
+    for diagram of isosteres)";
+
+  x_sat_T_adsorpt_lowerLimit = if diagramType<>
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters then 0 else
+    WorkingPair.IsothermModel.x_pT(
+      p_adsorpt= p_sat_T_adsorpt_lowerLimit,
+      T_adsorpt=max(T_adsorpt_, T_adsorpt_lowerLimit),
+      c=isothermCoefficients.c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Saturation uptake at p_sat(T_adsorpt_lowerLimit) and T_adsorpt_lowerLimit";
+  x_sat_T_adsorpt = if diagramType<>
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters then 0 else
+    WorkingPair.IsothermModel.x_pT(
+      p_adsorpt= p_sat_T_adsorpt,
+      T_adsorpt=T_adsorpt_,
+      c=isothermCoefficients.c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Saturation uptake at p_sat(T_adsorpt) and T_adsorpt";
+
+  //
+  // Calculate correct inputs
+  //
+  der(p_adsorpt_) = (p_adsorpt_max-max(p_adsorpt_min, p_adsorpt_lowerLimit)) / 20
+    "Predescriped slope";
+  der(T_adsorpt_) = (T_adsorpt_max-max(T_adsorpt_min, T_adsorpt_lowerLimit)) / 20
+    "Changing temperature";
+
+  if diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then
+    p_adsorpt = fill(p_adsorpt_, no_isoLines)
+      "Pressure";
+    T_adsorpt = {max(T_adsorpt_const_[i], T_sat_p_adsorpt) for i in 1:no_isoLines}
+      "Temperature";
+
+  elseif diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters then
+    x_adsorpt = {max(min(x_adsorpt_const_[i], x_sat_T_adsorpt),
+      x_sat_T_adsorpt_lowerLimit) for i in 1:no_isoLines}
+      "Uptake: Limited to its lower and upper limit";
+    T_adsorpt = fill(T_adsorpt_, no_isoLines)
+      "Temperature: Limitied to its lower limit";
+
+  else
+    p_adsorpt = {min(p_adsorpt_const_[i], p_sat_T_adsorpt) for i in 1:no_isoLines}
+      "Pressure";
+    T_adsorpt = fill(T_adsorpt_, no_isoLines)
+      "Temperature";
+
+  end if;
+
+  //
+  // Caclulate variables for plotting
+  //
+  x_sat_isotherms = if diagramType<>
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then 0 else
+    WorkingPair.IsothermModel.x_pT(
+      p_adsorpt=p_adsorpt_,
+      T_adsorpt=T_sat_p_adsorpt,
+      c=isothermCoefficients.c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Saturation uptake as function of changing pressure (i.e., required for 
+    diagram of isotherms)";
+  p_sat_isosters = if diagramType<>
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters then 0 else
+    p_sat_T_adsorpt
+    "Saturation pressure as function of changing temperature (i.e., required for
+    diagram of isosteres)";
+  x_sat_isobars = if diagramType<>
+    SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars then 0 else
+    WorkingPair.IsothermModel.x_pT(
+      p_adsorpt=p_sat_T_adsorpt,
+      T_adsorpt=T_adsorpt_,
+      c=isothermCoefficients.c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Saturation uptake as function of changing temperature (i.e., required for 
+    diagram of isobars)";
+
+  x_axis_isotherm = p_adsorpt_
+    "X-axis for isotherm diagram: Pressure p_adsorpt";
+  x_axis_isosters = -1/T_adsorpt_
+    "X-axis for isosters diagram: Negative reciproce temperature -1/T_adsorpt";
+  x_axis_isobars = T_adsorpt_
+    "X-axis for isobars diagram: Temperature T_adsorpt";
+
+  //
+  // Asserations
+  //
+  if diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then
+    assert(min(T_adsorpt_const_) > T_adsorpt_lowerLimit,
+      "Minimum isotherm temperature (" + String(min(T_adsorpt_const_)) +
+      ") is below the minimum temperature (" + String(T_adsorpt_lowerLimit) +
+      "). Thus, fluid property data calculation is impossible.",
+      level = AssertionLevel.error);
+
+  elseif diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars then
+    assert(min(p_adsorpt_const_) > p_adsorpt_lowerLimit,
+      "Minimum isotherm pressure (" + String(min(p_adsorpt_const_)) +
+      ") is below the minimum pressure (" + String(p_adsorpt_lowerLimit) +
+      "). Thus, fluid property data calculation is impossible.",
+      level = AssertionLevel.error);
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the basic model for all models creating fluid propertey diagrams
+for working pair models describing adsorption of pure components. These working paur models 
+use a isotherm model based on the model of Dubinin and a medium model of a rel fluid with 
+a two-regime based on the Modelica Standard Library. Note that the isotherms, isosters, and 
+isobars are limited to lower and upper bounds if necessary to perform calculations within a 
+feasble range.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ChartWorkingPairDubinin;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairGas.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairGas.mo
new file mode 100644
index 0000000..84bb15b
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairGas.mo
@@ -0,0 +1,97 @@
+within SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents;
+model ChartWorkingPairGas
+  "Model that creates a fluid property diagram of a pure component working pair using the MSL for fluid property data calculation of a fluid with just one-regime (i.e., gas/vapor)"
+  extends SorpLib.Media.WorkingPairs.BaseClasses.PartialPureCharts(
+    redeclare replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.CO2.ActivatedCarbon_Toth_DantasEtAl2011_Gas
+      constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+        redeclare package Medium=Medium));
+
+  //
+  // Definition of replaceable medium
+  //
+  replaceable package Medium = SorpLib.Media.IdealGases.CO2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+
+  //
+  // Definition of variables
+  //
+  Real x_axis_isotherm
+    "X-axis for isotherm diagram: Pressure p_adsorpt";
+  Real x_axis_isosters
+    "X-axis for isosters diagram: Negative reciproce temperature -1/T_adsorpt";
+  Real x_axis_isobars
+    "X-axis for isobars diagram: Temperature T_adsorpt";
+
+  //
+  // Definition of final parameters
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt_(start=p_adsorpt_min, fixed=true)
+    "Changing pressure";
+  Modelica.Units.SI.Temperature T_adsorpt_(start=T_adsorpt_min, fixed=true)
+    "Changing temperature";
+
+equation
+  //
+  // Calculate correct inputs
+  //
+  der(p_adsorpt_) = (p_adsorpt_max-p_adsorpt_min) / 20
+    "Predescriped slope";
+  der(T_adsorpt_) = (T_adsorpt_max-T_adsorpt_min) / 20
+    "Changing temperature";
+
+  if diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then
+    p_adsorpt = fill(p_adsorpt_, no_isoLines)
+      "Pressure";
+    T_adsorpt = T_adsorpt_const_
+      "Temperature";
+
+  elseif diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters then
+    x_adsorpt = x_adsorpt_const_
+      "Uptake";
+    T_adsorpt = fill(T_adsorpt_, no_isoLines)
+      "Temperature";
+
+  else
+    p_adsorpt = p_adsorpt_const_
+      "Pressure";
+    T_adsorpt = fill(T_adsorpt_, no_isoLines)
+      "Temperature";
+
+  end if;
+
+  //
+  // Caclulate variables for plotting
+  //
+  x_axis_isotherm = p_adsorpt_
+    "X-axis for isotherm diagram: Pressure p_adsorpt";
+  x_axis_isosters = -1/T_adsorpt_
+    "X-axis for isosters diagram: Negative reciproce temperature -1/T_adsorpt";
+  x_axis_isobars = T_adsorpt_
+    "X-axis for isobars diagram: Temperature T_adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the basic model for all models creating fluid propertey diagrams
+for working pair models describing adsorption of pure components and using a medium 
+model of a fluid with just one regime (i.e., gas/vapor) based on the Modelica Standard 
+Library.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ChartWorkingPairGas;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairVLE.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairVLE.mo
new file mode 100644
index 0000000..e5ecc6b
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/ChartWorkingPairVLE.mo
@@ -0,0 +1,135 @@
+within SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents;
+model ChartWorkingPairVLE
+  "Model that creates a fluid property diagram of a pure component working pair using the MSL for fluid property data calculation of a real fluid with a two-phase regime"
+  extends SorpLib.Media.WorkingPairs.BaseClasses.PartialPureCharts(
+    redeclare replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+      constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+        redeclare package Medium=Medium,
+        limitLowerPressure=true,
+        p_adsorpt_min=p_adsorpt_lowerLimit));
+
+  //
+  // Definition of replaceable medium
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+      constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+
+  //
+  // Definition of parameters
+  //
+  parameter Modelica.Units.SI.Pressure p_adsorpt_lowerLimit = 612
+    "Lower limit for the pressure to calculate fluod property data"
+    annotation (Dialog(tab = "Advanced", group = "Limiter"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Temperature T_adsorpt_lowerLimit = 273.17
+    "Lower limit for the temperature to calculate fluod property data"
+    annotation (Dialog(tab = "Advanced", group = "Limiter"),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of variables
+  //
+  Real x_axis_isotherm
+    "X-axis for isotherm diagram: Pressure p_adsorpt";
+  Real x_axis_isosters
+    "X-axis for isosters diagram: Negative reciproce temperature -1/T_adsorpt";
+  Real x_axis_isobars
+    "X-axis for isobars diagram: Temperature T_adsorpt";
+
+  //
+  // Definition of final parameters
+  //
+protected
+  Modelica.Units.SI.Pressure
+    p_adsorpt_(start=max(p_adsorpt_min, p_adsorpt_lowerLimit), fixed=true)
+    "Changing pressure";
+  Modelica.Units.SI.Temperature
+    T_adsorpt_(start=max(T_adsorpt_min, T_adsorpt_lowerLimit), fixed=true)
+    "Changing temperature";
+
+equation
+  //
+  // Calculate correct inputs
+  //
+  der(p_adsorpt_) = (p_adsorpt_max-max(p_adsorpt_min, p_adsorpt_lowerLimit)) / 20
+    "Predescriped slope";
+  der(T_adsorpt_) = (T_adsorpt_max-max(T_adsorpt_min, T_adsorpt_lowerLimit)) / 20
+    "Changing temperature";
+
+  if diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then
+    p_adsorpt = fill(p_adsorpt_, no_isoLines)
+      "Pressure";
+    T_adsorpt = {max(T_adsorpt_const_[i], T_adsorpt_lowerLimit) for i in 1:no_isoLines}
+      "Temperature";
+
+  elseif diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters then
+    x_adsorpt = x_adsorpt_const_
+      "Uptake";
+    T_adsorpt = fill(T_adsorpt_, no_isoLines)
+      "Temperature";
+
+  else
+    p_adsorpt = {max(p_adsorpt_const_[i], p_adsorpt_lowerLimit) for i in 1:no_isoLines}
+      "Pressure";
+    T_adsorpt = fill(T_adsorpt_, no_isoLines)
+      "Temperature";
+
+  end if;
+
+  //
+  // Caclulate variables for plotting
+  //
+  x_axis_isotherm = p_adsorpt_
+    "X-axis for isotherm diagram: Pressure p_adsorpt";
+  x_axis_isosters = -1/T_adsorpt_
+    "X-axis for isosters diagram: Negative reciproce temperature -1/T_adsorpt";
+  x_axis_isobars = T_adsorpt_
+    "X-axis for isobars diagram: Temperature T_adsorpt";
+
+  //
+  // Asserations
+  //
+  if diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms then
+    assert(min(T_adsorpt_const_) > T_adsorpt_lowerLimit,
+      "Minimum isotherm temperature (" + String(min(T_adsorpt_const_)) +
+      ") is below the minimum temperature (" + String(T_adsorpt_lowerLimit) +
+      "). Thus, fluid property data calculation is impossible.",
+      level = AssertionLevel.error);
+
+  elseif diagramType==SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars then
+    assert(min(p_adsorpt_const_) > p_adsorpt_lowerLimit,
+      "Minimum isotherm pressure (" + String(min(p_adsorpt_const_)) +
+      ") is below the minimum pressure (" + String(p_adsorpt_lowerLimit) +
+      "). Thus, fluid property data calculation is impossible.",
+      level = AssertionLevel.error);
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
+        coordinateSystem(preserveAspectRatio=false)),
+    Documentation(info="<html>
+<p>
+This partial model is the basic model for all models creating fluid propertey diagrams
+for working pair models describing adsorption of pure components and using a medium 
+model of a real fluid with a two-phase regime based on the Modelica Standard Library.
+Note that the pressure and temperature are limited if necessary to stay within
+a feasble range.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ChartWorkingPairVLE;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairDubinin.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairDubinin.mo
new file mode 100644
index 0000000..5fd5318
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairDubinin.mo
@@ -0,0 +1,96 @@
+within SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.Tester;
+model Test_ChartWorkingPairDubinin
+  "Tester for the fluid property diagram model using the model of Dubinin and the MSL for fluid property data calculation of a real fluid with a two-phase regime"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters describing packages and models
+  //
+  replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE
+    "Pure working pair model"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package WorkingPair =
+      Parametrizations.PureComponents.H2O.SilicaGel123_DubininLorentzianCumulative_Schawe2000
+    constrainedby
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin
+    "Parametrized working pair model"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+
+  //
+  // Instantiation of models
+  //
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairDubinin
+    diagramIsotherms(
+    redeclare final package Medium = Medium,
+    redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+    redeclare final package WorkingPair = WorkingPair,
+    final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms,
+    isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+    p_adsorpt_min=615,
+    p_adsorpt_max=5e5,
+    T_adsorpt_min=273.2,
+    T_adsorpt_max=423.15) "Diagram of isotherms"
+    annotation (Placement(transformation(extent={{-60,-12},{-40,8}})));
+
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairDubinin
+    diagramIsosters(
+    redeclare final package Medium = Medium,
+    redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+    redeclare final package WorkingPair = WorkingPair,
+    final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters,
+    isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+    T_adsorpt_min=273.2,
+    T_adsorpt_max=423.15,
+    x_adsorpt_min=0.05,
+    x_adsorpt_max=0.45) "Diagram of isosters"
+    annotation (Placement(transformation(extent={{-10,-12},{10,8}})));
+
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairDubinin
+    diagramIsobars(
+    redeclare final package Medium = Medium,
+    redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+    redeclare final package WorkingPair = WorkingPair,
+    final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars,
+    isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+    p_adsorpt_min=615,
+    p_adsorpt_max=5e5,
+    T_adsorpt_min=273.2,
+    T_adsorpt_max=423.15) "Diagram of isobars"
+    annotation (Placement(transformation(extent={{40,-12},{60,8}})));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This models demonstrates how to create a diagram of isotherms, isosters,
+or isobars for a working pair model using a real fluid with a two-regime
+and the model of Dubinin.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), experiment(StopTime=20, Tolerance=1e-06));
+end Test_ChartWorkingPairDubinin;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairGas.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairGas.mo
new file mode 100644
index 0000000..b727459
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairGas.mo
@@ -0,0 +1,87 @@
+within SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.Tester;
+model Test_ChartWorkingPairGas
+  "Tester for the fluid property diagram model using the MSL for fluid property data calculation of a fluid with just one-regime (i.e., gas/vapor)"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters describing packages and models
+  //
+  replaceable model PureWorkingPairModel =
+    SorpLib.Media.WorkingPairs.PureComponents.CO2.ActivatedCarbon_Toth_DantasEtAl2011_Gas
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas
+    "Pure working pair model"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package Medium = SorpLib.Media.IdealGases.CO2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+
+  //
+  // Instantiation of models
+  //
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairGas
+    diagramIsotherms(
+      redeclare final package Medium = Medium,
+      redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+      final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms,
+      isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+      p_adsorpt_min=1000,
+      p_adsorpt_max=1000000,
+      T_adsorpt_min=283.15,
+      T_adsorpt_max=423.15)
+      "Diagram of isotherms"
+    annotation (Placement(transformation(extent={{-60,-12},{-40,8}})));
+
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairGas
+    diagramIsosters(
+      redeclare final package Medium = Medium,
+      redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+      final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters,
+      isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+      p_adsorpt_max=1000000,
+      T_adsorpt_min=283.15,
+      T_adsorpt_max=423.15,
+      x_adsorpt_min=0.05,
+      x_adsorpt_max=0.25)
+    "Diagram of isosters"
+    annotation (Placement(transformation(extent={{-10,-12},{10,8}})));
+
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairGas
+    diagramIsobars(
+      redeclare final package Medium = Medium,
+      redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+      final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars,
+      isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+      p_adsorpt_min=1000,
+      p_adsorpt_max=1000000,
+      T_adsorpt_min=283.15,
+      T_adsorpt_max=423.15)
+      "Diagram of isobars"
+    annotation (Placement(transformation(extent={{40,-12},{60,8}})));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This models demonstrates how to create a diagram of isotherms, isosters,
+or isobars for a working pair model using a fluid with just one regime
+(i.e., gas/vapor).
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), experiment(StopTime=20, Tolerance=1e-06));
+end Test_ChartWorkingPairGas;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairVLE.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairVLE.mo
new file mode 100644
index 0000000..d417307
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/Test_ChartWorkingPairVLE.mo
@@ -0,0 +1,86 @@
+within SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.Tester;
+model Test_ChartWorkingPairVLE
+  "Tester for the fluid property diagram model using the MSL for fluid property data calculation of a real fluid with a two-regime"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters describing packages and models
+  //
+  replaceable model PureWorkingPairModel =
+    SorpLib.Media.WorkingPairs.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010_VLE
+    constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE
+    "Pure working pair model"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true,
+                Evaluate=true,
+                HideResult=true);
+
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Models and Media"),
+                choicesAllMatching = true);
+
+  //
+  // Instantiation of models
+  //
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairVLE
+    diagramIsotherms(
+      redeclare final package Medium = Medium,
+      redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+      final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isotherms,
+      isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+      p_adsorpt_min=1000,
+      p_adsorpt_max=1000000,
+      T_adsorpt_min=283.15,
+      T_adsorpt_max=423.15)
+      "Diagram of isotherms"
+    annotation (Placement(transformation(extent={{-60,-12},{-40,8}})));
+
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairVLE
+    diagramIsosters(
+      redeclare final package Medium = Medium,
+      redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+      final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isosters,
+      isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+      p_adsorpt_max=1000000,
+      T_adsorpt_min=283.15,
+      T_adsorpt_max=423.15,
+      x_adsorpt_min=0.05,
+      x_adsorpt_max=0.25)
+    "Diagram of isosters"
+    annotation (Placement(transformation(extent={{-10,-12},{10,8}})));
+
+  SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents.ChartWorkingPairVLE
+    diagramIsobars(
+      redeclare final package Medium = Medium,
+      redeclare final model PureWorkingPairModel = PureWorkingPairModel,
+      final diagramType=SorpLib.Choices.DiagramTypePureComponentWorkingPair.Isobars,
+      isoLineType=SorpLib.Choices.ChangingConstantVariableOfDiagram.Linespace,
+      p_adsorpt_min=1000,
+      p_adsorpt_max=1000000,
+      T_adsorpt_min=283.15,
+      T_adsorpt_max=423.15)
+      "Diagram of isobars"
+    annotation (Placement(transformation(extent={{40,-12},{60,8}})));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This models demonstrates how to create a diagram of isotherms, isosters,
+or isobars for a working pair model using a real fluid with a two-phase regime.
+<br/><br/>
+To see the model behavior, plot the variables of the models over the 
+time. The simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"), experiment(StopTime=20, Tolerance=1e-06));
+end Test_ChartWorkingPairVLE;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/package.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/package.mo
new file mode 100644
index 0000000..d06af8c
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.FluidPropertyDiagrams.PureComponents;
+package Tester "Package containing testers to test and varify models of fluid property diagrams for pure component working pairs"
+  extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented models of fluid property
+diagrams. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Tester;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/package.order b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/package.order
new file mode 100644
index 0000000..3be6fbc
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/Tester/package.order
@@ -0,0 +1,3 @@
+Test_ChartWorkingPairGas
+Test_ChartWorkingPairVLE
+Test_ChartWorkingPairDubinin
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/package.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/package.mo
new file mode 100644
index 0000000..86ad1c5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.WorkingPairs.FluidPropertyDiagrams;
+package PureComponents "Package containing diagram models of pure component working pairs"
+extends Modelica.Icons.VariantsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains models to generate fluid property diagrams for
+pure component working pairs. The implemented diagram types include 
+isotherms, isosterics, and isobars.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PureComponents;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/package.order b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/package.order
new file mode 100644
index 0000000..4f967ac
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/PureComponents/package.order
@@ -0,0 +1,4 @@
+ChartWorkingPairGas
+ChartWorkingPairVLE
+ChartWorkingPairDubinin
+Tester
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/package.mo b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/package.mo
new file mode 100644
index 0000000..aaf5a8d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs;
+package FluidPropertyDiagrams "Package containing models to create fluid property diagrams"
+extends Icons.MediaPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains models to generate fluid property diagrams. The 
+implemented diagram types include isotherms, isosterics, and isobars.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 23, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end FluidPropertyDiagrams;
diff --git a/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/package.order b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/package.order
new file mode 100644
index 0000000..185a1a8
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/FluidPropertyDiagrams/package.order
@@ -0,0 +1 @@
+PureComponents
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureMediumSpecificFunctions/package.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureMediumSpecificFunctions/package.mo
new file mode 100644
index 0000000..0e5655d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureMediumSpecificFunctions/package.mo
@@ -0,0 +1,839 @@
+within SorpLib.Media.WorkingPairs.Interfaces;
+partial package PartialPureMediumSpecificFunctions "Base package defining medium specific functions for pure component adsorption"
+  extends Modelica.Icons.FunctionsPackage;
+
+  //
+  // Definition of models
+  //
+  replaceable partial model AdsorptiveProperties
+    "Calculates all properties of the adsorptive at gas/vapor phase required for the working pair model at once"
+    extends Modelica.Icons.MaterialProperty;
+
+    //
+    // Definition of parameters
+    //
+    parameter Boolean calcCaloricProperties = true
+      "= true, if caloric properties are calculated (i.e., h, u, h_ads, and cp)"
+      annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                  choices(checkBox=true),
+                  Evaluate=true,
+                  HideResult=true);
+    parameter Boolean calcEntropicProperties = false
+      "= true, if caloric properties are calculated (i.e., s, g, a, and s_ads)"
+      annotation (Dialog(tab = "General", group = "Calculation Setup",
+                  enable = calcCaloricProperties),
+                  choices(checkBox=true),
+                  Evaluate=true,
+                  HideResult=true);
+
+    parameter Boolean calcAdsorptAdsorbateState = false
+      "= true, if state properties of average adsorpt phase and adosrbate phase are
+    calculated (i.e., requires numerical integration)"
+      annotation (Dialog(tab = "General", group = "Calculation Setup",
+                  enable = calcCaloricProperties),
+                  choices(checkBox=true),
+                  Evaluate=true,
+                  HideResult=true);
+
+    parameter Boolean calcDerivativesIsotherm = true
+      "= true, if partial derivatives of isotherms required for mass, energy, and
+    entropy balance of working paur volumes are calculated"
+      annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                  choices(checkBox=true),
+                  Evaluate=true,
+                  HideResult=true);
+    parameter Boolean calcDerivativesMassEnergyBalance = true
+      "= true, if partial derivatives required for mass and energy balance of
+    working pair volumes are calculated"
+      annotation (Dialog(tab = "General", group = "Calculation Setup",
+                  enable = calcDerivativesIsotherm and calcCaloricProperties),
+                  choices(checkBox=true),
+                  Evaluate=true,
+                  HideResult=true);
+    parameter Boolean calcDerivativesEntropyBalance = false
+      "= true, if partial derivatives required for entropy balance of working
+    pair volumes are calculated"
+      annotation (Dialog(tab = "General", group = "Calculation Setup",
+                  enable = calcDerivativesIsotherm and
+                    calcDerivativesMassEnergyBalance and calcCaloricProperties),
+                  choices(checkBox=true),
+                  Evaluate=true,
+                  HideResult=true);
+
+    parameter Boolean adsorptiveAtDewPoint = false
+      "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T"
+      annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                  Evaluate=true,
+                  HideResult=true,
+                  choices(checkBox=true));
+
+    parameter Boolean neglectSpecifcVolume = false
+      "= true, if specific volume of the adsorpt is neglected (i.e., v_adsorpt = 0
+    -> u_adsorpt = h_adsorpt and g_adsorpt = a_adsorpt)"
+      annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                  choices(checkBox=true),
+                  Evaluate= false,
+                  HideResult=true);
+    parameter SorpLib.Choices.SpecificVolumeAdsorpt approachSpecificVolume=
+        SorpLib.Choices.SpecificVolumeAdsorpt.Constant
+      "Calculation approach for the specific volume of the adsorpt"
+      annotation (Dialog(tab = "General", group = "Calculation Setup",
+                  enable=not neglectSpecifcVolume),
+                  Evaluate=false,
+                  HideResult=true,
+                  choicesAllMatching=true);
+    parameter SorpLib.Choices.SpecificHeatCapacityAdsorpt
+      approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.Constant
+      "Calculation approach for the specific heat capacity of the adsorpt"
+      annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                  Evaluate=false,
+                  HideResult=true,
+                  choicesAllMatching=true);
+    parameter SorpLib.Choices.SorptionEnthalpy approachSorptionEnthalpy=
+      SorpLib.Choices.SorptionEnthalpy.Constant
+      "Calculation approach for the sorption enthalpy"
+      annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                  Evaluate=false,
+                  HideResult=true,
+                  choicesAllMatching=true);
+
+    parameter Modelica.Units.SI.PressureDifference dp = 1e-3
+      "Pressure difference if derivative is calculated numerically"
+      annotation (Dialog(tab="Advanced", group="Numerics - Derivatives"),
+                  Evaluate=true,
+                  HideResult=true);
+    parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+      "Temperature difference if derivative is calculated numerically"
+      annotation (Dialog(tab="Advanced", group="Numerics - Derivatives"),
+                  Evaluate=true,
+                  HideResult=true);
+
+    //
+    // Definition of general inputs
+    //
+    input Modelica.Units.SI.Pressure p
+      "Pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T
+      "Temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output SorpLib.Media.WorkingPairs.Records.PropertiesPureAdsorptive properties=
+      SorpLib.Media.WorkingPairs.Records.PropertiesPureAdsorptive(
+        state = SorpLib.Media.WorkingPairs.Records.StateVariables(
+          p=p,
+          T=T,
+          v=v,
+          h=h,
+          u=u,
+          s=s,
+          g=g,
+          a=a),
+        cp=cp,
+        p_sat=p_sat,
+        v_satLiq=v_satLiq,
+        h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+        cp_satLiq=cp_satLiq,
+        dv_dp_T=dv_dp_T,
+        dv_dT_p=dv_dT_p,
+        dp_sat_dT=dp_sat_dT,
+        dv_satLiq_dT=dv_satLiq_dT,
+        ddv_satLiq_dT_dT=ddv_satLiq_dT_dT,
+        dh_adsorptiveToLiquid_dp_T=dh_adsorptiveToLiquid_dp_T,
+        dh_adsorptiveToLiquid_dT_p=dh_adsorptiveToLiquid_dT_p)
+      "Record containing all required properties of the adsorptive"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+    //
+    // Parameters indicating which parameters must be calculated
+    //
+protected
+    parameter Boolean require_caloricAdsorptAdsorbateState=
+      (calcCaloricProperties and calcAdsorptAdsorbateState)
+      "= true, if uptake-averaged thermal and caloric properties of the adsorpt and 
+    adsorbate phase are required";
+    parameter Boolean require_entropicAdsorptAdsorbateState=
+      (require_caloricAdsorptAdsorbateState and calcEntropicProperties)
+      "= true, if uptake-averaged entropic properties of the adsorpt and adsorbate 
+    phase are required";
+
+    parameter Boolean require_massEnergyBalances=
+      (calcCaloricProperties and calcDerivativesIsotherm and
+      calcDerivativesMassEnergyBalance)
+      "= true, if properties for mass and energy balance are required";
+    parameter Boolean require_entropyBalance=
+      (require_massEnergyBalances and calcDerivativesEntropyBalance)
+      "= true, if properties for entropy balance are required";
+
+    parameter Boolean require_dxv_avg_dp_T=
+      (require_massEnergyBalances)
+      "= true, if partial derivative of uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. pressure at constant temperature is required";
+    parameter Boolean require_dxv_avg_dT_p=
+      (require_massEnergyBalances)
+      "= true, if partial derivative of uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. temperature at constant pressure is required";
+
+    parameter Boolean require_h_ads_Formal=
+      (calcCaloricProperties and approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Formal)
+      "= true, if properties for the specific enthalpy of adsorption are required";
+    parameter Boolean require_h_ads_CC=
+      (calcCaloricProperties and approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron)
+      "= true, if properties for the specific enthalpy of adsorption according to
+    Clausius Clapeyron are required";
+    parameter Boolean require_h_ads_Dubinin=
+      (calcCaloricProperties and approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Dubinin)
+      "= true, if properties for the specific enthalpy of adsorption according to
+    Dubinin are required";
+
+    parameter Boolean require_cp_adsorpt_ChakrabortyElAl=
+      (require_h_ads_Formal and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl)
+      "= true, if properties for the specific heat capacity according to Chakraborty
+    et al. are required";
+    parameter Boolean require_cp_adsorpt_ChakrabortyElAl_CC=
+      (require_h_ads_CC and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl)
+      "= true, if properties for the specific heat capacity according to Chakraborty
+    et al. with the adsorption enthalpy according to Clausius Clapeyron are required";
+    parameter Boolean require_cp_adsorpt_ChakrabortyElAl_Dubinin=
+      (require_h_ads_Dubinin and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl)
+      "= true, if properties for the specific heat capacity according to Chakraborty
+    et al. with the adsorption enthalpy according to Dubinin are required";
+
+    parameter Boolean require_cp_adsorpt_WaltonLeVan=
+      (require_h_ads_Formal and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan)
+      "= true, if properties for the specific heat capacity according to Walton and
+    Le Van are required";
+    parameter Boolean require_cp_adsorpt_WaltonLeVan_CC=
+      (require_h_ads_CC and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan)
+      "= true, if properties for the specific heat capacity according to Walton and
+    Le Van with the adsorption enthalpy according to Clausius Clapeyron are required";
+    parameter Boolean require_cp_adsorpt_WaltonLeVan_Dubinin=
+      (require_h_ads_Dubinin and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan)
+      "= true, if properties for the specific heat capacity according to Walton and
+    Le Van with the adsorption enthalpy according to Dubinin are required";
+
+    parameter Boolean require_cp_adsorpt_SchwambergerSchmidt=
+      (require_h_ads_Formal and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.SchwambergerSchmidt)
+      "= true, if properties for the specific heat capacity according to Schwamberger
+    and Schmidt are required";
+    parameter Boolean require_cp_adsorpt_SchwambergerSchmidt_CC=
+      (require_h_ads_CC and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.SchwambergerSchmidt)
+      "= true, if properties for the specific heat capacity according to Schwamberger
+    and Schmidt with the adsorption enthalpy according to Clausius Clapeyron are required";
+    parameter Boolean require_cp_adsorpt_SchwambergerSchmidt_Dubinin=
+      (require_h_ads_Dubinin and approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.SchwambergerSchmidt)
+      "= true, if properties for the specific heat capacity according to Schwamberger
+    and Schmidt with the adsorption enthalpy according to Dubinin are required";
+
+    parameter Boolean require_v_adsorpt=
+      not neglectSpecifcVolume or
+      not neglectSpecifcVolume and
+      ((require_dxv_avg_dp_T) or
+      (require_dxv_avg_dT_p) or
+      (require_caloricAdsorptAdsorbateState and require_h_ads_Formal) or
+      (require_entropicAdsorptAdsorbateState and require_h_ads_Formal) or
+      (require_h_ads_Formal) or
+      (require_cp_adsorpt_ChakrabortyElAl) or
+      (require_cp_adsorpt_ChakrabortyElAl_CC) or
+      (require_cp_adsorpt_WaltonLeVan) or
+      (require_cp_adsorpt_SchwambergerSchmidt)) or
+      (require_h_ads_Dubinin) or
+      (require_caloricAdsorptAdsorbateState and require_h_ads_Dubinin) or
+      (require_entropicAdsorptAdsorbateState and require_h_ads_Dubinin) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin) or
+      (require_cp_adsorpt_SchwambergerSchmidt_Dubinin)
+      "= true, if specific volume of the adsorpt is required";
+    parameter Boolean require_dv_adsorpt_dp_T=
+      not neglectSpecifcVolume and
+      ((require_dxv_avg_dp_T) or
+      (require_cp_adsorpt_ChakrabortyElAl) or
+      (require_cp_adsorpt_WaltonLeVan) or
+      (require_cp_adsorpt_SchwambergerSchmidt)) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin) or
+      (require_cp_adsorpt_SchwambergerSchmidt_Dubinin)
+      "= true, if the partial derivative of the specific volume of the adsorpt w.r.t.
+    pressure at constant temperature is required";
+    parameter Boolean require_dv_adsorpt_dT_p=
+      (require_dv_adsorpt_dp_T) or
+      not neglectSpecifcVolume and
+      ((require_dxv_avg_dT_p) or
+      (require_cp_adsorpt_ChakrabortyElAl) or
+      (require_cp_adsorpt_ChakrabortyElAl_CC) or
+      (require_cp_adsorpt_WaltonLeVan) or
+      (require_cp_adsorpt_SchwambergerSchmidt)) or
+      (require_h_ads_Dubinin) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin) or
+      (require_cp_adsorpt_SchwambergerSchmidt_Dubinin)
+      "= true, if the partial derivative of the specific volume of the adsorpt w.r.t.
+    temperature at pressure temperature is required";
+    parameter Boolean require_ddv_adsorpt_dT_dT_p=
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin) or
+      (require_cp_adsorpt_SchwambergerSchmidt)
+      "= true, if the second-order partial derivative of the specific volume of the 
+    adsorpt w.r.t. temperature at pressure temperature is required";
+
+    parameter Boolean require_dv_adsorptive_dp_T=
+      (require_h_ads_Formal and require_massEnergyBalances) or
+      (require_h_ads_Formal and require_entropyBalance) or
+      (require_cp_adsorpt_ChakrabortyElAl)
+      "= true, if the partial derivative of the specific volume of the adsorptive 
+    w.r.t. pressure at constant temperature is required";
+    parameter Boolean require_dv_adsorptive_dT_p=
+      (require_dv_adsorptive_dp_T) or
+      (require_cp_adsorpt_ChakrabortyElAl) or
+      (require_cp_adsorpt_ChakrabortyElAl_CC) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin)
+      "= true, if the partial derivative of the specific volume of the adsorptive 
+    w.r.t. temperature at pressure temperature is required";
+
+    parameter Boolean require_cp_adsorptive=
+      (require_massEnergyBalances) or
+      (require_entropyBalance) or
+      (require_cp_adsorpt_ChakrabortyElAl) or
+      (require_cp_adsorpt_ChakrabortyElAl_CC) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan) or
+      (require_cp_adsorpt_WaltonLeVan_CC) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin)
+      "= true, if the specific heat capacity of the adsorptive is required";
+
+    parameter Boolean require_p_sat=
+      (require_v_adsorpt and approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve) or
+      (require_h_ads_Dubinin) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin) or
+      (require_cp_adsorpt_SchwambergerSchmidt_Dubinin)
+      "= true, if the vapor pressure is required";
+    parameter Boolean require_dp_sat_dT=
+      (require_massEnergyBalances and
+      approachSpecificVolume == SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve) or
+      (require_massEnergyBalances and require_h_ads_Dubinin) or
+      (require_entropyBalance and require_h_ads_Dubinin) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin) or
+      (require_cp_adsorpt_SchwambergerSchmidt_Dubinin)
+      "= true, if the partial derivative of the vapor pressure w.r.. temperature is
+    required";
+
+    parameter Boolean require_rho_satLiq_T=
+      (require_v_adsorpt and approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve)
+      "= true, if the bubble point density at given temperature is required";
+    parameter Boolean require_drho_satLiq_dT=
+      (require_dv_adsorpt_dT_p and approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve)
+      "= true, if the partial derivative of the bubble point density at given 
+    temperature w.r.t. tempreature is required";
+    parameter Boolean require_ddrho_satLiq_dT_dT=
+      (require_ddv_adsorpt_dT_dT_p and approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve)
+      "= true, if the second-order partial derivative of the bubble point density 
+    at given temperature w.r.t. tempreature is required";
+
+    parameter Boolean require_h_adsorptiveToLiquid=
+      (require_h_ads_Dubinin) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin) or
+      (require_cp_adsorpt_SchwambergerSchmidt_Dubinin)
+      "= true, if the specific enthalpy of vaporization is required";
+    parameter Boolean require_dh_adsorptiveToLiquid_dp_T=
+      (require_h_ads_Dubinin and require_massEnergyBalances) or
+      (require_h_ads_Dubinin and require_entropyBalance) or
+      (require_cp_adsorpt_ChakrabortyElAl_Dubinin) or
+      (require_cp_adsorpt_WaltonLeVan_Dubinin) or
+      (require_cp_adsorpt_SchwambergerSchmidt_Dubinin)
+      "= true, if the partial derivatieve of the specific enthalpy of vaporization 
+    w.r.t. pressure and constant temperature is required";
+    parameter Boolean require_dh_adsorptiveToLiquid_dT_p=
+      (require_dh_adsorptiveToLiquid_dp_T)
+      "= true, if the partial derivatieve of the specific enthalpy of vaporization 
+    w.r.t. temperature and constant pressure is required";
+
+    parameter Boolean require_cp_satLiq_T=
+      (calcCaloricProperties and approachSpecificHeatCapacity==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve)
+      "= true, if the specific heat capacity of the bubble point at given temperature
+     is required";
+
+    //
+    // State variables
+    //
+    Modelica.Units.SI.SpecificVolume v
+      "Specific volume";
+    Modelica.Units.SI.SpecificEnthalpy h
+      "Specific enthalpy";
+    Modelica.Units.SI.SpecificInternalEnergy u
+      "Specific internal energy";
+    Modelica.Units.SI.SpecificEntropy s
+      "Specific entropy";
+    Modelica.Units.SI.SpecificGibbsFreeEnergy  g
+      "Specific free enthalpy (i.e., Gibbs free energy)";
+    Modelica.Units.SI.SpecificHelmholtzFreeEnergy  a
+      "Specific free energy (i.e., Helmholts free energy)";
+
+    //
+    // Additional properties of the one-phase regime
+    //
+    Modelica.Units.SI.SpecificHeatCapacity cp
+      "Specific heat capacity";
+
+    //
+    // Additional properties of the two-phase regime
+    //
+    Modelica.Units.SI.Pressure p_sat
+      "Saturated vapor pressure";
+    Modelica.Units.SI.SpecificVolume v_satLiq
+      "Specific volume at the bubble point at given temperature";
+
+    Modelica.Units.SI.SpecificEnthalpy  h_adsorptiveToLiquid
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+
+    Modelica.Units.SI.SpecificHeatCapacity cp_satLiq
+      "Specific heat capacaity at the bubble point at given temperature";
+
+    //
+    // Partial derivatives
+    //
+    SorpLib.Units.DerSpecificVolumeByPressure dv_dp_T
+      "Partial derivative of the specific volume w.r.t. pressure at constant
+    temperature";
+    SorpLib.Units.DerSpecificVolumeByTemperature dv_dT_p
+      "Partial derivative of the specific volume w.r.t. temperature at constant
+    pressure";
+
+    Modelica.Media.Common.DerPressureByTemperature dp_sat_dT
+      "Partial derivative of saturated vapor pressure w.r.t. temperature";
+
+    SorpLib.Units.DerSpecificVolumeByTemperature dv_satLiq_dT
+      "Partial derivative of the specific volume at the bubble point at given
+    temperature w.r.t. temperature";
+    SorpLib.Units.DerSpecificVolumeByTemperatureTemperature ddv_satLiq_dT_dT
+      "Second-order partial derivative of the specific volume at the bubble point 
+    at given temperature w.r.t. temperature";
+
+    SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp_T
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+    Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT_p
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This model calculates all properties of the adsorptive required for the working
+pair model at once. Thus, computational costs are reduced because redundant
+calculations of the same properties are avoided.
+</p>
+</html>"));
+  end AdsorptiveProperties;
+  //
+  // Functions of the two-phase regime
+  //
+  replaceable partial function p_sat_T
+    "Calculates the vapor pressure as function of temperature"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Temperature T
+      "Saturated vapor temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.Pressure p_sat
+      "Saturated vapor pressure"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This function calculates the vapor pressure at the bubble point and its first- 
+and second-order partial derivatives w.r.t. temperature as function of temperaure.
+</p>
+</html>"));
+  end p_sat_T;
+
+  replaceable partial function rho_satLiq_T
+    "Calculates the density at the bubble point as function of temperature"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Temperature T
+      "Saturated vapor temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.Density rho_satLiq
+      "Density at bubble point"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This function calculates the specific volume at the bubble point and its first- 
+and second-order partial derivatives w.r.t. temperature as function of temperaure.
+</p>
+</html>"));
+  end rho_satLiq_T;
+
+  replaceable partial function pRho_satLiq
+    "Calculates the vapor pressure, density at the bubble point, and their first- and second-order partial derivatives w.r.t. temperature"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Temperature T
+      "Saturated vapor temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.TemperatureDifference dT
+      "Temperature difference if derivative is calculated numerically"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.Pressure p_sat
+      "Saturated vapor pressure"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+    output Modelica.Units.SI.DerPressureByTemperature dp_sat_dT
+      "Partial derivative of the vapor pressure w.r.t. temperature"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+    output SorpLib.Units.DerPressureByTemperatureTemperature ddp_sat_dT_dT
+      "Calculates the second-order partial derivative of the vapor pressure w.r.t. 
+    temperature"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+
+    output Modelica.Units.SI.Density rho_satLiq
+      "Density at bubble point"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+    output SorpLib.Units.DerDensityByTemperature drho_satLiq_dT
+      "Calculates the partial derivative of the density at the bubble point w.r.t.
+      temperature"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+    output SorpLib.Units.DerDensityByTemperatureTemperature ddrho_satLiq_dT_dT
+    "Calculates the second-order partial derivative of the density at the bubble 
+    point w.r.t. temperature"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This function calculates the vapor pressure and the specific volume at the
+bubble point as function of temperature. For both properties, this function 
+also calculates the first- and second-order partial derivatives w.r.t. temperature.
+</p>
+</html>"));
+  end pRho_satLiq;
+  //
+  // Functions of the one-phase regime
+  //
+  replaceable partial function h_pT
+    "Calculates the specific enthalpy of the adsorptive as function of pressure
+    and temperature"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Pressure p
+      "Pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T
+      "Temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Modelica.Units.SI.Pressure p_lb
+      "Lower bound of pressure (i.e., if gas state and p < p_lb, assume ideal gas)"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Modelica.Units.SI.SpecificEnthalpy h_ref
+      "Specific enthalpy at reference pressure and temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Pressure p_ref
+      "Reference pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T_ref
+      "Reference temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.SpecificEnthalpy h
+      "Specific enthalpy"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This function calculates the specific enthalpy as function of pressure and temperature.
+If the pressure is below its lower bound <i>p_lb</i>, the specific enthalpy is calculated
+assuming an ideal gas using the reference point and the specific heat capacity evaluated
+at <i>p_lb</i> and <i>T</i>.
+</p>
+</html>"));
+  end h_pT;
+
+  replaceable partial function s_pT
+    "Calculates the specific entropy of the adsorptive as function of pressure
+    and temperature"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Pressure p
+      "Pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T
+      "Temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Modelica.Units.SI.Pressure p_lb
+      "Lower bound of pressure (i.e., if gas state and p < p_lb, assume ideal gas)"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Modelica.Units.SI.SpecificEntropy s_ref
+      "Specific entropy at reference pressure and temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Pressure p_ref
+      "Reference pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T_ref
+      "Reference temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.SpecificEntropy s
+      "Specific entropy"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This function calculates the specific entropy as function of pressure and temperature.
+If the pressure is below its lower bound <i>p_lb</i>, the specific entropy is calculated
+assuming an ideal gas using the reference point and the specific heat capacity evaluated
+at <i>p_lb</i> and <i>T</i>.
+</p>
+</html>"));
+  end s_pT;
+  //
+  // Functions calculating properties required for calculating the specific heat
+  // capacity of the adsorpt
+  //
+  replaceable partial function calc_properties
+  "Calculates all properties of the adsorptive at gas/vapor phase required for the working pair model at once"
+    extends Modelica.Icons.Function;
+
+    input Modelica.Units.SI.Pressure p
+      "Pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T
+      "Temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Modelica.Units.SI.PressureDifference dp
+      "Pressure difference if derivative is calculated numerically"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.TemperatureDifference dT
+      "Temperature difference if derivative is calculated numerically"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Pressure p_min
+      "Minimal pressure at which fluid properties can be calculated (i.e., assumption
+    ideal gas at lower pressure)"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Boolean require_v_adsorptive
+      "= true, if the specific volume of the adsorptive and its partial derivatives
+    are required"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Boolean require_h_adsorptive
+      "= true, if the specific enthalpy of the adsorptive is required"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Boolean require_s_adsorptive
+      "= true, if the specific entropy of the adsorptive is required"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Boolean require_dh_adsorptive_dT_dp
+      "= true, if the partial derivative of the specific enthalpy w.r.t. temperature
+    at constant pressure is required"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Boolean require_h_adsorptiveToLiquid
+      "= true, if specific enthalpy difference between adsorptive phase and saturated
+    liquid phase is required"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Boolean adsorptiveAtDewPoint
+      "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.SpecificVolume v
+      "Specific volume"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+    output SorpLib.Units.DerSpecificVolumeByPressure dv_dp_T
+      "Partial derivative of the specific volume w.r.t. pressure at constant
+      temperature"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+    output SorpLib.Units.DerSpecificVolumeByTemperature dv_dT_p
+      "Partial derivative of the specific volume w.r.t. temperature at constant
+      pressure"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+    output Modelica.Units.SI.SpecificEnthalpy h
+      "Specific enthalpy"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+    output Modelica.Units.SI.SpecificEntropy s
+      "Specific enropy"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+    output Modelica.Units.SI.SpecificHeatCapacity dh_dT_p
+      "Partial derivative of the specific enthalpy w.r.t. temperature at constant
+      pressure"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+    output Modelica.Units.SI.SpecificEnthalpy h_atl
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+    output SorpLib.Units.DerSpecificEnthalpyByPressure dh_atl_dp
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant
+    temperature"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+    output Modelica.Units.SI.SpecificHeatCapacity dh_atl_dT
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This function calculates all properties of the adsorptive required for calculating
+the specific heat capacity of the adsorpt or uptake-averaged properties of the adsorpt
+and their partial derivatives. Thus, computational costs are reduced because redundant 
+calculations of the same properties are avoided.
+</p>
+</html>"));
+  end calc_properties;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This partial package defines basic models and functions that are required to calculate all thermodynamic
+properties of a pure component working pair. These basic models and functions are media-specific models
+and functions, thus depending on the selected media model. Packages that inherit properties from this 
+partial package must redeclare all partial models and functions. It may be that a partial model or function   
+cannot be calculated with the selected media model. An example is the saturated vapor pressure as a function 
+of temperature when the media model is an ideal gas. Such functions will not be accessed if the working pair 
+is parameterized correctly. Therefore, these functions shall just return a dummy value when redeclaring.
+</p>
+</html>"));
+end PartialPureMediumSpecificFunctions;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureMediumSpecificFunctions/package.order b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureMediumSpecificFunctions/package.order
new file mode 100644
index 0000000..41b0ed1
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureMediumSpecificFunctions/package.order
@@ -0,0 +1,7 @@
+AdsorptiveProperties
+p_sat_T
+rho_satLiq_T
+pRho_satLiq
+h_pT
+s_pT
+calc_properties
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/AdsorptProperties.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/AdsorptProperties.mo
new file mode 100644
index 0000000..8272bc9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/AdsorptProperties.mo
@@ -0,0 +1,1656 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+model AdsorptProperties
+  "Calculates all properties of the adsorpt required for the working pair model at once"
+  extends Modelica.Icons.MaterialProperty;
+
+  //
+  // Definition of parameters regarding the calculation approach
+  //
+  parameter SorpLib.Choices.IndependentVariablesPureComponentWorkingPair
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT
+    "Independent state variables of the working pair model"
+    annotation (Dialog(tab="General", group="Calculation Setup"),
+                choicesAllMatching=true,
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean calcCaloricProperties = true
+    "= true, if caloric properties are calculated (i.e., h, u, h_ads, and cp)"
+    annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcEntropicProperties = false
+    "= true, if caloric properties are calculated (i.e., s, g, a, and s_ads)"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean calcAdsorptAdsorbateState = false
+    "= true, if state properties of average adsorpt phase and adosrbate phase are
+    calculated (i.e., requires numerical integration)"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean calcDerivativesIsotherm = true
+    "= true, if partial derivatives of isotherms required for mass, energy, and
+    entropy balance of working paur volumes are calculated"
+    annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcDerivativesMassEnergyBalance = true
+    "= true, if partial derivatives required for mass and energy balance of
+    working pair volumes are calculated"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = calcDerivativesIsotherm and calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+  parameter Boolean calcDerivativesEntropyBalance = false
+    "= true, if partial derivatives required for entropy balance of working
+    pair volumes are calculated"
+    annotation (Dialog(tab = "General", group = "Calculation Setup",
+                enable = calcDerivativesIsotherm and
+                  calcDerivativesMassEnergyBalance and calcCaloricProperties),
+                choices(checkBox=true),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Boolean adsorptiveAtDewPoint = false
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab = "General", group = "Calculation Setup"),
+                Evaluate=true,
+                HideResult=true,
+                choices(checkBox=true));
+
+  //
+  // Definition of parameters regarding sorption enthalpy
+  //
+  parameter SorpLib.Choices.SorptionEnthalpy approachSorptionEnthalpy=
+    SorpLib.Choices.SorptionEnthalpy.Constant
+    "Calculation approach for the sorption enthalpy"
+    annotation (Dialog(tab="Sorption Enthalpy", group="General"),
+                Evaluate=false,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  parameter Modelica.Units.SI.SpecificEnthalpy h_ads_constant= 3000e3
+    "Constant specific enthalpy of adsorption"
+    annotation (Dialog(tab="Sorption Enthalpy", group="Constant",
+                enable=(approachSorptionEnthalpy==
+                  SorpLib.Choices.SorptionEnthalpy.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  //
+  // Definition of parameters regarding adsorpt phase's specific heat capacity
+  //
+  parameter SorpLib.Choices.SpecificHeatCapacityAdsorpt
+    approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.Constant
+    "Calculation approach for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="General"),
+                Evaluate=false,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  parameter Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt_constant= 4e3
+    "Constant specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Constant",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  parameter SorpLib.Choices.GeneralizedFunctionApproach cp_adsorpt_function=
+      SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Generalized function used to calculate the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Temperature T_ref_cp_adsorpt = 293.15
+    "Reference temperature for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Modelica.Units.SI.SpecificHeatCapacity cp_adsorpt_ref = 1
+    "Reference fluid property data for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_cp_adsorpt[:]={cp_adsorpt_constant}
+    "Coefficients of generalized function for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real exponents_cp_adsorpt[size(coefficients_cp_adsorpt,1)]={0}
+    "Exponents of generalized function for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Generalized Function",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+
+  parameter SorpLib.Choices.InterpolationApproach cp_adsorpt_interpolation=
+      SorpLib.Choices.InterpolationApproach.Linear
+    "Interpolation approach used to calculate the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=(approachSpecificHeatCapacity ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                Evaluate=false,
+                HideResult=true);
+  parameter Real abscissa_cp_adsorpt[:]={0, 1000}
+    "Known abscissa values for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real ordinate_cp_adsorpt[size(abscissa_cp_adsorpt,1)]=
+    {cp_adsorpt_constant, cp_adsorpt_constant}
+    "Known ordinate values for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=(approachSpecificHeatCapacity==
+                  SorpLib.Choices.SpecificHeatCapacityAdsorpt.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_cubicSplines_cp_adsorpt[size(abscissa_cp_adsorpt,1),4]=
+    SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients(
+      abscissa=abscissa_cp_adsorpt,
+      ordinate=ordinate_cp_adsorpt)
+    "Coefficient a to d for cubic polynomials for the specific heat capacity of the adsorpt"
+    annotation (Dialog(tab="Specific Heat Capacity", group="Interpolation",
+                enable=false),
+                HideResult=true,
+                Evaluate= true);
+
+  //
+  // Definition of parameters regarding adsorpt phase's specific volume
+  //
+  parameter Boolean neglectSpecifcVolume = false
+    "= true, if specific volume of the adsorpt is neglected (i.e., v_adsorpt = 0
+    -> u_adsorpt = h_adsorpt and g_adsorpt = a_adsorpt)"
+    annotation (Dialog(tab = "Specific Volume", group = "General"),
+                choices(checkBox=true),
+                Evaluate= false,
+                HideResult=true);
+  parameter SorpLib.Choices.SpecificVolumeAdsorpt approachSpecificVolume=
+      SorpLib.Choices.SpecificVolumeAdsorpt.Constant
+    "Calculation approach for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="General",
+                enable=not neglectSpecifcVolume),
+                Evaluate=false,
+                HideResult=true,
+                choicesAllMatching=true);
+
+  parameter Modelica.Units.SI.SpecificVolume v_adsorpt_constant= 1e-3
+    "Constant specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Constant",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Constant)),
+                HideResult=true,
+                Evaluate= false);
+
+  parameter SorpLib.Choices.GeneralizedFunctionApproach v_adsorpt_function=
+      SorpLib.Choices.GeneralizedFunctionApproach.PolynomialFunctionTemperature
+    "Generalized function used to calculate the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.Temperature T_ref_v_adsorpt = 293.15
+    "Reference temperature for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Modelica.Units.SI.SpecificVolume v_adsorpt_ref = 1
+    "Reference fluid property data for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_v_adsorpt[:]={v_adsorpt_constant}
+    "Coefficients of generalized function for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real exponents_v_adsorpt[size(coefficients_v_adsorpt,1)]={0}
+    "Exponents of generalized function for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Generalized Function",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction)),
+                HideResult=true,
+                Evaluate= true);
+
+  parameter SorpLib.Choices.InterpolationApproach v_adsorpt_interpolation=
+      SorpLib.Choices.InterpolationApproach.Linear
+    "Interpolation approach used to calculate the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                Evaluate=false,
+                HideResult=true);
+  parameter Real abscissa_v_adsorpt[:]={0, 1000}
+    "Known abscissa values for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real ordinate_v_adsorpt[size(abscissa_v_adsorpt,1)]=
+    {v_adsorpt_constant, v_adsorpt_constant}
+    "Known ordinate values for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=(not neglectSpecifcVolume and approachSpecificVolume ==
+                  SorpLib.Choices.SpecificVolumeAdsorpt.Interpolation)),
+                HideResult=true,
+                Evaluate= true);
+  parameter Real coefficients_cubicSplines_v_adsorpt[size(abscissa_v_adsorpt,1),4]=
+    SorpLib.Media.Functions.Utilities.calcCubicSplineCoefficients(
+      abscissa=abscissa_v_adsorpt,
+      ordinate=ordinate_v_adsorpt)
+    "Coefficient a to d for cubic polynomials for the specific volume of the adsorpt"
+    annotation (Dialog(tab="Specific Volume", group="Interpolation",
+                enable=false),
+                HideResult=true,
+                Evaluate= true);
+
+  //
+  // Definition of parameters regarding advanced options
+  //
+  parameter Modelica.Units.SI.Pressure p_adsorpt_min = 615
+    "Lower limit for the pressure p_adsorpt"
+    annotation (Dialog(tab = "Advanced", group = "Limiter"),
+                Evaluate=true,
+                HideResult=true);
+
+  parameter Modelica.Units.SI.PressureDifference dp = 1e-3
+    "Pressure difference used when calculating partial derivatives numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used when calculating partial derivatives numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Derivatives"),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_adsorpt_int_h = 1e-6
+    "Integration tolerance when calculating the specific average enthalpy of the
+    adsorpt numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcAdsorptAdsorbateState and calcCaloricProperties),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_adsorpt_int_s = 1e-6
+    "Integration tolerance when calculating the specific average entropy of the
+    adsorpt numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcAdsorptAdsorbateState and calcEntropicProperties),
+                Evaluate=true,
+                HideResult=true);
+  parameter Real tolerance_adsorpt_int_cp = 1e-2
+    "Integration tolerance when calculating the specific heat capacity numerically"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcCaloricProperties),
+                Evaluate=true,
+                HideResult=true);
+  parameter SorpLib.Units.Uptake x_adsorpt_lb = 0
+    "Lower limit for integral when calculating the specific heat capacity of the
+    adsorpt or uptake-averaged porperties of the adsorpt numerically (i.e., 
+    should be zero)"
+    annotation (Dialog(tab="Advanced", group="Numerics - Integrals",
+                enable=calcCaloricProperties),
+                Evaluate=true,
+                HideResult=true);
+
+  //
+  // Definition of general inputs
+  //
+  input Real[no_coefficients] c
+    "Isotherm coefficients"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Real[no_coefficients] dc_dT_adsorpt
+    "Partial derivatives of the isotherm coefficients w.r.t. temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Real[no_coefficients] ddc_dT_adsorpt_dT_adsorpt
+    "Second-prder partial derivatives of the isotherm coefficients w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  input Modelica.Units.SI.Pressure p_adsorpt
+    "Equilibrium pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input SorpLib.Units.Uptake x_adsorpt
+    "Equilibrium uptake"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input
+    SorpLib.Media.WorkingPairs.Records.PropertiesPureAdsorptive properties_adsorptive
+    "Record containing all properties of the adsorptive required for the working
+    pair model"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output SorpLib.Media.WorkingPairs.Records.PropertiesPureAdsorpt properties=
+    SorpLib.Media.WorkingPairs.Records.PropertiesPureAdsorpt(
+      state = SorpLib.Media.WorkingPairs.Records.StateVariables(
+        p=p_avg,
+        T=T_avg,
+        v=v_avg,
+        h=h_avg,
+        u=u_avg,
+        s=s_avg,
+        g=g_avg,
+        a=a_avg),
+      v=v,
+      h_ads=h_ads,
+      cp=cp,
+      derivatives_isotherm=
+        SorpLib.Media.WorkingPairs.Records.DerivativesPureIsothermModel(
+          dx_dp_T=dx_dp_T,
+          dx_dT_p=dx_dT_p,
+          dp_dx_T=dp_dx_T,
+          dp_dT_x=dp_dT_x),
+      dxv_avg_dp_T=dxv_avg_dp_T,
+      dxv_avg_dT_p=dxv_avg_dT_p,
+      dxh_avg_dp_T=dxh_avg_dp_T,
+      dxh_avg_dT_p=dxh_avg_dT_p,
+      dxh_avg_dx_T=dxh_avg_dx_T,
+      dxh_avg_dT_x=dxh_avg_dT_x,
+      dxs_avg_dp_T=dxs_avg_dp_T,
+      dxs_avg_dT_p=dxs_avg_dT_p,
+      dxs_avg_dx_T=dxs_avg_dx_T,
+      dxs_avg_dT_x=dxs_avg_dT_x)
+    "Record containing all required properties of the adsorpt"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of constants
+  //
+  constant Modelica.Units.SI.MolarMass M_adsorpt = M_adsorptive
+    "Molar mass of the adsorpt/adsorptive";
+
+  //
+  // Booleans indicating which variables must be calculated
+  //
+protected
+  parameter Boolean require_caloricAdsorptAdsorbateState=
+    (calcCaloricProperties and calcAdsorptAdsorbateState)
+    "= true, if uptake-averaged thermal and caloric properties of the adsorpt and 
+    adsorbate phase are required";
+  parameter Boolean require_entropicAdsorptAdsorbateState=
+    (require_caloricAdsorptAdsorbateState and calcEntropicProperties)
+    "= true, if uptake-averaged entropic properties of the adsorpt and adsorbate 
+    phase are required";
+
+  parameter Boolean require_massEnergyBalances=
+    (calcCaloricProperties and calcDerivativesIsotherm and
+    calcDerivativesMassEnergyBalance)
+    "= true, if properties for mass and energy balance are required";
+  parameter Boolean require_entropyBalance=
+    (require_massEnergyBalances and calcDerivativesEntropyBalance)
+    "= true, if properties for entropy balance are required";
+
+  parameter Boolean require_dxv_avg_dp_T=
+    (require_massEnergyBalances)
+    "= true, if partial derivative of uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. pressure at constant temperature is required";
+  parameter Boolean require_dxv_avg_dT_p=
+    (require_massEnergyBalances)
+    "= true, if partial derivative of uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. temperature at constant pressure is required";
+
+  parameter Boolean require_dxh_avg_dp_T=
+    (require_massEnergyBalances and stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT)
+    "= true, if partial derivative of uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. pressure at constant temperature is required";
+  parameter Boolean require_dxh_avg_dT_p=
+    (require_massEnergyBalances and stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT)
+    "= true, if partial derivative of uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. temperature at constant pressure is required";
+  parameter Boolean require_dxh_avg_dx_T=
+    (require_massEnergyBalances)
+    "= true, if partial derivative of uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. uptake at constant temperature is required";
+  parameter Boolean require_dxh_avg_dT_x=
+    (require_massEnergyBalances)
+    "= true, if partial derivative of uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. temperature at constant uptake is required";
+
+  parameter Boolean require_dxs_avg_dp_T=
+    (require_entropyBalance and stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT)
+    "= true, if partial derivative of uptake-averaged specific entropy of the adsorpt
+    times the uptake w.r.t. pressure at constant temperature is required";
+  parameter Boolean require_dxs_avg_dT_p=
+    (require_entropyBalance and stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT)
+    "= true, if partial derivative of uptake-averaged specific entropy of the adsorpt
+    times the uptake w.r.t. temperature at constant pressure is required";
+  parameter Boolean require_dxs_avg_dx_T=
+    (require_entropyBalance)
+    "= true, if partial derivative of uptake-averaged specific entropy of the adsorpt
+    times the uptake w.r.t. uptake at constant temperature is required";
+  parameter Boolean require_dxs_avg_dT_x=
+    (require_entropyBalance)
+    "= true, if partial derivative of uptake-averaged specific entropy of the adsorpt
+    times the uptake w.r.t. temperature at constant uptake is required";
+
+  parameter Boolean require_h_ads_Formal=
+    (calcCaloricProperties and approachSorptionEnthalpy ==
+    SorpLib.Choices.SorptionEnthalpy.Formal)
+    "= true, if properties for the specific enthalpy of adsorption are required";
+  parameter Boolean require_h_ads_CC=
+    (calcCaloricProperties and approachSorptionEnthalpy ==
+    SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron)
+    "= true, if properties for the specific enthalpy of adsorption according to
+    Clausius Clapeyron are required";
+  parameter Boolean require_h_ads_Dubinin=
+    (calcCaloricProperties and approachSorptionEnthalpy ==
+    SorpLib.Choices.SorptionEnthalpy.Dubinin)
+    "= true, if properties for the specific enthalpy of adsorption according to
+    Dubinin are required";
+
+  parameter Boolean require_cp_ChakrabortyElAl=
+    (require_h_ads_Formal and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl)
+    "= true, if properties for the specific heat capacity according to Chakraborty
+    et al. are required";
+  parameter Boolean require_cp_ChakrabortyElAl_CC=
+    (require_h_ads_CC and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl)
+    "= true, if properties for the specific heat capacity according to Chakraborty
+    et al. with the adsorption enthalpy according to Clausius Clapeyron are required";
+  parameter Boolean require_cp_ChakrabortyElAl_Dubinin=
+    (require_h_ads_Dubinin and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl)
+    "= true, if properties for the specific heat capacity according to Chakraborty
+    et al. with the adsorption enthalpy according to Dubinin are required";
+
+  parameter Boolean require_cp_WaltonLeVan=
+    (require_h_ads_Formal and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan)
+    "= true, if properties for the specific heat capacity according to Walton and
+    Le Van are required";
+  parameter Boolean require_cp_WaltonLeVan_CC=
+    (require_h_ads_CC and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan)
+    "= true, if properties for the specific heat capacity according to Walton and
+    Le Van with the adsorption enthalpy according to Clausius Clapeyron are required";
+  parameter Boolean require_cp_WaltonLeVan_Dubinin=
+    (require_h_ads_Dubinin and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan)
+    "= true, if properties for the specific heat capacity according to Walton and
+    Le Van with the adsorption enthalpy according to Dubinin are required";
+
+  parameter Boolean require_cp_SchwambergerSchmidt=
+    (require_h_ads_Formal and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.SchwambergerSchmidt)
+    "= true, if properties for the specific heat capacity according to Schwamberger
+    and Schmidt are required";
+  parameter Boolean require_cp_SchwambergerSchmidt_CC=
+    (require_h_ads_CC and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.SchwambergerSchmidt)
+    "= true, if properties for the specific heat capacity according to Schwamberger
+    and Schmidt with the adsorption enthalpy according to Clausius Clapeyron are required";
+  parameter Boolean require_cp_SchwambergerSchmidt_Dubinin=
+    (require_h_ads_Dubinin and approachSpecificHeatCapacity ==
+    SorpLib.Choices.SpecificHeatCapacityAdsorpt.SchwambergerSchmidt)
+    "= true, if properties for the specific heat capacity according to Schwamberger
+    and Schmidt with the adsorption enthalpy according to Dubinin are required";
+
+  parameter Boolean require_derivativesIsotherm_pT=
+    (calcDerivativesIsotherm) or
+    not neglectSpecifcVolume and (require_dxv_avg_dp_T) or
+    (require_h_ads_Formal) or
+    (require_h_ads_CC) or
+    (require_cp_ChakrabortyElAl) or
+    (require_cp_ChakrabortyElAl_CC) or
+    (require_cp_ChakrabortyElAl_Dubinin) or
+    (require_dxh_avg_dp_T) or
+    (require_dxh_avg_dT_p)
+    "= true, if partial derivatives of the isotherm model w.r.t. pressure and
+    temperature are required";
+  parameter Boolean require_derivativesIsotherm_xT=
+    (require_derivativesIsotherm_pT and stateVariables==
+    SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.xT) or
+    (require_cp_ChakrabortyElAl) or
+    (require_cp_ChakrabortyElAl_CC) or
+    (require_cp_ChakrabortyElAl_Dubinin) or
+    (require_dxh_avg_dp_T) or
+    (require_dxh_avg_dT_p)
+    "= true, if partial derivatives of the isotherm model w.r.t. uptake and
+    temperature are required";
+  parameter Boolean require_ddx_dp_dp_T=
+    (require_derivativesIsotherm_pT and require_massEnergyBalances and
+    (require_h_ads_Formal or require_h_ads_CC)) or
+    (require_derivativesIsotherm_pT and require_entropyBalance and
+    (require_h_ads_Formal or require_h_ads_CC)) or
+    (require_cp_ChakrabortyElAl) or
+    (require_cp_ChakrabortyElAl_CC)
+    "= true, if second-order partial derivative of the uptake w.r.t. pressure at
+    constant temperature is required";
+  parameter Boolean require_ddx_dT_dT_p=
+    (require_ddx_dp_dp_T)
+    "= true, if second-order partial derivative of the uptake w.r.t. temperature
+    at constant pressure is required";
+  parameter Boolean require_ddx_dp_dT=
+    (require_ddx_dp_dp_T)
+    "= true, if second-order partial derivative of the uptake w.r.t. pressure and
+    temperature is required";
+
+  parameter Boolean require_v=
+    not neglectSpecifcVolume or
+    not neglectSpecifcVolume and
+    ((require_dxv_avg_dp_T) or
+    (require_dxv_avg_dT_p) or
+    (require_caloricAdsorptAdsorbateState and require_h_ads_Formal) or
+    (require_entropicAdsorptAdsorbateState and require_h_ads_Formal) or
+    (require_h_ads_Formal) or
+    (require_cp_ChakrabortyElAl) or
+    (require_cp_ChakrabortyElAl_CC) or
+    (require_cp_WaltonLeVan) or
+    (require_cp_SchwambergerSchmidt)) or
+    (require_h_ads_Dubinin) or
+    (require_caloricAdsorptAdsorbateState and require_h_ads_Dubinin) or
+    (require_entropicAdsorptAdsorbateState and require_h_ads_Dubinin) or
+    (require_cp_ChakrabortyElAl_Dubinin) or
+    (require_cp_WaltonLeVan_Dubinin) or
+    (require_cp_SchwambergerSchmidt_Dubinin)
+    "= true, if specific volume of last adsorbed molecule is required";
+  parameter Boolean require_dv_dp_T=
+    not neglectSpecifcVolume and
+    ((require_dxv_avg_dp_T) or
+    (require_cp_ChakrabortyElAl) or
+    (require_cp_WaltonLeVan) or
+    (require_cp_SchwambergerSchmidt)) or
+    (require_cp_ChakrabortyElAl_Dubinin) or
+    (require_cp_WaltonLeVan_Dubinin) or
+    (require_cp_SchwambergerSchmidt_Dubinin)
+    "= true, if the partial derivative of the specific volume of the last adsorbed
+    molecule w.r.t. pressure at constant temperature is required";
+  parameter Boolean require_dv_dT_p=
+    (require_dv_dp_T) or
+    not neglectSpecifcVolume and
+    ((require_dxv_avg_dT_p) or
+    (require_cp_ChakrabortyElAl) or
+    (require_cp_ChakrabortyElAl_CC) or
+    (require_cp_WaltonLeVan) or
+    (require_cp_SchwambergerSchmidt)) or
+    (require_h_ads_Dubinin) or
+    (require_cp_ChakrabortyElAl_Dubinin) or
+    (require_cp_WaltonLeVan_Dubinin) or
+    (require_cp_SchwambergerSchmidt_Dubinin)
+    "= true, if the partial derivative of the specific volume of the last adsorbed
+    molecule w.r.t. temperature at pressure temperature is required";
+  parameter Boolean require_ddv_dT_dT_p=
+    (require_dbeta_dT_p)
+    "= true, if the second-order partial derivative of the specific volume of the 
+    last adsorbed molecule w.r.t. temperature at pressure temperature is required";
+
+  parameter Boolean require_cp=
+    calcCaloricProperties
+    "= true, if specific heat capacity of the last adsorbed molecule or uptake-
+    averaged adsorpt is required";
+
+  parameter Boolean require_beta=
+    (require_caloricAdsorptAdsorbateState and require_h_ads_Dubinin) or
+    (require_entropicAdsorptAdsorbateState and require_h_ads_Dubinin) or
+    (require_h_ads_Dubinin) or
+    (require_cp_ChakrabortyElAl_Dubinin) or
+    (require_cp_WaltonLeVan_Dubinin) or
+    (require_cp_SchwambergerSchmidt_Dubinin)
+    "= true, if isobaric expansion coefficient of the last adsorbed molecule is 
+    required";
+  parameter Boolean require_dbeta_dp_T=
+    (require_cp_ChakrabortyElAl_Dubinin) or
+    (require_cp_WaltonLeVan_Dubinin) or
+    (require_cp_SchwambergerSchmidt_Dubinin)
+    "= true, if the partial derivative of the isobaric expansion coefficient of 
+    the last adsorbed molecule w.r.t. pressure at constant temperature is 
+    required";
+  parameter Boolean require_dbeta_dT_p=
+    (require_dbeta_dp_T)
+    "= true, if the partial derivative of the isobaric expansion coefficient of 
+    the last adsorbed molecule w.r.t. temperature at pressure temperature is 
+    required";
+
+  parameter Boolean require_h_ads=
+    (calcCaloricProperties) or
+    (require_entropyBalance) or
+    (require_cp_ChakrabortyElAl) or
+    (require_cp_ChakrabortyElAl_CC) or
+    (require_cp_ChakrabortyElAl_Dubinin)
+    "= true, if the specific enthalpy of adsorption of the last adsorbed molecule
+    is required";
+  parameter Boolean require_dh_ads_dp_T=
+    (require_cp_ChakrabortyElAl) or
+    (require_cp_ChakrabortyElAl_CC) or
+    (require_cp_ChakrabortyElAl_Dubinin)
+    "= true, if the partial derivatieve of the specific enthalpy of adsorption 
+    of the last adsorbed molecule w.r.t. pressure and constant temperature is 
+    required";
+  parameter Boolean require_dh_ads_dT_p=
+    (require_dh_ads_dp_T)
+    "= true, if the partial derivatieve of the specific enthalpy of adsorption 
+    of the last adsorbed molecule w.r.t. temperature and constant pressure is 
+    required";
+
+  //
+  // State variables
+  //
+  Modelica.Units.SI.Pressure p_avg
+    "Uptake-averaged pressure of the adsorpt phase";
+  Modelica.Units.SI.Temperature T_avg
+    "Uptake-averaged temperature of the adsorpt phase";
+  Modelica.Units.SI.SpecificVolume v_avg
+    "Uptake-averaged specific volume of the adsorpt phase";
+  Modelica.Units.SI.SpecificEnthalpy h_avg
+    "Uptake-averaged specific enthalpy of the adsorpt phase";
+  Modelica.Units.SI.SpecificInternalEnergy u_avg
+    "Uptake-averaged specific internal energy of the adsorpt phase";
+  Modelica.Units.SI.SpecificEntropy s_avg
+    "Uptake-averaged specific entropy of the adsorpt phase";
+  Modelica.Units.SI.SpecificGibbsFreeEnergy g_avg
+    "Uptake-averaged specific free enthalpy (i.e., Gibbs free energy) of the 
+    adsorpt phase";
+  Modelica.Units.SI.SpecificHelmholtzFreeEnergy a_avg
+    "Uptake-averaged specific free energy (i.e., Helmholts free energy) of the 
+    adsorpt phase";
+
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume of last adsorbed molecule";
+
+  //
+  // Additional properties
+  //
+  Modelica.Units.SI.SpecificEnthalpy h_ads
+    "Specific enthalpy of adsorption of last adsorbed molecule";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity of last adsorbed molecule or the uptake-averaged 
+    adsorpt, depending on selected approach)";
+  Modelica.Units.SI.RelativePressureCoefficient beta
+    "Isobaric expansion coefficient of last adsorbed molecule";
+
+  //
+  // Partial derivatives
+  //
+  SorpLib.Units.DerUptakeSpecificVolumeByPressure dxv_avg_dp_T
+    "Partial derivative of the uptake-averaged specific volume times the uptake
+    w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificVolumeByTemperature dxv_avg_dT_p
+    "Partial derivative of the uptake-averaged specific volume times the uptake
+    w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerUptakeSpecificEnthalpyByPressure dxh_avg_dp_T
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake
+    w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByTemperature dxh_avg_dT_p
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake
+    w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByUptake dxh_avg_dx_T
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake
+    w.r.t. uptake at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByTemperature dxh_avg_dT_x
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake 
+    w.r.t. temperature at constant uptake";
+
+  SorpLib.Units.DerUptakeSpecificEntropyByPressure dxs_avg_dp_T
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEntropyByTemperature dxs_avg_dT_p
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerUptakeSpecificEntropyByUptake dxs_avg_dx_T
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. uptake at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEntropyByTemperature dxs_avg_dT_x
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. temperature at constant uptake";
+
+  SorpLib.Units.DerSpecificVolumeByPressure dv_dp_T
+    "Partial derivative of the specific volume of the last adsorbed molecule 
+    w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_dT_p
+    "Partial derivative of the specific volume of the last adsorbed molecule 
+    w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerSpecificVolumeByTemperatureTemperature ddv_dT_dT_p
+    "Second-order partial derivative of specific volume of the last adsorbed 
+    molecule w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_ads_dp_T
+    "Partial derivative of the specific enthalpy of adsorption w.r.t. pressure 
+    at constant temperature";
+  Modelica.Units.SI.SpecificHeatCapacity dh_ads_dT_p
+    "Partial derivative of the specific enthalpy of adsorption w.r.t. temperature 
+    at constant pressure";
+
+  SorpLib.Units.DerIsobaricExpansionCoefficientByPressure dbeta_dp_T
+    "Partial derivative of isobaric expansion coefficient of the adsorpt phase
+    w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_dT_p
+    "Partial derivative of isobaric expansion coefficient of the adsorpt phase
+    w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerUptakeByPressure dx_dp_T
+    "Partial derivative of the uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_dT_p
+    "Partial derivative of the uptake w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerPressureByUptake dp_dx_T
+    "Partial derivative of the uptake w.r.t. uptake at constant temperature";
+  Modelica.Units.SI.DerPressureByTemperature dp_dT_x
+    "Partial derivative of the uptake w.r.t. temperature at constant uptake";
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at constant 
+    temperature";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at constant 
+    pressure";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+equation
+  //
+  // Partial derivatives of the isotherm model
+  //
+  dx_dp_T =if not require_derivativesIsotherm_pT then 0 else
+    IsothermModel.dx_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Partial derivative of the uptake w.r.t. pressure at constant temperature";
+  dx_dT_p =if not require_derivativesIsotherm_pT then 0 else
+    IsothermModel.dx_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of the uptake w.r.t. temperature at constant pressure";
+
+  dp_dx_T =if not require_derivativesIsotherm_xT then 0 else 1/dx_dp_T
+    "Partial derivative of the uptake w.r.t. uptake at constant temperature";
+  dp_dT_x =if not require_derivativesIsotherm_xT then 0 else -dx_dT_p/dx_dp_T
+    "Partial derivative of the uptake w.r.t. temperature at constant uptake";
+
+  ddx_adsorpt_dp_dp =if not require_ddx_dp_dp_T then 0 else
+    IsothermModel.ddx_dp_dp(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant 
+    temperature";
+  ddx_adsorpt_dT_dT =if not require_ddx_dT_dT_p then 0 else
+    IsothermModel.ddx_dT_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT_adsorpt,
+    ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant 
+    pressure";
+  ddx_adsorpt_dp_dT =if not require_ddx_dp_dT then 0 else
+    IsothermModel.ddx_dp_dT(
+    p_adsorpt=p_adsorpt,
+    T_adsorpt=T_adsorpt,
+    c=c,
+    dc_dT_adsorpt=dc_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Uptake-averaged state properties of the adsorpt
+  //
+  p_avg = if not require_caloricAdsorptAdsorbateState then 0 else
+    p_adsorpt
+    "Uptake-averaged pressure of the adsorpt phase";
+  T_avg = if not require_caloricAdsorptAdsorbateState then 0 else
+    T_adsorpt
+    "Uptake-averaged temperature of the adsorpt phase";
+  v_avg = if not require_caloricAdsorptAdsorbateState or
+    neglectSpecifcVolume then 0 else v
+    "Uptake-averaged specific volume of the adsorpt phase: Corresponds to specific
+    volume of the last adsorbed molecule as specific volume is constant or only a
+    function of temperature for all implemented approaches";
+
+  if not require_caloricAdsorptAdsorbateState then
+    h_avg = 0
+      "Uptake-averaged specific enthalpy of the adsorpt phase";
+
+  else
+    if approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Constant then
+      h_avg = 1 / ((x_adsorpt-min(x_adsorpt_lb,0.5*x_adsorpt))) *
+        Modelica.Math.Nonlinear.quadratureLobatto(
+        f=function calc_integrand_h_avg_adsorpt_Constant(
+          T_adsorpt=T_adsorpt,
+          c=c,
+          h_ads = h_ads_constant,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+          p_clausiusClyperon=p_adsorpt_min,
+          dp=dp,
+          dT=dT),
+        a=min(x_adsorpt_lb,0.5*x_adsorpt),
+        b=x_adsorpt,
+        tolerance=tolerance_adsorpt_int_h)
+        "Uptake-averaged specific enthalpy of the adsorpt phase";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Formal then
+      h_avg = 1 / ((x_adsorpt-min(x_adsorpt_lb,0.5*x_adsorpt))) *
+        Modelica.Math.Nonlinear.quadratureLobatto(
+        f=function calc_integrand_h_avg_adsorpt_Formal(
+          T_adsorpt=T_adsorpt,
+          c=c,
+          dc_dT_adsorpt=dc_dT_adsorpt,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+          v_adsorpt=if neglectSpecifcVolume then 0 else v,
+          p_clausiusClyperon=p_adsorpt_min,
+          dp=dp,
+          dT=dT),
+        a=min(x_adsorpt_lb,0.5*x_adsorpt),
+        b=x_adsorpt,
+        tolerance=tolerance_adsorpt_int_h)
+        "Uptake-averaged specific enthalpy of the adsorpt phase";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron then
+      h_avg = 1 / ((x_adsorpt-min(x_adsorpt_lb,0.5*x_adsorpt))) *
+        Modelica.Math.Nonlinear.quadratureLobatto(
+        f=function calc_integrand_h_avg_adsorpt_CC(
+          T_adsorpt=T_adsorpt,
+          c=c,
+          dc_dT_adsorpt=dc_dT_adsorpt,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+          p_clausiusClyperon=p_adsorpt_min,
+          dp=dp,
+          dT=dT),
+        a=min(x_adsorpt_lb,0.5*x_adsorpt),
+        b=x_adsorpt,
+        tolerance=tolerance_adsorpt_int_h)
+        "Uptake-averaged specific enthalpy of the adsorpt phase";
+
+    else
+      h_avg = 1 / ((x_adsorpt-min(x_adsorpt_lb,0.5*x_adsorpt))) *
+        Modelica.Math.Nonlinear.quadratureLobatto(
+        f=function calc_integrand_h_avg_adsorpt_Dubinin(
+          T_adsorpt=T_adsorpt,
+          c=c,
+          dc_dT_adsorpt=dc_dT_adsorpt,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+          v_adsorpt=v,
+          beta_adsorpt=beta,
+          p_clausiusClyperon=p_adsorpt_min,
+          dp=dp,
+          dT=dT),
+        a=min(x_adsorpt_lb,0.5*x_adsorpt),
+        b=x_adsorpt,
+        tolerance=tolerance_adsorpt_int_h)
+        "Uptake-averaged specific enthalpy of the adsorpt phase";
+
+    end if;
+  end if;
+
+  u_avg = if not require_caloricAdsorptAdsorbateState then 0 else
+    h_avg - p_avg * v_avg
+    "Uptake-averaged specific internal energy of the adsorpt phase";
+
+
+  if not require_entropicAdsorptAdsorbateState then
+    s_avg = 0
+      "Uptake-averaged specific enthalpy of the adsorpt phase";
+
+  else
+    if approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Constant then
+      s_avg = 1 / ((x_adsorpt-x_adsorpt_lb)) *
+        Modelica.Math.Nonlinear.quadratureLobatto(
+        f=function calc_integrand_s_avg_adsorpt_Constant(
+          T_adsorpt=T_adsorpt,
+          c=c,
+          h_ads = h_ads_constant,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+          p_clausiusClyperon=p_adsorpt_min,
+          dp=dp,
+          dT=dT),
+        a=x_adsorpt_lb,
+        b=x_adsorpt,
+        tolerance=tolerance_adsorpt_int_h)
+        "Uptake-averaged specific entropy of the adsorpt phase";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Formal then
+      s_avg = 1 / ((x_adsorpt-x_adsorpt_lb)) *
+        Modelica.Math.Nonlinear.quadratureLobatto(
+        f=function calc_integrand_s_avg_adsorpt_Formal(
+          T_adsorpt=T_adsorpt,
+          c=c,
+          dc_dT_adsorpt=dc_dT_adsorpt,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+          v_adsorpt=if neglectSpecifcVolume then 0 else v,
+          p_clausiusClyperon=p_adsorpt_min,
+          dp=dp,
+          dT=dT),
+        a=x_adsorpt_lb,
+        b=x_adsorpt,
+        tolerance=tolerance_adsorpt_int_h)
+        "Uptake-averaged specific entropy of the adsorpt phase";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron then
+      s_avg = 1 / ((x_adsorpt-x_adsorpt_lb)) *
+        Modelica.Math.Nonlinear.quadratureLobatto(
+        f=function calc_integrand_s_avg_adsorpt_CC(
+          T_adsorpt=T_adsorpt,
+          c=c,
+          dc_dT_adsorpt=dc_dT_adsorpt,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+          p_clausiusClyperon=p_adsorpt_min,
+          dp=dp,
+          dT=dT),
+        a=x_adsorpt_lb,
+        b=x_adsorpt,
+        tolerance=tolerance_adsorpt_int_h)
+        "Uptake-averaged specific entropy of the adsorpt phase";
+
+    else
+      s_avg = 1 / ((x_adsorpt-x_adsorpt_lb)) *
+        Modelica.Math.Nonlinear.quadratureLobatto(
+        f=function calc_integrand_s_avg_adsorpt_Dubinin(
+          T_adsorpt=T_adsorpt,
+          c=c,
+          dc_dT_adsorpt=dc_dT_adsorpt,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+          v_adsorpt=v,
+          beta_adsorpt=beta,
+          p_clausiusClyperon=p_adsorpt_min,
+          dp=dp,
+          dT=dT),
+        a=x_adsorpt_lb,
+        b=x_adsorpt,
+        tolerance=tolerance_adsorpt_int_h)
+        "Uptake-averaged specific entropy of the adsorpt phase";
+
+    end if;
+  end if;
+
+  g_avg = if not require_entropicAdsorptAdsorbateState then 0 else
+    h_avg - T_avg * s_avg
+    "Uptake-averaged specific free enthalpy (i.e., Gibbs free energy) of the 
+    adsorpt phase";
+  a_avg = if not require_entropicAdsorptAdsorbateState then 0 else
+    u_avg - T_avg * s_avg
+    "Uptake-averaged specific free energy (i.e., Helmholts free energy) of the 
+    adsorpt phase";
+
+  //
+  // Specific volume of the last adsorbed molecule and its partial derivatives
+  //
+  if not require_v then
+    v =0
+      "Specific volume of the last adsorbed molecule";
+
+  else
+    if approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.Constant then
+      v = v_adsorpt_constant
+        "Specific volume of the last adsorbed molecule";
+
+    elseif approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve then
+      v = properties_adsorptive.v_satLiq
+        "Specific volume of the last adsorbed molecule";
+
+    elseif approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction then
+      v = SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+        T=T_adsorpt,
+        T_ref=T_ref_v_adsorpt,
+        z_ref=v_adsorpt_ref,
+        coefficients=coefficients_v_adsorpt,
+        exponents=exponents_v_adsorpt,
+        approach=v_adsorpt_function)
+        "Specific volume of the last adsorbed molecule";
+
+    else
+      if v_adsorpt_interpolation ==
+        SorpLib.Choices.InterpolationApproach.Linear then
+        v = SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+          T=T_adsorpt,
+          abscissa=abscissa_v_adsorpt,
+          ordinate=ordinate_v_adsorpt)
+          "Specific volume of the last adsorbed molecule";
+
+      else
+        v = SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+          T=T_adsorpt,
+          abscissa=abscissa_v_adsorpt,
+          ordinate=ordinate_v_adsorpt,
+          coefficients=coefficients_cubicSplines_v_adsorpt)
+          "Specific volume of the last adsorbed molecule";
+
+      end if;
+    end if;
+  end if;
+
+  dv_dp_T =if not require_dv_dp_T then 0 else 0
+    "Partial derivative of the specific volume of the last adsorbed molecule 
+    w.r.t. pressure at constant temperature: Corresponds to unity because v_adsorpt 
+    is  not a function of pressure";
+
+  if not require_dv_dT_p then
+    dv_dT_p =0
+    "Partial derivative of the specific volume of the last adsorbed molecule 
+    w.r.t. temperature at constant pressure";
+
+  else
+    if approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.Constant then
+      dv_dT_p = 0
+        "Partial derivative of the specific volume of the last adsorbed molecule 
+        w.r.t. temperature at constant pressure";
+
+    elseif approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve then
+      dv_dT_p = properties_adsorptive.dv_satLiq_dT
+        "Partial derivative of the specific volume of the last adsorbed molecule 
+        w.r.t. temperature at constant pressure";
+
+    elseif approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction then
+      dv_dT_p = SorpLib.Media.Functions.Utilities.dgeneralizedFunction_dT(
+        T=T_adsorpt,
+        T_ref=T_ref_v_adsorpt,
+        z_ref=v_adsorpt_ref,
+        coefficients=coefficients_v_adsorpt,
+        exponents=exponents_v_adsorpt,
+        approach=v_adsorpt_function)
+        "Partial derivative of the specific volume of the last adsorbed molecule 
+        w.r.t. temperature at constant pressure";
+
+    else
+      if v_adsorpt_interpolation ==
+        SorpLib.Choices.InterpolationApproach.Linear then
+        dv_dT_p = SorpLib.Media.Functions.Utilities.dlinearInterpolation_dT(
+          T=T_adsorpt,
+          abscissa=abscissa_v_adsorpt,
+          ordinate=ordinate_v_adsorpt)
+          "Partial derivative of the specific volume of the last adsorbed molecule 
+          w.r.t. temperature at constant pressure";
+
+      else
+        dv_dT_p = SorpLib.Media.Functions.Utilities.dcubicSplineInterpolation_dT(
+          T=T_adsorpt,
+          abscissa=abscissa_v_adsorpt,
+          ordinate=ordinate_v_adsorpt,
+          coefficients=coefficients_cubicSplines_v_adsorpt)
+          "Partial derivative of the specific volume of the last adsorbed molecule 
+          w.r.t. temperature at constant pressure";
+
+      end if;
+    end if;
+  end if;
+
+  if not require_ddv_dT_dT_p then
+    ddv_dT_dT_p =0
+      "Second-order partial derivative of the specific volume of the last adsorbed
+      molecule w.r.t. temperature at constant pressure";
+
+  else
+    if approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.Constant then
+      ddv_dT_dT_p = 0
+        "Second-order partial derivative of the specific volume of the last 
+        adsorbed molecule w.r.t. temperature at constant pressure";
+
+    elseif approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve then
+      ddv_dT_dT_p = properties_adsorptive.ddv_satLiq_dT_dT
+        "Second-order partial derivative of the specific volume of the last 
+        adsorbed molecule w.r.t. temperature at constant pressure";
+
+    elseif approachSpecificVolume ==
+      SorpLib.Choices.SpecificVolumeAdsorpt.GeneralizedFunction then
+      ddv_dT_dT_p =
+        SorpLib.Media.Functions.Utilities.ddgeneralizedFunction_dT_dT(
+        T=T_adsorpt,
+        T_ref=T_ref_v_adsorpt,
+        z_ref=v_adsorpt_ref,
+        coefficients=coefficients_v_adsorpt,
+        exponents=exponents_v_adsorpt,
+        approach=v_adsorpt_function)
+        "Second-order partial derivative of the specific volume of the last 
+        adsorbed molecule w.r.t. temperature at constant pressure";
+
+    else
+      if v_adsorpt_interpolation ==
+        SorpLib.Choices.InterpolationApproach.Linear then
+        ddv_dT_dT_p =
+          SorpLib.Media.Functions.Utilities.ddlinearInterpolation_dT_dT(
+          T=T_adsorpt,
+          abscissa=abscissa_v_adsorpt,
+          ordinate=ordinate_v_adsorpt)
+          "Second-order partial derivative of the specific volume of the last 
+          adsorbed molecule w.r.t. temperature at constant pressure";
+
+      else
+        ddv_dT_dT_p =
+          SorpLib.Media.Functions.Utilities.ddcubicSplineInterpolation_dT_dT(
+          T=T_adsorpt,
+          abscissa=abscissa_v_adsorpt,
+          ordinate=ordinate_v_adsorpt,
+          coefficients=coefficients_cubicSplines_v_adsorpt)
+          "Second-order partial derivative of the specific volume of the last 
+          adsorbed molecule w.r.t. temperature at constant pressure";
+
+      end if;
+    end if;
+  end if;
+
+  //
+  // Isobaric expansion coefficient of the last adsorbed molecule
+  //
+  beta =if not require_beta or not require_v then 0
+     else 1/v*dv_dT_p
+    "Isobaric expansion coefficient of the last adsorbed molecule";
+
+  dbeta_dp_T =if not require_dbeta_dp_T or not require_v
+     then 0 else 0
+    "Partial derivative of isobaric expansion coefficient of the last adsorbed 
+    molecule w.r.t. pressure at constant temperature: Corresponds to unity as 
+    v_adsorpt is not a function of pressure";
+  dbeta_dT_p =if not require_dbeta_dT_p or not require_v
+     then 0 else -(1/v*dv_dT_p)^2 + 1/v*ddv_dT_dT_p
+    "Partial derivative of isobaric expansion coefficient of the last adsorbed
+    molecule w.r.t. temperature at constant pressure";
+
+  //
+  // Specific enthalpy of adsorption of the last adsorbed molecule and its
+  // partial derivatives
+  //
+  if not require_h_ads then
+    h_ads =0
+      "Specific enthalpy of adsorption of the last adsorbed molecule";
+
+  else
+    if approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Constant then
+      h_ads = h_ads_constant
+        "Specific enthalpy of adsorption of the last adsorbed molecule";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Formal then
+      h_ads = SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+        M_adsorptive=M_adsorpt,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=properties_adsorptive.state.v,
+        v_adsorpt=if neglectSpecifcVolume then 0 else v,
+        dx_adsorpt_dp=dx_dp_T,
+        dx_adsorpt_dT=dx_dT_p) / M_adsorpt
+        "Specific enthalpy of adsorption of the last adsorbed molecule";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron then
+      h_ads =
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_dp_T,
+        dx_adsorpt_dT=dx_dT_p) / M_adsorpt
+        "Specific enthalpy of adsorption of the last adsorbed molecule";
+
+    else
+      h_ads = calc_h_ads_Dubinin(
+        c=c,
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        x_adsorpt=x_adsorpt,
+        v_adsorpt=v,
+        beta_adsorpt=beta,
+        properties_adsorptive=properties_adsorptive)
+        "Specific enthalpy of adsorption of the last adsorbed molecule";
+
+    end if;
+  end if;
+
+  if not require_dh_ads_dp_T then
+    dh_ads_dp_T = 0
+    "Partial derivative of the specific enthalpy of adsorption of the last 
+    adsorbed molecule w.r.t. pressure at constant temperature";
+
+  else
+    if approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Constant then
+      dh_ads_dp_T = 0
+      "Partial derivative of the specific enthalpy of adsorption of the last 
+      adsorbed molecule w.r.t. pressure at constant temperature";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Formal then
+      dh_ads_dp_T =
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp(
+        M_adsorptive=M_adsorpt,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=properties_adsorptive.state.v,
+        v_adsorpt=if neglectSpecifcVolume then 0 else v,
+        dv_adsorptive_dp=properties_adsorptive.dv_dp_T,
+        dv_adsorpt_dp=if neglectSpecifcVolume then 0 else dv_dp_T,
+        dx_adsorpt_dp=dx_dp_T,
+        dx_adsorpt_dT=dx_dT_p,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT) / M_adsorpt
+      "Partial derivative of the specific enthalpy of adsorption of the last 
+      adsorbed molecule w.r.t. pressure at constant temperature";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron then
+      dh_ads_dp_T =
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_dp_T,
+        dx_adsorpt_dT=dx_dT_p,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT) / M_adsorpt
+        "Partial derivative of the specific enthalpy of adsorption of the last 
+        adsorbed molecule w.r.t. pressure at constant temperature";
+
+    else
+      dh_ads_dp_T = calc_dh_ads_dp_T_Dubinin(
+        c=c,
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        x_adsorpt=x_adsorpt,
+        dx_adsorpt_dp=dx_dp_T,
+        v_adsorpt=v,
+        dv_adsorpt_dp=dv_dp_T,
+        beta_adsorpt=beta,
+        dbeta_adsorpt_dp=dbeta_dp_T,
+        properties_adsorptive=properties_adsorptive)
+        "Partial derivative of the specific enthalpy of adsorption of the last 
+        adsorbed molecule w.r.t. pressure at constant temperature";
+
+    end if;
+  end if;
+
+  if not require_dh_ads_dT_p then
+    dh_ads_dT_p = 0
+      "Partial derivative of the specific enthalpy of adsorption of the last
+      adsorbed molecule w.r.t. temperature at constant pressure";
+
+  else
+    if approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Constant then
+      dh_ads_dT_p = 0
+        "Partial derivative of the specific enthalpy of adsorption of the last
+        adsorbed molecule w.r.t. temperature at constant pressure";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.Formal then
+      dh_ads_dT_p =
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT(
+        M_adsorptive=M_adsorpt,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=properties_adsorptive.state.v,
+        v_adsorpt=if neglectSpecifcVolume then 0 else v,
+        dv_adsorptive_dT=properties_adsorptive.dv_dT_p,
+        dv_adsorpt_dT=if neglectSpecifcVolume then 0 else dv_dT_p,
+        dx_adsorpt_dp=dx_dp_T,
+        dx_adsorpt_dT=dx_dT_p,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT) / M_adsorpt
+        "Partial derivative of the specific enthalpy of adsorption of the last
+        adsorbed molecule w.r.t. temperature at constant pressure";
+
+    elseif approachSorptionEnthalpy ==
+      SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron then
+      dh_ads_dT_p =
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_dp_T,
+        dx_adsorpt_dT=dx_dT_p,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT) / M_adsorpt
+        "Partial derivative of the specific enthalpy of adsorption of the last
+        adsorbed molecule w.r.t. temperature at constant pressure";
+
+    else
+      dh_ads_dT_p = calc_dh_ads_dT_p_Dubinin(
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt,
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        x_adsorpt=x_adsorpt,
+        dx_adsorpt_dT=dx_dT_p,
+        v_adsorpt=v,
+        dv_adsorpt_dT=dv_dT_p,
+        beta_adsorpt=beta,
+        dbeta_adsorpt_dT=dbeta_dT_p,
+        properties_adsorptive=properties_adsorptive)
+        "Partial derivative of the specific enthalpy of adsorption of the last
+        adsorbed molecule w.r.t. temperature at constant pressure";
+
+    end if;
+  end if;
+
+  //
+  // Specific heat capacity of the last adsorbed molecule or uptake-averaged
+  // adsorpt
+  //
+  if not require_cp then
+    cp = 0
+      "Specific heat capacity: Corresponds to last adsorbed molecule but is
+      independent of uptake";
+  else
+    if approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.Constant then
+      cp = cp_adsorpt_constant
+        "Specific heat capacity: Corresponds to last adsorbed molecule but is
+        independent of uptake";
+
+    elseif approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve then
+      cp = properties_adsorptive.cp_satLiq
+        "Specific heat capacity: Corresponds to last adsorbed molecule but is
+        independent of uptake";
+
+    elseif approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.GeneralizedFunction then
+      cp = SorpLib.Media.Functions.Utilities.generalizedFunction_T(
+        T=T_adsorpt,
+        T_ref=T_ref_cp_adsorpt,
+        z_ref=cp_adsorpt_ref,
+        coefficients=coefficients_cp_adsorpt,
+        exponents=exponents_cp_adsorpt,
+        approach=cp_adsorpt_function)
+        "Specific heat capacity: Corresponds to last adsorbed molecule but is
+        independent of uptake";
+
+    elseif approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.Interpolation then
+      if cp_adsorpt_interpolation ==
+        SorpLib.Choices.InterpolationApproach.Linear then
+        cp = SorpLib.Media.Functions.Utilities.linearInterpolation_T(
+          T=T_adsorpt,
+          abscissa=abscissa_cp_adsorpt,
+          ordinate=ordinate_cp_adsorpt)
+          "Specific heat capacity: Corresponds to last adsorbed molecule but is
+          independent of uptake";
+
+      else
+        cp = SorpLib.Media.Functions.Utilities.cubicSplineInterpolation_T(
+          T=T_adsorpt,
+          abscissa=abscissa_cp_adsorpt,
+          ordinate=ordinate_cp_adsorpt,
+          coefficients=coefficients_cubicSplines_cp_adsorpt)
+          "Specific heat capacity: Corresponds to last adsorbed molecule but is
+          independent of uptake";
+
+      end if;
+
+    elseif approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.WaltonLeVan then
+      if approachSorptionEnthalpy ==
+        SorpLib.Choices.SorptionEnthalpy.Constant then
+        cp = properties_adsorptive.cp
+          "Specific heat capacity: Corresponds to last adsorbed molecule but is
+          dependent of uptake";
+
+      elseif approachSorptionEnthalpy ==
+        SorpLib.Choices.SorptionEnthalpy.Formal then
+        cp =  properties_adsorptive.cp -
+          1 / ((x_adsorpt-x_adsorpt_lb) * M_adsorpt) *
+          Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function calc_integrand_WaltonLeVan(
+            T_adsorpt=T_adsorpt,
+            c=c,
+            dc_dT_adsorpt=dc_dT_adsorpt,
+            ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt,
+            adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+            v_adsorpt=if neglectSpecifcVolume then 0 else v,
+            dv_adsorpt_dp=if neglectSpecifcVolume then 0 else dv_dp_T,
+            dv_adsorpt_dT=if neglectSpecifcVolume then 0 else dv_dT_p,
+            p_clausiusClyperon=p_adsorpt_min,
+            dp=dp,
+            dT=dT),
+          a=x_adsorpt_lb,
+          b=x_adsorpt,
+          tolerance=tolerance_adsorpt_int_cp)
+          "Specific heat capacity: Corresponds to last adsorbed molecule but is
+          dependent of uptake";
+
+      elseif approachSorptionEnthalpy ==
+        SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron then
+        cp =  properties_adsorptive.cp -
+          1 / ((x_adsorpt-x_adsorpt_lb) * M_adsorpt) *
+          Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function calc_integrand_WaltonLeVan_CC(
+            T_adsorpt=T_adsorpt,
+            c=c,
+            dc_dT_adsorpt=dc_dT_adsorpt,
+            ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt),
+          a=x_adsorpt_lb,
+          b=x_adsorpt,
+          tolerance=tolerance_adsorpt_int_cp)
+          "Specific heat capacity: Corresponds to last adsorbed molecule but is
+          dependent of uptake";
+
+      else
+        cp =  properties_adsorptive.cp -
+          1 / ((x_adsorpt-x_adsorpt_lb) * M_adsorpt) *
+          Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function calc_integrand_WaltonLeVan_Dubinin(
+            T_adsorpt=T_adsorpt,
+            c=c,
+            dc_dT_adsorpt=dc_dT_adsorpt,
+            ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt,
+            adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+            v_adsorpt=v,
+            dv_adsorpt_dp=dv_dp_T,
+            dv_adsorpt_dT=dv_dT_p,
+            beta_adsorpt=beta,
+            dbeta_adsorpt_dp=dbeta_dp_T,
+            dbeta_adsorpt_dT=dbeta_dT_p,
+            p_clausiusClyperon=p_adsorpt_min,
+            dp=dp,
+            dT=dT),
+          a=x_adsorpt_lb,
+          b=x_adsorpt,
+          tolerance=tolerance_adsorpt_int_cp)
+          "Specific heat capacity: Corresponds to last adsorbed molecule but is
+          dependent of uptake";
+
+      end if;
+
+    elseif approachSpecificHeatCapacity ==
+      SorpLib.Choices.SpecificHeatCapacityAdsorpt.ChakrabortyElAl then
+        cp =
+          SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.cp_ChakrabortyEtAl(
+          M_adsorptive=M_adsorpt,
+          T_adsorpt=T_adsorpt,
+          cp_adsorptive=properties_adsorptive.cp,
+          v_adsorptive=properties_adsorptive.state.v,
+          dv_adsorptive_dT=properties_adsorptive.dv_dT_p,
+          v_adsorpt=if neglectSpecifcVolume then 0 else v,
+          h_ads=h_ads*M_adsorpt,
+          dh_ads_dT_x=M_adsorpt * (dh_ads_dT_p + dh_ads_dp_T * dp_dT_x))
+          "Specific heat capacity: Corresponds to last adsorbed molecule but is
+          dependent of uptake";
+
+    else
+      if approachSorptionEnthalpy ==
+        SorpLib.Choices.SorptionEnthalpy.Constant then
+        cp = 1 / ((x_adsorpt-x_adsorpt_lb)) *
+          Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function calc_integrand_SchwambergerSchmidt_Constant(
+            T_adsorpt=T_adsorpt,
+            c=c,
+            adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+            p_clausiusClyperon=p_adsorpt_min,
+            dp=dp,
+            dT=dT),
+          a=x_adsorpt_lb,
+          b=x_adsorpt,
+          tolerance=tolerance_adsorpt_int_cp)
+          "Specific heat capacity: Corresponds to uptake-averaged adsorpt";
+
+      elseif approachSorptionEnthalpy ==
+        SorpLib.Choices.SorptionEnthalpy.Formal then
+        cp = 1 / ((x_adsorpt-x_adsorpt_lb)) *
+          Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function calc_integrand_SchwambergerSchmidt(
+            T_adsorpt=T_adsorpt,
+            c=c,
+            dc_dT_adsorpt=dc_dT_adsorpt,
+            ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt,
+            adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+            v_adsorpt=if neglectSpecifcVolume then 0 else v,
+            dv_adsorpt_dp=if neglectSpecifcVolume then 0 else dv_dp_T,
+            dv_adsorpt_dT=if neglectSpecifcVolume then 0 else dv_dT_p,
+            p_clausiusClyperon=p_adsorpt_min,
+            dp=dp,
+            dT=dT),
+          a=x_adsorpt_lb,
+          b=x_adsorpt,
+          tolerance=tolerance_adsorpt_int_cp)
+          "Specific heat capacity: Corresponds to uptake-averaged adsorpt";
+
+      elseif approachSorptionEnthalpy ==
+        SorpLib.Choices.SorptionEnthalpy.ClausiusClapeyron then
+        cp = 1 / ((x_adsorpt-x_adsorpt_lb)) *
+          Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function calc_integrand_SchwambergerSchmidt_CC(
+            T_adsorpt=T_adsorpt,
+            c=c,
+            dc_dT_adsorpt=dc_dT_adsorpt,
+            ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt,
+            adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+            p_clausiusClyperon=p_adsorpt_min,
+            dp=dp,
+            dT=dT),
+          a=x_adsorpt_lb,
+          b=x_adsorpt,
+          tolerance=tolerance_adsorpt_int_cp)
+          "Specific heat capacity: Corresponds to uptake-averaged adsorpt";
+
+      else
+        cp =  1 / ((x_adsorpt-x_adsorpt_lb)) *
+          Modelica.Math.Nonlinear.quadratureLobatto(
+          f=function calc_integrand_SchwambergerSchmidt_Dubinin(
+            T_adsorpt=T_adsorpt,
+            c=c,
+            dc_dT_adsorpt=dc_dT_adsorpt,
+            ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt,
+            adsorptiveAtDewPoint=adsorptiveAtDewPoint,
+            v_adsorpt=v,
+            dv_adsorpt_dp=dv_dp_T,
+            dv_adsorpt_dT=dv_dT_p,
+            beta_adsorpt=beta,
+            dbeta_adsorpt_dp=dbeta_dp_T,
+            dbeta_adsorpt_dT=dbeta_dT_p,
+            p_clausiusClyperon=p_adsorpt_min,
+            dp=dp,
+            dT=dT),
+          a=x_adsorpt_lb,
+          b=x_adsorpt,
+          tolerance=tolerance_adsorpt_int_cp)
+          "Specific heat capacity: Corresponds to uptake-averaged adsorpt";
+
+      end if;
+
+    end if;
+  end if;
+
+  //
+  // Partial derivatives required for mass, energy, and entropy balances
+  //
+  dxv_avg_dp_T = if not require_dxv_avg_dp_T or neglectSpecifcVolume then 0
+    else x_adsorpt * dv_dp_T + dx_dp_T * v
+    "Partial derivative of the uptake-averaged specific volume times the uptake 
+    w.r.t. pressure at constant temperature: Note that v_avg = v, as specific 
+    volume is just a function of temperature";
+  dxv_avg_dT_p = if not require_dxv_avg_dT_p or neglectSpecifcVolume then 0
+    else x_adsorpt * dv_dT_p + dx_dT_p * v
+    "Partial derivative of the uptake-averaged specific volume times the uptake  
+    w.r.t. temperature at constant pressure: Note that v_avg = v, as specific 
+    volume is just a function of temperature";
+
+  dxh_avg_dp_T = if not require_dxh_avg_dp_T then 0 else
+    dxh_avg_dx_T / dp_dx_T
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake 
+    w.r.t. pressure at constant temperature";
+  dxh_avg_dT_p = if not require_dxh_avg_dT_p then 0 else
+    dxh_avg_dT_x - dxh_avg_dp_T * dp_dT_x
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake
+    w.r.t. temperature at constant pressure";
+  dxh_avg_dx_T = if not require_dxh_avg_dx_T then 0 else
+    (properties_adsorptive.state.h - h_ads)
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake 
+    w.r.t. uptake at constant temperature";
+  dxh_avg_dT_x = if not require_dxh_avg_dT_x then 0 else
+    x_adsorpt * cp
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake 
+    w.r.t. temperature at constant uptake";
+
+  dxs_avg_dp_T = if not require_dxs_avg_dp_T then 0 else
+    dxs_avg_dx_T / dp_dx_T
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. pressure at constant temperature";
+  dxs_avg_dT_p = if not require_dxs_avg_dT_p then 0 else
+    dxs_avg_dT_x - dxs_avg_dp_T * dp_dT_x
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. temperature at constant pressure";
+  dxs_avg_dx_T = if not require_dxs_avg_dx_T then 0 else
+    (properties_adsorptive.state.s - h_ads / T_adsorpt)
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. uptake at constant temperature";
+  dxs_avg_dT_x = if not require_dxs_avg_dT_x then 0 else
+    x_adsorpt * cp  / T_adsorpt
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. temperature at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates all properties of the adsorpt required for the working
+pair model at once. Thus, computational costs are reduced because redundant
+calculations of the same properties are avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end AdsorptProperties;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/IsothermCoefficients.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/IsothermCoefficients.mo
new file mode 100644
index 0000000..67e25b9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/IsothermCoefficients.mo
@@ -0,0 +1,52 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+model IsothermCoefficients
+  "Calculates the temperature-dependent coefficients of the isotherm model"
+  extends Modelica.Icons.MaterialProperty;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Equilibrium temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference if derivatives are calculated numerically"
+    annotation (Dialog(tab="General",group="Inputs"),
+                HideResult=true);
+
+  //
+  // Definition of outputs
+  //
+  output Real[no_coefficients] c
+    "Isotherm coefficients"
+    annotation (Dialog(tab="General",group="Outputs",enable=false));
+  output Real[no_coefficients] dc_dT
+    "Partial derivative of isotherm coefficients w.r.t. temperature"
+    annotation (Dialog(tab="General",group="Outputs",enable=false));
+  output Real[no_coefficients] ddc_dT_dT
+    "Second-order partial derivative of isotherm coefficients w.r.t. temperature"
+    annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+equation
+    (c, dc_dT, ddc_dT_dT) = calc_coefficients(T_adsorpt=T_adsorpt, dT=dT)
+    "Isotherm coefficients and their partial derivatives w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates temperature-dependent isotherm coefficients <i>c</i> and 
+their partial derivatives with respect to temperature <i>dc_dT</i> (first order) 
+and <i>ddc_dT_dT</i> (second order).
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end IsothermCoefficients;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt.mo
new file mode 100644
index 0000000..7892096
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt.mo
@@ -0,0 +1,272 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_SchwambergerSchmidt
+  "Calculates the integrand required for calculating the specific heat capacity according to Schwamberger and Schmidt (2013)"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT_adsorpt[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ddc_dT_adsorpt_dT_adsorpt[:]
+    "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding the specific volume of the adsorpt
+  //
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+    "Partial derivative of the specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+    "Partial derivative of the specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_adsorptive_dp
+    "Partial derivative of specific volume of the adsorptive w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorptive_dT
+    "Partial derivative of specific volume of the adsorptive w.r.t. temperature at
+    constant pressure";
+
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptive_dT
+    "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := IsothermModel.ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := IsothermModel.ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := IsothermModel.ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    //
+    // Do not use-Clausius Clyperon assumptions
+    //
+    (v_adsorptive, dv_adsorptive_dp, dv_adsorptive_dT,,,dh_adsorptive_dT,,,) :=
+      MediumSpecificFunctions.calc_properties(
+        p=p_adsorpt,
+        T=T_adsorpt,
+        dp=dp,
+        dT=dT,
+        p_min=p_clausiusClyperon,
+        require_v_adsorptive=true,
+        require_h_adsorptive=false,
+        require_s_adsorptive=false,
+        require_dh_adsorptive_dT_dp=true,
+        require_h_adsorptiveToLiquid=false,
+        adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+      "Specific volume of the adsorptive and its partial derivatives as well as
+      the partial derivative of the specific enthalpy of the adsorptive w.r.t.
+      temperature at constant pressure";
+
+    //
+    // Calculation of partial derivatives of molar sorption enthalpy
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dv_adsorptive_dp=dv_adsorptive_dp,
+        dv_adsorpt_dp=dv_adsorpt_dp,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dv_adsorptive_dT=dv_adsorptive_dT,
+        dv_adsorpt_dT=dv_adsorpt_dT,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  else
+    //
+    // Use Clausius-Clyperon assumptions
+    //
+    (,,,,,  dh_adsorptive_dT,,,) :=
+      MediumSpecificFunctions.calc_properties(
+        p=p_adsorpt,
+        T=T_adsorpt,
+        dp=dp,
+        dT=dT,
+        p_min=p_clausiusClyperon,
+        require_v_adsorptive=false,
+        require_h_adsorptive=false,
+        require_s_adsorptive=false,
+        require_dh_adsorptive_dT_dp=true,
+        require_h_adsorptiveToLiquid=false,
+        adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+      "Partial derivative of the specific enthalpy of the adsorptive w.r.t.
+      temperature at constant pressure";
+
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  end if;
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  dh_adsorptive_dT -
+    (dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp) / M_adsorptive
+    "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of the 
+adsorpt with respect to temperature at constant uptake. For more information, 
+check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x\">SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x</a>.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_SchwambergerSchmidt;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt_CC.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt_CC.mo
new file mode 100644
index 0000000..820c64e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt_CC.mo
@@ -0,0 +1,189 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_SchwambergerSchmidt_CC
+  "Calculates the integrand required for calculating the specific heat capacity according to Schwamberger and Schmidt (2013) when using the specifc enthalpy of adsorption according to Clausius Clayperon"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT_adsorpt[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ddc_dT_adsorpt_dT_adsorpt[:]
+    "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptive_dT
+    "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := IsothermModel.ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := IsothermModel.ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := IsothermModel.ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of partial derivatives
+  //
+  (,,,,,  dh_adsorptive_dT,,,) :=
+    MediumSpecificFunctions.calc_properties(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp,
+      dT=dT,
+      p_min=p_clausiusClyperon,
+      require_v_adsorptive=false,
+      require_h_adsorptive=false,
+      require_s_adsorptive=false,
+      require_dh_adsorptive_dT_dp=true,
+      require_h_adsorptiveToLiquid=false,
+      adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+    "Partial derivative of the specific enthalpy of the adsorptive w.r.t.
+    temperature at constant pressure";
+
+  dh_ads_dp_T :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+      ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+  "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+  temperature";
+  dh_ads_dT_p :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+      ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  dh_adsorptive_dT -
+    (dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp) / M_adsorptive
+    "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of the 
+adsorpt with respect to temperature at constant uptake when using the molar adsorption
+enthalpy according to Clausius Clayperon. For more information, check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x_CC\">SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x_CC</a>.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_SchwambergerSchmidt_CC;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt_Constant.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt_Constant.mo
new file mode 100644
index 0000000..ef1dc06
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_SchwambergerSchmidt_Constant.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_SchwambergerSchmidt_Constant
+  "Calculates the integrand required for calculating the specific heat capacity according to Schwamberger and Schmidt (2013) when having a constant specific enthaloy of adsorption"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptive_dT
+    "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  //
+  // Calculation of further properties
+  //
+  (,,,,,  dh_adsorptive_dT,,,) :=
+    MediumSpecificFunctions.calc_properties(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp,
+      dT=dT,
+      p_min=p_clausiusClyperon,
+      require_v_adsorptive=false,
+      require_h_adsorptive=false,
+      require_s_adsorptive=false,
+      require_dh_adsorptive_dT_dp=true,
+      require_h_adsorptiveToLiquid=false,
+      adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+    "Partial derivative of the specific enthalpy of the adsorptive w.r.t.
+    temperature at constant pressure";
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  dh_adsorptive_dT
+    "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of the 
+adsorpt with respect to temperature at constant uptake when using a constant
+specific enthalpy of adsorption.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_SchwambergerSchmidt_Constant;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_WaltonLeVan.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_WaltonLeVan.mo
new file mode 100644
index 0000000..0b4aaf7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_WaltonLeVan.mo
@@ -0,0 +1,248 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_WaltonLeVan
+  "Calculates the integrand required for calculating the specific heat capacity according to Walton and Le Van (2005)"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT_adsorpt[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ddc_dT_adsorpt_dT_adsorpt[:]
+    "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding the specific volume of the adsorpt
+  //
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+    "Partial derivative of the specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+    annotation (Dialog(tab="General",group="Inputs"));
+  input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+    "Partial derivative of the specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive";
+  SorpLib.Units.DerSpecificVolumeByPressure dv_adsorptive_dp
+    "Partial derivative of specific volume of the adsorptive w.r.t. pressure at
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorptive_dT
+    "Partial derivative of specific volume of the adsorptive w.r.t. temperature at
+    constant pressure";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := IsothermModel.ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := IsothermModel.ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := IsothermModel.ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    //
+    // Do not use Clausius Clyperon assumptions
+    //
+    (v_adsorptive, dv_adsorptive_dp, dv_adsorptive_dT,,,,,,) :=
+      MediumSpecificFunctions.calc_properties(
+        p=p_adsorpt,
+        T=T_adsorpt,
+        dp=dp,
+        dT=dT,
+        p_min=p_clausiusClyperon,
+        require_v_adsorptive=true,
+        require_h_adsorptive=false,
+        require_s_adsorptive=false,
+        require_dh_adsorptive_dT_dp=false,
+        require_h_adsorptiveToLiquid=false,
+        adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+      "Specific volume of the adsorptive and its partial derivatives";
+
+    //
+    // Calculation of partial derivatives of molar sorption enthalpy
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dv_adsorptive_dp=dv_adsorptive_dp,
+        dv_adsorpt_dp=dv_adsorpt_dp,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dv_adsorptive_dT=dv_adsorptive_dT,
+        dv_adsorpt_dT=dv_adsorpt_dT,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  else
+    //
+    // Use Clausius-Clyperon assumptions: No further propiertes are required
+    //
+    dh_ads_dp_T :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    dh_ads_dT_p :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT,
+        ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+        ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+  end if;
+
+  //
+  // Calculation of the integrand
+  //
+  y := dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp
+    "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the molar adsorption enthalpy
+with respect to temperature at constant uptake. For more information, check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x\">SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x</a>.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_WaltonLeVan;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_WaltonLeVan_CC.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_WaltonLeVan_CC.mo
new file mode 100644
index 0000000..cd85f59
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_WaltonLeVan_CC.mo
@@ -0,0 +1,147 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_WaltonLeVan_CC
+  "Calculates the integrand required for calculating the specific heat capacity according to Walton and Le Van (2005) when using the specifc enthalpy of adsorption according to Clausius Clayperon"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT_adsorpt[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real ddc_dT_adsorpt_dT_adsorpt[:]
+    "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp
+    "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+  SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT
+    "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+  SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+    "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+  Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  ddx_adsorpt_dp_dp := IsothermModel.ddx_dp_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Second-order partial derivative of uptake w.r.t. pressure at constant temperature";
+  ddx_adsorpt_dT_dT := IsothermModel.ddx_dT_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt,
+      ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. temperature at constant pressure";
+  ddx_adsorpt_dp_dT := IsothermModel.ddx_dp_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+  //
+  // Calculation of partial derivatives
+  //
+  dh_ads_dp_T :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+      ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+  "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+  temperature";
+  dh_ads_dT_p :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+      ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+    "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+  //
+  // Calculation of the integrand
+  //
+  y := dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp
+    "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the molar adsorption enthalpy
+with respect to temperature at constant uptake when using the molar adsorption
+enthalpy according to Clausius Clayperon. For more information, check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x_CC\">SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x_CC</a>.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_WaltonLeVan_CC;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_CC.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_CC.mo
new file mode 100644
index 0000000..1ceb719
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_CC.mo
@@ -0,0 +1,135 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_h_avg_adsorpt_CC
+  "Calculates the integrand required for calculating the uptake-averaged specific enthalpy of adsorpt using the Clausius-Clapeyron definition of the adsorption enthalpy"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT_adsorpt[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptive
+    "Specific enthalpy of the adsorptive";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads
+    "Molar adsorption enthalpy";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  //
+  // Calculation of further properties
+  //
+  (,,,h_adsorptive,,,,,) :=
+    MediumSpecificFunctions.calc_properties(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp,
+      dT=dT,
+      p_min=p_clausiusClyperon,
+      require_v_adsorptive=false,
+      require_h_adsorptive=true,
+      require_s_adsorptive=false,
+      require_dh_adsorptive_dT_dp=false,
+      require_h_adsorptiveToLiquid=false,
+      adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+    "Specific enthalpy of the adsorptive";
+
+  h_ads :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar specific enthalpy of adsorption";
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  h_adsorptive - h_ads / M_adsorptive
+    "Integrand: Specific enthalpy difference between the adsorptive and adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy difference between the adsorptive
+and adsorpt using the Clausius-Clyperon definition of the specific enthalpy of 
+adsorption.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_h_avg_adsorpt_CC;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_Constant.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_Constant.mo
new file mode 100644
index 0000000..c6de764
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_Constant.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_h_avg_adsorpt_Constant
+  "Calculates the integrand required for calculating the uptake-averaged specific enthalpy of adsorpt using a constant specific enthalpy of adsorption"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificEnthalpy h_ads
+    "Constant specific enthalpy of adsorption"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptive
+    "Specific enthalpy of the adsorptive";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  //
+  // Calculation of further properties
+  //
+  (,,,h_adsorptive,,,,,) :=
+    MediumSpecificFunctions.calc_properties(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp,
+      dT=dT,
+      p_min=p_clausiusClyperon,
+      require_v_adsorptive=false,
+      require_h_adsorptive=true,
+      require_s_adsorptive=false,
+      require_dh_adsorptive_dT_dp=false,
+      require_h_adsorptiveToLiquid=false,
+      adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+    "Specific enthalpy of the adsorptive";
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  h_adsorptive - h_ads
+    "Integrand: Specific enthalpy difference between the adsorptive and adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy difference between the adsorptive
+and adsorpt using a constant specific enthalpy of adsorption.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_h_avg_adsorpt_Constant;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_Formal.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_Formal.mo
new file mode 100644
index 0000000..2529fe1
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_h_avg_adsorpt_Formal.mo
@@ -0,0 +1,178 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_h_avg_adsorpt_Formal
+  "Calculates the integrand required for calculating the uptake-averaged specific enthalpy of adsorpt using the formal definition of the adsorption enthalpy"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT_adsorpt[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding the specific volume of the adsorpt
+  //
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive";
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptive
+    "Specific enthalpy of the adsorptive";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads
+    "Molar adsorption enthalpy";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    //
+    // Do not use Clausius-Clyperon assumptions
+    //
+    (v_adsorptive,,,h_adsorptive,,,,,) :=
+      MediumSpecificFunctions.calc_properties(
+        p=p_adsorpt,
+        T=T_adsorpt,
+        dp=dp,
+        dT=dT,
+        p_min=p_clausiusClyperon,
+        require_v_adsorptive=true,
+        require_h_adsorptive=true,
+        require_s_adsorptive=false,
+        require_dh_adsorptive_dT_dp=false,
+        require_h_adsorptiveToLiquid=false,
+        adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+      "Specific volume of the adsorptive and specifc enthalpy of the adsorptive";
+
+    h_ads :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT)
+      "Molar specific enthalpy of adsorption";
+
+  else
+    //
+    // Use Clausius-Clyperon assumptions
+    //
+    (,,,h_adsorptive,,,,,) :=
+      MediumSpecificFunctions.calc_properties(
+        p=p_adsorpt,
+        T=T_adsorpt,
+        dp=dp,
+        dT=dT,
+        p_min=p_clausiusClyperon,
+        require_v_adsorptive=false,
+        require_h_adsorptive=true,
+        require_s_adsorptive=false,
+        require_dh_adsorptive_dT_dp=false,
+        require_h_adsorptiveToLiquid=false,
+        adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+      "Specific enthalpy of the adsorptive";
+
+    h_ads :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT)
+      "Molar specific enthalpy of adsorption";
+
+  end if;
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  h_adsorptive - h_ads / M_adsorptive
+    "Integrand: Specific enthalpy difference between the adsorptive and adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy difference between the adsorptive
+and adsorpt using the formal definition of the specific enthalpy of adsorption.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_h_avg_adsorpt_Formal;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_CC.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_CC.mo
new file mode 100644
index 0000000..2e539c5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_CC.mo
@@ -0,0 +1,135 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_s_avg_adsorpt_CC
+  "Calculates the integrand required for calculating the uptake-averaged specific entropy of adsorpt using the Clausius-Clapeyron definition of the adsorption enthalpy"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT_adsorpt[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificEntropy s_adsorptive
+    "Specific entropy of the adsorptive";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads
+    "Molar adsorption enthalpy";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  //
+  // Calculation of further properties
+  //
+  (,,,,s_adsorptive,,,,) :=
+    MediumSpecificFunctions.calc_properties(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp,
+      dT=dT,
+      p_min=p_clausiusClyperon,
+      require_v_adsorptive=false,
+      require_h_adsorptive=false,
+      require_s_adsorptive=true,
+      require_dh_adsorptive_dT_dp=false,
+      require_h_adsorptiveToLiquid=false,
+      adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+    "Specific entropy of the adsorptive";
+
+  h_ads :=
+    SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      dx_adsorpt_dT=dx_adsorpt_dT)
+    "Molar specific enthalpy of adsorption";
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  s_adsorptive - h_ads / M_adsorptive / T_adsorpt
+    "Integrand: Specific entropy difference between the adsorptive and adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific entropy difference between the adsorptive
+and adsorpt using the Clausius-Clyperon definition of the specific enthalpy of 
+adsorption.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_s_avg_adsorpt_CC;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_Constant.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_Constant.mo
new file mode 100644
index 0000000..07feeaf
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_Constant.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_s_avg_adsorpt_Constant
+  "Calculates the integrand required for calculating the uptake-averaged specific entropy of adsorpt using a constant specific enthalpy of adsorption"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Modelica.Units.SI.SpecificEnthalpy h_ads
+    "Constant specific enthalpy of adsorption"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificEntropy s_adsorptive
+    "Specific entropy of the adsorptive";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  //
+  // Calculation of further properties
+  //
+  (,,,,s_adsorptive,,,,) :=
+    MediumSpecificFunctions.calc_properties(
+      p=p_adsorpt,
+      T=T_adsorpt,
+      dp=dp,
+      dT=dT,
+      p_min=p_clausiusClyperon,
+      require_v_adsorptive=false,
+      require_h_adsorptive=false,
+      require_s_adsorptive=true,
+      require_dh_adsorptive_dT_dp=false,
+      require_h_adsorptiveToLiquid=false,
+      adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+    "Specific entropy of the adsorptive";
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  s_adsorptive - h_ads / T_adsorpt
+    "Integrand: Specific entropy difference between the adsorptive and adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific entropy difference between the adsorptive
+and adsorpt using a constant specific enthalpy of adsorption.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_s_avg_adsorpt_Constant;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_Formal.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_Formal.mo
new file mode 100644
index 0000000..6612d98
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/calc_integrand_s_avg_adsorpt_Formal.mo
@@ -0,0 +1,178 @@
+within SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization;
+function calc_integrand_s_avg_adsorpt_Formal
+  "Calculates the integrand required for calculating the uptake-averaged specific entropy of adsorpt using the formal definition of the adsorption enthalpy"
+  extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+  //
+  // Definition of inputs
+  //
+  input Modelica.Units.SI.Temperature T_adsorpt
+    "Temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Real c[:]
+    "Coefficients of the isotherm model"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real dc_dT_adsorpt[:]
+    "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  input Boolean adsorptiveAtDewPoint
+    "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of inputs regarding the specific volume of the adsorpt
+  //
+  input Modelica.Units.SI.SpecificVolume v_adsorpt
+    "Specific volume of the adsorpt"
+    annotation (Dialog(tab="General",group="Inputs"));
+
+  //
+  // Definition of inputs regarding numerics
+  //
+  input Modelica.Units.SI.Pressure p_clausiusClyperon
+    "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.PressureDifference dp
+    "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Modelica.Units.SI.TemperatureDifference dT
+    "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of variables
+  //
+protected
+  Modelica.Units.SI.Pressure p_adsorpt
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  Modelica.Units.SI.SpecificVolume v_adsorptive
+    "Specific volume of the adsorptive";
+  Modelica.Units.SI.SpecificEntropy s_adsorptive
+    "Specific entropy of the adsorptive";
+
+  SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  Modelica.Units.SI.MolarEnthalpy h_ads
+    "Molar adsorption enthalpy";
+
+algorithm
+  //
+  // Calculation of sorption equilibrium
+  //
+  p_adsorpt := IsothermModel.p_xT(
+      x_adsorpt=u,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      p_adsorpt_lb_start=1,
+      p_adsorpt_ub_start=10,
+      tolerance=100*Modelica.Constants.eps)
+    "Pressure at x_adsorpt = u and T_adsorpt";
+
+  dx_adsorpt_dp := IsothermModel.dx_dp(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c)
+    "Partial derivative of uptake w.r.t. pressure at constant temperature";
+  dx_adsorpt_dT := IsothermModel.dx_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+    "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+  //
+  // Calculation of further properties
+  //
+  if p_adsorpt > p_clausiusClyperon then
+    //
+    // Do not use Clausius-Clyperon assumptions
+    //
+    (v_adsorptive,,,,s_adsorptive,,,,) :=
+      MediumSpecificFunctions.calc_properties(
+        p=p_adsorpt,
+        T=T_adsorpt,
+        dp=dp,
+        dT=dT,
+        p_min=p_clausiusClyperon,
+        require_v_adsorptive=true,
+        require_h_adsorptive=false,
+        require_s_adsorptive=true,
+        require_dh_adsorptive_dT_dp=false,
+        require_h_adsorptiveToLiquid=false,
+        adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+      "Specific volume of the adsorptive and specifc entropy of the adsorptive";
+
+    h_ads :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads(
+        M_adsorptive=M_adsorptive,
+        T_adsorpt=T_adsorpt,
+        v_adsorptive=v_adsorptive,
+        v_adsorpt=v_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT)
+      "Molar specific enthalpy of adsorption";
+
+  else
+    //
+    // Use Clausius-Clyperon assumptions
+    //
+    (,,,,s_adsorptive,,,,) :=
+      MediumSpecificFunctions.calc_properties(
+        p=p_adsorpt,
+        T=T_adsorpt,
+        dp=dp,
+        dT=dT,
+        p_min=p_clausiusClyperon,
+        require_v_adsorptive=false,
+        require_h_adsorptive=false,
+        require_s_adsorptive=true,
+        require_dh_adsorptive_dT_dp=false,
+        require_h_adsorptiveToLiquid=false,
+        adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+      "Specific entropy of the adsorptive";
+
+    h_ads :=
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        dx_adsorpt_dp=dx_adsorpt_dp,
+        dx_adsorpt_dT=dx_adsorpt_dT)
+      "Molar specific enthalpy of adsorption";
+
+  end if;
+
+  //
+  // Calculation of the integrand
+  //
+  y :=  s_adsorptive - h_ads / M_adsorptive / T_adsorpt
+    "Integrand: Specific entropy difference between the adsorptive and adsorpt";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function calculates the specific entropy difference between the adsorptive
+and adsorpt using the formal definition of the specific enthalpy of adsorption.
+</p>
+</html>",
+        revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end calc_integrand_s_avg_adsorpt_Formal;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/package.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/package.mo
new file mode 100644
index 0000000..2c489e2
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/package.mo
@@ -0,0 +1,1086 @@
+within SorpLib.Media.WorkingPairs.Interfaces;
+partial package PartialPureParametrization "Base package defining all properties for parametrization of pure component working pairs"
+  extends Modelica.Icons.MaterialPropertiesPackage;
+
+  //
+  // Definition of constants
+  //  
+  constant Modelica.Units.SI.MolarMass M_adsorptive
+    "Molar mass of the adsorptive"
+    annotation (Dialog(tab="General",group="Constants", enable=false),
+                choices(checkBox=true));
+  constant Boolean twoPhaseAdsorptive
+    "= true, if media model of the adsorptive has a two-phase regime"
+    annotation (Dialog(tab="General",group="Constants", enable=false),
+                choices(checkBox=true));
+
+  constant Boolean modelOfDubinin
+    "= true, if the isotherm model is based on the model of Dubinin"
+    annotation (Dialog(tab="General",group="Constants", enable=false),
+                choices(checkBox=true));
+  constant Integer no_coefficients
+    "Number of isotherm model coefficients"
+    annotation (Dialog(tab="General",group="Constants", enable=false));
+  //
+  // Definition of packges
+  //
+  replaceable package IsothermModel =
+    SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative
+    constrainedby
+  SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents
+    "Package of the isotherm model providing all functions of the isotherm model"
+    annotation (Dialog(tab = "General", group = "Packages", enable=false));
+
+  replaceable package MediumSpecificFunctions =
+    SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+    constrainedby
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureMediumSpecificFunctions
+    "Package of medium specific functions"
+    annotation (Dialog(tab = "General", group = "Packages", enable=false));
+  //
+  // Definition of models
+  //
+  replaceable model Sorbent =
+    SorpLib.Media.Solids.Sorbents.GenericSorbent
+    constrainedby SorpLib.Media.Solids.BaseClasses.PartialSolid
+    "Calculates the thermodynamic properties of the sorbent"
+    annotation (Dialog(tab = "General", group = "Models"),
+                choicesAllMatching=true);
+  //
+  // Definition of functions
+  //
+  replaceable partial function calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Real[no_coefficients] c
+      "Isotherm coefficients"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This function calculates the temperature-dependent isotherm coefficients <i>c</i>.
+Functions that inherit from this partial function must add the equations of the
+isotherm coefficients. Typical temperature dependencies of isotherm coefficients 
+are provided as generalized functions in the package
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities</a>.
+Constants required to calculate the temperature dependencies should be implemented
+as new constants in the parametrization package.</p>
+</html>"));
+  end calc_c;
+
+  replaceable partial function calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs and outputs
+    //
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.TemperatureDifference dT = 1e-3
+      "Temperature difference if derivatives are calculated numerically"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Real[no_coefficients] c
+      "Isotherm coefficients"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+    output Real[no_coefficients] dc_dT
+      "Partial derivative of isotherm coefficients w.r.t. temperature"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+    output Real[no_coefficients] ddc_dT_dT
+      "Second-order partial derivative of isotherm coefficients w.r.t. temperature"
+      annotation (Dialog(tab="General",group="Outputs",enable=false));
+
+    //
+    // Annotations
+    //
+    annotation (Inline=true, Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This function calculates the temperature-dependent isotherm coefficients <i>c</i>
+and their first- and second-order partial derivatives with respect to temperature
+(<i>dc_dT</i> and <i>ddc_dT_dT</i>). Functions that inherit from this partial 
+function must add the equations of the isotherm coefficients and their partial
+derivatives. Typical temperature dependencies of isotherm coefficients are provided 
+as generalized functions in the package
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities</a>.
+Constants required to calculate the temperature dependencies should be implemented
+as new constants in the parametrization package.</p>
+</html>"));
+  end calc_coefficients;
+
+  replaceable partial function calc_h_ads_Dubinin
+    "Calculates the molar adsorption enthalpy according to the model of Dubinin"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Real[no_coefficients] c
+      "Isotherm coefficients"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Modelica.Units.SI.Pressure p_adsorpt
+      "Equilibrium pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.Uptake x_adsorpt
+      "Equilibrium uptake"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Modelica.Units.SI.SpecificVolume v_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+      "Isobaric expansion coefficient of the adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input
+      SorpLib.Media.WorkingPairs.Records.PropertiesPureAdsorptive properties_adsorptive
+      "Record containing all properties of the adsorptive required for the working
+    pair model"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.SpecificEnthalpy h_ads
+      "Specific enthalpy of adsorption"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=properties_adsorptive.p_sat,
+        T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+      "Partial derivative of the characteristic curve w.r.t. the molar adsorption
+    potential at constant pressure and temperaure";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>",   info="<html>
+<p>
+This function calculates the specific enthalpy of adsorption according to the
+model of Dubinin. For more information, check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin</a>.
+</p>
+</html>"));
+  end calc_h_ads_Dubinin;
+
+  replaceable partial function calc_dh_ads_dp_T_Dubinin
+    "Calculates the partial derivative of the molar adsorption enthalpy w.r.t. pressure at constant temperature according to the model of Dubinin"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Real[no_coefficients] c
+      "Isotherm coefficients"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Modelica.Units.SI.Pressure p_adsorpt
+      "Equilibrium pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input SorpLib.Units.Uptake x_adsorpt
+      "Equilibrium uptake"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp
+      "Partial derivative of uptake w.r.t. pressure"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Modelica.Units.SI.SpecificVolume v_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+      "Partial derivative of specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+      "Isobaric expansion coefficient of the adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input SorpLib.Units.DerIsobaricExpansionCoefficientByPressure dbeta_adsorpt_dp
+      "Partial derivative of isobaric expansion coefficient of the adsorpt phase
+    w.r.t. pressure at constant temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input
+      SorpLib.Media.WorkingPairs.Records.PropertiesPureAdsorptive properties_adsorptive
+      "Record containing all properties of the adsorptive required for the working
+    pair model"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output SorpLib.Units.DerSpecificEnthalpyByPressure dh_ads_dp
+      "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=properties_adsorptive.p_sat,
+        T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=properties_adsorptive.p_sat,
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+      "Partial derivative of the characteristic curve w.r.t. the molar adsorption
+    potential at constant pressure and temperaure";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+      "Second-order partial derivative of filled pore volume w.r.t. molar 
+    adsorption potential and temperature at constant pressure and temperature";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>",   info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of 
+adsorption with respect to pressure at constant temperature according to the
+model of Dubinin. For more information, check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin</a>.
+</p>
+</html>"));
+  end calc_dh_ads_dp_T_Dubinin;
+
+  replaceable partial function calc_dh_ads_dT_p_Dubinin
+    "Calculates the partial derivative of the molar adsorption enthalpy w.r.t. temperature at constant pressure according to the model of Dubinin"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of inputs
+    //
+    input Real[no_coefficients] c
+      "Isotherm coefficients"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Real[no_coefficients] dc_dT_adsorpt
+      "Partial derivative of isotherm coefficients w.r.t. temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input Modelica.Units.SI.Pressure p_adsorpt
+      "Equilibrium pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Equilibrium temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    input SorpLib.Units.Uptake x_adsorpt
+      "Equilibrium uptake"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT
+      "Partial derivative of uptake w.r.t. temperature at constant pressure"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Modelica.Units.SI.SpecificVolume v_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+      "Partial derivative of specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+      "Isobaric expansion coefficient of the adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_adsorpt_dT
+      "Partial derivative of isobaric expansion coefficient of the adsorpt phase
+    w.r.t. temperature at constant pressure"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input
+      SorpLib.Media.WorkingPairs.Records.PropertiesPureAdsorptive properties_adsorptive
+      "Record containing all properties of the adsorptive required for the working
+    pair model"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of outputs
+    //
+    output Modelica.Units.SI.SpecificHeatCapacity dh_ads_dT
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure"
+      annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+    //
+    // Definition of variables
+    //
+protected
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=properties_adsorptive.p_sat,
+        T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=properties_adsorptive.p_sat,
+        T_adsorpt=T_adsorpt,
+        dp_sat_dT_adsorpt=properties_adsorptive.dp_sat_dT)
+      "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+      "Partial derivative of the characteristic curve w.r.t. the molar adsorption
+    potential at constant pressure and temperaure";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+      "Second-order partial derivative of filled pore volume w.r.t. molar 
+    adsorption potential and temperature at constant pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>",   info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of 
+adsorption with respect to temperature at constant pressure according to the
+model of Dubinin. For more information, check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin\">SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin</a>.
+</p>
+</html>"));
+  end calc_dh_ads_dT_p_Dubinin;
+
+  replaceable partial function calc_integrand_WaltonLeVan_Dubinin
+    "Calculates the integrand required for calculating the specific heat capacity according to Walton and Le Van (2005) when using the specifc enthalpy of adsorption according to Dubinin"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Real c[:]
+      "Coefficients of the isotherm model"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Real dc_dT_adsorpt[:]
+      "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Real ddc_dT_adsorpt_dT_adsorpt[:]
+      "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Boolean adsorptiveAtDewPoint
+      "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    //
+    // Definition of inputs regarding the specific volume of the adsorpt
+    //
+    input Modelica.Units.SI.SpecificVolume v_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+      "Partial derivative of the specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+      "Partial derivative of the specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of inputs regarding the isobaric expansion coefficient of the adsorpt
+    //
+    input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.DerIsobaricExpansionCoefficientByPressure dbeta_adsorpt_dp
+      "Partial derivative of the specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_adsorpt_dT
+      "Partial derivative of the specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of inputs regarding numerics
+    //
+    input Modelica.Units.SI.Pressure p_clausiusClyperon
+      "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.PressureDifference dp
+      "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.TemperatureDifference dT
+      "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.Pressure p_adsorpt=
+      IsothermModel.p_xT(
+        x_adsorpt=u,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_adsorpt_lb_start=1,
+        p_adsorpt_ub_start=10,
+        tolerance=100*Modelica.Constants.eps)
+      "Pressure at x_adsorpt = u and T_adsorpt";
+
+    SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp=
+      IsothermModel.dx_dp(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c)
+      "Partial derivative of uptake w.r.t. pressure at constant temperature";
+    SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT=
+      IsothermModel.dx_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+    SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp=
+      IsothermModel.ddx_dp_dp(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c)
+      "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+    SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT=
+      IsothermModel.ddx_dT_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt,
+        ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt)
+      "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+    SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT=
+      IsothermModel.ddx_dp_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt,
+        dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential and temperature at constant pressure";
+
+    Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+    SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+    Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+    SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+      "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the molar adsorption enthalpy
+with respect to temperature at constant uptake when using the molar adsorption
+enthalpy according to Dubinin. For more information, check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x_Dubinin\">SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_ads_dT_x_Dubinin</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end calc_integrand_WaltonLeVan_Dubinin;
+
+  replaceable partial function calc_integrand_SchwambergerSchmidt_Dubinin
+    "Calculates the integrand required for calculating the specific heat capacity according to Schwamberger and Schmidt (2013) when using the specifc enthalpy of adsorption according to Dubinin"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Real c[:]
+      "Coefficients of the isotherm model"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Real dc_dT_adsorpt[:]
+      "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Real ddc_dT_adsorpt_dT_adsorpt[:]
+      "Second-order partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Boolean adsorptiveAtDewPoint
+      "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    //
+    // Definition of inputs regarding the specific volume of the adsorpt
+    //
+    input Modelica.Units.SI.SpecificVolume v_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.DerSpecificVolumeByPressure dv_adsorpt_dp
+      "Partial derivative of the specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.DerSpecificVolumeByTemperature dv_adsorpt_dT
+      "Partial derivative of the specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of inputs regarding the isobaric expansion coefficient of the adsorpt
+    //
+    input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.DerIsobaricExpansionCoefficientByPressure dbeta_adsorpt_dp
+      "Partial derivative of the specific volume of the adsorpt w.r.t. pressure at
+    constant temperature"
+      annotation (Dialog(tab="General",group="Inputs"));
+    input SorpLib.Units.DerIsobaricExpansionCoefficientByTemperature dbeta_adsorpt_dT
+      "Partial derivative of the specific volume of the adsorpt w.r.t. temperature at
+    constant pressure"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of inputs regarding numerics
+    //
+    input Modelica.Units.SI.Pressure p_clausiusClyperon
+      "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.PressureDifference dp
+      "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.TemperatureDifference dT
+      "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.Pressure p_adsorpt=
+      IsothermModel.p_xT(
+        x_adsorpt=u,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_adsorpt_lb_start=1,
+        p_adsorpt_ub_start=10,
+        tolerance=100*Modelica.Constants.eps)
+      "Pressure at x_adsorpt = u and T_adsorpt";
+
+    SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp=
+      IsothermModel.dx_dp(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c)
+      "Partial derivative of uptake w.r.t. pressure at constant temperature";
+    SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT=
+      IsothermModel.dx_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+    SorpLib.Units.DerUptakeByPressurePressure ddx_adsorpt_dp_dp=
+      IsothermModel.ddx_dp_dp(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c)
+      "Second-order partial derivative of uptake w.r.t. pressure at contant 
+    temperature";
+    SorpLib.Units.DerUptakeByTemperatureTemperature ddx_adsorpt_dT_dT=
+      IsothermModel.ddx_dT_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt,
+        ddc_dT_adsorpt_dT_adsorpt=ddc_dT_adsorpt_dT_adsorpt)
+      "Second-order partial derivative of uptake w.r.t. temperature at contant 
+    pressure";
+    SorpLib.Units.DerUptakeByPressureTemperature ddx_adsorpt_dp_dT=
+      IsothermModel.ddx_dp_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of uptake w.r.t. pressure and temperature";
+
+    Modelica.Units.SI.SpecificHeatCapacity dh_adsorptive_dT
+      "Partial derivative of the specific enthalpy of the adsorptive w.r.t. temperature
+    at constant pressure";
+
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    SorpLib.Units.DerMolarAdsorptionPotentialByPressure dA_dp=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dp(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Partial derivative of molar adsorption potential w.r.t. pressure at
+    constant temperature";
+    SorpLib.Units.DerMolarAdsorptionPotentialByTemperature dA_dT=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.dA_dT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt,
+        dp_sat_dT_adsorpt=dc_dT_adsorpt[1])
+      "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential ddW_dA_dA
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotentialTemperature ddW_dA_dT
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+    potential and temperature at constant pressure";
+
+    Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+    SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+    Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+    SorpLib.Units.DerMolarEnthalpyByPressure dh_ads_dp_T
+      "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+    Modelica.Units.SI.MolarHeatCapacity dh_ads_dT_p
+      "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+    pressure";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the partial derivative of the specific enthalpy of the 
+adsorpt with respect to temperature at constant uptake when using the molar adsorption
+enthalpy according to Dubinin. For more information, check the model
+<a href=\"Modelica://SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x_Dubinin\">SorpLib.Media.Functions.SpecificHeatCapacitiesAdsorpt.PureComponents.Integrands.dh_adsorpt_dT_x_Dubinin</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end calc_integrand_SchwambergerSchmidt_Dubinin;
+
+  replaceable partial function calc_integrand_h_avg_adsorpt_Dubinin
+    "Calculates the integrand required for calculating the uptake-averaged specific enthalpy of adsorpt using the adsorption enthalpy according to Dubinin"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Real c[:]
+      "Coefficients of the isotherm model"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Real dc_dT_adsorpt[:]
+      "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Boolean adsorptiveAtDewPoint
+      "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    //
+    // Definition of inputs regarding the specific volume of the adsorpt
+    //
+    input Modelica.Units.SI.SpecificVolume v_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of inputs regarding the isobaric expansion coefficient of the adsorpt
+    //
+    input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of inputs regarding numerics
+    //
+    input Modelica.Units.SI.Pressure p_clausiusClyperon
+      "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.PressureDifference dp
+      "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.TemperatureDifference dT
+      "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.Pressure p_adsorpt=
+      IsothermModel.p_xT(
+        x_adsorpt=u,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_adsorpt_lb_start=1,
+        p_adsorpt_ub_start=10,
+        tolerance=100*Modelica.Constants.eps)
+      "Pressure at x_adsorpt = u and T_adsorpt";
+
+    Modelica.Units.SI.SpecificEnthalpy h_adsorptive
+      "Specific enthalpy of the adsorptive";
+
+    SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp=
+      IsothermModel.dx_dp(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c)
+      "Partial derivative of uptake w.r.t. pressure at constant temperature";
+    SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT=
+      IsothermModel.dx_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+
+    Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+
+    Modelica.Units.SI.MolarEnthalpy h_ads
+      "Molar adsorption enthalpy";
+
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the specific enthalpy difference between the adsorptive
+and adsorpt using the specific enthalpy of adsorption according to Dubinin.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end calc_integrand_h_avg_adsorpt_Dubinin;
+
+
+
+  replaceable partial function calc_integrand_s_avg_adsorpt_Dubinin
+    "Calculates the integrand required for calculating the uptake-averaged specific entropy of adsorpt using the adsorption enthalpy according to Dubinin"
+    extends Modelica.Math.Nonlinear.Interfaces.partialScalarFunction;
+
+    //
+    // Definition of inputs
+    //
+    input Modelica.Units.SI.Temperature T_adsorpt
+      "Temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Real c[:]
+      "Coefficients of the isotherm model"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Real dc_dT_adsorpt[:]
+      "Partial derivative of coefficients of the isotherm model w.r.t. 
+    temperature"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    input Boolean adsorptiveAtDewPoint
+      "= true, if adsorptive (gas/vapor phase) is assumed to be at dew point at
+    T_adsorpt"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    //
+    // Definition of inputs regarding the specific volume of the adsorpt
+    //
+    input Modelica.Units.SI.SpecificVolume v_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of inputs regarding the isobaric expansion coefficient of the adsorpt
+    //
+    input Modelica.Units.SI.RelativePressureCoefficient beta_adsorpt
+      "Specific volume of the adsorpt"
+      annotation (Dialog(tab="General",group="Inputs"));
+
+    //
+    // Definition of inputs regarding numerics
+    //
+    input Modelica.Units.SI.Pressure p_clausiusClyperon
+      "Maximum pressure up to which the molar adsorption enthalpy is calculated
+    according to the Clausius Clyperon assumptions"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.PressureDifference dp
+      "Pressure difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+      annotation (Dialog(tab="General", group="Inputs"));
+    input Modelica.Units.SI.TemperatureDifference dT
+      "Temperature difference used to calculate partial derivatives w.r.t. pressure
+    numerially (just used if analytical solution does not exist)"
+      annotation (Dialog(tab="General", group="Inputs"));
+
+    //
+    // Definition of variables
+    //
+protected
+    Modelica.Units.SI.Pressure p_adsorpt=
+      IsothermModel.p_xT(
+        x_adsorpt=u,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        p_adsorpt_lb_start=1,
+        p_adsorpt_ub_start=10,
+        tolerance=100*Modelica.Constants.eps)
+      "Pressure at x_adsorpt = u and T_adsorpt";
+
+    Modelica.Units.SI.SpecificEntropy s_adsorptive
+      "Specific entropy of the adsorptive";
+
+    SorpLib.Units.DerUptakeByPressure dx_adsorpt_dp=
+      IsothermModel.dx_dp(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c)
+      "Partial derivative of uptake w.r.t. pressure at constant temperature";
+    SorpLib.Units.DerUptakeByTemperature dx_adsorpt_dT=
+      IsothermModel.dx_dT(
+        p_adsorpt=p_adsorpt,
+        T_adsorpt=T_adsorpt,
+        c=c,
+        dc_dT_adsorpt=dc_dT_adsorpt)
+      "Partial derivative of uptake w.r.t. temperature at constant pressure";
+
+    SorpLib.Units.MolarAdsorptionPotential A=
+      SorpLib.Media.Functions.SorptionEquilibria.Utilities.A_ppsT(
+        p_adsorpt=p_adsorpt,
+        p_sat=c[1],
+        T_adsorpt=T_adsorpt)
+      "Molar adsorption potential";
+    SorpLib.Units.DerFilledPoreVolumeByAdsorptionPotential dW_dA
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+
+    Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+
+    Modelica.Units.SI.MolarEnthalpy h_ads
+      "Molar adsorption enthalpy";
+
+    //
+    // Annotations
+    //
+    annotation (Documentation(info="<html>
+<p>
+This function calculates the specific entropy difference between the adsorptive
+and adsorpt using the specific enthalpy of adsorption according to Dubinin.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+  end calc_integrand_s_avg_adsorpt_Dubinin;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package contains all declaration for parametrization of a pure component working
+pair. This means that constants, packages, models, and functions are defined that every pure
+component working pair must support. Note that only some of the medium specific functions are 
+optional (see 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.BaseClasses.PartialPureMediumSpecificFunctions\">SorpLib.Media.WorkingPairs.BaseClasses.PartialPureMediumSpecificFunctions</a>).
+Packages that inherit properties from this partial package must redeclare all constants, the
+two partial packages <i>IsothermModel</i> and <i>MediumSpecificFunctions</i>, the model <i>Sorbent</i>, 
+the two functions <i>calc_c</i> and <i>calc_coefficients</i>, and optionally the five functions
+<i>calc_h_ads_Dubinin</i>, <i>calc_dh_ads_dp_T_Dubinin</i>, <i>calc_dh_ads_dT_dp_Dubinin</i>, 
+<i>calc_integrand_WaltonLeVan_Dubinin</i>, and <i>calc_integrand_SchwambergerSchmidt_Dubinin</i>
+(if using the model of Dubinin).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureParametrization;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/package.order b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/package.order
new file mode 100644
index 0000000..e47c07f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrization/package.order
@@ -0,0 +1,29 @@
+M_adsorptive
+twoPhaseAdsorptive
+modelOfDubinin
+no_coefficients
+IsothermModel
+MediumSpecificFunctions
+Sorbent
+IsothermCoefficients
+AdsorptProperties
+calc_c
+calc_coefficients
+calc_h_ads_Dubinin
+calc_dh_ads_dp_T_Dubinin
+calc_dh_ads_dT_p_Dubinin
+calc_integrand_WaltonLeVan
+calc_integrand_WaltonLeVan_CC
+calc_integrand_WaltonLeVan_Dubinin
+calc_integrand_SchwambergerSchmidt_Constant
+calc_integrand_SchwambergerSchmidt
+calc_integrand_SchwambergerSchmidt_CC
+calc_integrand_SchwambergerSchmidt_Dubinin
+calc_integrand_h_avg_adsorpt_Constant
+calc_integrand_h_avg_adsorpt_Formal
+calc_integrand_h_avg_adsorpt_CC
+calc_integrand_h_avg_adsorpt_Dubinin
+calc_integrand_s_avg_adsorpt_Constant
+calc_integrand_s_avg_adsorpt_Formal
+calc_integrand_s_avg_adsorpt_CC
+calc_integrand_s_avg_adsorpt_Dubinin
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationDubinin/package.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationDubinin/package.mo
new file mode 100644
index 0000000..d3996eb
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationDubinin/package.mo
@@ -0,0 +1,551 @@
+within SorpLib.Media.WorkingPairs.Interfaces;
+partial package PartialPureParametrizationDubinin "Base package defining all properties for parametrization of pure component working pairs based on the Dubinin model"
+  extends SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization(
+    final twoPhaseAdsorptive = true,
+    final modelOfDubinin = true,
+    redeclare replaceable package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin
+      constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponentsDubinin);
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_h_ads_Dubinin
+    "Molar adsorption enthalpy according to the model of Dubinin"
+  algorithm
+    //
+    // Calculate additional properties
+    //
+    dW_dA :=IsothermModel.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of the characteristic curve w.r.t. the molar adsorption
+      potential at constant pressure and temperaure";
+
+    //
+    // Calculate specific enthalpy of adsorption
+    //
+    h_ads := 1 / M_adsorptive *
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+      M_adsorptive=M_adsorptive,
+      T_adsorpt=T_adsorpt,
+      x_adsorpt=x_adsorpt,
+      h_adsorptiveToLiquid=properties_adsorptive.h_adsorptiveToLiquid,
+      v_adsorpt=v_adsorpt,
+      beta_adsorpt=beta_adsorpt,
+      A=A,
+      dW_dA=dW_dA)
+      "Specific enthalpy of adsorption";
+  end calc_h_ads_Dubinin;
+
+  redeclare final function extends calc_dh_ads_dp_T_Dubinin
+    "Calculates the partial derivative of the molar adsorption enthalpy w.r.t. pressure at constant temperature according to the model of Dubinin"
+  algorithm
+    //
+    // Calculate additional properties
+    //
+    dW_dA :=IsothermModel.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of the characteristic curve w.r.t. the molar adsorption
+      potential at constant pressure and temperaure";
+    ddW_dA_dA := IsothermModel.ddW_dA_dA(
+      A=A,
+      c=c)
+      "Second-order partial derivative of filled pore volume w.r.t. molar 
+      adsorption potential and temperature at constant pressure and temperature";
+
+    //
+    // Calculate specific enthalpy of adsorption
+    //
+    dh_ads_dp := 1 / M_adsorptive *
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin(
+      M_adsorptive=M_adsorptive,
+      T_adsorpt=T_adsorpt,
+      x_adsorpt=x_adsorpt,
+      dx_adsorpt_dp=dx_adsorpt_dp,
+      h_adsorptiveToLiquid=properties_adsorptive.h_adsorptiveToLiquid,
+      dh_adsorptiveToLiquid_dp=properties_adsorptive.dh_adsorptiveToLiquid_dp_T,
+      v_adsorpt=v_adsorpt,
+      dv_adsorpt_dp=dv_adsorpt_dp,
+      beta_adsorpt=beta_adsorpt,
+      dbeta_adsorpt_dp=dbeta_adsorpt_dp,
+      dA_dp=dA_dp,
+      dW_dA=dW_dA,
+      ddW_dA_dA=ddW_dA_dA)
+      "Partial derivative of molar adsorption potential w.r.t. pressure at
+     constant temperature";
+  end calc_dh_ads_dp_T_Dubinin;
+
+  redeclare final function extends calc_dh_ads_dT_p_Dubinin
+    "Calculates the partial derivative of the molar adsorption enthalpy w.r.t. temperature at constant pressure according to the model of Dubinin"
+  algorithm
+    //
+    // Calculate additional properties
+    //
+    dW_dA :=IsothermModel.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of the characteristic curve w.r.t. the molar adsorption
+    potential at constant pressure and temperaure";
+    ddW_dA_dT := IsothermModel.ddW_dA_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      A=A,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of filled pore volume w.r.t. molar 
+    adsorption potential and temperature at constant pressure";
+
+    //
+    // Calculate specific enthalpy of adsorption
+    //
+    dh_ads_dT := 1 / M_adsorptive *
+      SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin(
+      M_adsorptive=M_adsorptive,
+      T_adsorpt=T_adsorpt,
+      x_adsorpt=x_adsorpt,
+      dx_adsorpt_dT=dx_adsorpt_dT,
+      h_adsorptiveToLiquid=properties_adsorptive.h_adsorptiveToLiquid,
+      dh_adsorptiveToLiquid_dT=properties_adsorptive.dh_adsorptiveToLiquid_dT_p,
+      v_adsorpt=v_adsorpt,
+      dv_adsorpt_dT=dv_adsorpt_dT,
+      beta_adsorpt=beta_adsorpt,
+      dbeta_adsorpt_dT=dbeta_adsorpt_dT,
+      dA_dT=dA_dT,
+      dW_dA=dW_dA,
+      ddW_dA_dT=ddW_dA_dT)
+      "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure";
+  end calc_dh_ads_dT_p_Dubinin;
+
+  redeclare final function extends calc_integrand_WaltonLeVan_Dubinin
+  "Calculates the integrand required for calculating the specific heat capacity according to Walton and Le Van (2005) when using the specifc enthalpy of adsorption according to Dubinin"
+  algorithm
+    dW_dA:=IsothermModel.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+      at constant pressure and temperature";
+    ddW_dA_dA := IsothermModel.ddW_dA_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+      at constant pressure and temperature";
+    ddW_dA_dT := IsothermModel.ddW_dA_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      A=A,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential and temperature at constant pressure";
+
+    //
+    // Calculation of further properties
+    //
+    if p_adsorpt > p_clausiusClyperon then
+      //
+      // Do not use Clausius Clyperon assumptions
+      //
+      (,,,,,,h_adsorptiveToLiquid,dh_adsorptiveToLiquid_dp,dh_adsorptiveToLiquid_dT) :=
+        MediumSpecificFunctions.calc_properties(
+          p=p_adsorpt,
+          T=T_adsorpt,
+          dp=dp,
+          dT=dT,
+          p_min=p_clausiusClyperon,
+          require_v_adsorptive=false,
+          require_h_adsorptive=false,
+          require_s_adsorptive=false,
+          require_dh_adsorptive_dT_dp=false,
+          require_h_adsorptiveToLiquid=true,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+        "Specific enthalpy difference between adsorptive state and saturated liquid
+       state (i.e., bubble point) and its partial derivatives";
+
+      dh_ads_dp_T :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin(
+          M_adsorptive=M_adsorptive,
+          T_adsorpt=T_adsorpt,
+          x_adsorpt=u,
+          dx_adsorpt_dp=dx_adsorpt_dp,
+          h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+          dh_adsorptiveToLiquid_dp=dh_adsorptiveToLiquid_dp,
+          v_adsorpt=v_adsorpt,
+          dv_adsorpt_dp=dv_adsorpt_dp,
+          beta_adsorpt=beta_adsorpt,
+          dbeta_adsorpt_dp=dbeta_adsorpt_dp,
+          dA_dp=dA_dp,
+          dW_dA=dW_dA,
+          ddW_dA_dA=ddW_dA_dA)
+      "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+      dh_ads_dT_p :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin(
+          M_adsorptive=M_adsorptive,
+          T_adsorpt=T_adsorpt,
+          x_adsorpt=u,
+          dx_adsorpt_dT=dx_adsorpt_dT,
+          h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+          dh_adsorptiveToLiquid_dT=dh_adsorptiveToLiquid_dT,
+          v_adsorpt=v_adsorpt,
+          dv_adsorpt_dT=dv_adsorpt_dT,
+          beta_adsorpt=beta_adsorpt,
+          dbeta_adsorpt_dT=dbeta_adsorpt_dT,
+          dA_dT=dA_dT,
+          dW_dA=dW_dA,
+          ddW_dA_dT=ddW_dA_dT)
+        "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+    else
+      //
+      // Use Clausius Clyperon assumptions: No further propiertes are required
+      //
+      dh_ads_dp_T :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+          p_adsorpt=p_adsorpt,
+          T_adsorpt=T_adsorpt,
+          dx_adsorpt_dp=dx_adsorpt_dp,
+          dx_adsorpt_dT=dx_adsorpt_dT,
+          ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+          ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+      dh_ads_dT_p :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+          p_adsorpt=p_adsorpt,
+          T_adsorpt=T_adsorpt,
+          dx_adsorpt_dp=dx_adsorpt_dp,
+          dx_adsorpt_dT=dx_adsorpt_dT,
+          ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+          ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+        "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+    end if;
+
+    //
+    // Calculation of the integrand
+    //
+    y := dh_ads_dT_p - dh_ads_dp_T * dx_adsorpt_dT / dx_adsorpt_dp
+      "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake";
+  end calc_integrand_WaltonLeVan_Dubinin;
+
+  redeclare final function extends calc_integrand_SchwambergerSchmidt_Dubinin
+  "Calculates the integrand required for calculating the specific heat capacity according to Schwamberger and Schmidt (2013) when using the specifc enthalpy of adsorption according to Dubinin"
+  algorithm
+    dW_dA:=IsothermModel.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+      at constant pressure and temperature";
+    ddW_dA_dA := IsothermModel.ddW_dA_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+      at constant pressure and temperature";
+    ddW_dA_dT := IsothermModel.ddW_dA_dT(
+      p_adsorpt=p_adsorpt,
+      T_adsorpt=T_adsorpt,
+      A=A,
+      c=c,
+      dc_dT_adsorpt=dc_dT_adsorpt)
+      "Second-order partial derivative of filled pore volume w.r.t. molar adsorption 
+      potential and temperature at constant pressure";
+
+    //
+    // Calculation of further properties
+    //
+    if p_adsorpt > p_clausiusClyperon then
+      //
+      // Do not use Clausius Clyperon assumptions
+      //
+      (,,,,,  dh_adsorptive_dT,
+       h_adsorptiveToLiquid, dh_adsorptiveToLiquid_dp, dh_adsorptiveToLiquid_dT) :=
+        MediumSpecificFunctions.calc_properties(
+          p=p_adsorpt,
+          T=T_adsorpt,
+          dp=dp,
+          dT=dT,
+          p_min=p_clausiusClyperon,
+          require_v_adsorptive=false,
+          require_h_adsorptive=false,
+          require_s_adsorptive=false,
+          require_dh_adsorptive_dT_dp=true,
+          require_h_adsorptiveToLiquid=true,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+        "Partial derivative of the specific enthalpy of the adsorptive w.r.t.
+      temperature at constant pressure and specific enthalpy difference between 
+      adsorptive state and saturated liquid state (i.e., bubble point) and its 
+      partial derivatives";
+
+      dh_ads_dp_T :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_Dubinin(
+          M_adsorptive=M_adsorptive,
+          T_adsorpt=T_adsorpt,
+          x_adsorpt=u,
+          dx_adsorpt_dp=dx_adsorpt_dp,
+          h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+          dh_adsorptiveToLiquid_dp=dh_adsorptiveToLiquid_dp,
+          v_adsorpt=v_adsorpt,
+          dv_adsorpt_dp=dv_adsorpt_dp,
+          beta_adsorpt=beta_adsorpt,
+          dbeta_adsorpt_dp=dbeta_adsorpt_dp,
+          dA_dp=dA_dp,
+          dW_dA=dW_dA,
+          ddW_dA_dA=ddW_dA_dA)
+      "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+      dh_ads_dT_p :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_Dubinin(
+          M_adsorptive=M_adsorptive,
+          T_adsorpt=T_adsorpt,
+          x_adsorpt=u,
+          dx_adsorpt_dT=dx_adsorpt_dT,
+          h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+          dh_adsorptiveToLiquid_dT=dh_adsorptiveToLiquid_dT,
+          v_adsorpt=v_adsorpt,
+          dv_adsorpt_dT=dv_adsorpt_dT,
+          beta_adsorpt=beta_adsorpt,
+          dbeta_adsorpt_dT=dbeta_adsorpt_dT,
+          dA_dT=dA_dT,
+          dW_dA=dW_dA,
+          ddW_dA_dT=ddW_dA_dT)
+        "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+    else
+      //
+      // Use Clausius Clyperon assumptions: No further propiertes are required
+      //
+      (,,,,,  dh_adsorptive_dT,,,) :=
+        MediumSpecificFunctions.calc_properties(
+          p=p_adsorpt,
+          T=T_adsorpt,
+          dp=dp,
+          dT=dT,
+          p_min=p_clausiusClyperon,
+          require_v_adsorptive=false,
+          require_h_adsorptive=false,
+          require_s_adsorptive=false,
+          require_dh_adsorptive_dT_dp=true,
+          require_h_adsorptiveToLiquid=false,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+        "Partial derivative of the specific enthalpy of the adsorptive w.r.t.
+      temperature at constant pressure";
+
+      dh_ads_dp_T :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dp_clausiusClapeyron(
+          p_adsorpt=p_adsorpt,
+          T_adsorpt=T_adsorpt,
+          dx_adsorpt_dp=dx_adsorpt_dp,
+          dx_adsorpt_dT=dx_adsorpt_dT,
+          ddx_adsorpt_dp_dp=ddx_adsorpt_dp_dp,
+          ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT)
+      "Partial derivative of molar adsorption enthalpy w.r.t. pressure at constant
+    temperature";
+      dh_ads_dT_p :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.dh_ads_dT_clausiusClapeyron(
+          p_adsorpt=p_adsorpt,
+          T_adsorpt=T_adsorpt,
+          dx_adsorpt_dp=dx_adsorpt_dp,
+          dx_adsorpt_dT=dx_adsorpt_dT,
+          ddx_adsorpt_dp_dT=ddx_adsorpt_dp_dT,
+          ddx_adsorpt_dT_dT=ddx_adsorpt_dT_dT)
+        "Partial derivative of molar adsorption enthalpy w.r.t. temperature at constant
+      pressure";
+
+    end if;
+
+    //
+    // Calculation of the integrand
+    //
+    y :=  dh_adsorptive_dT  -
+      (dh_ads_dT_p - dh_ads_dp_T *  dx_adsorpt_dT / dx_adsorpt_dp) / M_adsorptive
+      "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake";
+  end calc_integrand_SchwambergerSchmidt_Dubinin;
+
+  redeclare final function extends calc_integrand_h_avg_adsorpt_Dubinin
+    "Calculates the integrand required for calculating the uptake-averaged specific enthalpy of adsorpt using the adsorption enthalpy according to Dubinin"
+  algorithm
+    dW_dA:=IsothermModel.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+
+    //
+    // Calculation of further properties
+    //
+    if p_adsorpt > p_clausiusClyperon then
+      //
+      // Do not use Clausius-Clyperon assumptions
+      //
+      (,,,h_adsorptive,,,h_adsorptiveToLiquid,,) :=
+        MediumSpecificFunctions.calc_properties(
+          p=p_adsorpt,
+          T=T_adsorpt,
+          dp=dp,
+          dT=dT,
+          p_min=p_clausiusClyperon,
+          require_v_adsorptive=false,
+          require_h_adsorptive=true,
+          require_s_adsorptive=false,
+          require_dh_adsorptive_dT_dp=false,
+          require_h_adsorptiveToLiquid=true,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+        "Specific enthalpy of the adsorptive and specific enthalpy difference between 
+      adsorptive state and saturated liquid state (i.e., bubble point)";
+
+      h_ads :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+          M_adsorptive=M_adsorptive,
+          T_adsorpt=T_adsorpt,
+          x_adsorpt=u,
+          h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+          v_adsorpt=v_adsorpt,
+          beta_adsorpt=beta_adsorpt,
+          A=A,
+          dW_dA=dW_dA)
+        "Molar specific enthalpy of adsorption";
+
+    else
+      //
+      // Use Clausius-Clyperon assumptions
+      //
+      (,,,h_adsorptive,,,,,)  :=
+        MediumSpecificFunctions.calc_properties(
+          p=p_adsorpt,
+          T=T_adsorpt,
+          dp=dp,
+          dT=dT,
+          p_min=p_clausiusClyperon,
+          require_v_adsorptive=false,
+          require_h_adsorptive=true,
+          require_s_adsorptive=false,
+          require_dh_adsorptive_dT_dp=false,
+          require_h_adsorptiveToLiquid=false,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+        "Partial enthalpy of the adsorptive";
+
+      h_ads :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+          p_adsorpt=p_adsorpt,
+          T_adsorpt=T_adsorpt,
+          dx_adsorpt_dp=dx_adsorpt_dp,
+          dx_adsorpt_dT=dx_adsorpt_dT)
+        "Molar specific enthalpy of adsorption";
+
+    end if;
+
+    //
+    // Calculation of the integrand
+    //
+    y :=  h_adsorptive - h_ads / M_adsorptive
+      "Integrand: Specific enthalpy difference between the adsorptive and adsorpt";
+  end calc_integrand_h_avg_adsorpt_Dubinin;
+
+  redeclare final function extends calc_integrand_s_avg_adsorpt_Dubinin
+    "Calculates the integrand required for calculating the uptake-averaged specific entropy of adsorpt using the adsorption enthalpy according to Dubinin"
+  algorithm
+    dW_dA:=IsothermModel.dW_dA(
+      A=A,
+      c=c)
+      "Partial derivative of filled pore volume w.r.t. molar adsorption potential
+    at constant pressure and temperature";
+
+    //
+    // Calculation of further properties
+    //
+    if p_adsorpt > p_clausiusClyperon then
+      //
+      // Do not use Clausius-Clyperon assumptions
+      //
+      (,,,,s_adsorptive,,h_adsorptiveToLiquid,,) :=
+        MediumSpecificFunctions.calc_properties(
+          p=p_adsorpt,
+          T=T_adsorpt,
+          dp=dp,
+          dT=dT,
+          p_min=p_clausiusClyperon,
+          require_v_adsorptive=false,
+          require_h_adsorptive=false,
+          require_s_adsorptive=true,
+          require_dh_adsorptive_dT_dp=false,
+          require_h_adsorptiveToLiquid=true,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+        "Specific entropy of the adsorptive and specific enthalpy difference between 
+      adsorptive state and saturated liquid state (i.e., bubble point)";
+
+      h_ads :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_Dubinin(
+          M_adsorptive=M_adsorptive,
+          T_adsorpt=T_adsorpt,
+          x_adsorpt=u,
+          h_adsorptiveToLiquid=h_adsorptiveToLiquid,
+          v_adsorpt=v_adsorpt,
+          beta_adsorpt=beta_adsorpt,
+          A=A,
+          dW_dA=dW_dA)
+        "Molar specific enthalpy of adsorption";
+
+    else
+      //
+      // Use Clausius-Clyperon assumptions
+      //
+      (,,,,s_adsorptive,,,,)  :=
+        MediumSpecificFunctions.calc_properties(
+          p=p_adsorpt,
+          T=T_adsorpt,
+          dp=dp,
+          dT=dT,
+          p_min=p_clausiusClyperon,
+          require_v_adsorptive=false,
+          require_h_adsorptive=false,
+          require_s_adsorptive=true,
+          require_dh_adsorptive_dT_dp=false,
+          require_h_adsorptiveToLiquid=false,
+          adsorptiveAtDewPoint=adsorptiveAtDewPoint)
+        "Partial entropy of the adsorptive";
+
+      h_ads :=
+        SorpLib.Media.Functions.SorptionEnthalpies.PureComponents.h_ads_clausiusClapeyron(
+          p_adsorpt=p_adsorpt,
+          T_adsorpt=T_adsorpt,
+          dx_adsorpt_dp=dx_adsorpt_dp,
+          dx_adsorpt_dT=dx_adsorpt_dT)
+        "Molar specific enthalpy of adsorption";
+
+    end if;
+
+    //
+    // Calculation of the integrand
+    //
+    y :=  s_adsorptive - h_ads / M_adsorptive / T_adsorpt
+      "Integrand: Specific entropy difference between the adsorptive and adsorpt";
+  end calc_integrand_s_avg_adsorpt_Dubinin;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package contains all declaration for parametrization of a pure component working
+pair based on the model of Dubinin. This means that constants, packages, models, and functions 
+are defined that every pure component working pair must support. Packages that inherit properties 
+from this partial package must redeclare all constants except of <i>twoPhaseAdsorptive</i> and 
+<i>modelOfDubinin</i>, the two partial packages <i>IsothermModel</i> and <i>MediumSpecificFunctions</i>, 
+the model <i>Sorbent</i>, and the two functions <i>calc_c</i> and <i>calc_coefficients</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureParametrizationDubinin;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationDubinin/package.order b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationDubinin/package.order
new file mode 100644
index 0000000..112bbe2
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationDubinin/package.order
@@ -0,0 +1,7 @@
+calc_h_ads_Dubinin
+calc_dh_ads_dp_T_Dubinin
+calc_dh_ads_dT_p_Dubinin
+calc_integrand_WaltonLeVan_Dubinin
+calc_integrand_SchwambergerSchmidt_Dubinin
+calc_integrand_h_avg_adsorpt_Dubinin
+calc_integrand_s_avg_adsorpt_Dubinin
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationNonDubinin/package.mo b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationNonDubinin/package.mo
new file mode 100644
index 0000000..7d6d12a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationNonDubinin/package.mo
@@ -0,0 +1,87 @@
+within SorpLib.Media.WorkingPairs.Interfaces;
+partial package PartialPureParametrizationNonDubinin "Base package defining all properties for parametrization of pure component working pairs not based on the Dubinin model"
+  extends SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrization(
+    final modelOfDubinin = false,
+    redeclare replaceable package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents
+      constrainedby
+    SorpLib.Media.Functions.SorptionEquilibria.Interfaces.PartialPureComponents);
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_h_ads_Dubinin
+    "Molar adsorption enthalpy according to the model of Dubinin (i.e., not required)"
+  algorithm
+    h_ads := 0
+      "Specific enthalpy of adsorption: Dummy value";
+  end calc_h_ads_Dubinin;
+
+  redeclare final function extends calc_dh_ads_dp_T_Dubinin
+    "Calculates the partial derivative of the molar adsorption enthalpy w.r.t. pressure at constant temperature according to the model of Dubinin (i.e., not required)"
+  algorithm
+    dh_ads_dp := 0
+      "Partial derivative of molar adsorption potential w.r.t. pressure at
+     constant temperature: Dummy value";
+  end calc_dh_ads_dp_T_Dubinin;
+
+  redeclare final function extends calc_dh_ads_dT_p_Dubinin
+    "Calculates the partial derivative of the molar adsorption enthalpy w.r.t. temperature at constant pressure according to the model of Dubinin (i.e., not required)"
+  algorithm
+    dh_ads_dT := 0
+      "Partial derivative of molar adsorption potential w.r.t. temperature at
+    constant pressure: Dummy value";
+  end calc_dh_ads_dT_p_Dubinin;
+
+  redeclare final function extends calc_integrand_WaltonLeVan_Dubinin
+  "Calculates the integrand required for calculating the specific heat capacity according to Walton and Le Van (2005) when using the specifc enthalpy of adsorption according to Dubinin (i.e., not required)"
+  algorithm
+    y := 0
+      "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake: Dummy value";
+  end calc_integrand_WaltonLeVan_Dubinin;
+
+  redeclare final function extends calc_integrand_SchwambergerSchmidt_Dubinin
+  "Calculates the integrand required for calculating the specific heat capacity according to Schwamberger and Schmidt (2013) when using the specifc enthalpy of adsorption according to Dubinin (i.e., not required)"
+  algorithm
+    y := 0
+      "Integrand: Partial derivative of molar sorption enthalpy w.r.t. temperature
+    at constant uptake: Dummy value";
+  end calc_integrand_SchwambergerSchmidt_Dubinin;
+
+  redeclare final function extends calc_integrand_h_avg_adsorpt_Dubinin
+  "Calculates the integrand required for calculating the uptake-averaged specific enthalpy of adsorpt using the adsorption enthalpy according to Dubinin (i.e., not required)"
+  algorithm
+    y := 0
+      "Integrand: Specific enthalpy difference between the adsorptive and adsorpt: 
+      Dummy value";
+  end calc_integrand_h_avg_adsorpt_Dubinin;
+
+  redeclare final function extends calc_integrand_s_avg_adsorpt_Dubinin
+  "Calculates the integrand required for calculating the uptake-averaged specific entropy of adsorpt using the adsorption enthalpy according to Dubinin (i.e., not required)"
+  algorithm
+    y := 0
+      "Integrand: Specific entropy difference between the adsorptive and adsorpt: 
+      Dummy value";
+  end calc_integrand_s_avg_adsorpt_Dubinin;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package contains all declaration for parametrization of a pure component working
+pair not based on the model of Dubinin. This means that constants, packages, models, and functions 
+are defined that every pure component working pair must support. Packages that inherit properties 
+from this partial package must redeclare all constants except of <i>modelOfDubinin</i>, the two 
+partial packages <i>IsothermModel</i> and <i>MediumSpecificFunctions</i>, the model <i>Sorbent</i>, 
+and the two functions <i>calc_c</i> and <i>calc_coefficients</i>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PartialPureParametrizationNonDubinin;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationNonDubinin/package.order b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationNonDubinin/package.order
new file mode 100644
index 0000000..112bbe2
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/PartialPureParametrizationNonDubinin/package.order
@@ -0,0 +1,7 @@
+calc_h_ads_Dubinin
+calc_dh_ads_dp_T_Dubinin
+calc_dh_ads_dT_p_Dubinin
+calc_integrand_WaltonLeVan_Dubinin
+calc_integrand_SchwambergerSchmidt_Dubinin
+calc_integrand_h_avg_adsorpt_Dubinin
+calc_integrand_s_avg_adsorpt_Dubinin
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/package.mo b/SorpLib/Media/WorkingPairs/Interfaces/package.mo
new file mode 100644
index 0000000..df582de
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Media.WorkingPairs;
+package Interfaces "Interfaces for working pair models"
+extends Modelica.Icons.InterfacesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package provides definitions of basic interfaces for working pair models. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Interfaces;
diff --git a/SorpLib/Media/WorkingPairs/Interfaces/package.order b/SorpLib/Media/WorkingPairs/Interfaces/package.order
new file mode 100644
index 0000000..13217e7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Interfaces/package.order
@@ -0,0 +1,4 @@
+PartialPureMediumSpecificFunctions
+PartialPureParametrization
+PartialPureParametrizationNonDubinin
+PartialPureParametrizationDubinin
diff --git a/SorpLib/Media/WorkingPairs/MultiComponents/Testers/package.mo b/SorpLib/Media/WorkingPairs/MultiComponents/Testers/package.mo
new file mode 100644
index 0000000..784c708
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/MultiComponents/Testers/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.WorkingPairs.MultiComponents;
+package Testers "Models to test and varify models of multi-component working pairs"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented working pair model. 
+Each working pair model has its own test model that is saved in the correct adsorptive
+package.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/WorkingPairs/MultiComponents/Testers/package.order b/SorpLib/Media/WorkingPairs/MultiComponents/Testers/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/WorkingPairs/MultiComponents/package.mo b/SorpLib/Media/WorkingPairs/MultiComponents/package.mo
new file mode 100644
index 0000000..ca60b53
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/MultiComponents/package.mo
@@ -0,0 +1,34 @@
+within SorpLib.Media.WorkingPairs;
+package MultiComponents "Package containing multi-component working pair models"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains fully parameterized working models. For this purpose, 
+the partially parametrized multi-component working pair models are extended by a 
+specific <i>MediumSpecificFunctions</i> package. This package calculates fluid 
+properties based on the open-source Modelica Standard Library (MSL).
+</p>
+
+<h4>Structure</h4>
+<p>
+The package 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.MultiComponents.MediumSpecificFunctions\">SorpLib.Media.WorkingPairs.MultiComponents.MediumSpecificFunctions</a>
+contains different versions of packages providing medium specific functions. For 
+each package version there is also a corresponding working pair model. The finally
+parametrized working pair models are alphabetically sorted by available asdsorptives 
+and are stored in seperate packages. The naming convention for the parameterized working 
+pair models is as follows
+</p>
+<pre>
+    NameSorbent_NameIsothermModel_NameAuthorsYear_MediumType;
+</pre>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MultiComponents;
diff --git a/SorpLib/Components/Cells/Wall/package.order b/SorpLib/Media/WorkingPairs/MultiComponents/package.order
similarity index 61%
rename from SorpLib/Components/Cells/Wall/package.order
rename to SorpLib/Media/WorkingPairs/MultiComponents/package.order
index c459b36..f9d890e 100644
--- a/SorpLib/Components/Cells/Wall/package.order
+++ b/SorpLib/Media/WorkingPairs/MultiComponents/package.order
@@ -1,2 +1 @@
-Wall
 Testers
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/CO2_H2O/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/CO2_H2O/package.mo
new file mode 100644
index 0000000..76b75ba
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/CO2_H2O/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.MultiComponents;
+package CO2_H2O "Package containing parametrizations for CO2 and H2O as adsorptives"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for CO<sub>2</sub> and H<sub>2</sub>O
+as adsorptives.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CO2_H2O;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/CO2_H2O/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/CO2_H2O/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/package.mo
new file mode 100644
index 0000000..897e7d5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.WorkingPairs.Parametrizations;
+package MultiComponents "Package containing parametrizations of multi-component working pairs"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrized multi-component working pair models. Check
+the package content to see for which adsorptive mixtures working pair models 
+are already implemented.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MultiComponents;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/package.order
new file mode 100644
index 0000000..46ee6a8
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/MultiComponents/package.order
@@ -0,0 +1 @@
+CO2_H2O
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011/package.mo
new file mode 100644
index 0000000..6fe9f1e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011/package.mo
@@ -0,0 +1,108 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2;
+package ActivatedCarbon_Toth_DantasEtAl2011 "CO2 & Activated carbon via the Toth isotherm model according to Dantas et al. (2011)"
+  extends SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=44.0095/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 10.05 * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 7.62e-5 / (1e5)
+    "Second contants of the isotherm model";
+  constant Real Q_star(unit="K") = -21.84e3 / Modelica.Constants.R
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = 0.678
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    c[3] :=t;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    c[3] :=t;
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    dc_dT[3] :=0;
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    ddc_dT_dT[3] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+CO<sub>2</sub> & activated carbon using the Toth isotherm model according to Dantas 
+et al. (2011). Packages that inherit properties from this partial package may 
+redeclare the package <i>MediumSpecificFunctions</i>, the model <i>Sorbent</i>,
+and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Dantas, T.L.P. and Luna, F.M.T. and Silva Jr., I.J. and Azevedo, D.C.S. and Grande, C.A. and Rodrigues, A.E. and Moreira, R.F.P.M. (2011). Carbon dioxide–nitrogen separation through adsorption on activated carbon in a fixed bed, Chemical Engineering Journal, 169:11–19. DOI: https://doi.org/10.1016/j.cej.2010.08.026.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ActivatedCarbon_Toth_DantasEtAl2011;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011/package.order
new file mode 100644
index 0000000..99a9913
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011/package.order
@@ -0,0 +1,6 @@
+x_sat
+b_ref
+Q_star
+t
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009/package.mo
new file mode 100644
index 0000000..5f2beec
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009/package.mo
@@ -0,0 +1,131 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2;
+package SilicaGel_Toth_WangDouglasLeVan2009 "CO2 & silica gel via the Toth isotherm model according to Wang and Douglas LeVan (2009)"
+  extends
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=44.0095/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 7.678e-9 / b_ref * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 5.164e-10
+    "Second contants of the isotherm model";
+  constant Real E(unit="K") = 2.330e3
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = -3.053e-1
+    "Fourth contants of the isotherm model";
+  constant Real alpha(unit="1/K") = 2.386e2
+    "Fivth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    dc_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    ddc_dT_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+CO<sub>2</sub> & silica gel using the Toth isotherm model according to Wang 
+and Douglas LeVan (2010). Packages that inherit properties from this partial 
+package may redeclare the package <i>MediumSpecificFunctions</i>, the model 
+<i>Sorbent</i>, and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGel_Toth_WangDouglasLeVan2009;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009/package.order
new file mode 100644
index 0000000..e5bc23d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009/package.order
@@ -0,0 +1,7 @@
+x_sat
+b_ref
+E
+t
+alpha
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011/package.mo
new file mode 100644
index 0000000..cef108f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011/package.mo
@@ -0,0 +1,109 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2;
+package Zeolith13X_Toth_DantasEtAl2011 "CO2 & Zeolith 13X via the Toth isotherm model according to Dantas et al. (2011)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=44.0095/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 5.09 * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 4.305e-4 / (1e5)
+    "Second contants of the isotherm model";
+  constant Real Q_star(unit="K") = -29.38e3 / Modelica.Constants.R
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = 0.429
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    c[3] :=t;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    c[3] :=t;
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    dc_dT[3] :=0;
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    ddc_dT_dT[3] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+CO<sub>2</sub> & Zeolith 13X using the Toth isotherm model according to Dantas 
+et al. (2011). Packages that inherit properties from this partial package may 
+redeclare the package <i>MediumSpecificFunctions</i>, the model <i>Sorbent</i>,
+and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Dantas, T.L.P. and Luna, F.M.T. and Silva Jr., I.J. and Torres, A.E.B. and Azevedo, D.C.S. and Rodrigues, A.E. and Moreira, R.F.P.M. (2011). Carbon dioxide–nitrogen separation through pressure swing adsorption, Chemical Engineering Journal, 172:698-704. DOI: https://doi.org/10.1016/j.cej.2011.06.037.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_DantasEtAl2011;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011/package.order
new file mode 100644
index 0000000..99a9913
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011/package.order
@@ -0,0 +1,6 @@
+x_sat
+b_ref
+Q_star
+t
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010/package.mo
new file mode 100644
index 0000000..4a3002e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010/package.mo
@@ -0,0 +1,134 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2;
+package Zeolith13X_Toth_WangDouglasLeVan2010 "CO2 & Zeolith 13X via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=44.0095/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 6.509e-6 / b_ref * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 4.884e-7
+    "Second contants of the isotherm model";
+  constant Real E(unit="K") = 2.991e3
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = 7.487e-2
+    "Fourth contants of the isotherm model";
+  constant Real alpha(unit="1/K") = 3.805e1
+    "Fivth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    dc_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    ddc_dT_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+CO<sub>2</sub> & Zeolith 13X using the Toth isotherm model according to Wang 
+and Douglas LeVan (2010). Packages that inherit properties from this partial 
+package may redeclare the package <i>MediumSpecificFunctions</i>, the model 
+<i>Sorbent</i>, and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2010). Adsorption Equilibrium of Binary Mixtures of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X, Hournal of Chemical & Engineering Data, 55(9):3189–3195. DOI: https://doi.org/10.1021/je100053g.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_WangDouglasLeVan2010;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010/package.order
new file mode 100644
index 0000000..e5bc23d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010/package.order
@@ -0,0 +1,7 @@
+x_sat
+b_ref
+E
+t
+alpha
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010/package.mo
new file mode 100644
index 0000000..0aad73a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010/package.mo
@@ -0,0 +1,134 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2;
+package Zeolith5A_Toth_WangDouglasLeVan2010 "CO2 & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=44.0095/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 9.875e-10 / b_ref * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 6.761e-11
+    "Second contants of the isotherm model";
+  constant Real E(unit="K") = 5.625e3
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = 2.7e-1
+    "Fourth contants of the isotherm model";
+  constant Real alpha(unit="1/K") = -2.002e1
+    "Fivth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    dc_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    ddc_dT_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+CO<sub>2</sub> & Zeolith 5A using the Toth isotherm model according to Wang 
+and Douglas LeVan (2010). Packages that inherit properties from this partial 
+package may redeclare the package <i>MediumSpecificFunctions</i>, the model 
+<i>Sorbent</i>, and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2010). Adsorption Equilibrium of Binary Mixtures of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X, Journal of Chemical & Engineering Data, 55(9):3189–3195. DOI: https://doi.org/10.1021/je100053g.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith5A_Toth_WangDouglasLeVan2010;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010/package.order
new file mode 100644
index 0000000..e5bc23d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010/package.order
@@ -0,0 +1,7 @@
+x_sat
+b_ref
+E
+t
+alpha
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/package.mo
new file mode 100644
index 0000000..cb74850
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents;
+package CO2 "Package containing parametrizations for CO2 as adsorptive"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for CO<sub>2</sub> as adsorptive.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CO2;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/package.order
new file mode 100644
index 0000000..f006038
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/CO2/package.order
@@ -0,0 +1,5 @@
+ActivatedCarbon_Toth_DantasEtAl2011
+SilicaGel_Toth_WangDouglasLeVan2009
+Zeolith5A_Toth_WangDouglasLeVan2010
+Zeolith13X_Toth_DantasEtAl2011
+Zeolith13X_Toth_WangDouglasLeVan2010
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
new file mode 100644
index 0000000..e4e1899
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
@@ -0,0 +1,115 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017 "H2O & AQSOA-Z01 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a = 0.204162691322846 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 1.714393556857407e2 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -13.888991966535533 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 0.005500438155033 / 1000
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & AQSOA-Z01 (FAM-Z01) using the Dubinin isotherm model with a Lorentzian 
+Cumulative characteristic curve generated by Bau (2017) using measurement data from
+Goldsworthy (2014). Packages that inherit properties from this partial package 
+may redeclare the package <i>MediumSpecificFunctions</i> and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Goldsworthy (2014). Measurements of water vapour sorption isotherms for RD silica gel, AQSOA-Z01, AQSOA-Z02, AQSOA-Z05 and CECA zeolite 3A, Microporous and Mesoporous Materials, 196:59-67. DOI: http://dx.doi.org/10.1016/j.micromeso.2014.04.046.
+  </li>
+  <li>
+  Bau (2018). From Dynamic Simulation to Optimal Design and Control of Adsorption Energy Systems, PhD thesis. DOI: https://doi.org/10.18154/RWTH-2018-222524.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  December 14, 2020, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  November 17, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
new file mode 100644
index 0000000..73c893c
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
@@ -0,0 +1,125 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017 "H2O & AQSOA-Z02 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE);
+
+  //
+  // Definition of further constants
+  //
+  /* Coefficients as published in Bau's PhD thesis vs. coefficients of SorpLib V1
+  constant SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = -3.461028e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 3.096522e2 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = 9.726662e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 3.535178e-1 / 1000
+    "Fourth contants of the isotherm model";
+  */
+  constant SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = 3.466e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 3.094e2 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -9.765e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 7.312e-4 / 1000
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & AQSOA-Z02 (FAM-Z02) using the Dubinin isotherm model with a Lorentzian 
+Cumulative characteristic curve generated by Bau (2017) using measurement data from
+Goldsworthy (2014). Packages that inherit properties from this partial package 
+may redeclare the package <i>MediumSpecificFunctions</i> and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Goldsworthy (2014). Measurements of water vapour sorption isotherms for RD silica gel, AQSOA-Z01, AQSOA-Z02, AQSOA-Z05 and CECA zeolite 3A, Microporous and Mesoporous Materials, 196:59-67. DOI: http://dx.doi.org/10.1016/j.micromeso.2014.04.046.
+  </li>
+  <li>
+  Bau (2018). From Dynamic Simulation to Optimal Design and Control of Adsorption Energy Systems, PhD thesis. DOI: https://doi.org/10.18154/RWTH-2018-222524.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  December 14, 2020, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  November 17, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
new file mode 100644
index 0000000..55d5433
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.mo
@@ -0,0 +1,115 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017 "H2O & AQSOA-Z05 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a = 0.214158550589450 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 1.491564711211805e2 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -5.363761702090807 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 0.004607265196576 / 1000
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & AQSOA-Z05 (FAM-Z05) using the Dubinin isotherm model with a Lorentzian 
+Cumulative characteristic curve generated by Bau (2017) using measurement data from
+Goldsworthy (2014). Packages that inherit properties from this partial package 
+may redeclare the package <i>MediumSpecificFunctions</i> and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Goldsworthy (2014). Measurements of water vapour sorption isotherms for RD silica gel, AQSOA-Z01, AQSOA-Z02, AQSOA-Z05 and CECA zeolite 3A, Microporous and Mesoporous Materials, 196:59-67. DOI: http://dx.doi.org/10.1016/j.micromeso.2014.04.046.
+  </li>
+  <li>
+  Bau (2018). From Dynamic Simulation to Optimal Design and Control of Adsorption Energy Systems, PhD thesis. DOI: https://doi.org/10.18154/RWTH-2018-222524.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  December 14, 2020, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  November 17, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000/package.mo
new file mode 100644
index 0000000..a699da3
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000/package.mo
@@ -0,0 +1,134 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package NaZeolithY_DubininEmpirical2_Schawe2000 "H2O & Na-Zeolith Y via the Dubinin isotherm model with an empirical 2 approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=9,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.GenericSorbent (
+        v_constant=1/450,
+        c_constant=920,
+        lambda_constant=0.085));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a=
+    3.393156e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b=
+    8.766651e-3 * sqrt(1 / 1000 / M_adsorptive)
+    "Second contants of the isotherm model";
+  constant Real char_curve_c=
+    -1.104630e-2 / 1000 * sqrt(1 / 1000 / M_adsorptive)
+    "Third contants of the isotherm model";
+  constant Real char_curve_d=
+    -2.448014e-3 / 1000 / M_adsorptive
+    "Fourth contants of the isotherm model";
+  constant Real char_curve_e=
+    9.055743e-5 / 1000 / 1000 / M_adsorptive
+    "Fivth contants of the isotherm model";
+  constant Real char_curve_f=
+    6.243287e-5 / 1000 / M_adsorptive * sqrt(1 / 1000 / M_adsorptive)
+    "Sixth contants of the isotherm model";
+  constant Real char_curve_g=
+    0
+    "Seventh contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+    c[9] :=char_curve_g;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+    c[9] :=char_curve_g;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+    dc_dT[7] :=0;
+    dc_dT[8] :=0;
+    dc_dT[9] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+    ddc_dT_dT[7] :=0;
+    ddc_dT_dT[8] :=0;
+    ddc_dT_dT[9] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & Na-Zeolith Y using the Dubinin isotherm model with an empirical 2
+characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end NaZeolithY_DubininEmpirical2_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000/package.order
new file mode 100644
index 0000000..85e4137
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000/package.order
@@ -0,0 +1,9 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+char_curve_e
+char_curve_f
+char_curve_g
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel123_DubininLorentzianCumulative_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel123_DubininLorentzianCumulative_Schawe2000/package.mo
new file mode 100644
index 0000000..c1769f0
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel123_DubininLorentzianCumulative_Schawe2000/package.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGel123_DubininLorentzianCumulative_Schawe2000 "H2O & Silica gel 123 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a = 5.072313e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 1.305531e2 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -8.492403e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 4.128962e-3 / 1000
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel 123 using the Dubinin isotherm model with a Lorentzian 
+Cumulative characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGel123_DubininLorentzianCumulative_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel123_DubininLorentzianCumulative_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel123_DubininLorentzianCumulative_Schawe2000/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel123_DubininLorentzianCumulative_Schawe2000/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000/package.mo
new file mode 100644
index 0000000..fa3cf01
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000/package.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGel125_DubininLorentzianCumulative_Schawe2000 "H2O & Silica gel 125 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a = 4.527805e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 1.229005e2 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -8.847167e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 6.034706e-4 / 1000
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel 125 using the Dubinin isotherm model with a Lorentzian 
+Cumulative characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGel125_DubininLorentzianCumulative_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000/package.mo
new file mode 100644
index 0000000..e41c34f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000/package.mo
@@ -0,0 +1,108 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGelAF25_DubininLorentzianCumulative_Schawe2000 "H2O & Silica gel AF-25 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel (
+        v_constant=1/600,
+        lambda_constant=0.2));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a = 6.452704e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 8.979911e1 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -7.845557e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 0
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel AF-25 using the Dubinin isotherm model with a Lorentzian 
+Cumulative characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelAF25_DubininLorentzianCumulative_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000/package.mo
new file mode 100644
index 0000000..0d764ec
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000/package.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGelFuji_DubininLorentzianCumulative_Schawe2000 "H2O & Silica gel Fuji via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a = 3.857567e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 1.262497e2 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -9.919397e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 0
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel Fuji using the Dubinin isotherm model with a Lorentzian 
+Cumulative characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelFuji_DubininLorentzianCumulative_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000/package.mo
new file mode 100644
index 0000000..00d9b47
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000/package.mo
@@ -0,0 +1,121 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGelH_DubininPearsonIV_Schawe2000 "H2O & Silica gel H via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=8,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel (
+        v_constant=1/700,
+        lambda_constant=0.2));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = -2.243367e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol")=7.354090e-1 / 1000
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = 1.044776e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d=
+    3.678460e1 * 1000 * M_adsorptive
+    "Fourth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_e= 7.419258e-2
+    "Fivth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_f= 2.927265e-1
+    "Sixth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+    dc_dT[7] :=0;
+    dc_dT[8] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+    ddc_dT_dT[7] :=0;
+    ddc_dT_dT[8] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel H using the Dubinin isotherm model with a Pearson
+IV characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelH_DubininPearsonIV_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000/package.order
new file mode 100644
index 0000000..58ce5c4
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000/package.order
@@ -0,0 +1,8 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+char_curve_e
+char_curve_f
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000/package.mo
new file mode 100644
index 0000000..b64596a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000/package.mo
@@ -0,0 +1,121 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGelLE32_DubininPearsonIV_Schawe2000 "H2O & Silica gel LE-32 via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=8,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel (
+        v_constant=1/700,
+        lambda_constant=0.2));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = -1.044288e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol")=7.154669e-1 / 1000
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -2.345348e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d=
+    3.327467e1 * 1000 * M_adsorptive
+    "Fourth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_e= 1.201645e-1
+    "Fivth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_f= 5.058059e-1
+    "Sixth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+    dc_dT[7] :=0;
+    dc_dT[8] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+    ddc_dT_dT[7] :=0;
+    ddc_dT_dT[8] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel LE-32 using the Dubinin isotherm model with a Pearson
+IV characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelLE32_DubininPearsonIV_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000/package.order
new file mode 100644
index 0000000..58ce5c4
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000/package.order
@@ -0,0 +1,8 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+char_curve_e
+char_curve_f
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000/package.mo
new file mode 100644
index 0000000..74ce2f4
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000/package.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGelNAC_DubininEmpirical1_Schawe2000 "H2O & Silica gel NAC via the Dubinin isotherm model with an empirical 1 approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical1,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a = 3.570644 * 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b=8.569149e-6 * 1000 * (1 / 1000 / M_adsorptive)^2
+    "Second contants of the isotherm model";
+  constant Real char_curve_c = 1 / 1000 / M_adsorptive
+    "Third contants of the isotherm model";
+  constant Real char_curve_d=9.597209e-8 * 1000 * (1 / 1000 / M_adsorptive)^3
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel NAC using the Dubinin isotherm model with an empirical1 
+characteristic curve according to Schawe (2000). Packages that inherit properties 
+from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelNAC_DubininEmpirical1_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000/package.mo
new file mode 100644
index 0000000..e8157a3
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000/package.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGelN_DubininPearsonIV_Schawe2000 "H2O & Silica gel N via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=8,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel(lambda_constant=0.2));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = -7.689279e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol")=1.176831 / 1000
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = 1.485965e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d=
+    4.244922e1 * 1000 * M_adsorptive
+    "Fourth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_e= 2.207797e-2
+    "Fivth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_f= 1.146067e-1
+    "Sixth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+    dc_dT[7] :=0;
+    dc_dT[8] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+    ddc_dT_dT[7] :=0;
+    ddc_dT_dT[8] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel N using the Dubinin isotherm model with a Pearson IV 
+characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelN_DubininPearsonIV_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000/package.order
new file mode 100644
index 0000000..58ce5c4
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000/package.order
@@ -0,0 +1,8 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+char_curve_e
+char_curve_f
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000/package.mo
new file mode 100644
index 0000000..7414d2d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000/package.mo
@@ -0,0 +1,106 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGelWS_DubininLorentzianCumulative_Schawe2000 "H2O & Silica gel WS via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=6,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininLorentzianCumulative,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel(lambda_constant=0.2));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a = 5.046468e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol") = 1.002140e2 * 1000 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = -7.264229e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d = 0
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel WS using the Dubinin isotherm model with a Lorentzian 
+Cumulative characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelWS_DubininLorentzianCumulative_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000/package.order
new file mode 100644
index 0000000..c4d7e2f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000/package.order
@@ -0,0 +1,6 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009/package.mo
new file mode 100644
index 0000000..716de8a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009/package.mo
@@ -0,0 +1,131 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package SilicaGel_Toth_WangDouglasLeVan2009 "H2O & silica gel via the Toth isotherm model according to Wang and Douglas LeVan (2009)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=18.0153/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 1.767e-1 / b_ref * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 2.787e-8
+    "Second contants of the isotherm model";
+  constant Real E(unit="K") = 1.093e3
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = -1.190e-3
+    "Fourth contants of the isotherm model";
+  constant Real alpha(unit="1/K") = 2.213e1
+    "Fivth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    dc_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    ddc_dT_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & silica gel using the Toth isotherm model according to Wang 
+and Douglas LeVan (2010). Packages that inherit properties from this partial 
+package may redeclare the package <i>MediumSpecificFunctions</i>, the model 
+<i>Sorbent</i>, and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGel_Toth_WangDouglasLeVan2009;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009/package.order
new file mode 100644
index 0000000..e5bc23d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009/package.order
@@ -0,0 +1,7 @@
+x_sat
+b_ref
+E
+t
+alpha
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000/package.mo
new file mode 100644
index 0000000..9116d14
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000/package.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package Sizeo15_DubininPearsonIV_Schawe2000 "H2O & Sizeo 15 via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=8,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininPearsonIV,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.RDSilicaGel(v_constant=1/660));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a(min=-1) = -5.798998e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b(unit="J/mol")=9.685636e-1 / 1000
+    "Second contants of the isotherm model";
+  constant Real char_curve_c(unit="J/mol") = 1.313229e1 * 1000 * M_adsorptive
+    "Third contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_d=
+    3.586237e1 * 1000 * M_adsorptive
+    "Fourth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_e= 3.214072e-2
+    "Fivth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_f= 1.179455e-1
+    "Sixth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+    dc_dT[7] :=0;
+    dc_dT[8] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+    ddc_dT_dT[7] :=0;
+    ddc_dT_dT[8] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & Sizeo 15 using the Dubinin isotherm model with a Pearson IV 
+characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Sizeo15_DubininPearsonIV_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000/package.order
new file mode 100644
index 0000000..58ce5c4
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000/package.order
@@ -0,0 +1,8 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+char_curve_e
+char_curve_f
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000/package.mo
new file mode 100644
index 0000000..c9f47a5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000/package.mo
@@ -0,0 +1,134 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package Zeolith13X_DubininEmpirical2_Schawe2000 "H2O & Zeolith 13X via the Dubinin isotherm model with an empirical 2 approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=9,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.GenericSorbent (
+        v_constant=1/670,
+        c_constant=920,
+        lambda_constant=0.085));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a=
+    3.083531e-1 / 1000
+    "First contants of the isotherm model";
+  constant Real char_curve_b=
+    -5.415506e-2 * sqrt(1 / 1000 / M_adsorptive)
+    "Second contants of the isotherm model";
+  constant Real char_curve_c=
+    -1.969937e-2 / 1000 * sqrt(1 / 1000 / M_adsorptive)
+    "Third contants of the isotherm model";
+  constant Real char_curve_d=
+    8.174501e-4 / 1000 / M_adsorptive
+    "Fourth contants of the isotherm model";
+  constant Real char_curve_e=
+    4.362905e-4 / 1000 / 1000 / M_adsorptive
+    "Fivth contants of the isotherm model";
+  constant Real char_curve_f=
+    2.339058e-6 / 1000 / M_adsorptive * sqrt(1 / 1000 / M_adsorptive)
+    "Sixth contants of the isotherm model";
+  constant Real char_curve_g=
+    -3.199002e-6 / 1000 / 1000 / M_adsorptive * sqrt(1 / 1000 / M_adsorptive)
+    "Seventh contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+    c[9] :=char_curve_g;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+    c[9] :=char_curve_g;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+    dc_dT[7] :=0;
+    dc_dT[8] :=0;
+    dc_dT[9] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+    ddc_dT_dT[7] :=0;
+    ddc_dT_dT[8] :=0;
+    ddc_dT_dT[9] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & Zeolith 13X using the Dubinin isotherm model with an empirical 2
+characteristic curve according to Schawe (2000). Packages that inherit 
+properties from this partial package may redeclare the package <i>MediumSpecificFunctions</i>
+and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_DubininEmpirical2_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000/package.order
new file mode 100644
index 0000000..85e4137
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000/package.order
@@ -0,0 +1,9 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+char_curve_e
+char_curve_f
+char_curve_g
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010/package.mo
new file mode 100644
index 0000000..d95e884
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010/package.mo
@@ -0,0 +1,134 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package Zeolith13X_Toth_WangDouglasLeVan2010 "H2O & Zeolith 13X via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=18.0153/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 3.634e-9 / b_ref * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 2.408e-10
+    "Second contants of the isotherm model";
+  constant Real E(unit="K") = 6.852e3
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = 3.974e-1
+    "Fourth contants of the isotherm model";
+  constant Real alpha(unit="1/K") = -4.199
+    "Fivth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    dc_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    ddc_dT_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & Zeolith 13X using the Toth isotherm model according to Wang 
+and Douglas LeVan (2010). Packages that inherit properties from this partial 
+package may redeclare the package <i>MediumSpecificFunctions</i>, the model 
+<i>Sorbent</i>, and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2010). Adsorption Equilibrium of Binary Mixtures of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X, Hournal of Chemical & Engineering Data, 55(9):3189–3195. DOI: https://doi.org/10.1021/je100053g.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_WangDouglasLeVan2010;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010/package.order
new file mode 100644
index 0000000..e5bc23d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010/package.order
@@ -0,0 +1,7 @@
+x_sat
+b_ref
+E
+t
+alpha
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010/package.mo
new file mode 100644
index 0000000..d7d79af
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010/package.mo
@@ -0,0 +1,134 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package Zeolith5A_Toth_WangDouglasLeVan2010 "H2O & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=18.0153/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 1.106e-11 / b_ref * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 4.714e-13
+    "Second contants of the isotherm model";
+  constant Real E(unit="K") = 9.955e3
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = 3.548e-1
+    "Fourth contants of the isotherm model";
+  constant Real alpha(unit="1/K") = -5.114e1
+    "Fivth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    c[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    dc_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=E);
+    ddc_dT_dT[3] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+      T=T_adsorpt,
+      a=t,
+      b=0,
+      c=alpha,
+      d=1);
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & Zeolith 5A using the Toth isotherm model according to Wang 
+and Douglas LeVan (2010). Packages that inherit properties from this partial 
+package may redeclare the package <i>MediumSpecificFunctions</i>, the model 
+<i>Sorbent</i>, and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2010). Adsorption Equilibrium of Binary Mixtures of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X, Hournal of Chemical & Engineering Data, 55(9):3189–3195. DOI: https://doi.org/10.1021/je100053g.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith5A_Toth_WangDouglasLeVan2010;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010/package.order
new file mode 100644
index 0000000..e5bc23d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010/package.order
@@ -0,0 +1,7 @@
+x_sat
+b_ref
+E
+t
+alpha
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000/package.mo
new file mode 100644
index 0000000..b99299e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000/package.mo
@@ -0,0 +1,148 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O;
+package ZeolithTypeA_DubininChebyshevSeries33_Schawe2000 "H2O & Type A via the Dubinin isotherm model with a Chebyshev series rational order 3/3 approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationDubinin(
+    final M_adsorptive=18.0153/1000,
+    final no_coefficients=11,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.DubininEmpirical2,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE,
+    redeclare replaceable model Sorbent =
+      SorpLib.Media.Solids.Sorbents.GenericSorbent (
+        v_constant=1/740,
+        c_constant=920,
+        lambda_constant=0.085));
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.FilledPoreVolume char_curve_a=
+    3.472616e-2 / 100
+    "First contants of the isotherm model";
+  constant Real char_curve_b=
+     1.322831
+    "Second contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_c=
+    9.401171e-3 / 1000
+    "Third contants of the isotherm model";
+  constant Real char_curve_d=
+    5.760414e-1
+    "Fourth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_e=
+    1.350676e-3 / 1000
+    "Fivth contants of the isotherm model";
+  constant Real char_curve_f=
+    1.313913e-1
+    "Sixth contants of the isotherm model";
+  constant SorpLib.Units.FilledPoreVolume char_curve_g(min=-1)=
+    -1.926730e-4 / 1000
+    "Seventh contants of the isotherm model";
+  constant SorpLib.Units.MolarAdsorptionPotential char_curve_h=
+    1061.930 * 1000 * M_adsorptive
+    "Eigth contants of the isotherm model";
+  constant SorpLib.Units.MolarAdsorptionPotential char_curve_i=
+    1065.595 * 1000 * M_adsorptive
+    "Ninth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] := MediumSpecificFunctions.p_sat_T(
+       T=T_adsorpt);
+    c[2] := MediumSpecificFunctions.rho_satLiq_T(
+       T=T_adsorpt);
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+    c[9] :=char_curve_g;
+    c[10] :=char_curve_h;
+    c[11] :=char_curve_i;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Get medium-specific functions (p_sat, rho_satLiq, and their partial
+    // derivatives w.r.t. temperature)
+    //
+    (c[1],dc_dT[1],ddc_dT_dT[1],c[2],dc_dT[2],ddc_dT_dT[2]) :=
+      MediumSpecificFunctions.pRho_satLiq(T=T_adsorpt, dT=dT)
+      "Calculates saturated vapor pressure, density and bubble point, and their
+      first- and secon-order partial derivatives w.r.t. temperature)";
+
+    //
+    // Calculate further coefficients
+    //
+    c[3] :=char_curve_a;
+    c[4] :=char_curve_b;
+    c[5] :=char_curve_c;
+    c[6] :=char_curve_d;
+    c[7] :=char_curve_e;
+    c[8] :=char_curve_f;
+    c[9] :=char_curve_g;
+    c[10] :=char_curve_h;
+    c[11] :=char_curve_i;
+
+    //
+    // Calculate further partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    dc_dT[3] :=0;
+    dc_dT[4] :=0;
+    dc_dT[5] :=0;
+    dc_dT[6] :=0;
+    dc_dT[7] :=0;
+    dc_dT[8] :=0;
+    dc_dT[9] :=0;
+    dc_dT[10] :=0;
+    dc_dT[11] :=0;
+
+    //
+    // Calculate further second-order partial derivatives of the coefficients
+    // w.r.t. temperature
+    //
+    ddc_dT_dT[3] :=0;
+    ddc_dT_dT[4] :=0;
+    ddc_dT_dT[5] :=0;
+    ddc_dT_dT[6] :=0;
+    ddc_dT_dT[7] :=0;
+    ddc_dT_dT[8] :=0;
+    ddc_dT_dT[9] :=0;
+    ddc_dT_dT[10] :=0;
+    ddc_dT_dT[11] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+H<sub>2</sub>0 & Zeolith Type A using the Dubinin isotherm model with a Chebyshev 
+series rational order 3/3 characteristic curve according to Schawe (2000). Packages 
+that inherit properties from this partial package may redeclare the package 
+<i>MediumSpecificFunctions</i> and the model <i>Sorbent</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeolithTypeA_DubininChebyshevSeries33_Schawe2000;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000/package.order
new file mode 100644
index 0000000..97dd261
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000/package.order
@@ -0,0 +1,11 @@
+char_curve_a
+char_curve_b
+char_curve_c
+char_curve_d
+char_curve_e
+char_curve_f
+char_curve_g
+char_curve_h
+char_curve_i
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/package.mo
new file mode 100644
index 0000000..3e7c086
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents;
+package H2O "Package containing parametrizations for H2O as adsorptive"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for H<sub>2</sub>O as adsorptive.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end H2O;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/package.order
new file mode 100644
index 0000000..543f6ed
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/H2O/package.order
@@ -0,0 +1,19 @@
+AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017
+AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017
+AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017
+NaZeolithY_DubininEmpirical2_Schawe2000
+SilicaGel_Toth_WangDouglasLeVan2009
+SilicaGel123_DubininLorentzianCumulative_Schawe2000
+SilicaGelAF25_DubininLorentzianCumulative_Schawe2000
+SilicaGel125_DubininLorentzianCumulative_Schawe2000
+SilicaGelFuji_DubininLorentzianCumulative_Schawe2000
+SilicaGelH_DubininPearsonIV_Schawe2000
+SilicaGelLE32_DubininPearsonIV_Schawe2000
+SilicaGelNAC_DubininEmpirical1_Schawe2000
+SilicaGelN_DubininPearsonIV_Schawe2000
+SilicaGelWS_DubininLorentzianCumulative_Schawe2000
+Sizeo15_DubininPearsonIV_Schawe2000
+Zeolith5A_Toth_WangDouglasLeVan2010
+Zeolith13X_DubininEmpirical2_Schawe2000
+Zeolith13X_Toth_WangDouglasLeVan2010
+ZeolithTypeA_DubininChebyshevSeries33_Schawe2000
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/Gas/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/Gas/package.mo
new file mode 100644
index 0000000..36677ce
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/Gas/package.mo
@@ -0,0 +1,340 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions;
+package Gas "Medium-specific functions using a fluid with just one regime (i.e., gas/vapor)"
+
+  //
+  // Definition of replaceable medium package: This is required to have access to
+  // functions that change with the selected medium.
+  //
+  replaceable package Medium = Modelica.Media.IdealGases.SingleGases.H2O
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Medium"),
+                choicesAllMatching = true);
+  //
+  // Inherit from base class and finalize it
+  //
+  extends
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureMediumSpecificFunctions;
+
+  //
+  // Redeclare models
+  //
+  redeclare final model extends AdsorptiveProperties
+    "Calculates all properties of the adsorptive at gas/vapor phase required for the working pair model at once"
+
+    //
+    // Definition of state records
+    //
+protected
+    Medium.ThermodynamicState state
+      "Thermodynamic properties at p and T or at p_sat(T) and T";
+
+  equation
+    //
+    // Calculate state records
+    //
+    if adsorptiveAtDewPoint or
+      require_dp_sat_dT or
+      require_rho_satLiq_T or
+      require_drho_satLiq_dT or
+      require_h_adsorptiveToLiquid or
+      require_cp_satLiq_T or
+      require_dh_adsorptiveToLiquid_dp_T or
+      require_dh_adsorptiveToLiquid_dT_p or
+      require_ddrho_satLiq_dT_dT or
+      (adsorptiveAtDewPoint and require_dv_adsorptive_dT_p) then
+      assert(false,
+        "Selected adsorptive medium model does not have a two-phase regime. " +
+        "Cannot calculate state properties of bubble or dew point at T_adsorpt." +
+        "Thus, the specific volume or heat capacity of the adsorpt at the bubble " +
+        "point can also not be calculated.",
+        level = AssertionLevel.error);
+    end if;
+
+    state = Medium.setState_pTX(p=p, T=T, X=Medium.reference_X)
+      "Thermodynamic properties at p and T or at p_sat(T) and T";
+
+    //
+    // State variables
+    //
+    v = 1/Medium.density(state=state)
+      "Specific volume";
+
+    if calcCaloricProperties then
+      h = Medium.specificEnthalpy(state=state)
+        "Specific enthalpy";
+      u = h - p*v
+        "Specific internal energy";
+
+    else
+      h = 0
+        "Specific enthalpy";
+      u = 0
+        "Specific internal energy";
+
+    end if;
+
+    if calcCaloricProperties and calcEntropicProperties then
+      s = Medium.specificEntropy(state=state)
+        "Specific entropy";
+      g = h - T*s
+        "Free enthalpy (i.e., Gibbs free energy)";
+      a = u - T*s
+        "Free energy (i.e., Helmholts free energy)";
+
+    else
+      s = 0
+        "Specific entropy";
+      g = 0
+        "Free enthalpy (i.e., Gibbs free energy)";
+      a = 0
+        "Free energy (i.e., Helmholts free energy)";
+
+    end if;
+
+    //
+    // Additional properties of the one-phase regime
+    //
+    cp = if not require_cp_adsorptive then 0 else
+      Medium.specificHeatCapacityCp(state=state)
+      "Specific heat capacity";
+
+    //
+    // Additional properties of the two-phase regime
+    //
+    p_sat =  0
+      "Saturated vapor pressure";
+    v_satLiq =  0
+      "Specific volume at the bubble point at given temperature";
+
+    h_adsorptiveToLiquid =  0
+      "Specific enthalpy of vaporization";
+
+    cp_satLiq = 0
+      "Specific heat capacity at the bubble point at given temeprature";
+
+    //
+    // Partial derivatives of the one-phase regime
+    //
+    dv_dp_T =  if not require_dv_adsorptive_dp_T then 0 else
+      (1/Medium.density_pTX(p=p + dp, T=T, X=Medium.reference_X) -
+      1/Medium.density_pTX(p=p - dp, T=T, X=Medium.reference_X))/(2*dp)
+      "Partial derivative of the specific volume w.r.t. pressure at constant
+    temperature";
+
+    dv_dT_p =  if not require_dv_adsorptive_dT_p then 0 else
+      (1/Medium.density_pTX(p=p, T=T + dT, X=Medium.reference_X) -
+      1/Medium.density_pTX(p=p, T=T - dT, X=Medium.reference_X))/(2*dT)
+      "Partial derivative of the specific volume w.r.t. temperature at constant
+    pressure";
+
+    //
+    // Partial derivatives of the two-phase regime
+    //
+    dp_sat_dT = 0
+      "Partial derivative of saturated vapor pressure w.r.t. temperature";
+
+    dv_satLiq_dT = 0
+      "Partial derivative of the specific volume at the bubble point at given
+    temperature w.r.t. temperature";
+    ddv_satLiq_dT_dT = 0
+      "Second-order partial derivative of the specific volume at the bubble point 
+    at given temperature w.r.t. temperature";
+
+    dh_adsorptiveToLiquid_dp_T = 0
+      "Partial derivative of specific enthalpy of vaporization w.r.t. pressure
+    at constant temperature";
+    dh_adsorptiveToLiquid_dT_p = 0
+      "Partial derivative of specific enthalpy of vaporization w.r.t. pressure
+    at constant temperature";
+  end AdsorptiveProperties;
+  //
+  // Redeclare functions of the two-phase regime
+  //
+  redeclare final function extends p_sat_T
+    "Calculates the vapor pressure as function of temperature (i.e., not supported)"
+  algorithm
+    p_sat :=0
+      "Saturated vapor pressure: Dummy value";
+  end p_sat_T;
+
+  redeclare final function extends rho_satLiq_T
+    "Calculates the density at the bubble point as function of temperature (i.e., not supported)"
+  algorithm
+    rho_satLiq:=0
+      "Density at bubble point: Dummy value";
+  end rho_satLiq_T;
+
+  redeclare final function extends pRho_satLiq
+    "Calculates the vapor pressure, density at the bubble point, and their first- and second-order partial derivatives w.r.t. temperature (i.e., not supported)"
+    extends Modelica.Icons.Function;
+  algorithm
+    p_sat := 0
+      "Saturated vapor pressure: Dummy value";
+    dp_sat_dT:= 0
+      "Partial derivative of the vapor pressure w.r.t. temperature: Dummy value";
+    ddp_sat_dT_dT :=0
+      "Calculates the second-order partial derivative of the vapor pressure w.r.t. 
+      temperature: Dummy value";
+
+    rho_satLiq:=0
+      "Density at bubble point: Dummy value";
+    drho_satLiq_dT :=0
+      "Calculates the partial derivative of the density at the bubble point w.r.t.
+      temperature: Dummy value";
+    ddrho_satLiq_dT_dT:=0
+      "Calculates the second-order partial derivative of the density at the bubble 
+    point w.r.t. temperature: Dummy value";
+  end pRho_satLiq;
+  //
+  // Functions of the one-phase regime
+  //
+  redeclare final function extends h_pT
+    "Calculates the specific enthalpy of the adsorptive as function of pressure
+    and temperature"
+  algorithm
+    h := if p > p_lb then
+      Medium.specificEnthalpy_pTX(p=p, T=T, X=Medium.reference_X) else
+      h_ref + (T - T_ref) * Medium.specificHeatCapacityCp(state=
+        Medium.setState_pTX(p=p_lb, T=T, X=Medium.reference_X))
+      "Specific enthalpy";
+  end h_pT;
+
+  redeclare final function extends s_pT
+    "Calculates the specific entropy of the adsorptive as function of pressure
+    and temperature"
+  algorithm
+    s :=if p > p_lb then
+      Medium.specificEntropy_pTX(p=p, T=T, X=Medium.reference_X) else
+      s_ref - Modelica.Constants.R * log(p_lb / p_ref) + (T - T_ref) / T  *
+      Medium.specificHeatCapacityCp(state=
+        Medium.setState_pTX(p=p_lb, T=T, X=Medium.reference_X))
+      "Specific entropy";
+  end s_pT;
+  //
+  // Functions calculating properties required for calculating the specific heat
+  // capacity of the adsorpt
+  //
+  redeclare final function extends calc_properties
+    "Calculates all properties of the adsorptive at gas/vapor phase required for the working pair model at once"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of state records
+    //
+protected
+    Medium.ThermodynamicState state
+      "Thermodynamic properties at p and T";
+
+  algorithm
+    //
+    // Calculate state records
+    //
+    if adsorptiveAtDewPoint or require_h_adsorptiveToLiquid then
+      assert(false,
+        "Selected adsorptive medium model does not have a two-phase regime. " +
+        "Cannot calculate state properties of bubble or dew point at T_adsorpt.",
+        level = AssertionLevel.error);
+    end if;
+
+    if require_v_adsorptive or
+      require_h_adsorptive or
+      require_dh_adsorptive_dT_dp or
+      require_s_adsorptive then
+      state := Medium.setState_pTX(p=max(p,p_min), T=T, X=Medium.reference_X)
+        "Thermodynamic properties at p and T";
+
+    end if;
+
+    //
+    // Calculate specific volume
+    //
+    if require_v_adsorptive then
+      v := 1 / Medium.density(state=state)
+        "Specific volume";
+      dv_dp_T := if p > p_min then
+        (1 / Medium.density_pTX(p=p+dp, T=T, X=Medium.reference_X) -
+        1 / Medium.density_pTX(p=p-dp, T=T, X=Medium.reference_X)) / (2 * dp) else
+        (1 / Medium.density_pTX(p=p_min+dp, T=T, X=Medium.reference_X) -
+        1 / Medium.density_pTX(p=p_min, T=T, X=Medium.reference_X)) / (2 * dp)
+        "Partial derivative of the specific volume w.r.t. pressure at constant
+      temperature";
+      dv_dT_p :=
+        (1 / Medium.density_pTX(p=max(p,p_min), T=T+dT, X=Medium.reference_X) -
+        1 / Medium.density_pTX(p=max(p,p_min), T=T-dT, X=Medium.reference_X)) /
+        (2 * dT)
+        "Partial derivative of the specific volume w.r.t. temperature at constant
+      pressure";
+
+    else
+      v :=0
+        "Specific volume";
+      dv_dp_T :=0
+        "Partial derivative of the specific volume w.r.t. pressure at constant
+      temperature";
+      dv_dT_p :=0
+        "Partial derivative of the specific volume w.r.t. temperature at constant
+      pressure";
+
+    end if;
+
+    //
+    // Calculate specific enthalpy
+    //
+    h := if not require_h_adsorptive then 0 else
+      Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+    dh_dT_p := if not require_dh_adsorptive_dT_dp then 0 else
+      Medium.specificHeatCapacityCp(state=state)
+      "Partial derivative of the specific enthalpy w.r.t. temperature at constant
+    pressure";
+
+    //
+    // Calculate specific enthalpy
+    //
+    s := if not require_s_adsorptive then 0 else s_pT(
+      p=p,
+      T=T,
+      p_lb=p_min,
+      s_ref=Medium.specificEntropy(state=state),
+      p_ref=p_min,
+      T_ref=T)
+      "Specific entropy";
+
+    //
+    // Calculate specific enthalpy difference between adsorptive phase and bubble
+    // phase: Cannot be calculated for ideal gas, so set dummy values
+    //
+    h_atl :=0
+      "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+    dh_atl_dp :=0
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant
+    temperature";
+    dh_atl_dT :=0
+      "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+  end calc_properties;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This package provides media-specific functions for a fluid with just one regime,
+i.e., the gas or vapor phase. Thus, this fluid does not support functions of
+the two-phase regime and cannot be used for isotherm models based on the model
+of Dubinin.
+</p>
+</html>"));
+end Gas;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/Gas/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/Gas/package.order
new file mode 100644
index 0000000..1ae20c0
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/Gas/package.order
@@ -0,0 +1,8 @@
+Medium
+AdsorptiveProperties
+p_sat_T
+rho_satLiq_T
+pRho_satLiq
+h_pT
+s_pT
+calc_properties
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/VLE/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/VLE/package.mo
new file mode 100644
index 0000000..f6d5f89
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/VLE/package.mo
@@ -0,0 +1,502 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions;
+package VLE "Medium-specific functions using a real fluid with a two-phase regime"
+
+  //
+  // Definition of replaceable medium package: This is required to have access to
+  // functions that change with the selected medium.
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Medium"),
+                choicesAllMatching = true);
+  //
+  // Inherit from base class and finalize it
+  //
+  extends
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureMediumSpecificFunctions;
+
+  //
+  // Redeclare models
+  //
+  redeclare final model extends AdsorptiveProperties
+    "Calculates all properties of the adsorptive at gas/vapor phase required for the working pair model at once"
+
+    //
+    // Definition of state records
+    //
+protected
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+    Medium.SaturationProperties sat_T_pdT
+      "Saturated state properties at T + dT";
+    Medium.SaturationProperties sat_T_mdT
+      "Saturated state properties at T - dT";
+
+    Medium.ThermodynamicState state
+      "Thermodynamic properties at p and T or at p_sat(T) and T";
+    Medium.ThermodynamicState state_bubble
+      "Thermodynamic properties at bubble point calculated with T";
+
+  equation
+    //
+    // Calculate state records
+    //
+    if adsorptiveAtDewPoint or
+      require_dp_sat_dT or
+      require_rho_satLiq_T or
+      require_drho_satLiq_dT or
+      require_h_adsorptiveToLiquid or
+      require_cp_satLiq_T then
+      sat_T = Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+
+    else
+      sat_T = Medium.setSat_T(T=Medium.reference_T)
+        "Saturated state properties at reference temperature";
+
+    end if;
+
+    if require_ddrho_satLiq_dT_dT or
+      (adsorptiveAtDewPoint and require_dv_adsorptive_dT_p) then
+      sat_T_pdT = Medium.setSat_T(T=T + dT)
+        "Saturated state properties at T + dT";
+      sat_T_mdT = Medium.setSat_T(T=T - dT)
+        "Saturated state properties at T - dT";
+
+    else
+      sat_T_pdT = Medium.setSat_T(T=Medium.reference_T)
+        "Saturated state properties at reference temperature";
+      sat_T_mdT = Medium.setSat_T(T=Medium.reference_T)
+        "Saturated state properties at reference temperature";
+
+    end if;
+
+    state = if adsorptiveAtDewPoint then Medium.setDewState(sat=sat_T) else
+      Medium.setState_pTX(p=p, T=T, X=Medium.reference_X)
+      "Thermodynamic properties at p and T or at p_sat(T) and T";
+
+    if require_h_adsorptiveToLiquid or
+      require_dh_adsorptiveToLiquid_dT_p or
+      require_cp_satLiq_T then
+      state_bubble =  Medium.setBubbleState(sat=sat_T)
+        "Thermodynamic properties at bubble point calculated with T";
+
+    else
+      state_bubble =  Medium.setBubbleState(sat=sat_T)
+        "Thermodynamic properties at bubble point calculated at reference temperature";
+
+    end if;
+
+    //
+    // State variables
+    //
+    // v = if adsorptiveAtDewPoint then 1/Medium.dewDensity(sat=sat_T) else
+    //   1/Medium.density(state=state)
+    //   "Specific volume";
+    v = 1/Medium.density(state=state)
+      "Specific volume";
+
+    if calcCaloricProperties then
+      // h = if adsorptiveAtDewPoint then Medium.dewEnthalpy(sat=sat_T) else
+      //   Medium.specificEnthalpy(state=state)
+      //   "Specific enthalpy";
+      h = Medium.specificEnthalpy(state=state)
+        "Specific enthalpy";
+      u = h - p*v
+        "Specific internal energy";
+
+    else
+      h = 0
+        "Specific enthalpy";
+      u = 0
+        "Specific internal energy";
+
+    end if;
+
+    if calcCaloricProperties and calcEntropicProperties then
+      // s = if adsorptiveAtDewPoint then Medium.dewEntropy(sat=sat_T) else
+      //   Medium.specificEntropy(state=state)
+      //   "Specific entropy";
+      s = Medium.specificEntropy(state=state)
+        "Specific entropy";
+      g = h - T*s
+        "Free enthalpy (i.e., Gibbs free energy)";
+      a = u - T*s
+        "Free energy (i.e., Helmholts free energy)";
+
+    else
+      s = 0
+        "Specific entropy";
+      g = 0
+        "Free enthalpy (i.e., Gibbs free energy)";
+      a = 0
+        "Free energy (i.e., Helmholts free energy)";
+
+    end if;
+
+    //
+    // Additional properties of the one-phase regime
+    //
+    cp = if not require_cp_adsorptive then 0 else
+      Medium.specificHeatCapacityCp(state=state)
+      "Specific heat capacity";
+
+    //
+    // Additional properties of the two-phase regime
+    //
+    p_sat =  if not require_p_sat then 0 else
+      Medium.saturationPressure(T)
+      "Saturated vapor pressure";
+    v_satLiq =  if not require_rho_satLiq_T then 0 else
+      1/Medium.bubbleDensity(sat=sat_T)
+      "Specific volume at the bubble point at given temperature";
+
+    h_adsorptiveToLiquid = if not require_h_adsorptiveToLiquid then 0 else
+      h - Medium.specificEnthalpy(state=state_bubble)
+      "Specific enthalpy of vaporization";
+
+    cp_satLiq = if not require_cp_satLiq_T then 0 else
+      Medium.specificHeatCapacityCp(state=state_bubble)
+      "Specific heat capacity at the bubble point at given temeprature";
+
+    //
+    // Partial derivatives of the one-phase regime
+    //
+    dv_dp_T =  if not require_dv_adsorptive_dp_T then 0 else
+      (if adsorptiveAtDewPoint then 0 else
+      (1/Medium.density_pTX(p=p+dp, T=T, X=Medium.reference_X) -
+      1/Medium.density_pTX(p=p-dp, T=T, X=Medium.reference_X))/(2*dp))
+      "Partial derivative of the specific volume w.r.t. pressure at constant
+    temperature";
+
+    dv_dT_p =  if not require_dv_adsorptive_dT_p then 0 else
+      (if adsorptiveAtDewPoint then
+      (1/Medium.dewDensity(sat=sat_T_pdT) -
+      1 /Medium.dewDensity(sat=sat_T_mdT))/(2*dT) else
+      (1/Medium.density_pTX(p=p, T=T+dT, X=Medium.reference_X) -
+      1/Medium.density_pTX(p=p, T=T-dT, X=Medium.reference_X))/(2*dT))
+      "Partial derivative of the specific volume w.r.t. temperature at constant
+    pressure";
+
+    //
+    // Partial derivatives of the two-phase regime
+    //
+    dp_sat_dT =  if not require_dp_sat_dT then 0 else
+      1/Medium.saturationTemperature_derp_sat(sat=sat_T)
+      "Partial derivative of saturated vapor pressure w.r.t. temperature";
+
+    dv_satLiq_dT =  if not require_drho_satLiq_dT then 0 else
+      -v_satLiq^2*Medium.dBubbleDensity_dPressure(sat=sat_T)* dp_sat_dT
+      "Partial derivative of the specific volume at the bubble point at given
+    temperature w.r.t. temperature";
+    ddv_satLiq_dT_dT =  if not require_ddrho_satLiq_dT_dT then 0 else
+      ((-Medium.dBubbleDensity_dPressure(sat=sat_T_pdT)/
+      Medium.saturationTemperature_derp_sat(sat=sat_T_pdT)/Medium.bubbleDensity(
+       sat=sat_T_pdT)^2 +
+       Medium.dBubbleDensity_dPressure(sat=sat_T_mdT)/
+      Medium.saturationTemperature_derp_sat(sat=sat_T_mdT)/Medium.bubbleDensity(
+       sat=sat_T_mdT)^2)/(2*dT))
+      "Second-order partial derivative of the specific volume at the bubble point 
+    at given temperature w.r.t. temperature";
+
+    dh_adsorptiveToLiquid_dp_T = if not require_dh_adsorptiveToLiquid_dp_T then 0
+      else v * (1 - T * Medium.isobaricExpansionCoefficient(state=state)) - 0
+      "Partial derivative of specific enthalpy of vaporization w.r.t. pressure
+    at constant temperature";
+    dh_adsorptiveToLiquid_dT_p = if not require_dh_adsorptiveToLiquid_dT_p then 0
+      else
+      Medium.specificHeatCapacityCp(state=state) -
+      Medium.specificHeatCapacityCp(state=state_bubble)
+      "Partial derivative of specific enthalpy of vaporization w.r.t. pressure
+    at constant temperature";
+  end AdsorptiveProperties;
+  //
+  // Redeclare functions of the two-phase regime
+  //
+  redeclare final function extends p_sat_T
+    "Calculates the vapor pressure as function of temperature"
+  algorithm
+    p_sat :=Medium.saturationPressure(T)
+      "Saturated vapor pressure";
+  end p_sat_T;
+
+  redeclare final function extends rho_satLiq_T
+    "Calculates the density at the bubble point as function of temperature"
+  algorithm
+    rho_satLiq:=Medium.bubbleDensity(sat=Medium.setSat_T(T=T))
+      "Density at bubble point";
+  end rho_satLiq_T;
+
+  redeclare final function extends pRho_satLiq
+    "Calculates the vapor pressure, density at the bubble point, and their first- and second-order partial derivatives w.r.t. temperature"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of variables
+    //
+protected
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+    Medium.SaturationProperties sat_T_pdT
+      "Saturated state properties at T + dT";
+    Medium.SaturationProperties sat_T_mdT
+      "Saturated state properties at T - dT";
+
+  algorithm
+    sat_T :=Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+    sat_T_pdT :=Medium.setSat_T(T=T + dT)
+      "Saturated state properties at T";
+    sat_T_mdT :=Medium.setSat_T(T=T - dT)
+      "Saturated state properties at T";
+
+    p_sat := Medium.saturationPressure(T)
+      "Saturated vapor pressure";
+    dp_sat_dT:= 1 / Medium.saturationTemperature_derp_sat(sat=sat_T)
+      "Partial derivative of the vapor pressure w.r.t. temperature";
+    ddp_sat_dT_dT :=
+      (1 / Medium.saturationTemperature_derp_sat(sat=sat_T_pdT) -
+      1 / Medium.saturationTemperature_derp_sat(sat=sat_T_mdT)) / (2 * dT)
+      "Calculates the second-order partial derivative of the vapor pressure w.r.t. 
+      temperature";
+
+    rho_satLiq:=Medium.bubbleDensity(sat=sat_T)
+      "Density at bubble point";
+    drho_satLiq_dT :=Medium.dBubbleDensity_dPressure(sat=sat_T) * dp_sat_dT
+      "Calculates the partial derivative of the density at the bubble point w.r.t.
+      temperature";
+    ddrho_satLiq_dT_dT:=
+      (Medium.dBubbleDensity_dPressure(sat=sat_T_pdT) /
+      Medium.saturationTemperature_derp_sat(sat=sat_T_pdT) -
+      Medium.dBubbleDensity_dPressure(sat=sat_T_mdT) /
+      Medium.saturationTemperature_derp_sat(sat=sat_T_mdT)) / (2 * dT)
+      "Calculates the second-order partial derivative of the density at the bubble 
+    point w.r.t. temperature";
+  end pRho_satLiq;
+  //
+  // Functions of the one-phase regime
+  //
+  redeclare final function extends h_pT
+    "Calculates the specific enthalpy of the adsorptive as function of pressure
+    and temperature"
+  algorithm
+    h := if p > p_lb then
+      Medium.specificEnthalpy_pTX(p=p, T=T, X=Medium.reference_X) else
+      h_ref + (T - T_ref) * Medium.specificHeatCapacityCp(state=
+        Medium.setState_pTX(p=p_lb, T=T, X=Medium.reference_X))
+      "Specific enthalpy";
+  end h_pT;
+
+  redeclare final function extends s_pT
+    "Calculates the specific entropy of the adsorptive as function of pressure
+    and temperature"
+  algorithm
+    s :=if p > p_lb then
+      Medium.specificEntropy_pTX(p=p, T=T, X=Medium.reference_X) else
+      s_ref - Modelica.Constants.R * log(p_lb / p_ref) + (T - T_ref) / T  *
+      Medium.specificHeatCapacityCp(state=
+        Medium.setState_pTX(p=p_lb, T=T, X=Medium.reference_X))
+      "Specific entropy";
+  end s_pT;
+  //
+  // Functions calculating properties required for calculating the specific heat
+  // capacity of the adsorpt
+  //
+  redeclare final function extends calc_properties
+    "Calculates all properties of the adsorptive at gas/vapor phase required for the working pair model at once"
+    extends Modelica.Icons.Function;
+
+    //
+    // Definition of state records
+    //
+protected
+    Medium.SaturationProperties sat_T
+      "Saturated state properties at T";
+    Medium.SaturationProperties sat_T_pdT
+      "Saturated state properties at T + dT";
+    Medium.SaturationProperties sat_T_mdT
+      "Saturated state properties at T - dT";
+
+    Medium.ThermodynamicState state
+      "Thermodynamic properties at p and T or at p_sat(T) and T";
+    Medium.ThermodynamicState state_bubble
+      "Thermodynamic properties at bubble point calculated with T";
+
+  algorithm
+    //
+    // Calculate state records
+    //
+    if adsorptiveAtDewPoint and (
+      require_v_adsorptive or
+      require_h_adsorptive or
+      require_dh_adsorptive_dT_dp or
+      require_s_adsorptive or
+      require_h_adsorptiveToLiquid) or
+      require_h_adsorptiveToLiquid then
+      sat_T :=Medium.setSat_T(T=T)
+      "Saturated state properties at T";
+    end if;
+
+    if adsorptiveAtDewPoint and
+      (require_v_adsorptive) then
+      sat_T_pdT :=Medium.setSat_T(T=T+dT)
+        "Saturated state properties at T + dT";
+      sat_T_mdT :=Medium.setSat_T(T=T-dT)
+        "Saturated state properties at T - dT";
+    end if;
+
+    if require_v_adsorptive or
+      require_h_adsorptive or
+      require_dh_adsorptive_dT_dp or
+      require_s_adsorptive or
+      require_h_adsorptiveToLiquid then
+      state := if adsorptiveAtDewPoint then
+        Medium.setDewState(sat=sat_T) else
+        Medium.setState_pTX(p=max(p,p_min), T=T, X=Medium.reference_X)
+        "Thermodynamic properties at p and T or at p_sat(T) and T";
+    end if;
+
+    if require_h_adsorptiveToLiquid then
+      state_bubble := Medium.setBubbleState(sat=sat_T)
+        "Thermodynamic properties at bubble point calculated with T";
+    end if;
+
+    //
+    // Calculate specific volume
+    //
+    if require_h_adsorptiveToLiquid then
+      v := 1 / Medium.density(state=state)
+        "Specific volume";
+
+    elseif require_v_adsorptive then
+      // v := if adsorptiveAtDewPoint then 1 / Medium.dewDensity(sat=sat_T) else
+      //   1 / Medium.density_pTX(p=p, T=T, X=Medium.reference_X)
+      //   "Specific volume";
+      v := 1 / Medium.density(state=state)
+        "Specific volume";
+
+    else
+      v :=0
+        "Specific volume";
+
+    end if;
+
+    if require_v_adsorptive then
+      if adsorptiveAtDewPoint then
+        dv_dp_T :=0
+          "Partial derivative of the specific volume w.r.t. pressure at constant
+        temperature: Corresponds to unity as dew state is determined by temperature";
+        dv_dT_p :=
+          (1 / Medium.dewDensity(sat=sat_T_pdT) -
+          1 / Medium.dewDensity(sat=sat_T_mdT)) / (2 * dT)
+          "Partial derivative of the specific volume w.r.t. temperature at constant
+        pressure";
+
+      else
+        dv_dp_T := if p > p_min then
+          (1 / Medium.density_pTX(p=p+dp, T=T, X=Medium.reference_X) -
+          1 / Medium.density_pTX(p=p-dp, T=T, X=Medium.reference_X)) / (2 * dp) else
+          (1 / Medium.density_pTX(p=p_min+dp, T=T, X=Medium.reference_X) -
+          1 / Medium.density_pTX(p=p_min, T=T, X=Medium.reference_X)) / (2 * dp)
+          "Partial derivative of the specific volume w.r.t. pressure at constant
+        temperature";
+        dv_dT_p :=
+          (1 / Medium.density_pTX(p=max(p,p_min), T=T+dT, X=Medium.reference_X) -
+          1 / Medium.density_pTX(p=max(p,p_min), T=T-dT, X=Medium.reference_X)) /
+          (2 * dT)
+          "Partial derivative of the specific volume w.r.t. temperature at constant
+        pressure";
+
+      end if;
+
+    else
+      dv_dp_T :=0
+        "Partial derivative of the specific volume w.r.t. pressure at constant
+      temperature";
+      dv_dT_p :=0
+        "Partial derivative of the specific volume w.r.t. temperature at constant
+      pressure";
+
+    end if;
+
+    //
+    // Calculate specific enthalpy
+    //
+    h := if not require_h_adsorptive then 0 else
+      Medium.specificEnthalpy(state=state)
+      "Specific enthalpy";
+
+    dh_dT_p := if not require_dh_adsorptive_dT_dp then 0 else
+      Medium.specificHeatCapacityCp(state=state)
+      "Partial derivative of the specific enthalpy w.r.t. temperature at constant
+    pressure";
+
+    //
+    // Calculate specific enthalpy
+    //
+    s := if not require_s_adsorptive then 0 else s_pT(
+      p=p,
+      T=T,
+      p_lb=p_min,
+      s_ref=Medium.specificEntropy(state=state),
+      p_ref=p_min,
+      T_ref=T)
+      "Specific entropy";
+
+    //
+    // Calculate specific enthalpy difference between adsorptive phase and bubble phase
+    //
+    if require_h_adsorptiveToLiquid then
+      h_atl :=
+        Medium.specificEnthalpy(state=state) -
+        Medium.specificEnthalpy(state=state_bubble)
+        "Specific enthalpy difference between adsorptive state and saturated liquid
+      state (i.e., bubble point)";
+      dh_atl_dp := v * (1 - T *
+        Medium.isobaricExpansionCoefficient(state=state)) - 0
+        "Partial derivative of specific enthalpy difference between adsorptive state 
+      and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant
+      temperature";
+      dh_atl_dT :=
+        Medium.specificHeatCapacityCp(state=state) -
+        Medium.specificHeatCapacityCp(state=state_bubble)
+        "Partial derivative of specific enthalpy difference between adsorptive state 
+      and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+      pressure";
+
+    else
+      h_atl :=0
+        "Specific enthalpy difference between adsorptive state and saturated liquid
+      state (i.e., bubble point)";
+      dh_atl_dp :=0
+        "Partial derivative of specific enthalpy difference between adsorptive state 
+      and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant
+      temperature";
+      dh_atl_dT :=0
+        "Partial derivative of specific enthalpy difference between adsorptive state 
+      and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+      pressure";
+
+    end if;
+
+  end calc_properties;
+  //
+  // Annotations
+  //
+  annotation (Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This package provides media-specific functions for a real fluid. The term 
+\"real\" is used to indicate that the fluid has a two-phase regime. Such fluids 
+are necessary, for example, when using the model of Dubinin as the isotherm 
+model.
+</p>
+</html>"));
+end VLE;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/VLE/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/VLE/package.order
new file mode 100644
index 0000000..1ae20c0
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/VLE/package.order
@@ -0,0 +1,8 @@
+Medium
+AdsorptiveProperties
+p_sat_T
+rho_satLiq_T
+pRho_satLiq
+h_pT
+s_pT
+calc_properties
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/package.mo
new file mode 100644
index 0000000..f6f9f96
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents;
+package MediumSpecificFunctions "Package containing packages with medium-specific functions using the Modelica standard library"
+  extends Modelica.Icons.InternalPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains packages that provide media-specific functions. The 
+provided packages are required to fully parameterize working pair models.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end MediumSpecificFunctions;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/package.order
new file mode 100644
index 0000000..581a2df
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/MediumSpecificFunctions/package.order
@@ -0,0 +1,2 @@
+Gas
+VLE
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011/package.mo
new file mode 100644
index 0000000..74ff951
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011/package.mo
@@ -0,0 +1,109 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.N2;
+package ActivatedCarbon_Toth_DantasEtAl2011 "N2 & Activated carbon via the Toth isotherm model according to Dantas et al. (2011)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=28.0134/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 9.74 * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 6.91e-5 / (1e5)
+    "Second contants of the isotherm model";
+  constant Real Q_star(unit="K") = -16.31e3 / Modelica.Constants.R
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = 0.518
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    c[3] :=t;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    c[3] :=t;
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    dc_dT[3] :=0;
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    ddc_dT_dT[3] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+N<sub>2</sub> & activated carbon using the Toth isotherm model according to Dantas 
+et al. (2011). Packages that inherit properties from this partial package may 
+redeclare the package <i>MediumSpecificFunctions</i>, the model <i>Sorbent</i>,
+and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Dantas, T.L.P. and Luna, F.M.T. and Silva Jr., I.J. and Azevedo, D.C.S. and Grande, C.A. and Rodrigues, A.E. and Moreira, R.F.P.M. (2011). Carbon dioxide–nitrogen separation through adsorption on activated carbon in a fixed bed, Chemical Engineering Journal, 169:11–19. DOI: https://doi.org/10.1016/j.cej.2010.08.026.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ActivatedCarbon_Toth_DantasEtAl2011;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011/package.order
new file mode 100644
index 0000000..99a9913
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011/package.order
@@ -0,0 +1,6 @@
+x_sat
+b_ref
+Q_star
+t
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011/package.mo
new file mode 100644
index 0000000..bfca394
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011/package.mo
@@ -0,0 +1,109 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.N2;
+package Zeolith13X_Toth_DantasEtAl2011 "N2 & Zeolith 13X via the Toth isotherm model according to Dantas et al. (2011)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=28.0134/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=3,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Toth,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake x_sat = 3.08 * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real b_ref(unit="1/Pa") = 0.882e-4 / (1e5)
+    "Second contants of the isotherm model";
+  constant Real Q_star(unit="K") = -17.19e3 / Modelica.Constants.R
+    "Third contants of the isotherm model";
+  constant Real t(unit="1") = 0.869
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    c[3] :=t;
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=x_sat;
+    c[2] :=SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    c[3] :=t;
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=0;
+    dc_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    dc_dT[3] :=0;
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=0;
+    ddc_dT_dT[2] :=
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=b_ref,
+      b=0,
+      c=0,
+      d=-Q_star);
+    ddc_dT_dT[3] :=0;
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+N<sub>2</sub> & Zeolith 13X using the Toth isotherm model according to Dantas 
+et al. (2011). Packages that inherit properties from this partial package may 
+redeclare the package <i>MediumSpecificFunctions</i>, the model <i>Sorbent</i>,
+and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Dantas, T.L.P. and Luna, F.M.T. and Silva Jr., I.J. and Torres, A.E.B. and Azevedo, D.C.S. and Rodrigues, A.E. and Moreira, R.F.P.M. (2011). Carbon dioxide–nitrogen separation through pressure swing adsorption, Chemical Engineering Journal, 172:698-704. DOI: https://doi.org/10.1016/j.cej.2011.06.037.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_DantasEtAl2011;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011/package.order
new file mode 100644
index 0000000..99a9913
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011/package.order
@@ -0,0 +1,6 @@
+x_sat
+b_ref
+Q_star
+t
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.mo
new file mode 100644
index 0000000..e794af8
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.mo
@@ -0,0 +1,131 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.N2;
+package ZeolithLiLSX_Langmuir_LiEtAl2021 "N2 & Zeolith LiLSX via the Langmuir isotherm model according to Li et al. (2021)"
+  extends
+  SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive=28.0134/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake k1 = 7.488 * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real k2(unit="kg/(kg.K)") = -0.016 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real k3(unit="1/Pa") = 0.012 * 1e-5
+    "Third contants of the isotherm model";
+  constant Modelica.Units.SI.Temperature k4 = 1070.199
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=k1,
+      b=k2,
+      c=0,
+      d=1);
+    c[2] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=k3,
+      b=0,
+      c=0,
+      d=k4);
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=k1,
+      b=k2,
+      c=0,
+      d=1);
+    c[2] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=k3,
+      b=0,
+      c=0,
+      d=k4);
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+      T=T_adsorpt,
+      a=k1,
+      b=k2,
+      c=0,
+      d=1);
+    dc_dT[2] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=k3,
+      b=0,
+      c=0,
+      d=k4);
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+      T=T_adsorpt,
+      a=k1,
+      b=k2,
+      c=0,
+      d=1);
+    ddc_dT_dT[2] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=k3,
+      b=0,
+      c=0,
+      d=k4);
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+N<sub>2</sub> & Zeolith LiLSX using the Langmuir isotherm model according to Li 
+et al. (2011). Packages that inherit properties from this partial package may 
+redeclare the package <i>MediumSpecificFunctions</i>, the model <i>Sorbent</i>,
+and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Li, L., and Yu, M., and Zi, Y., and Dang, Y., and Wu, Q., and Wang, Z., and Xu, Y., and Yan, H, and Dang, Y. (2021). A Thermodynamic Model for Pure and Binary Adsorption Equilibria of N<sub>2</sub> and O<sub>2</sub> on Lithium-Exchanged Low Silicon-to-Aluminum Ratio X Zeolite, Journal of Chemical & Engineering Data, 60:1032-1042. DOI: https://dx.doi.org/10.1021/acs.jced.0c00830.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeolithLiLSX_Langmuir_LiEtAl2021;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.order
new file mode 100644
index 0000000..bf326a6
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.order
@@ -0,0 +1,6 @@
+k1
+k2
+k3
+k4
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/package.mo
new file mode 100644
index 0000000..c70de2d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents;
+package N2 "Package containing parametrizations for N2 as adsorptive"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for N<sub>2</sub> as adsorptive.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end N2;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/package.order
new file mode 100644
index 0000000..9280fa7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/N2/package.order
@@ -0,0 +1,3 @@
+ActivatedCarbon_Toth_DantasEtAl2011
+Zeolith13X_Toth_DantasEtAl2011
+ZeolithLiLSX_Langmuir_LiEtAl2021
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.mo
new file mode 100644
index 0000000..8d411b3
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.mo
@@ -0,0 +1,131 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.O2;
+package ZeolithLiLSX_Langmuir_LiEtAl2021 "O2 & Zeolith LiLSX via the Langmuir isotherm model according to Li et al. (2021)"
+  extends
+    SorpLib.Media.WorkingPairs.Interfaces.PartialPureParametrizationNonDubinin(
+    final M_adsorptive= 31.9988/1000,
+    twoPhaseAdsorptive=false,
+    final no_coefficients=2,
+    redeclare final package IsothermModel =
+      SorpLib.Media.Functions.SorptionEquilibria.PureComponents.Langmuir,
+    redeclare replaceable package MediumSpecificFunctions =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas);
+
+  //
+  // Definition of further constants
+  //
+  constant SorpLib.Units.Uptake k1 = 33.947 * M_adsorptive
+    "First contants of the isotherm model";
+  constant Real k2(unit="kg/(kg.K)") = -0.090 * M_adsorptive
+    "Second contants of the isotherm model";
+  constant Real k3(unit="1/Pa") = 0.090 * 1e-5
+    "Third contants of the isotherm model";
+  constant Modelica.Units.SI.Temperature k4(min=-500) = -426.018
+    "Fourth contants of the isotherm model";
+
+  //
+  // Redeclare functions
+  //
+  redeclare final function extends calc_c
+    "Calculates temperature-dependent coefficients of the isotherm model"
+  algorithm
+    c[1] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=k1,
+      b=k2,
+      c=0,
+      d=1);
+    c[2] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=k3,
+      b=0,
+      c=0,
+      d=k4);
+  end calc_c;
+
+  redeclare final function extends calc_coefficients
+    "Calculates temperature-dependent coefficients and their the partial derivatives w.r.t. temperature"
+  algorithm
+    //
+    // Calculate coefficients
+    //
+    c[1] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+      T=T_adsorpt,
+      a=k1,
+      b=k2,
+      c=0,
+      d=1);
+    c[2] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+      T=T_adsorpt,
+      a=k3,
+      b=0,
+      c=0,
+      d=k4);
+
+    //
+    // Calculate partial derivatives of the coefficients w.r.t. temperature
+    //
+    dc_dT[1] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+      T=T_adsorpt,
+      a=k1,
+      b=k2,
+      c=0,
+      d=1);
+    dc_dT[2] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+      T=T_adsorpt,
+      a=k3,
+      b=0,
+      c=0,
+      d=k4);
+
+    //
+    // Calculate second-order partial derivatives of the coefficients w.r.t.
+    // temperature
+    //
+    ddc_dT_dT[1] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+      T=T_adsorpt,
+      a=k1,
+      b=k2,
+      c=0,
+      d=1);
+    ddc_dT_dT[2] :=
+      SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+      T=T_adsorpt,
+      a=k3,
+      b=0,
+      c=0,
+      d=k4);
+  end calc_coefficients;
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This partial package describes the adsorption equilibrium of the working pair 
+O<sub>2</sub> & Zeolith LiLSX using the Langmuir isotherm model according to Li 
+et al. (2011). Packages that inherit properties from this partial package may 
+redeclare the package <i>MediumSpecificFunctions</i>, the model <i>Sorbent</i>,
+and the constant <i>twoPhaseAdsorptive</i>.
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Li, L., and Yu, M., and Zi, Y., and Dang, Y., and Wu, Q., and Wang, Z., and Xu, Y., and Yan, H, and Dang, Y. (2021). A Thermodynamic Model for Pure and Binary Adsorption Equilibria of N<sub>2</sub> and O<sub>2</sub> on Lithium-Exchanged Low Silicon-to-Aluminum Ratio X Zeolite, Journal of Chemical & Engineering Data, 60:1032-1042. DOI: https://dx.doi.org/10.1021/acs.jced.0c00830.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeolithLiLSX_Langmuir_LiEtAl2021;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.order
new file mode 100644
index 0000000..bf326a6
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/ZeolithLiLSX_Langmuir_LiEtAl2021/package.order
@@ -0,0 +1,6 @@
+k1
+k2
+k3
+k4
+calc_c
+calc_coefficients
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/package.mo
new file mode 100644
index 0000000..5a855f0
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.PureComponents;
+package O2 "Package containing parametrizations for O2 as adsorptive"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for O<sub>2</sub> as adsorptive.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end O2;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/package.order
new file mode 100644
index 0000000..7ccdea9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/O2/package.order
@@ -0,0 +1 @@
+ZeolithLiLSX_Langmuir_LiEtAl2021
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/package.mo
new file mode 100644
index 0000000..702b8cf
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.WorkingPairs.Parametrizations;
+package PureComponents "Package containing parametrizations of pure component working pairs"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrized pure component working pair models. Check
+the package content to see for which adsorptives working pair models are
+already implemented.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PureComponents;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/package.order
new file mode 100644
index 0000000..1956989
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/PureComponents/package.order
@@ -0,0 +1,5 @@
+MediumSpecificFunctions
+CO2
+H2O
+N2
+O2
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_exponential1.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_exponential1.mo
new file mode 100644
index 0000000..348440b
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_exponential1.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities.Testers;
+model Test_exponential1
+  "Tester for the function 'exponential1' and all corresponding functions"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real a = 0.1
+    "First coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real b = 1
+    "Second coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real c = 0.001
+    "Third coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real d = 100
+    "Fourth coefficient"
+    annotation (Dialog(tab="General", group="General"));
+
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate derivatives numerically"
+    annotation (Dialog(tab="General", group="General"));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Temperature T(start=273.15, fixed=true)
+    "Temperature";
+
+  Real z
+    "Temperature-dependent coefficient";
+
+  Real dz_dT
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature";
+  Real dz_dT_num
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature
+    calculated numerically";
+
+  Real ddz_dT_dT
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature";
+  Real ddz_dT_dT_num
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature calculated numerically";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(T) = 1000/20
+    "Predecsriped slope of T";
+
+  //
+  // Calculation of coefficients and their partial derivatives
+  //
+  z = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+    T=T, a=a, b=b, c=c, d=d)
+    "Temperature-dependent coefficient";
+
+  dz_dT = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+    T=T, a=a, b=b, c=c, d=d)
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature";
+  dz_dT_num = (SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+    T=T+dT, a=a, b=b, c=c, d=d) -
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1(
+    T=T-dT, a=a, b=b, c=c, d=d)) / (2 * dT)
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature
+    calculated numerically";
+
+  ddz_dT_dT = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential1_dT_dT(
+    T=T, a=a, b=b, c=c, d=d)
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature";
+  ddz_dT_dT_num = (SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+    T=T+dT, a=a, b=b, c=c, d=d) -
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential1_dT(
+    T=T-dT, a=a, b=b, c=c, d=d)) / (2 * dT)
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature calculated numerically";
+
+  //
+  // Definition of assertions: Check numerical implementations
+  //
+  assert(abs(dz_dT-dz_dT_num) < 1e-6,
+    "Partial derivative of z w.r.t. temperature is not valied: Deviation (|" +
+    String(abs(dz_dT-dz_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(ddz_dT_dT-ddz_dT_dT_num) < 1e-6,
+    "Second-order partial derivative of z w.r.t. temperature is not valied: Deviation (|" +
+    String(abs(ddz_dT_dT-ddz_dT_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'exponential1' function and its partials derivatives 
+with resprect to temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>z_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_exponential1;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_exponential2.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_exponential2.mo
new file mode 100644
index 0000000..e134ef6
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_exponential2.mo
@@ -0,0 +1,128 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities.Testers;
+model Test_exponential2
+  "Tester for the function 'exponential2' and all corresponding functions"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real a = 10
+    "First coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real b = 1
+    "Second coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real c = 0.001
+    "Third coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real d = 100
+    "Fourth coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real f = 5
+    "Fivth coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real g = -0.1
+    "Sixth coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real h = 0.1
+    "Seventh coefficient"
+    annotation (Dialog(tab="General", group="General"));
+
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate derivatives numerically"
+    annotation (Dialog(tab="General", group="General"));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Temperature T(start=273.15, fixed=true)
+    "Temperature";
+
+  Real z
+    "Temperature-dependent coefficient";
+
+  Real dz_dT
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature";
+  Real dz_dT_num
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature
+    calculated numerically";
+
+  Real ddz_dT_dT
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature";
+  Real ddz_dT_dT_num
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature calculated numerically";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(T) = 1000/20
+    "Predecsriped slope of T";
+
+  //
+  // Calculation of coefficients and their partial derivatives
+  //
+  z = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential2(
+    T=T, a=a, b=b, c=c, d=d, f=f, g=g, h=h)
+    "Temperature-dependent coefficient";
+
+  dz_dT = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential2_dT(
+    T=T, a=a, b=b, c=c, d=d, f=f, g=g, h=h)
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature";
+  dz_dT_num = (SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential2(
+    T=T+dT, a=a, b=b, c=c, d=d, f=f, g=g, h=h) -
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential2(
+    T=T-dT, a=a, b=b, c=c, d=d, f=f, g=g, h=h)) / (2 * dT)
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature
+    calculated numerically";
+
+  ddz_dT_dT = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddexponential2_dT_dT(
+    T=T, a=a, b=b, c=c, d=d, f=f, g=g, h=h)
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature";
+  ddz_dT_dT_num = (SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential2_dT(
+    T=T+dT, a=a, b=b, c=c, d=d, f=f, g=g, h=h) -
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dexponential2_dT(
+    T=T-dT, a=a, b=b, c=c, d=d, f=f, g=g, h=h)) / (2 * dT)
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature calculated numerically";
+
+  //
+  // Definition of assertions: Check numerical implementations
+  //
+  assert(abs(dz_dT-dz_dT_num) < 1e-6,
+    "Partial derivative of z w.r.t. temperature is not valied: Deviation (|" +
+    String(abs(dz_dT-dz_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(ddz_dT_dT-ddz_dT_dT_num) < 1e-6,
+    "Second-order partial derivative of z w.r.t. temperature is not valied: Deviation (|" +
+    String(abs(ddz_dT_dT-ddz_dT_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'exponential2' function and its partials derivatives 
+with resprect to temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>z_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_exponential2;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_linear1.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_linear1.mo
new file mode 100644
index 0000000..9b259d8
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/Test_linear1.mo
@@ -0,0 +1,119 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities.Testers;
+model Test_linear1
+  "Tester for the function 'linear1' and all corresponding functions"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real a = 0.1
+    "First coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real b = 1
+    "Second coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real c = -5
+    "Third coefficient"
+    annotation (Dialog(tab="General", group="General"));
+  parameter Real d = -1
+    "Fourth coefficient"
+    annotation (Dialog(tab="General", group="General"));
+
+  parameter Modelica.Units.SI.TemperatureDifference dT = 1e-3
+    "Temperature difference used to calculate derivatives numerically"
+    annotation (Dialog(tab="General", group="General"));
+
+  //
+  // Definition of variables
+  //
+  Modelica.Units.SI.Temperature T(start=273.15, fixed=true)
+    "Temperature";
+
+  Real z
+    "Temperature-dependent coefficient";
+
+  Real dz_dT
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature";
+  Real dz_dT_num
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature
+    calculated numerically";
+
+  Real ddz_dT_dT
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature";
+  Real ddz_dT_dT_num
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature calculated numerically";
+
+equation
+  //
+  // Definition of derivatives
+  //
+  der(T) = 1000/20
+    "Predecsriped slope of T";
+
+  //
+  // Calculation of coefficients and their partial derivatives
+  //
+  z = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+    T=T, a=a, b=b, c=c, d=d)
+    "Temperature-dependent coefficient";
+
+  dz_dT = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+    T=T, a=a, b=b, c=c, d=d)
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature";
+  dz_dT_num = (SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+    T=T+dT, a=a, b=b, c=c, d=d) -
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1(
+    T=T-dT, a=a, b=b, c=c, d=d)) / (2 * dT)
+    "Partial derivative of temperature-dependent coefficient w.r.t. temperature
+    calculated numerically";
+
+  ddz_dT_dT = SorpLib.Media.WorkingPairs.Parametrizations.Utilities.ddlinear1_dT_dT(
+    T=T, a=a, b=b, c=c, d=d)
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature";
+  ddz_dT_dT_num = (SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+    T=T+dT, a=a, b=b, c=c, d=d) -
+    SorpLib.Media.WorkingPairs.Parametrizations.Utilities.dlinear1_dT(
+    T=T-dT, a=a, b=b, c=c, d=d)) / (2 * dT)
+    "Second-order partial derivative of temperature-dependent coefficient w.r.t. 
+    temperature calculated numerically";
+
+  //
+  // Definition of assertions: Check numerical implementations
+  //
+  assert(abs(dz_dT-dz_dT_num) < 1e-6,
+    "Partial derivative of z w.r.t. temperature is not valied: Deviation (|" +
+    String(abs(dz_dT-dz_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+  assert(abs(ddz_dT_dT-ddz_dT_dT_num) < 1e-6,
+    "Second-order partial derivative of z w.r.t. temperature is not valied: Deviation (|" +
+    String(abs(ddz_dT_dT-ddz_dT_dT_num)) +
+    "|) is greater than 1e-6!",
+    level = AssertionLevel.warning);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'linear1' function and its partials derivatives 
+with resprect to temperature.
+<br/><br/>
+To see the function behavior, plot the variables <i>z_i</i> over the time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s). 
+</p>
+</html>"));
+end Test_linear1;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/package.mo
new file mode 100644
index 0000000..5e069ad
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+package Testers "Models to test and varify utility functions"
+extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all utility functions. The test 
+models check the implementation and demonstrate the utility functions' general 
+applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/package.order
new file mode 100644
index 0000000..77b32f2
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/Testers/package.order
@@ -0,0 +1,3 @@
+Test_linear1
+Test_exponential1
+Test_exponential2
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddexponential1_dT_dT.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddexponential1_dT_dT.mo
new file mode 100644
index 0000000..193896c
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddexponential1_dT_dT.mo
@@ -0,0 +1,46 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function ddexponential1_dT_dT
+  "Second-order partial derivative of generalized exponential function 1 w.r.t. temperature"
+  extends BaseClasses.Partial_ddz_dT_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  ddz_dT_dT := (2 * a * d * exp(c * T + d / T + b)) / T^3 +
+    a * (c - d / T^2)^2 * exp(c * T + d / T + b)
+    "Second-order partial derivative of coefficient w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This function is the second-order partial derivative of the function 'exponential1' 
+with respect to the temperature. For full details of the original function 'exponential1,' 
+check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddexponential1_dT_dT;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddexponential2_dT_dT.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddexponential2_dT_dT.mo
new file mode 100644
index 0000000..376e827
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddexponential2_dT_dT.mo
@@ -0,0 +1,58 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function ddexponential2_dT_dT
+  "Second-order partial derivative of generalized exponential function 2 w.r.t. temperature"
+  extends BaseClasses.Partial_ddz_dT_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f
+    "Fivth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real g
+    "Sixth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real h
+    "Seventh parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  ddz_dT_dT := (a * (f^2 * T^2 * (g * T - 1)^2 * exp(2 * g * T) +
+    f * T * (T * (g^2 * h * T^3 - 2 * g * h * T^2 + 2 * h * T - 2 * b * g * T -
+    4 * d * g + 2 * b) + 4 * d) * exp(g * T) + 2 * b * h * T^3 + (6 * d * h + b^2) *
+    T^2 + 4 * b * d * T + 4 * d^2) * exp((T * (f * exp(g * T) + c * T + b) + d) /
+    (h * T^2))) / (h^2 * T^6)
+    "Second-order partial derivative of coefficient w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This function is the second-order partial derivative of the function 'exponential2' 
+with respect to the temperature. For full details of the original function 'exponential2,' 
+check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential2\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential2</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddexponential2_dT_dT;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddlinear1_dT_dT.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddlinear1_dT_dT.mo
new file mode 100644
index 0000000..35c6834
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/ddlinear1_dT_dT.mo
@@ -0,0 +1,46 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function ddlinear1_dT_dT
+  "Second-order partial derivative of generalized linear function 1 w.r.t. temperature"
+  extends BaseClasses.Partial_ddz_dT_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  ddz_dT_dT := (2 * c * d * (b * T + c / T + a) ^ (d - 1)) / T^3 +
+    (d - 1) * d * (b - c / T^2)^2 * (b * T + c / T + a) ^ (d - 2)
+    "Second-order partial derivative of coefficient w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This function is the second-order partial derivative of the function 'linear1' 
+with respect to the temperature. For full details of the original function 'linear1,' 
+check the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ddlinear1_dT_dT;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dexponential1_dT.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dexponential1_dT.mo
new file mode 100644
index 0000000..0c53134
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dexponential1_dT.mo
@@ -0,0 +1,45 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function dexponential1_dT
+  "Partial derivative of generalized exponential function 1 w.r.t. temperature"
+  extends BaseClasses.Partial_dz_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dz_dT := a * (c - d / T^2) * exp(c * T + d / T + b)
+    "Partial derivative of coefficient w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'exponential1' with respect 
+to the temperature. For full details of the original function 'exponential1,' check 
+the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential1</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dexponential1_dT;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dexponential2_dT.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dexponential2_dT.mo
new file mode 100644
index 0000000..a01d538
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dexponential2_dT.mo
@@ -0,0 +1,55 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function dexponential2_dT
+  "Partial derivative of generalized exponential function 2 w.r.t. temperature"
+  extends BaseClasses.Partial_dz_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f
+    "Fivth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real g
+    "Sixth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real h
+    "Seventh parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dz_dT := (a * (T * (f * (g * T - 1) * exp(g * T) - b) - 2 * d) *
+    exp((T * (f * exp(g * T) + c * T + b) + d) / (h * T^2))) / (h * T^3)
+    "Partial derivative of coefficient w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'exponential2' with respect 
+to the temperature. For full details of the original function 'exponential2,' check 
+the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential2\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities.exponential2</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dexponential2_dT;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dlinear1_dT.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dlinear1_dT.mo
new file mode 100644
index 0000000..794adc4
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/dlinear1_dT.mo
@@ -0,0 +1,45 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function dlinear1_dT
+  "Partial derivative of generalized linear function 1 w.r.t. temperature"
+  extends BaseClasses.Partial_dz_dT;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  dz_dT := d * (b - c / T^2) * (b * T + c / T + a) ^ (d - 1)
+    "Partial derivative of coefficient w.r.t. temperature";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This function is the partial derivative of the function 'linear1' with respect 
+to the temperature. For full details of the original function 'linear1,' check 
+the documentation of the function 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities.linear1</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end dlinear1_dT;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/exponential1.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/exponential1.mo
new file mode 100644
index 0000000..d0a46fa
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/exponential1.mo
@@ -0,0 +1,53 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function exponential1 "Generalized exponential function 1"
+  extends BaseClasses.Partial_z_T;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  z := a * exp(b + c * T + d / T)
+    "Coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This generalized exponential function calculates temperature-dependent isotherm 
+coefficients.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The generalized exponential function has the following form:
+</p>
+<pre>
+    z = a * <strong>exp</strong>(b + c * T + d / T);
+</pre>
+<p>
+where <i>a</i>, <i>b</i>, <i>c</i>, and <i>d</i> are the coefficients.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end exponential1;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/exponential2.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/exponential2.mo
new file mode 100644
index 0000000..ec47cb9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/exponential2.mo
@@ -0,0 +1,63 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function exponential2 "Generalized exponential function 2"
+  extends BaseClasses.Partial_z_T;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f
+    "Fivth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real g
+    "Sixth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real h
+    "Seventh parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  z := a * exp((b + c * T + d / T + f * exp(g * T)) / (h * T))
+    "Coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This generalized exponential function calculates temperature-dependent isotherm 
+coefficients.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The generalized exponential function has the following form:
+</p>
+<pre>
+    z = a * <strong>exp</strong>((b + c * T + d / T + f * <strong>exp</strong>(g * T)) / (h * T));
+</pre>
+<p>
+where <i>a</i>, <i>b</i>, <i>c</i>, <i>d</i>, <i>f</i>, <i>g</i>, and <i>h</i> 
+are the coefficients.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end exponential2;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/linear1.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/linear1.mo
new file mode 100644
index 0000000..8602b21
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/linear1.mo
@@ -0,0 +1,53 @@
+within SorpLib.Media.WorkingPairs.Parametrizations.Utilities;
+function linear1 "Generalized linear function 1"
+  extends BaseClasses.Partial_z_T;
+
+  //
+  // Definition of inputs
+  //
+  input Real a
+    "First parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real b
+    "Second parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real c
+    "Third parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real d
+    "Fourth parameter"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+algorithm
+  z :=(a + b*T + c/T)^d
+    "Coefficient";
+
+  //
+  // Annotations
+  //
+  annotation (Inline=true,
+  Documentation(info="<html>
+<p>
+This generalized linear function calculates temperature-dependent isotherm 
+coefficients.
+</p>
+
+<h4>Main equations</h4>
+<p>
+The generalized linear function has the following form:
+</p>
+<pre>
+    z = (a + b * T + c / T) ^ d;
+</pre>
+<p>
+where <i>a</i>, <i>b</i>, <i>c</i>, and <i>d</i> are the coefficients.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end linear1;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/package.mo
new file mode 100644
index 0000000..1c0ec8b
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.Parametrizations;
+package Utilities "Package containing utility functions used to parametrize working pairs"
+extends Modelica.Icons.UtilitiesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains utility functions used to parametrize working pair
+models. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Utilities;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/package.order
new file mode 100644
index 0000000..9105f11
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/Utilities/package.order
@@ -0,0 +1,10 @@
+linear1
+dlinear1_dT
+ddlinear1_dT_dT
+exponential1
+dexponential1_dT
+ddexponential1_dT_dT
+exponential2
+dexponential2_dT
+ddexponential2_dT_dT
+Testers
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/package.mo b/SorpLib/Media/WorkingPairs/Parametrizations/package.mo
new file mode 100644
index 0000000..dde0eef
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/package.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs;
+package Parametrizations "Parametrized working pair models without fixed media models"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parameterized working models. For this purpose, the interfaces 
+of the pure and multi-component working pair models are extended by the parameterization 
+of the isotherm model. Furthermore, the <i>MediumSpecificFunctions</i> package has been
+selected but can still be replaced. Note that this is a design decision to enable using 
+different Modelica libraries for the fluid property calculation, e.g., the open-source 
+Modelica Standard Library (MSL) or the commercial library TILMedia.
+</p>
+
+<h4>Structure</h4>
+<p>
+The package 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations.Utilities\">SorpLib.Media.WorkingPairs.Parametrizations.Utilities</a>
+contains auxiliary functions for calculating temperature-dependent coefficients of 
+the isotherm model. The <i>PureComponents</i> and <i>MultiComponents</i> packages 
+contain parameterized pure component or multi-component working pair models. In each 
+package, a separate package is provided for each available adsorptive or adsorptive 
+mixture, sorted alphabetically. The naming convention for the parameterized working 
+pair models is as follows
+</p>
+<pre>
+    NameSorbent_NameIsothermModel_NameAuthorsYear;
+</pre>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Parametrizations;
diff --git a/SorpLib/Media/WorkingPairs/Parametrizations/package.order b/SorpLib/Media/WorkingPairs/Parametrizations/package.order
new file mode 100644
index 0000000..5950ae1
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Parametrizations/package.order
@@ -0,0 +1,3 @@
+Utilities
+PureComponents
+MultiComponents
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..82c2293
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/CO2/ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
@@ -0,0 +1,46 @@
+within SorpLib.Media.WorkingPairs.PureComponents.CO2;
+model ActivatedCarbon_Toth_DantasEtAl2011_Gas
+  "CO2 & Activated carbon via the Toth isotherm model according to Dantas et al. (2011)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.CO2,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2.ActivatedCarbon_Toth_DantasEtAl2011
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent =
+      Solids.Sorbents.GenericSorbent (
+        v_constant=1/1138,
+        c_constant=880,
+        lambda_constant=0.075),
+    v_adsorpt_constant=1/990,
+    cp_adsorpt_constant=2.5e3,
+    h_ads_constant=496e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair CO<sub>2</sub> & activated carbon using the Toth isotherm model 
+according to Dantas et al. (2011).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Dantas, T.L.P. and Luna, F.M.T. and Silva Jr., I.J. and Azevedo, D.C.S. and Grande, C.A. and Rodrigues, A.E. and Moreira, R.F.P.M. (2011). Carbon dioxide–nitrogen separation through adsorption on activated carbon in a fixed bed, Chemical Engineering Journal, 169: 11–19. DOI: https://doi.org/10.1016/j.cej.2010.08.026.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ActivatedCarbon_Toth_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
new file mode 100644
index 0000000..bc19a91
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/CO2/SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
@@ -0,0 +1,43 @@
+within SorpLib.Media.WorkingPairs.PureComponents.CO2;
+model SilicaGel_Toth_WangDouglasLeVan2009_Gas
+  "CO2 & silica gel via the Toth isotherm model according to Wang and Douglas LeVan (2009)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.CO2,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2.SilicaGel_Toth_WangDouglasLeVan2009
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent =
+      Solids.Sorbents.RDSilicaGel,
+    v_adsorpt_constant=1/990,
+    cp_adsorpt_constant=2.5e3,
+    h_ads_constant=496e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair CO<sub>2</sub> & silica gel using the Toth isotherm model 
+according to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGel_Toth_WangDouglasLeVan2009_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..7166ccf
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo
@@ -0,0 +1,46 @@
+within SorpLib.Media.WorkingPairs.PureComponents.CO2;
+model Zeolith13X_Toth_DantasEtAl2011_Gas
+  "CO2 & Zeolith 13X via the Toth isotherm model according to Dantas et al. (2011)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.CO2,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2.Zeolith13X_Toth_DantasEtAl2011
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent =
+      Solids.Sorbents.GenericSorbent (
+        v_constant=1/1940,
+        c_constant=920,
+        lambda_constant=0.085),
+    v_adsorpt_constant=1/990,
+    cp_adsorpt_constant=2.5e3,
+    h_ads_constant=496e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair CO<sub>2</sub> & Zeolith 13X using the Toth isotherm model according 
+to Dantas et al. (2011).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Dantas, T.L.P. and Luna, F.M.T. and Silva Jr., I.J. and Torres, A.E.B. and Azevedo, D.C.S. and Rodrigues, A.E. and Moreira, R.F.P.M. (2011). Carbon dioxide–nitrogen separation through pressure swing adsorption, Chemical Engineering Journal, 172:698-704. DOI: https://doi.org/10.1016/j.cej.2011.06.037.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
new file mode 100644
index 0000000..790c4f4
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
@@ -0,0 +1,49 @@
+within SorpLib.Media.WorkingPairs.PureComponents.CO2;
+model Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+  "CO2 & Zeolith 13X via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.CO2,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2.Zeolith13X_Toth_WangDouglasLeVan2010
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent =
+      Solids.Sorbents.GenericSorbent (
+        v_constant=1/670,
+        c_constant=920,
+        lambda_constant=0.085),
+    v_adsorpt_constant=1/990,
+    cp_adsorpt_constant=2.5e3,
+    h_ads_constant=496e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair CO<sub>2</sub> & Zeolith 13X using the Toth isotherm model 
+according to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2010). Adsorption Equilibrium of Binary Mixtures of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X, Hournal of Chemical & Engineering Data, 55(9):3189–3195. DOI: https://doi.org/10.1021/je100053g.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_WangDouglasLeVan2010_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
new file mode 100644
index 0000000..7bab7f7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/CO2/Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
@@ -0,0 +1,49 @@
+within SorpLib.Media.WorkingPairs.PureComponents.CO2;
+model Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+  "CO2 & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.CO2,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2.Zeolith5A_Toth_WangDouglasLeVan2010
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent =
+      Solids.Sorbents.GenericSorbent (
+        v_constant=1/670,
+        c_constant=920,
+        lambda_constant=0.085),
+    v_adsorpt_constant=1/990,
+    cp_adsorpt_constant=2.5e3,
+    h_ads_constant=496e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair CO<sub>2</sub> & Zeolith 5A using the Toth isotherm model 
+according to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2010). Adsorption Equilibrium of Binary Mixtures of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X, Hournal of Chemical & Engineering Data, 55(9):3189–3195. DOI: https://doi.org/10.1021/je100053g.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith5A_Toth_WangDouglasLeVan2010_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/CO2/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/CO2/package.mo
new file mode 100644
index 0000000..218b2fc
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/CO2/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.PureComponents;
+package CO2 "Package containing parametrizations for CO2 as adsorptive"
+  extends Modelica.Icons.VariantsPackage;
+
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for CO<sub>2</sub> as adsorptive.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CO2;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/CO2/package.order b/SorpLib/Media/WorkingPairs/PureComponents/CO2/package.order
new file mode 100644
index 0000000..cc9361c
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/CO2/package.order
@@ -0,0 +1,5 @@
+ActivatedCarbon_Toth_DantasEtAl2011_Gas
+SilicaGel_Toth_WangDouglasLeVan2009_Gas
+Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+Zeolith13X_Toth_DantasEtAl2011_Gas
+Zeolith13X_Toth_WangDouglasLeVan2010_Gas
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
new file mode 100644
index 0000000..e83878b
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
@@ -0,0 +1,53 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+  "H2O & AQSOA-Z01 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & AQSOA-Z02 (FAM-Z02) using the Dubinin isotherm 
+model with a Lorentzian Cumulative characteristic curve generated by Bau (2017) 
+using measurement data from Goldsworthy (2014).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Goldsworthy (2014). Measurements of water vapour sorption isotherms for RD silica gel, AQSOA-Z01, AQSOA-Z02, AQSOA-Z05 and CECA zeolite 3A, Microporous and Mesoporous Materials, 196:59-67. DOI: http://dx.doi.org/10.1016/j.micromeso.2014.04.046.
+  </li>
+  <li>
+  Bau (2018). From Dynamic Simulation to Optimal Design and Control of Adsorption Energy Systems, PhD thesis. DOI: https://doi.org/10.18154/RWTH-2018-222524.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  December 14, 2020, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  November 17, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
new file mode 100644
index 0000000..1408df8
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
@@ -0,0 +1,53 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+  "H2O & AQSOA-Z02 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & AQSOA-Z02 (FAM-Z02) using the Dubinin isotherm 
+model with a Lorentzian Cumulative characteristic curve generated by Bau (2017) 
+using measurement data from Goldsworthy (2014).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Goldsworthy (2014). Measurements of water vapour sorption isotherms for RD silica gel, AQSOA-Z01, AQSOA-Z02, AQSOA-Z05 and CECA zeolite 3A, Microporous and Mesoporous Materials, 196:59-67. DOI: http://dx.doi.org/10.1016/j.micromeso.2014.04.046.
+  </li>
+  <li>
+  Bau (2018). From Dynamic Simulation to Optimal Design and Control of Adsorption Energy Systems, PhD thesis. DOI: https://doi.org/10.18154/RWTH-2018-222524.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  December 14, 2020, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  November 17, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
new file mode 100644
index 0000000..7cd8535
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
@@ -0,0 +1,53 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+  "H2O & AQSOA-Z05 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & AQSOA-Z05 (FAM-Z05) using the Dubinin isotherm 
+model with a Lorentzian Cumulative characteristic curve generated by Bau (2017) 
+using measurement data from Goldsworthy (2014).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Goldsworthy (2014). Measurements of water vapour sorption isotherms for RD silica gel, AQSOA-Z01, AQSOA-Z02, AQSOA-Z05 and CECA zeolite 3A, Microporous and Mesoporous Materials, 196:59-67. DOI: http://dx.doi.org/10.1016/j.micromeso.2014.04.046.
+  </li>
+  <li>
+  Bau (2018). From Dynamic Simulation to Optimal Design and Control of Adsorption Energy Systems, PhD thesis. DOI: https://doi.org/10.18154/RWTH-2018-222524.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  December 14, 2020, by Mirko Engelpracht:<br/>
+  Revision after restructering of the library.
+  </li>
+  <li>
+  November 17, 2017, by Uwe Bau:<br/>
+  Tidy up implementation and enhance documentation for publication of library.
+  </li>
+</ul>
+</html>"));
+end AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000_VLE.mo
new file mode 100644
index 0000000..db43dc9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/NaZeolithY_DubininEmpirical2_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model NaZeolithY_DubininEmpirical2_Schawe2000_VLE
+  "H2O & Na-Zeolith Y via the Dubinin isotherm model with an empirical 2 approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.NaZeolithY_DubininEmpirical2_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & Na-Zeolith Y using the Dubinin isotherm model 
+with an empirical 2 characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end NaZeolithY_DubininEmpirical2_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..1aef553
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE
+  "H2O & Silica gel 125 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGel125_DubininLorentzianCumulative_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel 125 using the Dubinin isotherm model 
+with a Lorentzian Cumulative characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..8f5f81f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE
+  "H2O & Silica gel AF-25 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGelAF25_DubininLorentzianCumulative_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel AF-25 using the Dubinin isotherm model 
+with a Lorentzian Cumulative characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..ebaa675
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE
+  "H2O & Silica gel Fuji via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGelFuji_DubininLorentzianCumulative_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel Fuji using the Dubinin isotherm model 
+with a Lorentzian Cumulative characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000_VLE.mo
new file mode 100644
index 0000000..7514915
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelH_DubininPearsonIV_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGelH_DubininPearsonIV_Schawe2000_VLE
+  "H2O & Silica gel H via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGelH_DubininPearsonIV_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel H using the Dubinin isotherm model 
+with a Pearson IV characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelH_DubininPearsonIV_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE.mo
new file mode 100644
index 0000000..687134f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE
+  "H2O & Silica gel LE-32 via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGelLE32_DubininPearsonIV_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel LE-32 using the Dubinin isotherm model 
+with a Pearson IV characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE.mo
new file mode 100644
index 0000000..d1b15b3
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE
+  "H2O & Silica gel NAC via the Dubinin isotherm model with an empircal 1 approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGelNAC_DubininEmpirical1_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel NAC using the Dubinin isotherm model 
+with an empirical 1 characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000_VLE.mo
new file mode 100644
index 0000000..54247f1
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelN_DubininPearsonIV_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGelN_DubininPearsonIV_Schawe2000_VLE
+  "H2O & Silica gel N via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGelN_DubininPearsonIV_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel N using the Dubinin isotherm model 
+with a Pearson IV characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelN_DubininPearsonIV_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..fcb9a0c
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE
+  "H2O & Silica gel WS via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGelWS_DubininLorentzianCumulative_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel WS using the Dubinin isotherm model 
+with a Lorentzian Cumulative characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
new file mode 100644
index 0000000..0a76159
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGel_Toth_WangDouglasLeVan2009_Gas
+  "H2O & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.H2O,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGel_Toth_WangDouglasLeVan2009
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel using the Toth isotherm model according 
+to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGel_Toth_WangDouglasLeVan2009_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo
new file mode 100644
index 0000000..9048d35
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model SilicaGel_Toth_WangDouglasLeVan2009_VLE
+  "H2O & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGel_Toth_WangDouglasLeVan2009
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel using the Toth isotherm model according 
+to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end SilicaGel_Toth_WangDouglasLeVan2009_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..8697483
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+  "H2O & Silica gel 123 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.SilicaGel123_DubininLorentzianCumulative_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & silica gel 123 using the Dubinin isotherm model 
+with a Lorentzian Cumulative characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo
new file mode 100644
index 0000000..b3b6e0c
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model Sizeo15_DubininPearsonIV_Schawe2000_VLE
+  "H2O & Sizeo 15 via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.Sizeo15_DubininPearsonIV_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & Sizeo 15 using the Dubinin isotherm model 
+with a Pearson IV characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Sizeo15_DubininPearsonIV_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000_VLE.mo
new file mode 100644
index 0000000..f68e5d8
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_DubininEmpirical2_Schawe2000_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model Zeolith13X_DubininEmpirical2_Schawe2000_VLE
+  "H2O & Zeolith 13X via the Dubinin isotherm model with an empircal 2 approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.Zeolith13X_DubininEmpirical2_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & Zeolith 13X using the Dubinin isotherm model 
+with an empirical 2 characteristic curve according to Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_DubininEmpirical2_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
new file mode 100644
index 0000000..bb594a1
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+  "H2O & Zeolith 13X via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.H2O,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & Zeolith 13X using the Toth isotherm model according 
+to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_WangDouglasLeVan2010_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010_VLE.mo
new file mode 100644
index 0000000..fa2fcbe
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith13X_Toth_WangDouglasLeVan2010_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model Zeolith13X_Toth_WangDouglasLeVan2010_VLE
+  "H2O & Zeolith 13X via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & Zeolith 13X using the Toth isotherm model according 
+to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_WangDouglasLeVan2010_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
new file mode 100644
index 0000000..5888020
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+  "H2O & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.H2O,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.Zeolith5A_Toth_WangDouglasLeVan2010
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & Zeolith 5A using the Toth isotherm model according 
+to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith5A_Toth_WangDouglasLeVan2010_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo
new file mode 100644
index 0000000..1bd7ddf
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model Zeolith5A_Toth_WangDouglasLeVan2010_VLE
+  "H2O & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.Zeolith5A_Toth_WangDouglasLeVan2010
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & Zeolith 5A using the Toth isotherm model according 
+to Wang and Douglas LeVan (2010).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Wang, Y. and Douglas LeVan, M. (2009). Adsorption Equilibrium of Carbon Dioxide and Water Vapor on Zeolites 5A and 13X and Silica Gel: Pure Components, Journal of Chemical & Engineering Data, 54:2839-2844. DOI: https://doi.org/10.1021/je800900a.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith5A_Toth_WangDouglasLeVan2010_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE.mo
new file mode 100644
index 0000000..803eaa9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE.mo
@@ -0,0 +1,42 @@
+within SorpLib.Media.WorkingPairs.PureComponents.H2O;
+model ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE
+  "H2O & Zeolith Type A via the Dubinin isotherm model with a Chebyshev Series rational order 3/3 approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE(
+    redeclare replaceable package Medium =
+      Modelica.Media.Water.StandardWater,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.H2O.Zeolith13X_DubininEmpirical2_Schawe2000
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.VLE
+            (
+          redeclare final package Medium = Medium)),
+    v_adsorpt_constant=1/947,
+    cp_adsorpt_constant=4.3e3,
+    h_ads_constant=2750e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair H<sub>2</sub>0 & Zeolith Type A using the Dubinin isotherm model 
+with a Chebyshev series rational order 3/3 characteristic curve according to 
+Schawe (2000).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Schawe (2000). Theoretical and Experimental Investigations of an Adsorption Heat Pump with Heat Transfer between two Adsorbers, PhD thesis. DOI: http://dx.doi.org/10.18419/opus-1518.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/H2O/package.mo
new file mode 100644
index 0000000..8e87de5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.PureComponents;
+package H2O "Package containing internal models used just for testing purposes"
+extends Modelica.Icons.VariantsPackage;
+
+
+annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for H<sub>2</sub>O as adsorptive.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end H2O;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/H2O/package.order b/SorpLib/Media/WorkingPairs/PureComponents/H2O/package.order
new file mode 100644
index 0000000..a83cc71
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/H2O/package.order
@@ -0,0 +1,22 @@
+AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+NaZeolithY_DubininEmpirical2_Schawe2000_VLE
+SilicaGel_Toth_WangDouglasLeVan2009_Gas
+SilicaGel_Toth_WangDouglasLeVan2009_VLE
+Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE
+SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE
+SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE
+SilicaGelH_DubininPearsonIV_Schawe2000_VLE
+SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE
+SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE
+SilicaGelN_DubininPearsonIV_Schawe2000_VLE
+SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE
+Sizeo15_DubininPearsonIV_Schawe2000_VLE
+Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+Zeolith5A_Toth_WangDouglasLeVan2010_VLE
+Zeolith13X_DubininEmpirical2_Schawe2000_VLE
+Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+Zeolith13X_Toth_WangDouglasLeVan2010_VLE
+ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..d1d4055
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/N2/ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
@@ -0,0 +1,46 @@
+within SorpLib.Media.WorkingPairs.PureComponents.N2;
+model ActivatedCarbon_Toth_DantasEtAl2011_Gas
+  "N2 & Activated carbon via the Toth isotherm model according to Dantas et al. (2011)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.N2,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.N2.ActivatedCarbon_Toth_DantasEtAl2011
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent =
+      Solids.Sorbents.GenericSorbent (
+        v_constant=1/1138,
+        c_constant=880,
+        lambda_constant=0.075),
+    v_adsorpt_constant=1/730,
+    cp_adsorpt_constant=2.4e3,
+    h_ads_constant=582e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair N<sub>2</sub> & activated carbon using the Toth isotherm model 
+according to Dantas et al. (2011).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Dantas, T.L.P. and Luna, F.M.T. and Silva Jr., I.J. and Azevedo, D.C.S. and Grande, C.A. and Rodrigues, A.E. and Moreira, R.F.P.M. (2011). Carbon dioxide–nitrogen separation through adsorption on activated carbon in a fixed bed, Chemical Engineering Journal, 169: 11–19. DOI: https://doi.org/10.1016/j.cej.2010.08.026.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ActivatedCarbon_Toth_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..6c569c2
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/N2/Zeolith13X_Toth_DantasEtAl2011_Gas.mo
@@ -0,0 +1,46 @@
+within SorpLib.Media.WorkingPairs.PureComponents.N2;
+model Zeolith13X_Toth_DantasEtAl2011_Gas
+  "N2 & Zeolith 13X via the Toth isotherm model according to Dantas et al. (2011)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.N2,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.N2.Zeolith13X_Toth_DantasEtAl2011
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent =
+      Solids.Sorbents.GenericSorbent (
+        v_constant=1/1940,
+        c_constant=920,
+        lambda_constant=0.085),
+    v_adsorpt_constant=1/730,
+    cp_adsorpt_constant=2.4e3,
+    h_ads_constant=582e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair N<sub>2</sub> & Zeolith 13X using the Toth isotherm model according 
+to Dantas et al. (2011).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Dantas, T.L.P. and Luna, F.M.T. and Silva Jr., I.J. and Torres, A.E.B. and Azevedo, D.C.S. and Rodrigues, A.E. and Moreira, R.F.P.M. (2011). Carbon dioxide–nitrogen separation through pressure swing adsorption, Chemical Engineering Journal, 172:698-704. DOI: https://doi.org/10.1016/j.cej.2011.06.037.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Zeolith13X_Toth_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/N2/ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/N2/ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..9bd6776
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/N2/ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
@@ -0,0 +1,45 @@
+within SorpLib.Media.WorkingPairs.PureComponents.N2;
+model ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
+  "N2 & Zeolith LiLSX via the Langmuir isotherm model according to Li et al. (2021)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.N2,
+    redeclare final package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.N2.ZeolithLiLSX_Langmuir_LiEtAl2021
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent = Solids.Sorbents.GenericSorbent (
+      v_constant=1/1940,
+      c_constant=920,
+      lambda_constant=0.085),
+    v_adsorpt_constant=1/730,
+    cp_adsorpt_constant=2.4e3,
+    h_ads_constant=582e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair N<sub>2</sub> & Zeolith LiLSX using the Langmuir isotherm model according 
+to Li et al. (2011).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Li, L., and Yu, M., and Zi, Y., and Dang, Y., and Wu, Q., and Wang, Z., and Xu, Y., and Yan, H, and Dang, Y. (2021). A Thermodynamic Model for Pure and Binary Adsorption Equilibria of N<sub>2</sub> and O<sub>2</sub> on Lithium-Exchanged Low Silicon-to-Aluminum Ratio X Zeolite, Journal of Chemical & Engineering Data, 60:1032-1042. DOI: https://dx.doi.org/10.1021/acs.jced.0c00830.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/N2/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/N2/package.mo
new file mode 100644
index 0000000..66e5698
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/N2/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Media.WorkingPairs.PureComponents;
+package N2 "Package containing parametrizations for N2 as adsorptive"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for N<sub>2</sub> as adsorptive.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end N2;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/N2/package.order b/SorpLib/Media/WorkingPairs/PureComponents/N2/package.order
new file mode 100644
index 0000000..c6943f7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/N2/package.order
@@ -0,0 +1,3 @@
+ActivatedCarbon_Toth_DantasEtAl2011_Gas
+Zeolith13X_Toth_DantasEtAl2011_Gas
+ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/O2/ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/O2/ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..153b91e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/O2/ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
@@ -0,0 +1,45 @@
+within SorpLib.Media.WorkingPairs.PureComponents.O2;
+model ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
+  "O2 & Zeolith LiLSX via the Langmuir isotherm model according to Li et al. (2021)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas(
+    redeclare replaceable package Medium =
+      SorpLib.Media.IdealGases.O2,
+    redeclare final package WorkingPair =
+        SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.O2.ZeolithLiLSX_Langmuir_LiEtAl2021
+        (redeclare final package MediumSpecificFunctions =
+          SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.MediumSpecificFunctions.Gas
+            (
+          redeclare final package Medium = Medium)),
+    redeclare replaceable model Sorbent = Solids.Sorbents.GenericSorbent (
+        v_constant=1/1940,
+        c_constant=920,
+        lambda_constant=0.085),
+    v_adsorpt_constant=1/2200,
+    cp_adsorpt_constant=1e3,
+    h_ads_constant=250e3);
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the adsorption equilibrium and thermodynamic properties of 
+the working pair O<sub>2</sub> & Zeolith LiLSX using the Langmuir isotherm model according 
+to Li et al. (2011).
+</p>
+
+<h4>References</h4>
+<ul>
+  <li>
+  Li, L., and Yu, M., and Zi, Y., and Dang, Y., and Wu, Q., and Wang, Z., and Xu, Y., and Yan, H, and Dang, Y. (2021). A Thermodynamic Model for Pure and Binary Adsorption Equilibria of N<sub>2</sub> and O<sub>2</sub> on Lithium-Exchanged Low Silicon-to-Aluminum Ratio X Zeolite, Journal of Chemical & Engineering Data, 60:1032-1042. DOI: https://dx.doi.org/10.1021/acs.jced.0c00830.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/O2/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/O2/package.mo
new file mode 100644
index 0000000..5b5919f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/O2/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Media.WorkingPairs.PureComponents;
+package O2 "Package containing parametrizations for O2 as adsorptive"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains parametrizations for O<sub>2</sub> as adsorptive.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end O2;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/O2/package.order b/SorpLib/Media/WorkingPairs/PureComponents/O2/package.order
new file mode 100644
index 0000000..478957a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/O2/package.order
@@ -0,0 +1 @@
+ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..51dee56
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
@@ -0,0 +1,34 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.CO2;
+model Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas
+  "Tester for the working pair CO2 & Activated carbon via the Toth isotherm model according to Dantas et al. (2011)"
+  extends
+    SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+      stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+      T_adsorpt_der=0,
+      p_adsorpt_der=(3e5-1)/20,
+      T_adsorpt_start=301,
+      p_adsorpt_start=1,
+      redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.CO2.ActivatedCarbon_Toth_DantasEtAl2011_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This tester shows the behavior of the working pair CO<sub>2</sub> & activated 
+carbon using the Toth isotherm model according to Dantas et al. (2011).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_SilicaGel_Toth_WangDouglasLeVan2010.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_SilicaGel_Toth_WangDouglasLeVan2010.mo
new file mode 100644
index 0000000..9a4079a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_SilicaGel_Toth_WangDouglasLeVan2010.mo
@@ -0,0 +1,36 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.CO2;
+model Test_SilicaGel_Toth_WangDouglasLeVan2010
+  "Tester for the working pair CO2 & silica gel via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+      stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+      T_adsorpt_der=0,
+      p_adsorpt_der=(1e5-1)/20,
+      T_adsorpt_start=283.15,
+      p_adsorpt_start=1,
+      redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.CO2.SilicaGel_Toth_WangDouglasLeVan2009_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  CO<sub>2</sub> & silica gel 
+using the Toth isotherm model according to Wang and Douglas LeVan (2009, 2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGel_Toth_WangDouglasLeVan2010;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..81d14f0
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo
@@ -0,0 +1,33 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.CO2;
+model Test_Zeolith13X_Toth_DantasEtAl2011_Gas
+  "Tester for the working pair CO2 & Zeolith 13X via the Toth isotherm model according to Dantas et al. (2011)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+      stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+      T_adsorpt_der=0,
+      p_adsorpt_der=(5e5-1)/20,
+      T_adsorpt_start=273.15+28,
+      p_adsorpt_start=1,
+      redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.CO2.Zeolith13X_Toth_DantasEtAl2011_Gas
+        (    approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This tester shows the behavior of the working pair CO<sub>2</sub> & Zeolith 13X
+using the Toth isotherm model according to Dantas et al. (2011).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_Zeolith13X_Toth_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
new file mode 100644
index 0000000..d8a825c
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
@@ -0,0 +1,36 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.CO2;
+model Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+  "Tester for the working pair CO2 & Zeolith 13X via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+      stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+      T_adsorpt_der=0,
+      p_adsorpt_der=(1e5-1)/20,
+      T_adsorpt_start=273.15-45,
+      p_adsorpt_start=1,
+      redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.CO2.Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  CO<sub>2</sub> & Zeolith 13X 
+using the Toth isotherm model according to Wang and Douglas LeVan (2009, 2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
new file mode 100644
index 0000000..96a4f3a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.CO2;
+model Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+  "Tester for the working pair CO2 & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends
+    SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+      stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+      T_adsorpt_der=0,
+      p_adsorpt_der=(1e5-1)/20,
+      T_adsorpt_start=273.15-45,
+      p_adsorpt_start=1,
+      redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.CO2.Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  CO<sub>2</sub> & Zeolith 5A 
+using the Toth isotherm model according to Wang and Douglas LeVan (2009, 2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/package.mo
new file mode 100644
index 0000000..2bcd0ad
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers;
+package CO2 "Model to test and varify working pair models that use CO2 as adsorptive"
+extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented working pair models
+using CO<sub>2</sub> as adsorptive. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end CO2;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/package.order b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/package.order
new file mode 100644
index 0000000..cfaa6dd
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/CO2/package.order
@@ -0,0 +1,5 @@
+Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas
+Test_SilicaGel_Toth_WangDouglasLeVan2010
+Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+Test_Zeolith13X_Toth_DantasEtAl2011_Gas
+Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
new file mode 100644
index 0000000..04a3109
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
@@ -0,0 +1,38 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+  "Tester for the working pair H2O & AQSOA-Z01 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-615)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=615,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+        (approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & AQSOA-Z01 
+(FAM-Z01) using the Dubinin isotherm model with a Lorentzian Cumulative 
+characteristic curve generated by Bau (2017) using measurement data from
+Goldsworthy (2014).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
new file mode 100644
index 0000000..81969f7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
@@ -0,0 +1,44 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+  "Tester for the working pair H2O & AQSOA-Z02 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=1,
+    p_adsorpt_der=(1e5-615)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=615,
+    redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.H2O.AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+        (
+        redeclare model Sorbent = SorpLib.Media.Solids.Sorbents.RDSilicaGel (
+          approach_c=SorpLib.Choices.SpecificHeatCapacitySolid.Constant),
+        calcAdsorptAdsorbateState=false,
+        approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Dubinin,
+        approachSpecificHeatCapacity=SorpLib.Choices.SpecificHeatCapacityAdsorpt.BoilingCurve,
+        approachSpecificVolume=SorpLib.Choices.SpecificVolumeAdsorpt.BoilingCurve));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & AQSOA-Z02 
+(FAM-Z02) using the Dubinin isotherm model with a Lorentzian Cumulative 
+characteristic curve generated by Bau (2017) using measurement data from
+Goldsworthy (2014).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
new file mode 100644
index 0000000..e27d8d8
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE.mo
@@ -0,0 +1,38 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+  "Tester for the working pair H2O & AQSOA-Z05 via the Dubinin isotherm model with a Lorentzian Cumulative according to measurment data from Goldsworty (2014) and fit from Bau (2017)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-615)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=615,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & AQSOA-Z05 
+(FAM-Z05) using the Dubinin isotherm model with a Lorentzian Cumulative 
+characteristic curve generated by Bau (2017) using measurement data from
+Goldsworthy (2014).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_NaZeolithY_DubininEmpirical2_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_NaZeolithY_DubininEmpirical2_Schawe2000_VLE.mo
new file mode 100644
index 0000000..fd1c931
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_NaZeolithY_DubininEmpirical2_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_NaZeolithY_DubininEmpirical2_Schawe2000_VLE
+  "Tester for the working pair H2O & Na-Zeolith Y via the Dubinin isotherm model with an empirical 2 approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.NaZeolithY_DubininEmpirical2_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & Na-Zeolith Y 
+using the Dubinin isotherm model with an empirical 2 characteristic curve according 
+to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_NaZeolithY_DubininEmpirical2_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..aa083a7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel 125 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel 125 
+using the Dubinin isotherm model with a Lorentzian Cumulative characteristic curve 
+according to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..f696fd9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel AF-25 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel AF-25 
+using the Dubinin isotherm model with a Lorentzian Cumulative characteristic curve 
+according to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..4942321
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel Fuji via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel Fuji 
+using the Dubinin isotherm model with a Lorentzian Cumulative characteristic curve 
+according to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelH_DubininPearsonIV_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelH_DubininPearsonIV_Schawe2000_VLE.mo
new file mode 100644
index 0000000..0f23894
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelH_DubininPearsonIV_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGelH_DubininPearsonIV_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel H via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGelH_DubininPearsonIV_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel H 
+using the Dubinin isotherm model with a Pearson IV characteristic curve according 
+to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGelH_DubininPearsonIV_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE.mo
new file mode 100644
index 0000000..832d14e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel LE-32 via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel LE-32 
+using the Dubinin isotherm model with a Pearson IV characteristic curve according 
+to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE.mo
new file mode 100644
index 0000000..2e5a87e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel NAC via the Dubinin isotherm model with an empircal 1 approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel NAC 
+using the Dubinin isotherm model with an empirical 1 characteristic curve according 
+to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelN_DubininPearsonIV_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelN_DubininPearsonIV_Schawe2000_VLE.mo
new file mode 100644
index 0000000..a0caf0a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelN_DubininPearsonIV_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGelN_DubininPearsonIV_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel N via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.9e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGelN_DubininPearsonIV_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel N
+using the Dubinin isotherm model with a Pearson IV characteristic curve according 
+to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGelN_DubininPearsonIV_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..73483b6
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel WS via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.9e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGelN_DubininPearsonIV_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel WS 
+using the Dubinin isotherm model with a Lorentzian Cumulative characteristic curve 
+according to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
new file mode 100644
index 0000000..1f94349
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel_Toth_WangDouglasLeVan2009_Gas.mo
@@ -0,0 +1,36 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGel_Toth_WangDouglasLeVan2009_Gas
+  "Tester for the working pair H2O & silica gel via the Toth isotherm model according to Wang and Douglas LeVan (2009)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.1e5-615)/20,
+    T_adsorpt_start=348.15,
+    p_adsorpt_start=615,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGel_Toth_WangDouglasLeVan2009_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel 
+using the Toth isotherm model according to Wang and Douglas LeVan (2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGel_Toth_WangDouglasLeVan2009_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo
new file mode 100644
index 0000000..e695ef9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_SilicaGel_Toth_WangDouglasLeVan2009_VLE.mo
@@ -0,0 +1,36 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_SilicaGel_Toth_WangDouglasLeVan2009_VLE
+  "Tester for the working pair H2O & silica gel via the Toth isotherm model according to Wang and Douglas LeVan (2009)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.1e5-615)/20,
+    T_adsorpt_start=348.15,
+    p_adsorpt_start=615,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.SilicaGel_Toth_WangDouglasLeVan2009_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel 
+using the Toth isotherm model according to Wang and Douglas LeVan (2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_SilicaGel_Toth_WangDouglasLeVan2009_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE.mo
new file mode 100644
index 0000000..8ad1d5e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE.mo
@@ -0,0 +1,38 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+  "Tester for the working pair H2O & Silica gel 123 via the Dubinin isotherm model with a Lorentzian Cumulative approach according to Schawe (2000)"
+  extends
+    SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+      redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.H2O.Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & silica gel 
+123 using the Dubinin isotherm model with a Lorentzian Cumulative characteristic 
+curve according to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo
new file mode 100644
index 0000000..940c2d7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Sizeo15_DubininPearsonIV_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_Sizeo15_DubininPearsonIV_Schawe2000_VLE
+  "Tester for the working pair H2O & Sizeo 15 via the Dubinin isotherm model with a Pearson IV approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.9e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Sizeo15_DubininPearsonIV_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & Sizeo 15 using 
+the Dubinin isotherm model with a Pearson IV characteristic curve according to 
+Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Sizeo15_DubininPearsonIV_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_DubininEmpirical2_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_DubininEmpirical2_Schawe2000_VLE.mo
new file mode 100644
index 0000000..b4463dc
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_DubininEmpirical2_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_Zeolith13X_DubininEmpirical2_Schawe2000_VLE
+  "Tester for the working pair H2O & Zeolith 13X via the Dubinin isotherm model with an empircal 2 approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Zeolith13X_DubininEmpirical2_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & Zeolith 13X 
+using the Dubinin isotherm model with an empirical 2 characteristic curve according 
+to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Zeolith13X_DubininEmpirical2_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
new file mode 100644
index 0000000..281d526
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas.mo
@@ -0,0 +1,36 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+  "Tester for the working pair H2O & Zeolith 13X via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & Zeolith 13X 
+using the Toth isotherm model according to Wang and Douglas LeVan (2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_Toth_WangDouglasLeVan2010_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_Toth_WangDouglasLeVan2010_VLE.mo
new file mode 100644
index 0000000..646e0e0
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith13X_Toth_WangDouglasLeVan2010_VLE.mo
@@ -0,0 +1,36 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_Zeolith13X_Toth_WangDouglasLeVan2010_VLE
+  "Tester for the working pair H2O & Zeolith 13X via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Zeolith13X_Toth_WangDouglasLeVan2010_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & Zeolith 13X 
+using the Toth isotherm model according to Wang and Douglas LeVan (2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Zeolith13X_Toth_WangDouglasLeVan2010_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
new file mode 100644
index 0000000..ab50c5e
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas.mo
@@ -0,0 +1,36 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+  "Tester for the working pair H2O & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & Zeolith 5A 
+using the Toth isotherm model according to Wang and Douglas LeVan (2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo
new file mode 100644
index 0000000..586e65f
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_Zeolith5A_Toth_WangDouglasLeVan2010_VLE.mo
@@ -0,0 +1,36 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_Zeolith5A_Toth_WangDouglasLeVan2010_VLE
+  "Tester for the working pair H2O & Zeolith 5A via the Toth isotherm model according to Wang and Douglas LeVan (2010)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(0.1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.Zeolith5A_Toth_WangDouglasLeVan2010_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & Zeolith 5A 
+using the Toth isotherm model according to Wang and Douglas LeVan (2010).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_Zeolith5A_Toth_WangDouglasLeVan2010_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE.mo
new file mode 100644
index 0000000..3f964fe
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/Test_ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE.mo
@@ -0,0 +1,37 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.H2O;
+model Test_ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE
+  "Tester for the working pair H2O & Zeolith Type A via the Dubinin isotherm model with a Chebyshev Series rational order 3/3 approach according to Schawe (2000)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairVLE(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(1e5-1000)/20,
+    T_adsorpt_start=373.15,
+    p_adsorpt_start=1000,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.H2O.ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  November 21, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the working pair  H<sub>2</sub>0 & Zeolith Type A 
+using the Dubinin isotherm model with a Chebyshev series rational order 3/3 
+characteristic curve according to Schawe (2000).
+<br/><br/>
+As an example, this tester increases the uptake and temperature with time. The 
+simulation time is correctly preset (Start: 0 s, Stop = 20 s).
+</p>
+</html>"));
+end Test_ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/package.mo
new file mode 100644
index 0000000..4ac8975
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers;
+package H2O "Model to test and varify working pair models that use H2O as adsorptive"
+extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented working pair models
+using H<sub>2</sub> as adsorptive. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end H2O;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/package.order b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/package.order
new file mode 100644
index 0000000..8cc90e5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/H2O/package.order
@@ -0,0 +1,22 @@
+Test_AQSOAZ01_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+Test_AQSOAZ02_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+Test_AQSOAZ05_DubininLorentzianCumulative_Goldsworthy2014_Bau2017_VLE
+Test_NaZeolithY_DubininEmpirical2_Schawe2000_VLE
+Test_SilicaGel_Toth_WangDouglasLeVan2009_Gas
+Test_SilicaGel_Toth_WangDouglasLeVan2009_VLE
+Test_Silicagel123_DubininLorentzianCumulative_Schawe2000_VLE
+Test_SilicaGelAF25_DubininLorentzianCumulative_Schawe2000_VLE
+Test_SilicaGel125_DubininLorentzianCumulative_Schawe2000_VLE
+Test_SilicaGelFuji_DubininLorentzianCumulative_Schawe2000_VLE
+Test_SilicaGelH_DubininPearsonIV_Schawe2000_VLE
+Test_SilicaGelLE32_DubininPearsonIV_Schawe2000_VLE
+Test_SilicaGelNAC_DubininEmpirical1_Schawe2000_VLE
+Test_SilicaGelN_DubininPearsonIV_Schawe2000_VLE
+Test_SilicaGelWS_DubininLorentzianCumulative_Schawe2000_VLE
+Test_Sizeo15_DubininPearsonIV_Schawe2000_VLE
+Test_Zeolith5A_Toth_WangDouglasLeVan2010_Gas
+Test_Zeolith5A_Toth_WangDouglasLeVan2010_VLE
+Test_Zeolith13X_DubininEmpirical2_Schawe2000_VLE
+Test_Zeolith13X_Toth_WangDouglasLeVan2010_Gas
+Test_Zeolith13X_Toth_WangDouglasLeVan2010_VLE
+Test_ZeolithTypeA_DubininChebyshevSeries33_Schawe2000_VLE
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..00a1d82
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas.mo
@@ -0,0 +1,34 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.N2;
+model Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas
+  "Tester for the working pair N2 & Activated carbon via the Toth isotherm model according to Dantas et al. (2011)"
+  extends
+    SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(5e5-1)/20,
+    T_adsorpt_start=323.15,
+    p_adsorpt_start=1,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.N2.ActivatedCarbon_Toth_DantasEtAl2011_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This tester shows the behavior of the working pair N<sub>2</sub> & activated 
+carbon using the Toth isotherm model according to Dantas et al. (2011).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..e3f5cc1
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_Zeolith13X_Toth_DantasEtAl2011_Gas.mo
@@ -0,0 +1,34 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.N2;
+model Test_Zeolith13X_Toth_DantasEtAl2011_Gas
+  "Tester for the working pair N2 & Zeolith 13X via the Toth isotherm model according to Dantas et al. (2011)"
+  extends
+    SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+      stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+      T_adsorpt_der=0,
+      p_adsorpt_der=(5e5-1)/20,
+      T_adsorpt_start=323.15,
+      p_adsorpt_start=1,
+    redeclare final model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.N2.Zeolith13X_Toth_DantasEtAl2011_Gas
+        (  approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This tester shows the behavior of the working pair N<sub>2</sub> & Zeolith 13X
+using the Toth isotherm model according to Dantas et al. (2011).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_Zeolith13X_Toth_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..908f91d
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
@@ -0,0 +1,33 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.N2;
+model Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
+  "Tester for the working pair N2 & Zeolith LiLSX via the Langmuir isotherm model according to Li et al. (2021)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(7e5 - 1)/20,
+    T_adsorpt_start=293.15,
+    p_adsorpt_start=1,
+    redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.N2.ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
+        (approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This tester shows the behavior of the working pair N<sub>2</sub> & Zeolith LiLSX
+using the Langmuir isotherm model according to Dantas et al. (2011).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/package.mo
new file mode 100644
index 0000000..d68f0c5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers;
+package N2 "Model to test and varify working pair models that use N2 as adsorptive"
+extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented working pair models
+using N<sub>2</sub> as adsorptive. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end N2;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/package.order b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/package.order
new file mode 100644
index 0000000..aa6bcb9
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/N2/package.order
@@ -0,0 +1,3 @@
+Test_ActivatedCarbon_Toth_DantasEtAl2011_Gas
+Test_Zeolith13X_Toth_DantasEtAl2011_Gas
+Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
new file mode 100644
index 0000000..57dd6df
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas.mo
@@ -0,0 +1,33 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers.O2;
+model Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
+  "Tester for the working pair O2 & Zeolith LiLSX via the Langmuir isotherm model according to Li et al. (2021)"
+  extends SorpLib.Media.WorkingPairs.PureComponents.Testers.TestWorkingPairGas(
+    stateVariables=SorpLib.Choices.IndependentVariablesPureComponentWorkingPair.pT,
+    T_adsorpt_der=0,
+    p_adsorpt_der=(7e5 - 1)/20,
+    T_adsorpt_start=293.15,
+    p_adsorpt_start=1,
+    redeclare final model PureWorkingPairModel =
+        SorpLib.Media.WorkingPairs.PureComponents.O2.ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
+        (approachSorptionEnthalpy=SorpLib.Choices.SorptionEnthalpy.Formal));
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This tester shows the behavior of the working pair N<sub>2</sub> & Zeolith LiLSX
+using the Toth isotherm model according to Dantas et al. (2011).
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/package.mo
new file mode 100644
index 0000000..88a77cb
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers;
+package O2 "Model to test and varify working pair models that use O2 as adsorptive"
+extends Modelica.Icons.ExamplesPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented working pair models
+using O<sub>2</sub> as adsorptive. 
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end O2;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/package.order b/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/package.order
new file mode 100644
index 0000000..70e3016
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/O2/package.order
@@ -0,0 +1 @@
+Test_ZeolithLiLSX_Langmuir_DantasEtAl2011_Gas
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/TestWorkingPairGas.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/TestWorkingPairGas.mo
new file mode 100644
index 0000000..7415eff
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/TestWorkingPairGas.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers;
+model TestWorkingPairGas
+  "Tester for working pair models using a fluid with just one regime (i.e., gas/vapor) based on the MSL"
+  extends SorpLib.Media.WorkingPairs.BaseClasses.PartialPureTest(
+    redeclare replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas
+      constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairGas);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model is the basic model for all testers of working pair models describing 
+adsorption of pure components and using a medium model of a fluid with just one 
+regime (i.e., gas/vapor) based on the Modelica Standard Library.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TestWorkingPairGas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/TestWorkingPairVLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/TestWorkingPairVLE.mo
new file mode 100644
index 0000000..3fa3927
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/TestWorkingPairVLE.mo
@@ -0,0 +1,29 @@
+within SorpLib.Media.WorkingPairs.PureComponents.Testers;
+model TestWorkingPairVLE
+  "Tester for working pair models using a real fluid with a two-phase regime based on the MSL"
+  extends SorpLib.Media.WorkingPairs.BaseClasses.PartialPureTest(
+    redeclare replaceable model PureWorkingPairModel =
+      SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE
+      constrainedby SorpLib.Media.WorkingPairs.PureComponents.WorkingPairVLE);
+
+  //
+  // Annotations
+  //
+  annotation (experiment(
+      StopTime=20,
+      Tolerance=1e-06),
+Documentation(info="<html>
+<p>
+This model is the basic model for all testers of working pair models describing 
+adsorption of pure components and using a medium model of a fluid with a two-phase 
+regime based on the Modelica Standard Library.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end TestWorkingPairVLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/Testers/package.mo
new file mode 100644
index 0000000..c199c03
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/package.mo
@@ -0,0 +1,19 @@
+within SorpLib.Media.WorkingPairs.PureComponents;
+package Testers "Models to test and varify models of pure component working pairs"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all implemented working pair model. 
+Each working pair model has its own test model that is saved in the correct adsorptive
+package.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/Testers/package.order b/SorpLib/Media/WorkingPairs/PureComponents/Testers/package.order
new file mode 100644
index 0000000..5e28fc5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/Testers/package.order
@@ -0,0 +1,6 @@
+CO2
+H2O
+N2
+O2
+TestWorkingPairGas
+TestWorkingPairVLE
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/WorkingPairGas.mo b/SorpLib/Media/WorkingPairs/PureComponents/WorkingPairGas.mo
new file mode 100644
index 0000000..5ee3251
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/WorkingPairGas.mo
@@ -0,0 +1,41 @@
+within SorpLib.Media.WorkingPairs.PureComponents;
+model WorkingPairGas
+  "Model of a pure working pair using the MSL for fluid property data calculation of a fluid with just one-regime (i.e., gas/vapor)"
+
+  //
+  // Definition of replaceable medium
+  //
+  replaceable package Medium = SorpLib.Media.IdealGases.CO2
+    constrainedby Modelica.Media.IdealGases.Common.SingleGasNasa
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Working Pair and Medium"),
+                choicesAllMatching = true);
+
+  //
+  // Finalize base classe
+  //
+  extends SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs(
+    redeclare replaceable package WorkingPair =
+      SorpLib.Media.WorkingPairs.Parametrizations.PureComponents.CO2.ActivatedCarbon_Toth_DantasEtAl2011
+        (
+      MediumSpecificFunctions(redeclare replaceable package Medium = Medium)));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the thermodynamic properties of a working pair using
+a fluid with just one regime (i.e., gas/vapor) as medium model for the adsorptive.
+For details on the working pair model, check the model
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs\">SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end WorkingPairGas;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/WorkingPairVLE.mo b/SorpLib/Media/WorkingPairs/PureComponents/WorkingPairVLE.mo
new file mode 100644
index 0000000..a5751d6
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/WorkingPairVLE.mo
@@ -0,0 +1,42 @@
+within SorpLib.Media.WorkingPairs.PureComponents;
+model WorkingPairVLE
+  "Model of a pure working pair using the MSL for fluid property data calculation of a real fluid with a two-phase regime"
+
+  //
+  // Definition of replaceable medium
+  //
+  replaceable package Medium = Modelica.Media.Water.StandardWater
+    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium
+    "Medium (i.e., adsorptive)"
+    annotation (Dialog(tab="General",group="Working Pair and Medium"),
+                choicesAllMatching = true);
+
+  //
+  // Finalize base classe
+  //
+  extends SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs(
+    redeclare replaceable package WorkingPair =
+      Parametrizations.PureComponents.H2O.SilicaGel123_DubininLorentzianCumulative_Schawe2000
+        (
+        MediumSpecificFunctions(redeclare replaceable package Medium = Medium)));
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This model calculates the thermodynamic properties of a working pair using
+a real fluid with a two-phase regime as medium model for the adsorptive. Note
+that isotherm models based on the model of Dubinin must have a real fluid. For
+details on the working pair model, check the model
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs\">SorpLib.Media.WorkingPairs.BaseClasses.PartialPureWorkingPairs</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end WorkingPairVLE;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/package.mo b/SorpLib/Media/WorkingPairs/PureComponents/package.mo
new file mode 100644
index 0000000..8945edb
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/package.mo
@@ -0,0 +1,34 @@
+within SorpLib.Media.WorkingPairs;
+package PureComponents "Package containing pure component working pair models"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains fully parameterized working models. For this purpose, 
+the partially parametrized pure working pair models are extended by a specific 
+<i>MediumSpecificFunctions</i> package. This package calculates fluid properties 
+based on the open-source Modelica Standard Library (MSL).
+</p>
+
+<h4>Structure</h4>
+<p>
+The package 
+<a href=\"Modelica://SorpLib.Media.WorkingPairs.PureComponents.MediumSpecificFunctions\">SorpLib.Media.WorkingPairs.PureComponents.MediumSpecificFunctions</a>
+contains different versions of packages providing medium specific functions. For 
+each package version there is also a corresponding working pair model. The finally
+parametrized working pair models are alphabetically sorted by available asdsorptives 
+and are stored in seperate packages. The naming convention for the parameterized working 
+pair models is as follows
+</p>
+<pre>
+    NameSorbent_NameIsothermModel_NameAuthorsYear_MediumType;
+</pre>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PureComponents;
diff --git a/SorpLib/Media/WorkingPairs/PureComponents/package.order b/SorpLib/Media/WorkingPairs/PureComponents/package.order
new file mode 100644
index 0000000..062901a
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/PureComponents/package.order
@@ -0,0 +1,7 @@
+CO2
+H2O
+N2
+O2
+WorkingPairGas
+WorkingPairVLE
+Testers
diff --git a/SorpLib/Media/WorkingPairs/Records/DerivativesPureEntropyBalance.mo b/SorpLib/Media/WorkingPairs/Records/DerivativesPureEntropyBalance.mo
new file mode 100644
index 0000000..63684f7
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Records/DerivativesPureEntropyBalance.mo
@@ -0,0 +1,51 @@
+within SorpLib.Media.WorkingPairs.Records;
+record DerivativesPureEntropyBalance
+  "This record contains partial derivatives required for entropy balances of a working pair volume"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of paramters
+  //
+  SorpLib.Units.DerSpecificEntropyByPressure ds_sorbent_dp_T
+    "Partial derivative of the specific entropy of the sorbent w.r.t. pressure
+    at constant temperature";
+  SorpLib.Units.DerSpecificEntropyByTemperature ds_sorbent_dT_p
+    "Partial derivative of the specific entropy of the sorbent w.r.t. temperature
+    at constant pressure";
+  SorpLib.Units.DerSpecificEntropyByUptake ds_sorbent_dx_T
+    "Partial derivative of the specific entropy of the sorbent w.r.t. uptake
+    at constant temperature";
+  SorpLib.Units.DerSpecificEntropyByTemperature ds_sorbent_dT_x
+    "Partial derivative of the specific entropy of the sorbent w.r.t. temperature
+    at constant uptake";
+
+  SorpLib.Units.DerUptakeSpecificEntropyByPressure dxs_avg_adsorpt_dp_T
+    "Partial derivative of the uptake-averaged specific entropy of the adsorpt
+    times the uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEntropyByTemperature dxs_avg_adsorpt_dT_p
+    "Partial derivative of the uptake-averaged specific entropy of the adsorpt 
+    times the uptake w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerUptakeSpecificEntropyByUptake dxs_avg_adsorpt_dx_T
+    "Partial derivative of the uptake-averaged specific entropy of the adsorpt 
+    times the uptake w.r.t. uptake at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEntropyByTemperature dxs_avg_adsorpt_dT_x
+    "Partial derivative of the uptake-averaged specific entropy of the adsorpt 
+    times the uptake w.r.t. temperature at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains partial derivatives required to calculate the entropy balance 
+of working pair volumes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DerivativesPureEntropyBalance;
diff --git a/SorpLib/Media/WorkingPairs/Records/DerivativesPureIsothermModel.mo b/SorpLib/Media/WorkingPairs/Records/DerivativesPureIsothermModel.mo
new file mode 100644
index 0000000..49f65ce
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Records/DerivativesPureIsothermModel.mo
@@ -0,0 +1,35 @@
+within SorpLib.Media.WorkingPairs.Records;
+record DerivativesPureIsothermModel
+  "This record contains partial derivatives of the isotherm model"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of paramters
+  //
+  SorpLib.Units.DerUptakeByPressure dx_dp_T
+    "Partial derivative of the uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeByTemperature dx_dT_p
+    "Partial derivative of the uptake w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerPressureByUptake dp_dx_T
+    "Partial derivative of the uptake w.r.t. uptake at constant temperature";
+  Modelica.Units.SI.DerPressureByTemperature dp_dT_x
+    "Partial derivative of the uptake w.r.t. temperature at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains partial derivatives of the isotherm model. These partial 
+derivatives may be required for the mass, energy, and entropy balance of working 
+pair volumes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DerivativesPureIsothermModel;
diff --git a/SorpLib/Media/WorkingPairs/Records/DerivativesPureMassEnergyBalances.mo b/SorpLib/Media/WorkingPairs/Records/DerivativesPureMassEnergyBalances.mo
new file mode 100644
index 0000000..def735b
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Records/DerivativesPureMassEnergyBalances.mo
@@ -0,0 +1,77 @@
+within SorpLib.Media.WorkingPairs.Records;
+record DerivativesPureMassEnergyBalances
+  "This record contains partial derivatives required for mass and energy balances of a working pair volume"
+  extends Modelica.Icons.Record;
+
+  //
+  // Definition of paramters
+  //
+  SorpLib.Units.DerSpecificVolumeByPressure dv_sorbent_dp_T
+    "Partial derivative of the specific volume of the sorbent w.r.t. pressure at 
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_sorbent_dT_p
+    "Partial derivative of the specific volume of the sorbent w.r.t. temperature 
+    at constant pressure";
+  SorpLib.Units.DerSpecificVolumeByUptake dv_sorbent_dx_T
+    "Partial derivative of the specific volume of the sorbent w.r.t. uptake at 
+    constant temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_sorbent_dT_x
+    "Partial derivative of the specific volume of the sorbent w.r.t. temperature 
+    at constant uptake";
+
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_sorbent_dp_T
+    "Partial derivative of the specific enthalpy of the sorbent w.r.t. pressure
+    at constant temperature";
+  Modelica.Units.SI.SpecificHeatCapacity dh_sorbent_dT_p
+    "Partial derivative of the specific enthalpy of the sorbent w.r.t. temperature
+    at constant pressure";
+  SorpLib.Units.DerSpecificEnthalpyByUptake dh_sorbent_dx_T
+    "Partial derivative of the specific enthalpy of the sorbent w.r.t. uptake
+    at constant temperature";
+  Modelica.Units.SI.SpecificHeatCapacity dh_sorbent_dT_x
+    "Partial derivative of the specific enthalpy of the sorbent w.r.t. temperature
+    at constant uptake";
+
+  SorpLib.Units.DerUptakeSpecificVolumeByPressure dxv_avg_adsorpt_dp_T
+    "Partial derivative of the uptake-averaged specific volume of the adsorpt  
+    times the uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificVolumeByTemperature dxv_avg_adsorpt_dT_p
+    "Partial derivative of the uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerUptakeSpecificVolumeByUptake dxv_avg_adsorpt_dx_T
+    "Partial derivative of the uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. uptake at constant temperature";
+  SorpLib.Units.DerUptakeSpecificVolumeByTemperature dxv_avg_adsorpt_dT_x
+    "Partial derivative of the uptake-averaged specific volume of the adsorpt
+    times the uptake w.r.t. temperature at constant uptake";
+
+  SorpLib.Units.DerUptakeSpecificEnthalpyByPressure dxh_avg_adsorpt_dp_T
+    "Partial derivative of the uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByTemperature dxh_avg_adsorpt_dT_p
+    "Partial derivative of the uptake-averaged specific enthalpy of the adsorpt 
+    times the uptake w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByUptake dxh_avg_adsorpt_dx_T
+    "Partial derivative of the uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. uptake at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByTemperature dxh_avg_adsorpt_dT_x
+    "Partial derivative of the uptake-averaged specific enthalpy of the adsorpt
+    times the uptake w.r.t. temperature at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains partial derivatives required for the mass and energy balance 
+of working pair volumes.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end DerivativesPureMassEnergyBalances;
diff --git a/SorpLib/Media/WorkingPairs/Records/PropertiesPureAdsorpt.mo b/SorpLib/Media/WorkingPairs/Records/PropertiesPureAdsorpt.mo
new file mode 100644
index 0000000..ff0f709
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Records/PropertiesPureAdsorpt.mo
@@ -0,0 +1,85 @@
+within SorpLib.Media.WorkingPairs.Records;
+record PropertiesPureAdsorpt
+  "This record contains required properties of the adsorpt for pure working pairs"
+  extends Modelica.Icons.Record;
+
+  //
+  // Uptake-averaged state variables
+  //
+  SorpLib.Media.WorkingPairs.Records.StateVariables state
+    "Thermodynamic state variables of the uptake-averaged adsorpt";
+
+  //
+  // State variables
+  //
+  Modelica.Units.SI.SpecificVolume v
+    "Specific volume of the last adsorbed molecule";
+
+  //
+  // Additional properties
+  //
+  Modelica.Units.SI.SpecificEnthalpy h_ads
+    "Specific enthalpy of adsorption of the last adsorbed molecule";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity of the last adsorbed molecule or uptake-averaged 
+    adsorpt, depending on the calculation approach";
+
+  //
+  // Partial derivatives
+  //
+  SorpLib.Media.WorkingPairs.Records.DerivativesPureIsothermModel derivatives_isotherm
+    "Partial derivatives of the isotherm model";
+
+  SorpLib.Units.DerUptakeSpecificVolumeByPressure dxv_avg_dp_T
+    "Partial derivative of the uptake-averaged specific volume times the uptake 
+    w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificVolumeByTemperature dxv_avg_dT_p
+    "Partial derivative of the uptake-averaged specific volume times the uptake 
+    w.r.t. temperature at constant pressure";
+
+  SorpLib.Units.DerUptakeSpecificEnthalpyByPressure dxh_avg_dp_T
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake 
+    w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByTemperature dxh_avg_dT_p
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake 
+    w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByUptake dxh_avg_dx_T
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake 
+    w.r.t. uptake at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEnthalpyByTemperature dxh_avg_dT_x
+    "Partial derivative of the uptake-averaged specific enthalpy times the uptake 
+    w.r.t. temperature at constant uptake";
+
+  SorpLib.Units.DerUptakeSpecificEntropyByPressure dxs_avg_dp_T
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. pressure at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEntropyByTemperature dxs_avg_dT_p
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. temperature at constant pressure";
+  SorpLib.Units.DerUptakeSpecificEntropyByUptake dxs_avg_dx_T
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. uptake at constant temperature";
+  SorpLib.Units.DerUptakeSpecificEntropyByTemperature dxs_avg_dT_x
+    "Partial derivative of the uptake-averaged specific entropy times the uptake 
+    w.r.t. temperature at constant uptake";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains properties of the adsorption required for pure working pairs.
+These properties are calculated at once if required, to keep the computational
+costs low. Thus, e.g., multiple calculation of the same fluid property data is 
+avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PropertiesPureAdsorpt;
diff --git a/SorpLib/Media/WorkingPairs/Records/PropertiesPureAdsorptive.mo b/SorpLib/Media/WorkingPairs/Records/PropertiesPureAdsorptive.mo
new file mode 100644
index 0000000..9ec7f02
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Records/PropertiesPureAdsorptive.mo
@@ -0,0 +1,81 @@
+within SorpLib.Media.WorkingPairs.Records;
+record PropertiesPureAdsorptive
+  "This record contains required properties of the adsorptive in the gas/vapor phase for pure working pairs"
+  extends Modelica.Icons.Record;
+
+  //
+  // State variables
+  //
+  SorpLib.Media.WorkingPairs.Records.StateVariables state
+    "Thermodynamic state variables of the adsorptive";
+
+  //
+  // Additional properties of the one-phase regime
+  //
+  Modelica.Units.SI.SpecificHeatCapacity cp
+    "Specific heat capacity";
+
+  //
+  // Additional properties of the two-phase regime
+  //
+  Modelica.Units.SI.Pressure p_sat
+    "Saturated vapor pressure";
+
+  Modelica.Units.SI.SpecificVolume v_satLiq
+    "Specific volume at the bubble point at given temperature";
+
+  Modelica.Units.SI.SpecificEnthalpy h_adsorptiveToLiquid
+    "Specific enthalpy difference between adsorptive state and saturated liquid
+    state (i.e., bubble point)";
+
+  Modelica.Units.SI.SpecificHeatCapacity cp_satLiq
+    "Specific heat capacaity at the bubble point at given temperature";
+
+  //
+  // Partial derivatives
+  //
+  SorpLib.Units.DerSpecificVolumeByPressure dv_dp_T
+    "Partial derivative of the specific volume w.r.t. pressure at constant
+    temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_dT_p
+    "Partial derivative of the specific volume w.r.t. temperature at constant
+    pressure";
+
+  Modelica.Media.Common.DerPressureByTemperature dp_sat_dT
+    "Partial derivative of saturated vapor pressure w.r.t. temperature";
+
+  SorpLib.Units.DerSpecificVolumeByTemperature dv_satLiq_dT
+    "Partial derivative of the specific volume at the bubble point at given
+    temperature w.r.t. temperature";
+  SorpLib.Units.DerSpecificVolumeByTemperatureTemperature ddv_satLiq_dT_dT
+    "Second-order partial derivative of the specific volume at the bubble point 
+    at given temperature w.r.t. temperature";
+
+  SorpLib.Units.DerSpecificEnthalpyByPressure dh_adsorptiveToLiquid_dp_T
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. pressure at constant 
+    temperature";
+  Modelica.Units.SI.SpecificHeatCapacity dh_adsorptiveToLiquid_dT_p
+    "Partial derivative of specific enthalpy difference between adsorptive state 
+    and saturated liquid state (i.e., bubble point) w.r.t. temperature at constant
+    pressure";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains properties of the adsorptie in the gas/vapor phase required 
+for pure working pairs. These properties are calculated at once if required, to 
+keep the computational costs low. Thus, e.g., multiple calculation of the same 
+fluid property data is avoided.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end PropertiesPureAdsorptive;
diff --git a/SorpLib/Media/WorkingPairs/Records/StateVariables.mo b/SorpLib/Media/WorkingPairs/Records/StateVariables.mo
new file mode 100644
index 0000000..15972de
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Records/StateVariables.mo
@@ -0,0 +1,21 @@
+within SorpLib.Media.WorkingPairs.Records;
+record StateVariables
+  "This record contains thermodynamic state variables"
+  extends SorpLib.Media.Solids.Records.StateVariables;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This record contains thermodynamic state variables.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  November 22, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end StateVariables;
diff --git a/SorpLib/Media/WorkingPairs/Records/package.mo b/SorpLib/Media/WorkingPairs/Records/package.mo
new file mode 100644
index 0000000..b382670
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Records/package.mo
@@ -0,0 +1,18 @@
+within SorpLib.Media.WorkingPairs;
+package Records "Package containing records"
+  extends Modelica.Icons.RecordsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains definitions of records. These records are used to cluster 
+variables and tidy up the model output.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end Records;
diff --git a/SorpLib/Media/WorkingPairs/Records/package.order b/SorpLib/Media/WorkingPairs/Records/package.order
new file mode 100644
index 0000000..093ab60
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/Records/package.order
@@ -0,0 +1,6 @@
+StateVariables
+DerivativesPureIsothermModel
+DerivativesPureMassEnergyBalances
+DerivativesPureEntropyBalance
+PropertiesPureAdsorpt
+PropertiesPureAdsorptive
diff --git a/SorpLib/Media/WorkingPairs/package.mo b/SorpLib/Media/WorkingPairs/package.mo
new file mode 100644
index 0000000..6c083c5
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/package.mo
@@ -0,0 +1,64 @@
+within SorpLib.Media;
+package WorkingPairs "Models to calcualte fluid property data of sorption working pairs"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains models calculating thermodynamic properties of pure component
+and multi-component working pairs. Independent state variables may be (1) the pressure 
+and temperature or (2) the uptake and temperature. In the models, fundamental 
+thermodynamic properties can be calculated:
+</p>
+<ol>
+  <li>
+  Thermal state variables: <i>p</i>, <i>T</i>, and <i>&rho;</i>.
+  </li>
+  <li>
+  Caloric state variables: <i>h</i> and <i>u</i>.
+  </li>
+  <li>
+  Entropic state variables: <i>s</i>, <i>g</i>, and <i>a</i>.
+  </li>
+</ol>
+<p>
+Moreover, the model allow to calculate all partial derivatives with respect to the
+independent state variables that are required for dynamic mass, energy, and entropy
+balances in finite volume models.
+</p>
+
+<h4>How to add new working pair models</h4>
+<p>
+To add a new working pair models, three steps are required:
+</p>
+<ol>
+  <li>
+  Duplicate an existing parametrization package and save it into the correct sub-pacakge
+  of the 
+  <a href=\"Modelica://SorpLib.Media.WorkingPairs.Parametrizations\">Parametrizations package</a>.
+  Then, parametrize the dublicated package and write the documentation, including 
+  references for the thermodynamic properties.
+  </li>
+  <li>
+  Duplicate an existing working pair model and save it into the correct sub-pacakge of the 
+  <a href=\"Modelica://SorpLib.Media.WorkingPairs.PureComponents\">PureComponents package</a>
+  or the
+  <a href=\"Modelica://SorpLib.Media.WorkingPairs.MultiComponents\">MultiComponents package</a>.
+  Then, finalize the model.
+  </li>
+  <li>
+  Duplicate an existing test model and save it into the correct sub-pacakge of the 
+  <a href=\"Modelica://SorpLib.Media.WorkingPairs.PureComponents.Testers\">PureComponents.Testers package</a>
+  or the
+  <a href=\"Modelica://SorpLib.Media.WorkingPairs.MultiComponents.Testers\">MultiComponents.Testers package</a>.
+  Then, test the new working pair model and varify calculations.
+  </li>
+</ol>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end WorkingPairs;
diff --git a/SorpLib/Media/WorkingPairs/package.order b/SorpLib/Media/WorkingPairs/package.order
new file mode 100644
index 0000000..fc209c6
--- /dev/null
+++ b/SorpLib/Media/WorkingPairs/package.order
@@ -0,0 +1,7 @@
+BaseClasses
+Interfaces
+Records
+Parametrizations
+PureComponents
+MultiComponents
+FluidPropertyDiagrams
diff --git a/SorpLib/Media/package.mo b/SorpLib/Media/package.mo
index c63b847..54e5cdb 100644
--- a/SorpLib/Media/package.mo
+++ b/SorpLib/Media/package.mo
@@ -1,10 +1,42 @@
 within SorpLib;
-package Media "Equilibrium data of adsorbent / adsorbate working pairs"
-extends SorpLib.Internals.ClassTypes.ModelPackage;
+package Media "Library of media property models"
+  extends SorpLib.Icons.MediaPackage;
 
-
-
-
-
-annotation (Icon(graphics));
+annotation (Documentation(info="<html>
+<p>
+This package contains functions required for calculating substance property data. 
+The functions are mainly used for calculating the adsorption equilibrium or 
+properties of a sorption working pair. This package contains the following 
+substance models:
+</p>
+<ul>
+  <li>
+  <a href=\"Modelica://SorpLib.Media.IdealGases\">IdealGases</a>: 
+  Models for calculating ideal gases.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Media.IdealGasMixtures\">IdealGasMixtures</a>: 
+  Models for calculating ideal gas mixtures.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Media.IdealGasVaporMixtures\">IdealGasVaporMixtures</a>: 
+  Models for calculating ideal gas-vapor mixtures, i.e., ideal gas mixtures with a condensable substance (usually water).
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Media.Solids\">Solids</a>: 
+  Models for calculating solids, such as metals or sorbents.
+  </li>
+  <li>
+  <a href=\"Modelica://SorpLib.Media.WorkingPairs\">WorkingPairs</a>: 
+  Models for calculating sorption working pairs, either with one or multi components.
+  </li>
+</ul>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
 end Media;
diff --git a/SorpLib/Media/package.order b/SorpLib/Media/package.order
index 6848852..f6920b3 100644
--- a/SorpLib/Media/package.order
+++ b/SorpLib/Media/package.order
@@ -1,2 +1,6 @@
 Functions
-AdsorbentAdsorbate
+IdealGases
+IdealGasMixtures
+IdealGasVaporMixtures
+Solids
+WorkingPairs
diff --git a/SorpLib/Modules/Controllers/package.mo b/SorpLib/Modules/Controllers/package.mo
new file mode 100644
index 0000000..33ffa39
--- /dev/null
+++ b/SorpLib/Modules/Controllers/package.mo
@@ -0,0 +1,17 @@
+within SorpLib.Modules;
+package Controllers "Controller to regulate soprtions modules or sorption systems"
+  extends SorpLib.Icons.ControllerPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED!
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Controllers;
diff --git a/SorpLib/Modules/Controllers/package.order b/SorpLib/Modules/Controllers/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/Modules/package.mo b/SorpLib/Modules/package.mo
new file mode 100644
index 0000000..8d0d16f
--- /dev/null
+++ b/SorpLib/Modules/package.mo
@@ -0,0 +1,17 @@
+within SorpLib;
+package Modules "Library containing sorption modules"
+  extends Modelica.Icons.VariantsPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+TO BE ADDED!
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Modules;
diff --git a/SorpLib/Modules/package.order b/SorpLib/Modules/package.order
new file mode 100644
index 0000000..5afbd13
--- /dev/null
+++ b/SorpLib/Modules/package.order
@@ -0,0 +1 @@
+Controllers
diff --git a/SorpLib/Numerics/Testers/Test_regSquareWFactors_regSquareWFactors_inv.mo b/SorpLib/Numerics/Testers/Test_regSquareWFactors_regSquareWFactors_inv.mo
new file mode 100644
index 0000000..0fcc1a1
--- /dev/null
+++ b/SorpLib/Numerics/Testers/Test_regSquareWFactors_regSquareWFactors_inv.mo
@@ -0,0 +1,70 @@
+within SorpLib.Numerics.Testers;
+model Test_regSquareWFactors_regSquareWFactors_inv
+  "Tester for the functions 'regSquareWFactors' and 'regSquareWFactors_inv'"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real delta_x = 0.001
+    "Defines region (-delta_x < x < delta_x) used to approximate square by a 3rd
+    order polynomial"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real f_positive = 2
+    "Multplicator for x > 0"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real f_negative = 2
+    "Multiplicator for x < 0"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of variables
+  //
+  Real x(start=-1.5, fixed=true)
+    "Abscissa value used for square aprroximation";
+
+  Real app_square = SorpLib.Numerics.regSquareWFactors(
+    x=x, delta_x=delta_x, f_positive=f_positive, f_negative=f_negative)
+    "Approximated square";
+  Real dapp_square_dtau
+    "First derivative of app_square wrt. time";
+  Real d2app_square_d2tau
+    "Second derivative of app_square wrt. time";
+
+  Real x_inv = SorpLib.Numerics.regSquareWFactors_inv(
+    y=app_square, delta_x=delta_x, f_positive=f_positive, f_negative=f_negative)
+    "Calculate inverse of function 'regSquare'";
+
+equation
+  der(x) = 0.1
+    "Predescribed slope of x to demonstrate function 'regSquare'";
+  der(app_square) = dapp_square_dtau
+    "First derivative of app_square wrt. time";
+  der(dapp_square_dtau) = d2app_square_d2tau
+    "Second derivative of app_square wrt. time";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=30, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the functions 'regSquareWFactors' and 
+'regSquare_invWFactors.' The approximation range can be influenced using the 
+value <i>delta_x</i>: Larger values cause a greater transition region than 
+smaller values.
+<br/><br/>
+To see the behavior of the approximated square, plot the variable <i>app_square</i>
+over the  variable <i>x</i>. To see the behavior of the inverse function, plot the 
+variables <i>x</i> and <i>x_inv</i> over the  variable <i>x</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 30 s).  
+</p>
+</html>"));
+end Test_regSquareWFactors_regSquareWFactors_inv;
diff --git a/SorpLib/Numerics/Testers/Test_regSquareWFactors_regSquareWFactors_inv_noEvent.mo b/SorpLib/Numerics/Testers/Test_regSquareWFactors_regSquareWFactors_inv_noEvent.mo
new file mode 100644
index 0000000..8911b48
--- /dev/null
+++ b/SorpLib/Numerics/Testers/Test_regSquareWFactors_regSquareWFactors_inv_noEvent.mo
@@ -0,0 +1,70 @@
+within SorpLib.Numerics.Testers;
+model Test_regSquareWFactors_regSquareWFactors_inv_noEvent
+  "Tester for the functions 'regSquareWFactors_noEvent' and 'regSquareWFactors_inv_noEvent'"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real delta_x = 0.1
+    "Defines region (-delta_x < x < delta_x) used to approximate square by a 3rd
+    order polynomial"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real f_positive = 2
+    "Multplicator for x > 0"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Real f_negative = 2
+    "Multiplicator for x < 0"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of variables
+  //
+  Real x(start=-1.5, fixed=true)
+    "Abscissa value used for square aprroximation";
+
+  Real app_square = SorpLib.Numerics.regSquareWFactors_noEvent(
+    x=x, delta_x=delta_x, f_positive=f_positive, f_negative=f_negative)
+    "Approximated square";
+  Real dapp_square_dtau
+    "First derivative of app_square wrt. time";
+  Real d2app_square_d2tau
+    "Second derivative of app_square wrt. time";
+
+  Real x_inv = SorpLib.Numerics.regSquareWFactors_inv_noEvent(
+    y=app_square, delta_x=delta_x, f_positive=f_positive, f_negative=f_negative)
+    "Calculate inverse of function 'regSquare'";
+
+equation
+  der(x) = 0.1
+    "Predescribed slope of x to demonstrate function 'regSquare'";
+  der(app_square) = dapp_square_dtau
+    "First derivative of app_square wrt. time";
+  der(dapp_square_dtau) = d2app_square_d2tau
+    "Second derivative of app_square wrt. time";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=30, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the functions 'regSquareWFactors_noEvent' and 
+'regSquare_invWFactors_noEvent.' The approximation range can be influenced using 
+the value <i>delta_x</i>: Larger values cause a greater transition region than 
+smaller values.
+<br/><br/>
+To see the behavior of the approximated square, plot the variable <i>app_square</i>
+over the  variable <i>x</i>. To see the behavior of the inverse function, plot the 
+variables <i>x</i> and <i>x_inv</i> over the  variable <i>x</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 30 s).  
+</p>
+</html>"));
+end Test_regSquareWFactors_regSquareWFactors_inv_noEvent;
diff --git a/SorpLib/Numerics/Testers/Test_regSquare_noEvent_regSquare_inv_noEvent.mo b/SorpLib/Numerics/Testers/Test_regSquare_noEvent_regSquare_inv_noEvent.mo
new file mode 100644
index 0000000..1c59244
--- /dev/null
+++ b/SorpLib/Numerics/Testers/Test_regSquare_noEvent_regSquare_inv_noEvent.mo
@@ -0,0 +1,62 @@
+within SorpLib.Numerics.Testers;
+model Test_regSquare_noEvent_regSquare_inv_noEvent
+  "Tester for the functions 'regSquare_noEvent' and 'regSquare_inv_noEvent'"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real delta_x = 0.1
+    "Defines region (-delta_x < x < delta_x) used to approximate square by a 3rd
+    order polynomial"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of variables
+  //
+  Real x(start=-1.5, fixed=true)
+    "Abscissa value used for square aprroximation";
+
+  Real app_square = SorpLib.Numerics.regSquare_noEvent(x=x, delta_x=delta_x)
+    "Approximated square";
+  Real dapp_square_dtau
+    "First derivative of app_square wrt. time";
+  Real d2app_square_d2tau
+    "Second derivative of app_square wrt. time";
+
+  Real x_inv = SorpLib.Numerics.regSquare_inv_noEvent(y=app_square, delta_x=delta_x)
+    "Calculate inverse of function 'regSquare'";
+
+equation
+  der(x) = 0.1
+    "Predescribed slope of x to demonstrate function 'regSquare'";
+  der(app_square) = dapp_square_dtau
+    "First derivative of app_square wrt. time";
+  der(dapp_square_dtau) = d2app_square_d2tau
+    "Second derivative of app_square wrt. time";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=30, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the functions 'regSquare_noEvent' and 
+'regSquare_inv_noEvent.' The approximation range can be influenced using the 
+value <i>delta_x</i>: Larger values cause a greater transition region than 
+smaller values.
+<br/><br/>
+To see the behavior of the approximated square, plot the variable <i>app_square</i>
+over the  variable <i>x</i>. To see the behavior of the inverse function, plot the 
+variables <i>x</i> and <i>x_inv</i> over the  variable <i>x</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 30 s).  
+</p>
+</html>"));
+end Test_regSquare_noEvent_regSquare_inv_noEvent;
diff --git a/SorpLib/Numerics/Testers/Test_regSquare_regSquare_inv.mo b/SorpLib/Numerics/Testers/Test_regSquare_regSquare_inv.mo
new file mode 100644
index 0000000..4d809cd
--- /dev/null
+++ b/SorpLib/Numerics/Testers/Test_regSquare_regSquare_inv.mo
@@ -0,0 +1,61 @@
+within SorpLib.Numerics.Testers;
+model Test_regSquare_regSquare_inv
+  "Tester for the functions 'regSquare' and 'regSquare_inv'"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real delta_x = 0.1
+    "Defines region (-delta_x < x < delta_x) used to approximate square by a 3rd
+    order polynomial"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of variables
+  //
+  Real x(start=-1.5, fixed=true)
+    "Abscissa value used for square aprroximation";
+
+  Real app_square = SorpLib.Numerics.regSquare(x=x, delta_x=delta_x)
+    "Approximated square";
+  Real dapp_square_dtau
+    "First derivative of app_square wrt. time";
+  Real d2app_square_d2tau
+    "Second derivative of app_square wrt. time";
+
+  Real x_inv = SorpLib.Numerics.regSquare_inv(y=app_square, delta_x=delta_x)
+    "Calculate inverse of function 'regSquare'";
+
+equation
+  der(x) = 0.1
+    "Predescribed slope of x to demonstrate function 'regSquare'";
+  der(app_square) = dapp_square_dtau
+    "First derivative of app_square wrt. time";
+  der(dapp_square_dtau) = d2app_square_d2tau
+    "Second derivative of app_square wrt. time";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=30, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the functions 'regSquare' and 'regSquare_inv.'
+The approximation range can be influenced using the value <i>delta_x</i>: Larger 
+values cause a greater transition region than smaller values.
+<br/><br/>
+To see the behavior of the approximated square, plot the variable <i>app_square</i>
+over the  variable <i>x</i>. To see the behavior of the inverse function, plot the 
+variables <i>x</i> and <i>x_inv</i> over the  variable <i>x</i>. The simulation 
+time is correctly preset (Start: 0 s, Stop = 30 s).  
+</p>
+</html>"));
+end Test_regSquare_regSquare_inv;
diff --git a/SorpLib/Numerics/Testers/Test_regStep.mo b/SorpLib/Numerics/Testers/Test_regStep.mo
new file mode 100644
index 0000000..e42f16d
--- /dev/null
+++ b/SorpLib/Numerics/Testers/Test_regStep.mo
@@ -0,0 +1,50 @@
+within SorpLib.Numerics.Testers;
+model Test_regStep "Tester for the function 'regStep'"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real x_small = 0
+    "Defines region (-x_small < x < x_small) used to approximate step by a 2nd
+    order polynomial"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of variables
+  //
+  Real x(start=-1, fixed=true)
+    "Abscissa value used for step";
+
+  Real reg_value = SorpLib.Numerics.regStep(x=x, y1=-1, y2=1, x_small=x_small)
+    "Regulated step";
+
+equation
+  der(x) = 0.1
+    "Predecsriped slope of x to demonstrate function 'regStep'";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=20, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'regStep' function. For example, the 
+function steps from <i>y1 = -1</i> (<i>x &gt; 0</i>) to <i>y2 = 1</i> (<i>x 
+&lt; 0</i>) at <i>x = 0</i>. The step characteristic at <i>x = 0</i> can be
+influenced using the transition value <i>x_small</i>: Larger values cause a 
+smoother transition than smaller values.
+<br/><br/>
+To see the jump behavior, plot the variable <i>reg_value</i> over the 
+variable <i>x</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 20 s).  
+</p>
+</html>"));
+end Test_regStep;
diff --git a/SorpLib/Numerics/Testers/Test_regStep_noEvent.mo b/SorpLib/Numerics/Testers/Test_regStep_noEvent.mo
new file mode 100644
index 0000000..a623277
--- /dev/null
+++ b/SorpLib/Numerics/Testers/Test_regStep_noEvent.mo
@@ -0,0 +1,50 @@
+within SorpLib.Numerics.Testers;
+model Test_regStep_noEvent "Tester for the function 'regStep_noEvent'"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real x_small = 0
+    "Defines region (-x_small < x < x_small) used to approximate step by a 2nd
+    order polynomial"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of variables
+  //
+  Real x(start=-1, fixed=true)
+    "Abscissa value used for step";
+
+  Real reg_value = SorpLib.Numerics.regStep_noEvent(x=x, y1=-1, y2=1, x_small=x_small)
+    "Regulated step";
+
+equation
+  der(x) = 0.1
+    "Predecsriped slope of x to demonstrate function 'regStep'";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=20, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'regStep_noEvent' function. For example, the 
+function steps from <i>y1 = -1</i> (<i>x &gt; 0</i>) to <i>y2 = 1</i> (<i>x 
+&lt; 0</i>) at <i>x = 0</i>. The step characteristic at <i>x = 0</i> can be
+influenced using the transition value <i>x_small</i>: Larger values cause a 
+smoother transition than smaller values.
+<br/><br/>
+To see the jump behavior, plot the variable <i>reg_value</i> over the 
+variable <i>x</i>. The simulation time is correctly preset (Start: 0 s, 
+Stop = 20 s).  
+</p>
+</html>"));
+end Test_regStep_noEvent;
diff --git a/SorpLib/Numerics/Testers/Test_smoothTransition.mo b/SorpLib/Numerics/Testers/Test_smoothTransition.mo
new file mode 100644
index 0000000..fcb124c
--- /dev/null
+++ b/SorpLib/Numerics/Testers/Test_smoothTransition.mo
@@ -0,0 +1,60 @@
+within SorpLib.Numerics.Testers;
+model Test_smoothTransition
+  "Tester for the function 'smoothTransition' and its derivatives"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real transitionLength = 1
+    "Defines transition length around transition point"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Integer noDiff = 1
+    "Specification how often function can be differentiated (i.e., 1, 2 or 3)"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of variables
+  //
+  Real x(start=0, fixed=true)
+    "Abscissa value used for step";
+
+  Real weightingFactor = SorpLib.Numerics.smoothTransition(x=x,
+    transitionPoint=1, transitionLength=transitionLength, noDiff=noDiff)
+    "Smooth transition from 1 to 0 around x = 1";
+  Real dweightingFactor_dtau
+    "First derivative of weighting_factor wrt. time";
+  Real d2weightingFactor_d2tau
+    "Second derivative of weighting_factor wrt. time";
+
+equation
+  der(x) = 0.1
+    "Predecsriped slope of x to demonstrate function 'smoothTransition'";
+  der(weightingFactor) = dweightingFactor_dtau
+    "First derivative of weighting_factor wrt. time";
+  der(dweightingFactor_dtau) = d2weightingFactor_d2tau
+    "Second derivative of weighting_factor wrt. time";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=20, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'smoothTransition' function. For example, 
+the function smoothly changes the output from 1 to 0 at <i>transitionPoint = 1</i>
+within <i>transitionLlength = 1</i>. The change characteristic can be
+influenced using the value <i>noDiff</i>.
+<br/><br/>
+To see the transition behavior, plot the variable <i>weightingFactor</i> over the 
+variable <i>x</i>. The simulation time is correctly preset (Start: 0 s, Stop = 20 s).  
+</p>
+</html>"));
+end Test_smoothTransition;
diff --git a/SorpLib/Numerics/Testers/Test_smoothTransition_noEvent.mo b/SorpLib/Numerics/Testers/Test_smoothTransition_noEvent.mo
new file mode 100644
index 0000000..dac916f
--- /dev/null
+++ b/SorpLib/Numerics/Testers/Test_smoothTransition_noEvent.mo
@@ -0,0 +1,60 @@
+within SorpLib.Numerics.Testers;
+model Test_smoothTransition_noEvent
+  "Tester for the function 'smoothTransition_noEvent' and its derivatives"
+  extends Modelica.Icons.Example;
+
+  //
+  // Definition of parameters
+  //
+  parameter Real transitionLength = 1
+    "Defines transition length around transition point"
+    annotation (Dialog(tab="General", group="Parameters"));
+  parameter Integer noDiff = 1
+    "Specification how often function can be differentiated (i.e., 1, 2 or 3)"
+    annotation (Dialog(tab="General", group="Parameters"));
+
+  //
+  // Definition of variables
+  //
+  Real x(start=0, fixed=true)
+    "Abscissa value used for step";
+
+  Real weigthingFactor = SorpLib.Numerics.smoothTransition_noEvent(x=x,
+    transitionPoint=1, transitionLength=transitionLength, noDiff=noDiff)
+    "Smooth transition from 1 to 0 around x = 1";
+  Real dweigthingFactor_dtau
+    "First derivative of weigthingFactor wrt. time";
+  Real d2weigthingFactor_d2tau
+    "Second derivative of weigthingFactor wrt. time";
+
+equation
+  der(x) = 0.1
+    "Predescribed slope of x to demonstrate function 'smoothTransition'";
+  der(weigthingFactor) = dweigthingFactor_dtau
+    "First derivative of weigthingFactor wrt. time";
+  der(dweigthingFactor_dtau) = d2weigthingFactor_d2tau
+    "Second derivative of weigthingFactor wrt. time";
+
+  //
+  // Annotations
+  //
+  annotation (experiment(StartTime=0, StopTime=20, Tolerance=1e-6),
+Documentation(revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This tester shows the behavior of the 'smoothTransition_noEvent' function. For example, 
+the function smoothly changes the output from 1 to 0 at <i>transitionPoint = 1</i>
+within <i>transitionLength = 1</i>. The change characteristic can be
+influenced using the value <i>noDiff</i>.
+<br/><br/>
+To see the transition behavior, plot the variable <i>weigthingFactor</i> over the 
+variable <i>x</i>. The simulation time is correctly preset (Start: 0 s, Stop = 20 s).  
+</p>
+</html>"));
+end Test_smoothTransition_noEvent;
diff --git a/SorpLib/Numerics/Testers/package.mo b/SorpLib/Numerics/Testers/package.mo
new file mode 100644
index 0000000..fa0fba9
--- /dev/null
+++ b/SorpLib/Numerics/Testers/package.mo
@@ -0,0 +1,20 @@
+within SorpLib.Numerics;
+package Testers "Models to test and/or varify functions for numerical implementations"
+  extends Modelica.Icons.ExamplesPackage;
+
+  annotation (Documentation(info="<html>
+<p>
+This package contains executable test models for all functions of the 'Numerics' 
+package. The test models check the implementation of the functions and enable 
+verification of the function behavior. In addition, the test models demonstrate 
+the functions' general applicability.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Testers;
diff --git a/SorpLib/Numerics/Testers/package.order b/SorpLib/Numerics/Testers/package.order
new file mode 100644
index 0000000..4b0a082
--- /dev/null
+++ b/SorpLib/Numerics/Testers/package.order
@@ -0,0 +1,8 @@
+Test_regStep
+Test_regStep_noEvent
+Test_smoothTransition
+Test_smoothTransition_noEvent
+Test_regSquare_regSquare_inv
+Test_regSquare_noEvent_regSquare_inv_noEvent
+Test_regSquareWFactors_regSquareWFactors_inv
+Test_regSquareWFactors_regSquareWFactors_inv_noEvent
diff --git a/SorpLib/Numerics/package.mo b/SorpLib/Numerics/package.mo
new file mode 100644
index 0000000..6a87549
--- /dev/null
+++ b/SorpLib/Numerics/package.mo
@@ -0,0 +1,35 @@
+within SorpLib;
+package Numerics "Library containing utility function regarding numeric implementations"
+  extends Modelica.Icons.FunctionsPackage;
+
+annotation (Documentation(info="<html>
+<p>
+This package contains utility functions to implement models in a mathematically
+&quot;robust&quot; way. Mathematical robustness refers to the following:
+</p>
+<ol>
+  <li>
+  Mathematical approximation of functions so that they are continuous and 
+  differentiable at specific points. 
+  </li>
+  <li>
+  Mathematical transition between function values so that the transition is 
+  continuous and differentiable. 
+  </li>
+  <li>
+  Avoidance of events.
+  </li>
+</ol>
+<p>
+A mathematically robust implementation of models is essential in the context of 
+mathematical optimization.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end Numerics;
diff --git a/SorpLib/Numerics/package.order b/SorpLib/Numerics/package.order
new file mode 100644
index 0000000..92aa2b7
--- /dev/null
+++ b/SorpLib/Numerics/package.order
@@ -0,0 +1,17 @@
+regStep
+regStep_noEvent
+smoothTransition
+smoothTransition_der
+smoothTransition_der2
+smoothTransition_noEvent
+smoothTransition_der_noEvent
+smoothTransition_der2_noEvent
+regSquare
+regSquare_inv
+regSquare_noEvent
+regSquare_inv_noEvent
+regSquareWFactors
+regSquareWFactors_inv
+regSquareWFactors_noEvent
+regSquareWFactors_inv_noEvent
+Testers
diff --git a/SorpLib/Numerics/regSquare.mo b/SorpLib/Numerics/regSquare.mo
new file mode 100644
index 0000000..6a551f8
--- /dev/null
+++ b/SorpLib/Numerics/regSquare.mo
@@ -0,0 +1,97 @@
+within SorpLib.Numerics;
+function regSquare
+  "Anti-symmetric square approximation with non-zero derivative in the origin"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Input value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real delta_x = 1e-4
+    "Regulation value for approximation"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real y
+    "Approximated value"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  if x > delta_x then
+    y := x*x
+      "No approximation";
+
+  elseif x < -delta_x then
+    y := -x*x
+      "Keep sign of input";
+
+  else
+    y := (0.5/delta_x * x^2 + 0.5*delta_x) * x
+      "Transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+smoothOrder=1,
+inverse(x=regSquare_inv(y,delta_x)),
+Documentation(info="<html>
+<p><p>
+This function is used to approximate the equation
+</p>
+<pre>
+    y = x<sup>2</sup>;
+</pre>
+
+<p>
+for (1) the slope to be non-zero at the origin, (2) the function to be continuous 
+and differentiable, and (3) the sign of the input to not change:
+</p>
+
+<pre>
+   y = <strong>if</strong> x &gt; delta_x <strong>then</strong> x<sup>2</sup> <strong>else</strong>
+       <strong>if</strong> x &lt; -delta_x <strong>then</strong> -x<sup>2</sup> <strong>else</strong>
+       0.5 * x * (x<sup>2</sup> / delta_x + delta_x);
+</pre>
+
+<p>
+In the region -delta_x &lt; x &lt; delta_x a 3rd order polynomial is used.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This function is used, for example, to calculate pressure drop correlations.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the approximated square for different values of <i>delta_x</i>.
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/numerics_regSquare.png\" alt=\"numerics_regSquare.png\">
+
+<h4>References</h4>
+<p>
+The function is based on the MSL library
+(<a href=\"Modelica://Modelica.Fluid.Utilities.regSquare\">Modelica.Fluid.Utilities.regSquare</a>)
+and TIL library
+(<a href=\"Modelica://TIL.Utilities.Numerics.squareFunction\">TIL.Utilities.Numerics.squareFunction</a>)
+and has been slightly adapted.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end regSquare;
diff --git a/SorpLib/Numerics/regSquareWFactors.mo b/SorpLib/Numerics/regSquareWFactors.mo
new file mode 100644
index 0000000..d96ad1c
--- /dev/null
+++ b/SorpLib/Numerics/regSquareWFactors.mo
@@ -0,0 +1,140 @@
+within SorpLib.Numerics;
+function regSquareWFactors
+  "Anti-symmetric square (with discontinuous factors) approximation with non-zero derivative in the origin"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Input value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real delta_x = 1e-4
+    "Regulation value for approximation"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f_positive(min=0) = 1
+    "Factor for x > 0 (must be >= 0)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f_negative(min=0) = 1
+    "Factor for x < 0 (must be >= 0)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real y
+    "Approximated value"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real f
+    "Factor";
+
+algorithm
+  //
+  // Calculate factor
+  //
+  if x > 0 then
+    f := f_positive
+    "Factor";
+
+  elseif x < 0 then
+    f := f_negative
+    "Factor";
+
+  else
+    f := (f_positive + f_negative) / 2
+    "Factor";
+  end if;
+
+  //
+  // Approximate value
+  //
+  if Modelica.Math.isEqual(s1=f, s2=0, eps=Modelica.Constants.small) then
+    y := Modelica.Constants.inf
+      "No finite solution";
+
+  elseif x > delta_x then
+    y := x*x / f
+      "No approximation";
+
+  elseif x < -delta_x then
+    y := -x*x / f
+      "Keep sign of input";
+
+  else
+    y := (0.5/delta_x * x^2 + 0.5*delta_x) * x / f
+      "Transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+smoothOrder=1,
+inverse(x=regSquareWFactors_inv(y,delta_x,f_positive,f_negative)),
+Documentation(info="<html>
+<p><p>
+This function is used to approximate the equation
+</p>
+<pre>
+   y = x<sup>2</sup> / f;
+</pre>
+<p>
+with the factor <i>f</i> beeing dependent on the flow direction:
+</p>
+<pre>
+   f = <strong>if</strong> x &gt; 0 <strong>then</strong> f_positive <strong>elseif</strong> x &lt; 0 <strong>then</strong> f_negative <strong>else</strong> (f_positive + f_negative) / 2;
+</pre>
+<p>
+for (1) the slope to be non-zero at the origin, (2) the function to be continuous 
+and differentiable, and (3) the sign of the input to not change:
+</p>
+
+<pre>
+   y = <strong>if</strong> x &gt; delta_x <strong>then</strong> x<sup>2</sup> / f <strong>else</strong>
+       <strong>if</strong> x &lt; -delta_x <strong>then</strong> -x<sup>2</sup> / f <strong>else</strong>
+       0.5 * x * (x<sup>2</sup> / delta_x + delta_x) / f;
+</pre>
+
+<p>
+In the region -delta_x &lt; x &lt; delta_x, a 3rd order polynomial is used.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This function is used, for example, to calculate mass flow rates depending on 
+prssure drops.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the approximated square for different values of 
+<i>delta_x</i>, <i>f_positive=3</i>, and <i>f_negative=2</i>.
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/numerics_regSquareWFactors.png\" alt=\"numerics_regSquareWFactors.png\">
+
+<h4>References</h4>
+<p>
+The function is based on the MSL library
+(<a href=\"Modelica://Modelica.Fluid.Utilities.regSquare2\">Modelica.Fluid.Utilities.regSquare2</a>)
+and TIL library
+(<a href=\"Modelica://TIL.Utilities.Numerics.inverseSquareRootFunctionWithFactorRevised\">TIL.Utilities.Numerics.inverseSquareRootFunctionWithFactorRevised</a>)
+and has been slightly adapted.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end regSquareWFactors;
diff --git a/SorpLib/Numerics/regSquareWFactors_inv.mo b/SorpLib/Numerics/regSquareWFactors_inv.mo
new file mode 100644
index 0000000..a95ac9f
--- /dev/null
+++ b/SorpLib/Numerics/regSquareWFactors_inv.mo
@@ -0,0 +1,99 @@
+within SorpLib.Numerics;
+function regSquareWFactors_inv
+  "Inverse function of the anti-symmetric square (with discontinuous factors) approximation with non-zero derivative in the origin"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real y
+    "Approximated value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real delta_x = 1e-4
+    "Regulation value for approximation"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f_positive(min=0) = 1
+    "Factor for x > 0 (must be >= 0)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f_negative(min=0) = 1
+    "Factor for x < 0 (must be >= 0)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real x
+    "Original input value"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real f
+    "Factor";
+
+algorithm
+  //
+  // Calculate factor
+  //
+  if y > 0 then
+    f := f_positive
+    "Factor";
+
+  elseif y < 0 then
+    f := f_negative
+    "Factor";
+
+  else
+    f := (f_positive + f_negative) / 2
+    "Factor";
+  end if;
+
+  //
+  // Approximate value
+  //
+  if Modelica.Math.isEqual(s1=f, s2=0, eps=Modelica.Constants.small) then
+    x := 0
+      "No finite solution";
+
+  elseif y > delta_x * delta_x / f then
+    x := sqrt(y * f)
+      "No approximation";
+
+  elseif y < -delta_x * delta_x / f then
+    x := -sqrt(-y * f)
+      "Keep sign of input";
+
+  else
+    x := delta_x^2 /
+      (-27*delta_x*y*f + sqrt(108*delta_x^6 + 2916*delta_x^2*y^2*f^2)/2)^(1/3) -
+      (-27*delta_x*y*f + sqrt(108*delta_x^6 + 2916*delta_x^2*y^2*f^2)/2)^(1/3) / 3
+      "Transition region: Solving cubic equations and discarding complex 
+      solutions";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+smoothOrder=1,
+inverse(y=regSquareWFactors(x,delta_x,f_positive,f_negative)),
+Documentation(info="<html>
+<p>
+This function is the inverse function of the function 'regSquareWFactors.' For full 
+details, check the documentation of the function
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors\">SorpLib.Numerics.regSquareWFactors</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end regSquareWFactors_inv;
diff --git a/SorpLib/Numerics/regSquareWFactors_inv_noEvent.mo b/SorpLib/Numerics/regSquareWFactors_inv_noEvent.mo
new file mode 100644
index 0000000..fa29690
--- /dev/null
+++ b/SorpLib/Numerics/regSquareWFactors_inv_noEvent.mo
@@ -0,0 +1,99 @@
+within SorpLib.Numerics;
+function regSquareWFactors_inv_noEvent
+  "Inverse function of the anti-symmetric square (with discontinuous factors) approximation with non-zero derivative in the origin (without events)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real y
+    "Approximated value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real delta_x = 1e-4
+    "Regulation value for approximation"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f_positive(min=0) = 1
+    "Factor for x > 0 (must be >= 0)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f_negative(min=0) = 1
+    "Factor for x < 0 (must be >= 0)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real x
+    "Original input value"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real f
+    "Factor";
+
+algorithm
+  //
+  // Calculate factor
+  //
+  if noEvent(y > 0) then
+    f := f_positive
+    "Factor";
+
+  elseif noEvent(y < 0) then
+    f := f_negative
+    "Factor";
+
+  else
+    f := (f_positive + f_negative) / 2
+    "Factor";
+  end if;
+
+  //
+  // Approximate value
+  //
+  if noEvent(Modelica.Math.isEqual(s1=f, s2=0, eps=Modelica.Constants.small)) then
+    x := 0
+      "No finite solution";
+
+  elseif noEvent(y > delta_x * delta_x / f) then
+    x := sqrt(y * f)
+      "No approximation";
+
+  elseif noEvent(y < -delta_x * delta_x / f) then
+    x := -sqrt(-y * f)
+      "Keep sign of input";
+
+  else
+    x := delta_x^2 /
+      (-27*delta_x*y*f + sqrt(108*delta_x^6 + 2916*delta_x^2*y^2*f^2)/2)^(1/3) -
+      (-27*delta_x*y*f + sqrt(108*delta_x^6 + 2916*delta_x^2*y^2*f^2)/2)^(1/3) / 3
+      "Transition region: Solving cubic equations and discarding complex 
+      solutions";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+smoothOrder=1,
+inverse(y=regSquareWFactors_noEvent(x,delta_x,f_positive,f_negative)),
+Documentation(info="<html>
+<p>
+This function is the inverse function of the function 'regSquareWFactors.' For full 
+details, check the documentation of the function
+<a href=\"Modelica://SorpLib.Numerics.regSquareWFactors_noEvent\">SorpLib.Numerics.regSquareWFactors_noEvent</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end regSquareWFactors_inv_noEvent;
diff --git a/SorpLib/Numerics/regSquareWFactors_noEvent.mo b/SorpLib/Numerics/regSquareWFactors_noEvent.mo
new file mode 100644
index 0000000..b56d794
--- /dev/null
+++ b/SorpLib/Numerics/regSquareWFactors_noEvent.mo
@@ -0,0 +1,140 @@
+within SorpLib.Numerics;
+function regSquareWFactors_noEvent
+  "Anti-symmetric square (with discontinuous factors) approximation with non-zero derivative in the origin (without events)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Input value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real delta_x = 1e-4
+    "Regulation value for approximation"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f_positive(min=0) = 1
+    "Factor for x > 0 (must be >= 0)"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real f_negative(min=0) = 1
+    "Factor for x < 0 (must be >= 0)"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real y
+    "Approximated value"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+  //
+  // Definition of variables
+  //
+protected
+  Real f
+    "Factor";
+
+algorithm
+  //
+  // Calculate factor
+  //
+  if noEvent(x > 0) then
+    f := f_positive
+    "Factor";
+
+  elseif noEvent(x < 0) then
+    f := f_negative
+    "Factor";
+
+  else
+    f := (f_positive + f_negative) / 2
+    "Factor";
+  end if;
+
+  //
+  // Approximate value
+  //
+  if noEvent(Modelica.Math.isEqual(s1=f, s2=0, eps=Modelica.Constants.small)) then
+    y := Modelica.Constants.inf
+      "No finite solution";
+
+  elseif noEvent(x > delta_x) then
+    y := x*x / f
+      "No approximation";
+
+  elseif noEvent(x < -delta_x) then
+    y := -x*x / f
+      "Keep sign of input";
+
+  else
+    y := (0.5/delta_x * x^2 + 0.5*delta_x) * x / f
+      "Transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+smoothOrder=1,
+inverse(x=regSquareWFactors_inv_noEvent(y,delta_x,f_positive,f_negative)),
+Documentation(info="<html>
+<p><p>
+This function is used to approximate the equation
+</p>
+<pre>
+   y = x<sup>2</sup> / f;
+</pre>
+<p>
+with the factor <i>f</i> beeing dependent on the flow direction:
+</p>
+<pre>
+   f = <strong>if</strong> x &gt; 0 <strong>then</strong> f_positive <strong>elseif</strong> x &lt; 0 <strong>then</strong> f_negative <strong>else</strong> (f_positive + f_negative) / 2;
+</pre>
+<p>
+for (1) the slope to be non-zero at the origin, (2) the function to be continuous 
+and differentiable, and (3) the sign of the input to not change:
+</p>
+
+<pre>
+   y = <strong>if</strong> x &gt; delta_x <strong>then</strong> x<sup>2</sup> / f <strong>else</strong>
+       <strong>if</strong> x &lt; -delta_x <strong>then</strong> -x<sup>2</sup> / f <strong>else</strong>
+       0.5 * x * (x<sup>2</sup> / delta_x + delta_x) / f;
+</pre>
+
+<p>
+In the region -delta_x &lt; x &lt; delta_x, a 3rd order polynomial is used.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This function is used, for example, to calculate mass flow rates depending on 
+prssure drops.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the approximated square for different values of 
+<i>delta_x</i>, <i>f_positive=3</i>, and <i>f_negative=2</i>.
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/numerics_regSquareWFactors.png\" alt=\"numerics_regSquareWFactors.png\">
+
+<h4>References</h4>
+<p>
+The function is based on the MSL library
+(<a href=\"Modelica://Modelica.Fluid.Utilities.regSquare2\">Modelica.Fluid.Utilities.regSquare2</a>)
+and TIL library
+(<a href=\"Modelica://TIL.Utilities.Numerics.inverseSquareRootFunctionWithFactorRevised\">TIL.Utilities.Numerics.inverseSquareRootFunctionWithFactorRevised</a>)
+and has been slightly adapted.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  December 19, 2023, by Mirko Engelpracht:<br/>
+  First implementation.
+  </li>
+</ul>
+</html>"));
+end regSquareWFactors_noEvent;
diff --git a/SorpLib/Numerics/regSquare_inv.mo b/SorpLib/Numerics/regSquare_inv.mo
new file mode 100644
index 0000000..a787560
--- /dev/null
+++ b/SorpLib/Numerics/regSquare_inv.mo
@@ -0,0 +1,62 @@
+within SorpLib.Numerics;
+function regSquare_inv
+  "Inverse function of the anti-symmetric square approximation with non-zero derivative in the origin"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real y
+    "Approximated value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real delta_x = 1e-4
+    "Regulation value for approximation"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real x
+    "Input value"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  if (y > delta_x*delta_x) then
+    x := sqrt(y)
+      "No approximation";
+
+  elseif (y < -delta_x*delta_x) then
+    x := -sqrt(-y)
+      "Keep sign of input";
+
+  else
+    x := delta_x^2 /
+      (-27*delta_x*y + sqrt(108*delta_x^6 + 2916*delta_x^2*y^2)/2)^(1/3) -
+      (-27*delta_x*y + sqrt(108*delta_x^6 + 2916*delta_x^2*y^2)/2)^(1/3) / 3
+      "Transition region: Solving cubic equations and discarding complex 
+      solutions";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+smoothOrder=1,
+inverse(y=regSquare(x,delta_x)),
+Documentation(info="<html>
+<p>
+This function is the inverse function of the function 'regSquare.' For full 
+details, check the documentation of the function
+<a href=\"Modelica://SorpLib.Numerics.regSquare\">SorpLib.Numerics.regSquare</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end regSquare_inv;
diff --git a/SorpLib/Numerics/regSquare_inv_noEvent.mo b/SorpLib/Numerics/regSquare_inv_noEvent.mo
new file mode 100644
index 0000000..256f4e2
--- /dev/null
+++ b/SorpLib/Numerics/regSquare_inv_noEvent.mo
@@ -0,0 +1,62 @@
+within SorpLib.Numerics;
+function regSquare_inv_noEvent
+  "Inverse function of the anti-symmetric square approximation with non-zero derivative in the origin (without events)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real y
+    "Approximated value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real delta_x = 1e-4
+    "Regulation value for approximation"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real x
+    "Input value"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  if noEvent(y > delta_x*delta_x) then
+    x := sqrt(y)
+      "No approximation";
+
+  elseif noEvent(y < -delta_x*delta_x) then
+    x := -sqrt(-y)
+      "Keep sign of input";
+
+  else
+    x := delta_x^2 /
+      (-27*delta_x*y + sqrt(108*delta_x^6 + 2916*delta_x^2*y^2)/2)^(1/3) -
+      (-27*delta_x*y + sqrt(108*delta_x^6 + 2916*delta_x^2*y^2)/2)^(1/3) / 3
+      "Transition region: Solving cubic equations and discarding complex 
+      solutions";
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+smoothOrder=1,
+inverse(y=regSquare_noEvent(x,delta_x)),
+Documentation(info="<html>
+<p>
+This function is the inverse function of the function 'regSquare_noEvent.' For
+full details, check the documentation of the function
+<a href=\"Modelica://SorpLib.Numerics.regSquare_noEvent\">SorpLib.Numerics.regSquare_noEvent</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end regSquare_inv_noEvent;
diff --git a/SorpLib/Numerics/regSquare_noEvent.mo b/SorpLib/Numerics/regSquare_noEvent.mo
new file mode 100644
index 0000000..64c1481
--- /dev/null
+++ b/SorpLib/Numerics/regSquare_noEvent.mo
@@ -0,0 +1,98 @@
+within SorpLib.Numerics;
+function regSquare_noEvent
+  "Anti-symmetric square approximation with non-zero derivative in the origin (without events)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Input value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real delta_x = 1e-4
+    "Regulation value for approximation"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real y
+    "Approximated value"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  if noEvent(x > delta_x) then
+    y := x*x
+      "No approximation";
+
+  elseif noEvent(x < -delta_x) then
+    y := -x*x
+      "Keep sign of input";
+
+  else
+    y := (0.5/delta_x * x^2 + 0.5*delta_x) * x
+      "Transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=false,
+LateInline=true,
+smoothOrder=1,
+inverse(x=regSquare_inv_noEvent(y,delta_x)),
+Documentation(info="<html>
+<p><p>
+This function is used to approximate the equation
+</p>
+<pre>
+    y = x<sup>2</sup>;
+</pre>
+
+<p>
+for (1) the slope to be non-zero at the origin, (2) the function to be continuous 
+and differentiable, (3) the sign of the input to not change, and (4) no events to
+occur:
+</p>
+
+<pre>
+   y = <strong>if</strong> x &gt; delta_x <strong>then</strong> x<sup>2</sup> <strong>else</strong>
+       <strong>if</strong> x &lt; -delta_x <strong>then</strong> -x<sup>2</sup> <strong>else</strong>
+       0.5 * x * (x<sup>2</sup> / delta_x + delta_x);
+</pre>
+
+<p>
+In the region -delta_x &lt; x &lt; delta_x a 3rd order polynomial is used.
+</p>
+
+<h4>Typical use</h4>
+<p>
+This function is used, for example, to calculate pressure drop correlations.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the approximated square for different values of <i>delta_x</i>.
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/numerics_regSquare.png\" alt=\"numerics_regSquare.png\">
+
+<h4>References</h4>
+<p>
+The function is based on the MSL library
+(<a href=\"Modelica://Modelica.Fluid.Utilities.regSquare\">Modelica.Fluid.Utilities.regSquare</a>)
+and TIL library
+(<a href=\"Modelica://TIL.Utilities.Numerics.squareFunction\">TIL.Utilities.Numerics.squareFunction</a>)
+and has been slightly adapted.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end regSquare_noEvent;
diff --git a/SorpLib/Numerics/regStep.mo b/SorpLib/Numerics/regStep.mo
new file mode 100644
index 0000000..8f2d749
--- /dev/null
+++ b/SorpLib/Numerics/regStep.mo
@@ -0,0 +1,84 @@
+within SorpLib.Numerics;
+function regStep
+  "Approximation of a general step to get a continuous and differentiable characteristic"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Abscissa value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real y1
+    "Ordinate value for x > 0"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real y2
+    "Ordinate value for x < 0"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real x_small(min=0) = 1e-5
+    "Approximation of step for -x_small <= x <= x_small; x_small >= 0 required"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real y
+    "Ordinate value to approximate y = if x > 0 then y1 else y2"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  y := smooth(1, if x >  x_small then y1 else
+                 if x < -x_small then y2 else
+                 if x_small > 0 then
+                   (x/x_small)*((x/x_small)^2 - 3)*(y2-y1)/4 + (y1+y2)/2 else
+                   (y1+y2)/2)
+    "Smooth transition";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is used to approximate the equation
+</p>
+<pre>
+    y = <strong>if</strong> x &gt; 0 <strong>then</strong> y1 <strong>else</strong> y2;
+</pre>
+
+<p>
+by a smooth characteristic to get a continuous and differentiable expression:
+</p>
+
+<pre>
+   y = <strong>smooth</strong>(1, <strong>if</strong> x &gt;  x_small <strong>then</strong> y1 <strong>else</strong>
+                 <strong>if</strong> x &lt; -x_small <strong>then</strong> y2 <strong>else</strong> f(y1, y2));
+</pre>
+
+<p>
+In the region -x_small &lt; x &lt; x_small a 2nd order polynomial is used
+for a smooth transition from y1 to y2.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the smooth characteristic for different values of
+<i>x_small</i>, <i>y1 = -1</i>, and <i>y2 = 1</i>.
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/numerics_regStep.png\" alt=\"numerics_regStep.png\">
+
+<h4>References</h4>
+<p>
+The function and documentation are taken from the Modelica standard library
+(<a href=\"Modelica://Modelica.Fluid.Utilities.regStep\">Modelica.Fluid.Utilities.regStep</a>)
+and have been slightly adapted.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end regStep;
diff --git a/SorpLib/Numerics/regStep_noEvent.mo b/SorpLib/Numerics/regStep_noEvent.mo
new file mode 100644
index 0000000..6d3b53d
--- /dev/null
+++ b/SorpLib/Numerics/regStep_noEvent.mo
@@ -0,0 +1,86 @@
+within SorpLib.Numerics;
+function regStep_noEvent
+  "Approximation of a general step to get a continuous and differentiable characteristic (without events)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Abscissa value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real y1
+    "Ordinate value for x > 0"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real y2
+    "Ordinate value for x < 0"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real x_small(min=0) = 1e-5
+    "Approximation of step for -x_small <= x <= x_small; x_small >= 0 required"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real y
+    "Ordinate value to approximate y = if x > 0 then y1 else y2"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+algorithm
+  y := smooth(1,
+              noEvent(if x >  x_small then y1 else
+                      if x < -x_small then y2 else
+                      if x_small > 0 then
+                        (x/x_small)*((x/x_small)^2 - 3)*(y2-y1)/4 + (y1+y2)/2 else
+                        (y1+y2)/2))
+    "Smooth transition";
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is used to approximate the equation
+</p>
+<pre>
+    y = <strong>if</strong> x &gt; 0 <strong>then</strong> y1 <strong>else</strong> y2;
+</pre>
+
+<p>
+by a smooth characteristic to get a continuous and differentiable expression
+and events are avoided:
+</p>
+
+<pre>
+   y = <strong>smooth</strong>(1, <strong>if</strong> x &gt;  x_small <strong>then</strong> y1 <strong>else</strong>
+                 <strong>if</strong> x &lt; -x_small <strong>then</strong> y2 <strong>else</strong> f(y1, y2));
+</pre>
+
+<p>
+In the region -x_small &lt; x &lt; x_small a 2nd order polynomial is used
+for a smooth transition from y1 to y2.
+</p>
+
+<h4>Example</h4>
+<p>
+The following figure shows the smooth characteristic for different values of
+<i>x_small</i>, <i>y1 = -1</i>, and <i>y2 = 1</i>.
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/numerics_regStep.png\" alt=\"numerics_regStep.png\">
+
+<h4>References</h4>
+<p>
+The function and documentation are taken from the Modelica standard library
+(<a href=\"Modelica://Modelica.Fluid.Utilities.regStep\">Modelica.Fluid.Utilities.regStep</a>)
+and have been slightly adapted.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end regStep_noEvent;
diff --git a/SorpLib/Numerics/smoothTransition.mo b/SorpLib/Numerics/smoothTransition.mo
new file mode 100644
index 0000000..0585afc
--- /dev/null
+++ b/SorpLib/Numerics/smoothTransition.mo
@@ -0,0 +1,147 @@
+within SorpLib.Numerics;
+function smoothTransition
+  "Smoothly changes the output from 1 to 0 around the transition point to get a continuous and differentiable transition"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Actual value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionPoint=1
+    "Transition point"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionLength=1
+    "Transition length"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Integer noDiff = 1
+    "Specification how often function can be differentiated (i.e., 1, 2 or 3)"
+    annotation (Dialog(tab="General", group="Numerics"));
+
+  //
+  // Definition of outputs
+  //
+  output Real weigthingFactor
+    "Weighting factor"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+protected
+  Real phi
+    "Phase";
+
+algorithm
+  if x < transitionPoint - 0.5*transitionLength then
+    weigthingFactor := 1
+    "No transition region";
+
+  elseif x < transitionPoint + 0.5*transitionLength then
+    phi := (x - transitionPoint)*Modelica.Constants.pi/transitionLength
+      "Phase";
+
+    if noDiff == 1 then
+      weigthingFactor := -1.0/2.0 * sin(phi) + 1.0/2.0
+        "Transition region";
+
+    elseif noDiff == 2 then
+      weigthingFactor := -1.0/2.0 * (2*cos(phi)*sin(phi) +
+        2*phi - Modelica.Constants.pi) / Modelica.Constants.pi
+        "Transition region";
+
+    else
+      weigthingFactor := 1.0/6.0 * (-4.0*sin(phi)*cos(phi)^3 -
+        6.0*phi - 3.0*sin(2.0*phi) + 3.0*Modelica.Constants.pi) /
+        Modelica.Constants.pi
+        "Transition region";
+
+    end if;
+
+  else
+    weigthingFactor := 0
+    "No transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=true,
+derivative(order=1,
+           noDerivative=transitionPoint,
+           noDerivative=transitionLength,
+           noDerivative=noDiff) = smoothTransition_der,
+Documentation(info="<html>
+<p>
+This function is used to smoothly change a weighting factor <i>WF</i> from 1 
+to 0 at the specified point <i>transitionPoint</i> within the specified length 
+<i>transitionLength</i>. The change is continuous and differentiable, and the 
+type of change is specified via the parameter <i>noDiff</i>.
+<br/><br/>
+The change is described using trigonometric functions that depend on the current 
+phase <i>&phi;</i>:
+</p>
+
+<pre>
+    &phi; = (x - transitionPoint) * &pi; / transitionLength;
+</pre>
+
+<p>
+For <i>noDiff = 1</i>, the change is continuously differentiable once:
+</p>
+
+<pre>
+    WF = -0.5 * <strong>sin</strong>(&phi;) + 0.5;
+</pre>
+
+<p>
+For <i>noDiff = 2</i>, the change can be continuously differentiated twice:
+</p>
+
+<pre>
+    WF = -0.5 * (2 * <strong>cos</strong>(&phi;) * <strong>sin</strong>(&phi;) + 2 * &phi; - &pi;) / &pi;;
+</pre>
+
+<p>
+For <i>noDiff = 3</i>, the change can be continuously differentiated three times:
+</p>
+
+<pre>
+    WF = 1/6 * (-4 * <strong>sin</strong>(&phi;) * <strong>cos</strong><sup>3</sup>(&phi;) - 6 * &phi; - 3 * <strong>sin</strong>(2 * &phi;) + 3 * &pi;) / &pi;;
+</pre>
+
+<h4>Typical use</h4>
+<p>
+This function is used, for example, to switch smoothly between different flow 
+regimes when calculating heat or mass transport. For this purpose, the function 
+can be used as follows:
+</p>
+
+<pre>
+    y = WF * y(Regime 1) + (1 - WF) * y(Regime 2);
+</pre>
+
+<h4>Example</h4>
+<p>
+The following figure shows the smooth transition of the weighting factor
+<i>WF</i> and its derivatives for different values of <i>noDiff</i> at 
+<i>transitionPoint = 1</i> for <i>transitionLength = 1</i>.
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/numerics_smoothTransition.png\" alt=\"numerics_smoothTransition.png\">
+
+<h4>References</h4>
+<p>
+The function is based on the TIL library
+(<a href=\"Modelica://TIL.Utilities.Numerics.smoothTransition\">TIL.Utilities.Numerics.smoothTransition</a>)
+and has been slightly adapted.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end smoothTransition;
diff --git a/SorpLib/Numerics/smoothTransition_der.mo b/SorpLib/Numerics/smoothTransition_der.mo
new file mode 100644
index 0000000..590af2d
--- /dev/null
+++ b/SorpLib/Numerics/smoothTransition_der.mo
@@ -0,0 +1,95 @@
+within SorpLib.Numerics;
+function smoothTransition_der
+  "First derivative of function 'smoothTransition'"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Actual value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionPoint=1
+    "Transition point"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionLength=1
+    "Transition length"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Integer noDiff = 1
+    "Specification how often function can be differentiated (i.e., 1, 2 or 3)"
+    annotation (Dialog(tab="General", group="Numerics"));
+
+  input Real x_der
+    "First derivative of actual value wrt. time"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real weigthingFactor
+    "First derivative of weighting factor"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+protected
+  Real phi
+    "Phase";
+  Real dphi_dtau
+    "First derivative of phase wrt. time";
+
+algorithm
+  if x < transitionPoint-0.5*transitionLength then
+    weigthingFactor := 0
+    "No transition region";
+
+  elseif x < transitionPoint+0.5*transitionLength then
+    phi := (x - transitionPoint)*Modelica.Constants.pi/transitionLength
+      "Phase";
+    dphi_dtau := x_der*Modelica.Constants.pi/transitionLength
+      "First derivative of weighting factor";
+
+    if noDiff == 1 then
+      weigthingFactor := -1.0/2.0 * cos(phi) * dphi_dtau
+        "Transition region";
+
+    elseif noDiff == 2 then
+      weigthingFactor := -dphi_dtau / Modelica.Constants.pi *
+        (cos(phi)^2 - sin(phi)^2 + 1)
+        "Transition region";
+
+    else
+      weigthingFactor := dphi_dtau / 3.0 / Modelica.Constants.pi *
+        (-2.0*cos(phi)^4 + 6.0*sin(phi)^2*cos(phi)^2 - 3.0 - 3.0*cos(2.0*phi))
+        "Transition region";
+
+    end if;
+
+  else
+    weigthingFactor := 0
+    "No transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=true,
+derivative(order=2,
+           noDerivative=transitionPoint,
+           noDerivative=transitionLength,
+           noDerivative=noDiff) = smoothTransition_der2,
+Documentation(info="<html>
+<p>
+This function is the first derivative of the function 'smoothTransition' with 
+respect to time. For full details, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end smoothTransition_der;
diff --git a/SorpLib/Numerics/smoothTransition_der2.mo b/SorpLib/Numerics/smoothTransition_der2.mo
new file mode 100644
index 0000000..14a705a
--- /dev/null
+++ b/SorpLib/Numerics/smoothTransition_der2.mo
@@ -0,0 +1,101 @@
+within SorpLib.Numerics;
+function smoothTransition_der2
+  "Second derivative of function 'smoothTransition'"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Actual value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionPoint=1
+    "Transition point"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionLength=1
+    "Transition length"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Integer noDiff = 1
+    "Specification how often function can be differentiated (i.e., 1, 2 or 3)"
+    annotation (Dialog(tab="General", group="Numerics"));
+
+  input Real x_der
+    "First derivative of actual value wrt. time"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real x_der2
+    "Second derivative of actual value wrt. time"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real weigthingFactor
+    "Second derivative of weighting factor"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+protected
+  Real phi
+    "Phase";
+  Real dphi_dtau
+    "First derivative of phase wrt. time";
+  Real d2phi_d2tau
+    "Second derivative of phase wrt. time";
+
+algorithm
+  if x < transitionPoint-0.5*transitionLength then
+    weigthingFactor := 0
+    "No transition region";
+
+  elseif x < transitionPoint+0.5*transitionLength then
+    phi := (x - transitionPoint)*Modelica.Constants.pi/transitionLength
+      "Phase";
+    dphi_dtau := x_der*Modelica.Constants.pi/transitionLength
+      "First derivative of weighting factor";
+    d2phi_d2tau := x_der2*Modelica.Constants.pi/transitionLength
+      "First derivative of weighting factor";
+
+    if noDiff == 1 then
+      weigthingFactor := -1.0/2.0 *
+        (-sin(phi) * dphi_dtau^2 + cos(phi) * d2phi_d2tau)
+        "Transition region";
+
+    elseif noDiff == 2 then
+      weigthingFactor := -d2phi_d2tau / Modelica.Constants.pi *
+        (cos(phi)^2 - sin(phi)^2 + 1) +
+        4 * dphi_dtau^2 / Modelica.Constants.pi * cos(phi)*sin(phi)
+        "Transition region";
+
+    else
+      weigthingFactor := d2phi_d2tau / 3.0 / Modelica.Constants.pi *
+        (-2.0*cos(phi)^4 + 6.0*sin(phi)^2*cos(phi)^2 - 3.0 - 3.0*cos(2.0*phi)) +
+        dphi_dtau^2 / 3.0 / Modelica.Constants.pi *
+        (8.0*cos(phi)^3*sin(phi) +  12.0*sin(phi)*cos(phi)^3 -
+        12.0*sin(phi)^2*cos(phi)*sin(phi) + 6.0*sin(2.0*phi))
+        "Transition region";
+
+    end if;
+
+  else
+    weigthingFactor := 0
+    "No transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the first derivative of the function 'smoothTransition' with 
+respect to time. For full details, check the documentation of the function 
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition\">SorpLib.Numerics.smoothTransition</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end smoothTransition_der2;
diff --git a/SorpLib/Numerics/smoothTransition_der2_noEvent.mo b/SorpLib/Numerics/smoothTransition_der2_noEvent.mo
new file mode 100644
index 0000000..7edd3ae
--- /dev/null
+++ b/SorpLib/Numerics/smoothTransition_der2_noEvent.mo
@@ -0,0 +1,101 @@
+within SorpLib.Numerics;
+function smoothTransition_der2_noEvent
+  "Second derivative of function 'smoothTransition_noEvent' (without events)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Actual value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionPoint=1
+    "Transition point"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionLength=1
+    "Transition length"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Integer noDiff = 1
+    "Specification how often function can be differentiated (i.e., 1, 2 or 3)"
+    annotation (Dialog(tab="General", group="Numerics"));
+
+  input Real x_der
+    "First derivative of actual value wrt. time"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real x_der2
+    "Second derivative of actual value wrt. time"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real weigthingFactor
+    "Second derivative of weighting factor"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+protected
+  Real phi
+    "Phase";
+  Real dphi_dtau
+    "First derivative of phase wrt. time";
+  Real d2phi_d2tau
+    "Second derivative of phase wrt. time";
+
+algorithm
+  if noEvent(x < transitionPoint-0.5*transitionLength) then
+    weigthingFactor := 0
+    "No transition region";
+
+  elseif noEvent(x < transitionPoint+0.5*transitionLength) then
+    phi := (x - transitionPoint)*Modelica.Constants.pi/transitionLength
+      "Phase";
+    dphi_dtau := x_der*Modelica.Constants.pi/transitionLength
+      "First derivative of weighting factor";
+    d2phi_d2tau := x_der2*Modelica.Constants.pi/transitionLength
+      "First derivative of weighting factor";
+
+    if noEvent(noDiff == 1) then
+      weigthingFactor := -1.0/2.0 *
+        (-sin(phi) * dphi_dtau^2 + cos(phi) * d2phi_d2tau)
+        "Transition region";
+
+    elseif noEvent(noDiff == 2) then
+      weigthingFactor := -d2phi_d2tau / Modelica.Constants.pi *
+        (cos(phi)^2 - sin(phi)^2 + 1) +
+        4 * dphi_dtau^2 / Modelica.Constants.pi * cos(phi)*sin(phi)
+        "Transition region";
+
+    else
+      weigthingFactor := d2phi_d2tau / 3.0 / Modelica.Constants.pi *
+        (-2.0*cos(phi)^4 + 6.0*sin(phi)^2*cos(phi)^2 - 3.0 - 3.0*cos(2.0*phi)) +
+        dphi_dtau^2 / 3.0 / Modelica.Constants.pi *
+        (8.0*cos(phi)^3*sin(phi) +  12.0*sin(phi)*cos(phi)^3 -
+        12.0*sin(phi)^2*cos(phi)*sin(phi) + 6.0*sin(2.0*phi))
+        "Transition region";
+
+    end if;
+
+  else
+    weigthingFactor := 0
+    "No transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Documentation(info="<html>
+<p>
+This function is the first derivative of the function 'smoothTransition_noEvent'
+with respect to time. For full details, check the documentation of the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition_noEvent\">SorpLib.Numerics.smoothTransition_noEvent</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end smoothTransition_der2_noEvent;
diff --git a/SorpLib/Numerics/smoothTransition_der_noEvent.mo b/SorpLib/Numerics/smoothTransition_der_noEvent.mo
new file mode 100644
index 0000000..4abd68c
--- /dev/null
+++ b/SorpLib/Numerics/smoothTransition_der_noEvent.mo
@@ -0,0 +1,95 @@
+within SorpLib.Numerics;
+function smoothTransition_der_noEvent
+  "First derivative of function 'smoothTransition_noEvent' (without events)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Actual value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionPoint=1
+    "Transition point"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionLength=1
+    "Transition length"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Integer noDiff = 1
+    "Specification how often function can be differentiated (i.e., 1, 2 or 3)"
+    annotation (Dialog(tab="General", group="Numerics"));
+
+  input Real x_der
+    "First derivative of actual value wrt. time"
+    annotation (Dialog(tab="General", group="Inputs"));
+
+  //
+  // Definition of outputs
+  //
+  output Real weigthingFactor
+    "First derivative of weighting factor"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+protected
+  Real phi
+    "Phase";
+  Real dphi_dtau
+    "First derivative of phase wrt. time";
+
+algorithm
+  if noEvent(x < transitionPoint-0.5*transitionLength) then
+    weigthingFactor := 0
+    "No transition region";
+
+  elseif noEvent(x < transitionPoint+0.5*transitionLength) then
+    phi := (x - transitionPoint)*Modelica.Constants.pi/transitionLength
+      "Phase";
+    dphi_dtau := x_der*Modelica.Constants.pi/transitionLength
+      "First derivative of weighting factor";
+
+    if noEvent(noDiff == 1) then
+      weigthingFactor := -1.0/2.0 * cos(phi) * dphi_dtau
+        "Transition region";
+
+    elseif noEvent(noDiff == 2) then
+      weigthingFactor := -dphi_dtau / Modelica.Constants.pi *
+        (cos(phi)^2 - sin(phi)^2 + 1)
+        "Transition region";
+
+    else
+      weigthingFactor := dphi_dtau / 3.0 / Modelica.Constants.pi *
+        (-2.0*cos(phi)^4 + 6.0*sin(phi)^2*cos(phi)^2 - 3.0 - 3.0*cos(2.0*phi))
+        "Transition region";
+
+    end if;
+
+  else
+    weigthingFactor := 0
+    "No transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=true,
+derivative(order=2,
+           noDerivative=transitionPoint,
+           noDerivative=transitionLength,
+           noDerivative=noDiff) = smoothTransition_der2_noEvent,
+Documentation(info="<html>
+<p>
+This function is the first derivative of the function 'smoothTransition_noEvent' 
+with respect to time. For full details, check the documentation of the function
+<a href=\"Modelica://SorpLib.Numerics.smoothTransition_noEvent\">SorpLib.Numerics.smoothTransition_noEvent</a>.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end smoothTransition_der_noEvent;
diff --git a/SorpLib/Numerics/smoothTransition_noEvent.mo b/SorpLib/Numerics/smoothTransition_noEvent.mo
new file mode 100644
index 0000000..0ec7cb1
--- /dev/null
+++ b/SorpLib/Numerics/smoothTransition_noEvent.mo
@@ -0,0 +1,148 @@
+within SorpLib.Numerics;
+function smoothTransition_noEvent
+  "Smoothly changes the output from 1 to 0 around the transition point to get a continuous and differentiable transition (without events)"
+  extends Modelica.Icons.Function;
+
+  //
+  // Definition of inputs
+  //
+  input Real x
+    "Actual value"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionPoint=1
+    "Transition point"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Real transitionLength=1
+    "Transition length"
+    annotation (Dialog(tab="General", group="Inputs"));
+  input Integer noDiff = 1
+    "Specification how often function can be differentiated (i.e., 1, 2 or 3)"
+    annotation (Dialog(tab="General", group="Numerics"));
+
+  //
+  // Definition of outputs
+  //
+  output Real weigthingFactor
+    "Weighting factor"
+    annotation (Dialog(tab="General", group="Outputs", enable=false));
+
+protected
+  Real phi
+    "Phase";
+
+algorithm
+  if noEvent(x < transitionPoint - 0.5*transitionLength) then
+    weigthingFactor := 1
+    "No transition region";
+
+  elseif noEvent(x < transitionPoint + 0.5*transitionLength) then
+    phi := (x - transitionPoint)*Modelica.Constants.pi/transitionLength
+      "Phase";
+
+    if noEvent(noDiff == 1) then
+      weigthingFactor := -1.0/2.0 * sin(phi) + 1.0/2.0
+        "Transition region";
+
+    elseif noEvent(noDiff == 2) then
+      weigthingFactor := -1.0/2.0 * (2*cos(phi)*sin(phi) +
+        2*phi - Modelica.Constants.pi) / Modelica.Constants.pi
+        "Transition region";
+
+    else
+      weigthingFactor := 1.0/6.0 * (-4.0*sin(phi)*cos(phi)^3 -
+        6.0*phi - 3.0*sin(2.0*phi) + 3.0*Modelica.Constants.pi) /
+        Modelica.Constants.pi
+        "Transition region";
+
+    end if;
+
+  else
+    weigthingFactor := 0
+    "No transition region";
+
+  end if;
+
+  //
+  // Annotations
+  //
+  annotation (Inline=false,
+InlineAfterIndexReduction=true,
+derivative(order=1,
+           noDerivative=transitionPoint,
+           noDerivative=transitionLength,
+           noDerivative=noDiff) = smoothTransition_der_noEvent,
+Documentation(info="<html>
+<p>
+This function is used to smoothly change a weighting factor <i>WF</i> from 1 
+to 0 at the specified point <i>transitionPoint</i> within the specified length 
+<i>transitionLength</i>. The change is continuous and differentiable, and the 
+type of change is specified via the parameter <i>noDiff</i>. The function is
+implemented to avoid events.
+<br/><br/>
+The change is described using trigonometric functions that depend on the current 
+phase <i>&phi;</i>:
+</p>
+
+<pre>
+    &phi; = (x - transitionPoint) * &pi; / transitionLength;
+</pre>
+
+<p>
+For <i>noDiff = 1</i>, the change is continuously differentiable once:
+</p>
+
+<pre>
+    WF = -0.5 * <strong>sin</strong>(&phi;) + 0.5;
+</pre>
+
+<p>
+For <i>noDiff = 2</i>, the change can be continuously differentiated twice:
+</p>
+
+<pre>
+    WF = -0.5 * (2 * <strong>cos</strong>(&phi;) * <strong>sin</strong>(&phi;) + 2 * &phi; - &pi;) / &pi;;
+</pre>
+
+<p>
+For <i>noDiff = 3</i>, the change can be continuously differentiated three times:
+</p>
+
+<pre>
+    WF = 1/6 * (-4 * <strong>sin</strong>(&phi;) * <strong>cos</strong><sup>3</sup>(&phi;) - 6 * &phi; - 3 * <strong>sin</strong>(2 * &phi;) + 3 * &pi;) / &pi;;
+</pre>
+
+<h4>Typical use</h4>
+<p>
+This function is used, for example, to switch smoothly between different flow 
+regimes when calculating heat or mass transport. For this purpose, the function 
+can be used as follows:
+</p>
+
+<pre>
+    y = WF * y(Regime 1) + (1 - WF) * y(Regime 2);
+</pre>
+
+<h4>Example</h4>
+<p>
+The following figure shows the smooth transition of the weighting factor
+<i>WF</i> and its derivatives for different values of <i>noDiff</i> at 
+<i>transitionPoint = 1</i> for <i>transitionLength = 1</i>.
+<br/><br/>
+</p>
+<img src=\"Modelica://SorpLib/Resources/doc/numerics_smoothTransition.png\" alt=\"numerics_smoothTransition.png\">
+
+<h4>References</h4>
+<p>
+The function is based on the TIL library
+(<a href=\"Modelica://TIL.Utilities.Numerics.smoothTransition\">TIL.Utilities.Numerics.smoothTransition</a>)
+and has been slightly adapted.
+</p>
+</html>", revisions="<html>
+<ul>
+  <li>
+  October 31, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
+end smoothTransition_noEvent;
diff --git a/SorpLib/Resources/Images/AdsorbensAdsorbate.png b/SorpLib/Resources/Images/AdsorbensAdsorbate.png
deleted file mode 100644
index f32bfe03948782418c489f02fa359daaeaf17ed7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5080
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
IIVCg!0IaH{VE_OC

diff --git a/SorpLib/Resources/Images/Adsorbent.png b/SorpLib/Resources/Images/Adsorbent.png
deleted file mode 100644
index 79195b53c8f323a753665cd84212426971fcc27d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 3004
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

diff --git a/SorpLib/Resources/Images/ClosedAdsorber.png b/SorpLib/Resources/Images/ClosedAdsorber.png
deleted file mode 100644
index f9c549dff10d5745cee0a1130a327814271e3125..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 9239
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

diff --git a/SorpLib/Resources/Images/DeltaP.png b/SorpLib/Resources/Images/DeltaP.png
deleted file mode 100644
index 0af655b541e5fdf2c0aceff50ee1f75d34d659c9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 16452
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

diff --git a/SorpLib/Resources/Images/Evaporator.png b/SorpLib/Resources/Images/Evaporator.png
deleted file mode 100644
index 40b19bd8b72d9e800cd5c6f0fa4a7d9e81121a83..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5584
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

diff --git a/SorpLib/Resources/Images/EvpCond.png b/SorpLib/Resources/Images/EvpCond.png
deleted file mode 100644
index 8669d89df4eed8b52155ef9d7926fd3c86ed91b8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1166
zcmeAS@N?(olHy`uVBq!ia0y~yVEDkmz?jFu%)r3-e|qRf1_lPk;vjb?hIQv;UNSH+
zu%tWsIx;Y9?C1WI$jZRLP!!-3;yU}p`&C!IGB7Y$)E}OB@YRB|pK_Mos^0i8Y2LNM
zRd>UuUEFZv$G*q^eEQDrfAZhB`ry{Pzch;XHg0{QS+bXbfuVfe{kC1tf+n5c_292=
z*?y1i)3(jWrX79Dz`(Hd;^*$YFBo7TebJ4WSy!CePJB*219Gc!NswRg|Np1|ql4ox
z0h9m#ZT`DVoA#!Lfq{Xuz$3Dlfk9jlgc(n%eYR&{U@r4?aSW-5dwch0myD%|YoMj=
zl;<05{6+PC|F6Gz@aZCTK{u{f9P)3!UJ-~fYkzlc+h(iFPk)y!$<gosu%q+1Z)$bf
zk{tQIDQ~||+_cv!Xq&lv#hoLMms!`<ta!5DC)XzLQQ_sVPfNGwYX7`+d)w5Sm$|pS
z_I=rwtNOn(|8b#k|Lk`^K7Q2C<}19@`PfgUJnG91p4<KNd2aXb=egbg*|mb<_*{#3
zM+(*ZtmoS7J7>=8_UCbJhx7G6-*@uEWx#s7<(}XE$o%c`AKO0-e=Y96l;0r#T$%wS
zpm+!*U@Ngf{`q-zwl~LrYQJZcDSxy>7}bFP?>}-b?>m3v@Xy~enum;9QaMfwOjFcx
zj%eG!lPC!jm?{0w#IdE`N8lm5u*;9ECXV}l0uTFzU4Fb~5v((JZ29~)9k*tXX=;ax
z=lojNBAoY3_ZfSf6b@@ZDpBl366kLGeEE8i;5mKA>0JeNZ=$sh{XF|NNbubG+1{=e
z`}5+o4*hg2U&-;j{E4@#g?*yF=)*rr^(#4^yZ>IQG^bvwF{I_QHR}?kIrS|~AuXRz
z^DI%C^Z)c_5riL+>>|#2I#TnJ!+sdOex07a)8}`zjW^G^^G9zaZ?I<DO(SA=DZ72V
zi|n5&!O{<VU9TME7Y}5wk9Lv$Q!H5e;kN6QgYU%y+3llTWdBqMmVUVGdgY+LSRniV
zNEg|fdco2U&t0z^{F!>>o5Y*GgYW1=<lQ}}t!X~}&uZ0}y1%T(zVY)Er{=u|Wo=Ja
KKbLh*2~7ZMh&X%z

diff --git a/SorpLib/Resources/Images/HXAirAir.png b/SorpLib/Resources/Images/HXAirAir.png
deleted file mode 100644
index 39dc642406eae3c8ae2d17d8cd86f8c42ef0848f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 5766
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

diff --git a/SorpLib/Resources/Images/HeatTransfer.png b/SorpLib/Resources/Images/HeatTransfer.png
deleted file mode 100644
index 2d5fc037c7c0c115317f1b8f9826a3850396deba..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1169
zcmeAS@N?(olHy`uVBq!ia0y~yVA#gMz~IZl#=yY9y>#9^1_lPk;vjb?CWiyHM;RCx
zI14-?iy0Wig+Q1wef}ko7ReIVh?3y^w370~qErUo%;ci{;{3D{1^=|P%;ePix2A;*
z3@n14E{-7;x8BZCobbp%#6ekm;)$sqDw~8lU6jI=Cb}w4^iU~!>ZKyo>9Wpck(l0I
zZsUjkL6fEk=gJ%BPrI9YODOKr{P|m6tqb`dzH;rqO7;w^TTkcyvkWm`x^IO*hVZSI
zix(*^=v6Q)aeni(XeGlewj|~xW(6|_D3PRWhTtfeDVU*22M0FX_)vdwy-#q2&I<7(
zdCfP1L+b+1_pFdUlDF%|eZGy{uh=%u)+xQOSbB2eFUL1(-FrWD#C~#=RV)iWYA4xQ
zZz8VvO}(_`hVPWB6wf`^a$0ZPzapGu9{8qrE^A?m`?^_jrL8x7Cs}QF>Yw~G`uvHU
z)3!_Z3GDVv@{e6<`}Y?2#_d<cldkuctM|{e_l*-}Tk)y$*Z*ym9|SA+<cEJdJW+M$
zhrbGCYtGafXY8)Jl$*LN>5b-e8KWsm(NFmv)iWQjd{PtNA*(fA<ky;;Gv%sNmy~&B
zpStIIGw#U7?p0If-JHMozv+F+r1lQg%UMs~&s-dC8*N)2b}{<-#N*qKzO9zJ8+_O?
z=Sbhws=$qJW4^87d)am3@$>bct|ZN7XFlSVGe1OI@$~iXw{I)TAHP`3ziD}YPK5D!
zvzd=qUHG|lO~+e#jku!+Hhf>?qoxwqeRA>*pAOwOTUP~6>GkWVb;vowCzvW1ac;Xq
z=ClGn<JEuklA`l%`fkXI-F`CXX-H|9^PBZYK5tNuKgJk7<5n-{#@o8z)KqKLKAk<N
z=yPD7o+9t+n8|<p*jjJA75zPD(!Am?UrtU|RVv@>sUcjt)bY(XZ`)OZZ9Vr*10Q9?
ztn3k#-Wa?0p53A~G21VC+qD1j4Jxk+6iEtCcMfZOYGk;!Ze=0g?HdM1j34}weynVk
zq&>O5Z{7=m&3z}$uUlP<cs}u|xXmoajm}B8BON4fMql^*SbOc|SKHNpxsJHKd9kKV
zS<k;O_o!&{?`6j-o!;<u>n=MY@597irCxabht<O$hi4?SAA2#k)`U69-n)>C*Y!-!
z{r=8Qb|o22p}xI!$EWPzNVnRp!L@PqW~JR+EBm+oSzmO6vG<6aNnCbK+Z=UQ#c!+Q
zHc!cY!6A9hNLJlx;$C%|52jOkosa2!H14srd@HkYw|3e6k1b2PBWK5k@V=92-qssg
zTE5|%agRXZtRIqL^Zw4=WpcFdM&AU*1h;(A3%5`ImTB*EGg-gG@<&$HufPYD&-Kqe
z+~`-+bmMMp|6Add_rkt+zH3y!i%Xbw;iiVr<1GD-yKkcpv!$u6H{f3*$<}5xf7zKm
zue<*WN;7O^6p$8>-pB}|!5oH-j2i`|1*8{LCNXbeJknOyRU7=u!_{H-j;Y@lzcSxh
xSG>$=fof3vyQe`(Y;qUeR<JnaG%WkT9%){1i_>t?YX$}e22WQ%mvv4FO#n7B6YT&1

diff --git a/SorpLib/Resources/Images/LTT_logo_RWTH_en.png b/SorpLib/Resources/Images/LTT_logo_RWTH_en.png
deleted file mode 100644
index 1d38d6fc5362d0e54fd679acbfc69a199ae9c185..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 28127
zcmeAS@N?(olHy`uVBq!ia0y~y;NHQ&!0?NMje&u|u!-vl0|NtFlDE4H!+#K5uy^@n
z1_lPs0*}aI1_r*vAk26?e?<xd0|R@Br>`sfLv9Wp26G{Pbs+`@1qM$S$B>F!Z|<Hg
z5((d?@nCCE)4t8o<sJ=-yVW!1sxL4pxZD$9u4dzMRli~N-Qt9MJKl&FbS`Wzi|*O*
z!QrUzmOm_4I2R{Wl%#KWJXOn{AiaTMrIz>7N&EC49mx#1dhSm4{}itEF_Mf7qkv{1
zaK?=b5xxiVznahAl2l%}QtxWel#JA4@4Y*}{oXe@aGTeY|GI&0+@X?R?fzwGOk!YH
zKPU@wQ^U&LyEoQWPdlz3=vKeKCNX!J;|{YOxoT%_B&|7We)l4~eR=H$sjt8PJDUcZ
z_vG((PGqofUB^Fd(UgDE_0w;5|Gv9c`0o43W&IIJ+D2tb=Gz`QmZvY;W+%HP**q-$
z+VuS0+x-tnn3wxM{XTQ@`mVq`@6CQ!f8Oe-u4JXYNPqoH`<iR(R#$2LzP$0r_wHJs
zxA#kp%Iy9>{;A&|UH^Nwe^mAP^J_w8PWPJP=VtaPpJnM010}iez-!gh^>bv88?Jhl
zwYL1}ofRjGe;+?~`Knsdk8i(T{QnTVeBEllISlKM*G5(Qlz#g;eect5>*Iy>KmL5G
z{4V+D*dhUt*BK0QXBK8JQx7PT5X|1pd#ESb;Yc2ja?+QFKZEjI(%cWE?MzcvO41Nu
zSneUa_I^zL>x{X7q@N0x_5UcIdDK|2@a^lslpNP5k0Uz1GTUbS*!5rBx^UT@o)b6E
zG-o%bO*))zb?j+S^7oLs`IfBTAEZj{H!n{!DqnVadi<Nv>bY9QR)4j23UB`Ry?gtY
z`X4KUPklMIasSVhTq)1($#YMCzpY&wnm0v!XVBC0x8sXVTZ|VA3(gg)eEn|m^2HjJ
z>sKy$eC*%b+`@7R_Mh7)JI6YGI<|VB|1P_G5w}ZYOFu1%nIG5x`%#{?_tlF1uf)^K
zl@@(u_mYxozO8p;&srfSZ~!ncFi1_k*>_@U$BW}}Hl5k=|E=vLYsA9Y*}Ws`FWl`E
zdcE2Df6?ZdZKrr9n{5`J&v#2r*<|&pJtlkC8b|%@UG9B+<^JIH6aLQMJU8<D#{Yl6
zox1DpKYxnWzSGmMuY39a!o;^{c7)p7|9<lB*tfU;o=u*1_2`tl0!+_dRcW)p9N-iB
zEXd`{W1mW)>-*$nG(J`tzCZJ!C0xpj@BXaJJLR*zuCUjIEh<@dv#$2fJ&m%=RUgk3
zWroSVwy(LiZ}-N%KeaaQwe2oG(R1y5=exh}w}-DWSY~!zY1%LT`CDC^DitBAoPmL%
zL3z^J6EU@sS8EG??-jkf|7D-jsW+>3yg&BpPrG#(e~hX8j|Kk@r@wuv?sQ)7VfFo7
zmBq$a@1>nlS@~OD+CTjDs(;_N{4VdX*zP5IzxHEBb;43Z-O|wYT}+>ynyg`-ao2ww
zHb>L{k$!Wzy7{%r{IcieLaXMdYoBZDI&fh^)xvqds!p9q-kjFIXi<gRw*FnKzTEA7
zdpq=*f^pwtW{1_~^11(a@Bew^u&2-Cd(YYw4D?lYFhk8YP`=rvwXZunp8wlglYi^q
zRZTIPb#rH|{F-yM9j_-(Siyh%=*5um_y0cxKacog*1v3j_0@Y5zkcs_zukOhN9mgN
zJ%Zj}yEo6CbSJYeFLn3+k0qWeGuVahz{-vpYtLMb(3$=5<$}HE`P0LX?w!-%wS1;`
zVeSRPlM6a+75h_kua;i5l)Gy?>tEPR_emc0-!Fbk7u;wi9$kJU=<lO52No^<SSq`)
z%evSR5gwbT?-Z$idcUytLt5&^yFZHB)UV#Oe_3}=<YbP)!hgpuFFj+is_WMDw0rl@
zs;}*_nB;X{)hqqg-=B5Ws>;8LOCx(?cJAI-d;8Vmi(jX0RN^|r%=r!)91JqTH@kw&
z?t2u05^B)3v@);VPp|!HHx2i9TV!{}Pj+WfiMN^6-?Qp#Bfpiu|2cE<>--dux3f-u
z0SQ_q>#bgxer#>#v9{of<)Sy=)$i9mIXBrK;r8Pv>^$Fv)|u|U+&OiJRmR!ci1OsC
zcbYn7aznrVpY!(2rp=+xCVty~ZcbGFYw>h8_lVm4KR@@siLNtQ8B!Q3V(|_UcLirs
zv|oL?tKa$b`|fDLREy2UmeT4AE@kdaj629;?dbO0BRprC_vSbGotG>hDf=zm|5v{5
z)f2(6`}42edHw%G@Numr8?S~rv6lDQA_ai`%(oW7`>Nlb|DIN+SGu!Q=}~3vhODH6
z56>#?+~Kov(NFf@zduA;E8lj%^Kj*t?dw*re0yItY4sF|X+npEQcbR&z991ZVCJ5q
zUDxc*=Iv5{5Ha}yA2f6i7*3tL!)%AFpy2o2*@4SuJN$Te`9xWabP3<zy+Uh~Mb9nj
zvhLYh@@h}jliPkrg8o0;{7vWA?(nyzeS7vxu3aXt0xpDKp8CD?h{5Y0pYQ*xu(SXF
z_~-v$e?I+udR~8i{J%f_;(E_!KL4-&`bV**;T)$LD^Ph7rp$Y8<?2NT3e^z#_ObTk
zuo|n3{l5;sS+(Q1#L0&<kLySpTJJw5WbxtE{6N#Mkt(zH-`SNm`A5|C(8Yh(df&?_
zk#qTCx4))t=lA8GU;qBQXM0WIau9QVyxsmek^0kxta;BLo*kxq_HNu$ulmoP-YORB
z#9E<#XJ|;yUC*PGWLft3w1x2Yv?9Klt3SSc;8$~5_H3z6`RTPCFJ^@l7=RMdC#AGc
z8@#4gYARjp`*T3mdZIDs_oc^<y?wa3tg~wA%5SfNcGd5%d3YfC;_n}e6YC$pEQ&2M
z-aK=A<rE?9Z|^mIe`<!@wZEe4c5-f{3@D9Go%zPFfB}&yEuL)>zRouH$2RMp?D+Mr
z&tCcXC7XvSKl)bFZWQ+D)dF$;UDnS;We(JzD_bP>|Mk)%=XP+OQ}uejV)yO)6}v*z
zJWl8Zx=G%Y%dS3^v1b2Qr@fa#`szA2)y;VFZT?ri_#3b4_uti(yl=XxHhs%4Y5(a}
z)Ae&AXPgDcQgCJY*H3F1veOuj2dctLYnkfExUjtSpH|<T>$0<uiRot7=8Z{C2N}a_
zMZ?u|lHS;AE8qUxe*TvG&HGlHjc<m@zMfpO|Nq~z;NQW@ze_bY2G6ZDEW7&U-u!dx
z%_C*^^lhoXd`H&t$fdydh6Mo#kI!IUziP+*_j#^U9_IKd-Y%@&VD)|Bns{3shMEg1
zp;x?*goR!eejEPPX>ZXH*?AfZ?O(Tc$~kF8>iOPk1r_2w5m_m>`!`*S-e+-9T7T85
zeU~3_#BS2c{4(vqitiE@FYal=eRQThT=a_Z`?K#v{2WBTp8+NEGwK!lr*~euDObJH
zHRtG~ch_2GpPQ&=l78$)wX>$-n^;S8E!AUw9Qwjx6Z$)Dto|l-`@Wj*jsA`owSO*d
zaFH}E@$wE+<Gp|5jtFy~G9tsCY44dH>h`|;`XZBQIu$o2zc}*s;2(8~Wi4huCU^=j
zeH|qCeVYEeDIFgt-#Pt+^FI64{|}dY_J93x^`DVU{p|jw|DH|0rlKC0YW69>q4UP8
zSj+1twyG(&_imYdah8eQhii9ozMIdhDribh59ENQWxt6*+m!fYW6L#_`W>BOw>{Et
zp86xa+*awm>yfoH=eWh@xw(|@Q+HZ-WO;L0&1G5Hk1R57Cy$>kTN=}4u}kH_^=p@2
zT(!yBbWwWZ&253Q{FBwZ^!Iq>oS*)`ehtf|GZ|ma=jnk`(yX%j*SlV&_zA54q&0E>
zlm7iS6HMCnK2Hx*O3Hl`DzbF)MBW_T$Lg>Cf7=u&7d~@!ugSLEJ46JXwWl0gXCr8y
zG>N@1feTS!&e6KrU0>GT{_ocE=CU_Oy`~fuFXP-1spop6>dmp~g=ub_?<BPgOD}Y@
z-<`X29@p-TQi9w2zsyjTKfe8LT7PA3fwhs9@eKCGKhh7^{(SP<Tks-ZUu#fO>ZF$U
z^Cw^OKGHvVN%ZxJ+Jzz~mrI7Lb4P3y6$}jhx?xJzo4-G=HnV0wuGzl-=aSGklj7b}
zZ1Tq<J8o$4ZrvKb+_tGr|LjH~LEDKBELOI_0=a?z*D~v_`m+5!`Twg7z3$9>II~1a
z>5*f(x>w}vvzjT|=Z?I()1NtQwwl?S_4_}TXc`}@D|Xe~A9iD%+Ip6{%vXQ!)?7Me
zxcZE{%M^{p_ofyv?&yfPGgm`$zst*>zfY%MJv;m3?&pV>&C1%uRPVNJZGhBX*^Zp=
z^*>fB3(2S>a*f5D{N3A?AMaN>burxFe2s3U;rp{XY)@5G+S9ey@rU_l{8($X**H;n
zf5`uNCOa+rAMvvOx3qp~SobnH|K}sWnF}7(xNZB*KY#0SsqI0glODt^>Zv*{F1`2I
zR1IbA?#HX9ylT@ZnB!5v4)yqh5AVviD-~C&dA_^Ot}iUH|1IC*DQjnbvEM9PFS+K-
zUyEz2b{zh9$|dyj>Q8A+-(QQ~J#P5+)hSi=*ZEWaeC*XNYGV1`(Xlrxf6c!%&Hecr
z3X3&acCIwjkDPB}XY0MDgXwrDOF7gohGU<NPVOy#a(wOLuc!a7`?PxI*Zo$ECm+uA
z-fv^T@Mo8alDhXdovYVozxDlQ;J5PgE0f>RMVp>nTeYe^e~b9X$0^alJy-7w-Mmuw
z?S|HakhhhRYyW+}J?W0686wpg?E8IpYlo4|rR1=Sb+3O|Z+=-*_UN)>^}FK%qU9Bb
zmt4K%Jtgq{sht<4ce|eK6k6t;mY(&u_Q#sJ6NTTV?(Mg)dTbRim2*9J>Y0COmfNa7
zE#bF3a3!C8RgtrZg&vYMGbfezeX01G&G}Bh-+s5&yWLN(-RX~imK7tr#V4g=>(MKr
z>4((nW}o;I=K9@P|8fT?=dWCId2d$!qJPtBf8E|)lep<$8o0#flV6@=E;xC+_9gS8
zl|6s<hl#rvMTaFtc)jV_SQoZz>-hr<zb7if!Z1PUep!3qsf@Ja@jY8-%33Esbx~>8
zKbEd$^ykqfm-~7@AK$LOy1OXP#P85c>3_xBjC;?8%@qD>em`*S-YF7(m-1>)tokZc
z{BUdO%#C*EzJHrHKT^=P52;aRl4!A6x&E@Ot7i6Q%ZhD}a?aEnMNFH$%wUhtq;oyz
zRC4!h{#8D$^V`XwqgOM(>~xvAVt?t8{@-Qhr>?cAm+koXPEXHNY|7oE6R#eKiNE%`
z!r<C>rTh-L;|HNVHU<U;gPnigOUnO`b6Iol$%WFLqK1dHKAk<XUi3Qq>caiI)AWj0
z{e7O3ereOjz5Vu5?|wH=vUltI?{H>G=ZoJj^KD|aCcgE&7143Se4?$lou1{t+lp$n
z7ZMg3?kUQ<QZhR<l>c?rr&&i-(|#NidFJ-s|M~Uzc2!oVoY%cS^WuxVUABKR?}0=Q
zcn(Oo$5a2={C-(`;oH}1PsCV#+I%wS_*O^teQ)`mTdh)83Y1q1-W1by;^Y4ReJSrd
zrgNTK8nXS^y)32MzUuR?&73<&B~G>MU)j$?|7!KFhPl{Y{Q0&1$I8#=*xBxF3*WlP
zYG3i|Q2VwpN%ykqpd{O46(^R&tq50o<Sm#o4Vs<~1Zr%oImKL{Y!vRx^7*NQSaOOG
z14Hu4PpdTyXPn%)`A$!ze~gW0=dT{)A9H`C1RPOZ<TK;L-1nXZ?`!{D{Lt-wTX^pM
zxUJVa-Q-<n>MXRscm2NhbGLHyZRJLbP4ga?#+LH!+I~&aJCp11>)#jm3MKD#edy*<
zkbVqqzr|ZlrR!|6lMmD|GWhNKv|rt4lFg30<ticf-mg2V9{*i=Q|Xt#=coQCxzLxt
zYw=FGW1!AT@+<qAYkGnHU&K0gO*#JluBP%fqog;<Av32hI?3{V(p=8%?~cpg2yPSH
zY4mTNNVxK&ZxiFr-kZFI|MQaapNFp9b@z9dylHo5Q}@zk_r)07RT0fawUWLk8cTZ~
z9gHu(_xJN3Eu*}%DonedhPjkHua@xlSY+3exc=7b5aG0H{Tc<!U!kqvHwxeJ?wq>p
z+suFb_N88(opKzjPO(oq=>1PZGFg2``jMde&z`Hd*AzZKq2|;%_wp__ua#!%wWk@5
z=LUSfXYt*2>8;(8g0_q)VbCA}CDNJx>~C*$FIBb-t5cX+WOywpAF0av>DOl?*!ioV
zV*RSc{viKUe_yd{%JI-=uWsD-aa+CrW64YB<CYz})>&D;>^86aUi0JLj4)8`w8{3T
zeY&;a#=JHo-E#A7`R7y4uUx$~Gu(6itE{y;SK9px>VGD5v6QE|A-XY>Z|ZJOdZcr*
z`PA|Ee?OYv4XpX}waR6kOs&Eu(exx!rG0Z=e*~qE0uNO$b@dew;=Fk5zszjySZnmK
z^4iR~KOC0+VBTetxW}#jcR=dbqj%R<6qao&JXxg4H|fE=r~HDMO2t1;-&=F<&!!#L
zJslTK_%H4*$}9PP@mrYOr?Y~RH}hU4N=djQT97?&e<f(Dt#GT!;AZzI()oGy%%i|l
zXMf6H$vK)-lU7tb3zW^$Q>qW8$<@DLKC99_&AWHam!5MizBL>4LE|{7hf@B8PhG<Q
z>EN`PJim9D-@A2sw$t%7NSV?moPF(z)8+1EdxEw-n*HuY^Zei2tb2moj5|Hktp6EB
z%=~{)*W9PTZ*tYbc@=lVo+fnOVPE;>-@V*rjpiX=_TSG-n1AXxyY>B(LU)We-L3zz
zCU@GQ8P%8Lw%VQh?$s%JF*)sX7`%mLv1N60n9j7bCvxO(8XEJ*HEua&ZQSi!%Cu@n
z`nJcv60W*D|B|slt7;|RtP_7LE;)lTxbel6&z}5UyU8xXss2d+WV!71w_eX!Y%mX0
z^%u&mIoT6t%zyZR#B~XH$^9T;9k12Kh<~y(z1^$sh;J-=aNe%}YsV(z*$k=bcCuR*
zPg%QD?)joF>*XFN&$-0+8@-CPG`BjD&L8#iZ|$pHv)<GcZ~Euv^2P37M#YAI(;hB4
zzRE~{<`RR8a;5oe-iH>3ewo3FXsODa`Fb!Y=698Vq<i#ETct%)wpLuQtvK|n`JLaC
zi20Fg%1*ECnDL(F`w71o>5@fLCZ0U+dF_71t|^jhIcHn`sIsqE`u)44^~2r!e=eCS
zC~UhRgzw`0dr!HAzi)SWDRcAO^u+Uzk3?GhPP$XQ=qhMfh@<EVQuk|z*$Wq!^!xKu
ze>zWz=n{H+V$Rv0y3gir+_zbLwXx;>o~ar?um17xDN>G8tKOz7<hRPIDD~4^U3vL0
zllOwkE_qwo)F(GyYZ-%k|Mxx}b>6=+>HW`{Q?m~7Jy%@4X}ZwiGvzVKd|Q^Lfd&Lt
zcBcGfp7XjsT6B&HD1DX7+s2+hF}3hpPlxj!SN2&uzKX*~%NBLb)hNvVFQ4Xe?!z6g
z$nN}qR#soW?|a$zX!81Y!JC%9CZ7vS*=ch7fa%5FnBJgk&-O}xV4SX&yWrHX4V~Ac
z4PQ1Z|F^u|Y4K;a)~Yj|zoXs%RIFI5a_ZWW>cY7<J9pL_vz_@=rX`nhY@zTS<HuPZ
z1<y~^o5F@@8h+nh+i^JbiLF$sdf8_4Z`WT-h6U>LhTH0=nsv@iRylmoX6BMjKh9Ul
z*O%=0yZK4Ka6V_`F|QE)K(%-84=D<t-7K@`(BJBFe<t1Jdi?wMQ||1gM;6}yHDRJQ
zsK=&sB5)F-|L;BXd*4IPyPfQJ=Wg5&9c>D<xy`%XV$Ma0EjoODt3ZXNTJGYWz|cLb
zUUgnCK6yCY<-L8)wR1Ca^0idUs;2A9tUJGS)*r^XM%~*B4|wjrYW*i#UP<Xy>#f6i
zGMb3Qwx?wOZn40!zVn<@zy3)7e!6q^Ny)Ind=nYp5C^t<5n-iqb1S+v+v|THU8ue9
zefgb^rH8{p@2&o3#oO}s!pT>lC|6ahzM)|p<!dv6VR_`Wj|pei-xILyn}ldQ)`j+Y
z8dYd6u9$e&?N*gwwt7;IQQ4v?x|2m_-T9=po-5A%kHxi($2~;qZzl?0Gk%=KoGAT0
zadzkL=<A`!*R+28`mdyJ?-YwKhkG8|1TasYfC#AdV*SoW6*oJz{>$+1IvX;%{=(hP
zplg07ICy=7GTiDvdul6BQ_D?HJago2j>5y;r}mWWcw73Z<=?8F%6qEyISDuPX6`hY
z+4J#T=c`q5qPBfqNRIyMTW<0><-?h{JMYb+SMIS=oBC2c^wUO9F5aK#Z=O5iz3GVG
z`%kSKzpdUirSp1mXVC+@FXr>~Qr)s2?fCodXTh4>9jn?W%UKy)sp<Lb=u>*v`~7H<
z^A`)PZYNlS@WAX(kcQOKo=5ZRW3%_%{e5@sk0-Aak36~Bo&L%v=jc31uHGE;(3so>
zGdDsyLX+QJoA?&g$p)2H{I%Q8y?L_4u-oX@?N3KH-dhJ6>3AsKzfGO5;{WfrQ$Zbl
z|H7;}x3oUa{95$>aetfdw#xG4>d!muX9S$exz{&IwLGox&b_DH(dD3goAUd@@3Y4)
zFD;aR)p!^wm}l>M%lG)!_2`K^OP(A*mvcOxP5a~ecfUk#?GsNuxB7qGW!bqMF0~eH
zUQ_&zEz!JhSSI=nWTvl5&2{dtUM@A24Sex)x9pa*oTKw><5WT6*l4e5-hvzR*e*{2
z4M*AK)}9l3J@MmBiR>S4J|7bJWkL`&)*rX2@n_%NczP`4*53QE-9c`}_GUA``vlDJ
z0gZblt`>j4Kh}5Ji<>@AUlc9qdh8o=QBTm`Z%eJ|1c~TN%ytGJ*ShTeaJ8b^VO^J;
z`={3pkjV!I28IvP-*;yVrly;*gPTY5f^L8B;oY-z%36($ci#M;y7lp$r+c&3U-od`
zUu`#ML+kO${rB62_x-m2bH$^6^%`}rfc4%pckGwkc;$Z0rC)FP-*guQfO11>54)ey
z;;aAbs$E%TZgYj#AqnxS`@4FgjV-_Bt#Lc@_So&%o~<`#2hNw0ogLBLbKWONYT`!W
z|8MxDb3fl&P&{XMOlsV$8p&xF?@!bBn-UT`^@f(^!w;$8Zb#L0{XNE!Ti31jd-kO8
zb?u*vE}v5rlUAD;)Pd$}T#np|zP?6Y+4+&K%$>a*5msOBg&)1z5g~53%oEWt`8_++
zsA8w!WsidY%dEQ~<6AZTzICG2LU$71$Syl_>IvuloyLW!U-qW`3U*(2<o7DW^q9F8
zX@b#{!<+O4Q$P9q4(HccbN2Qg@Z?WVj{lwitK|HCZD0(kzFHNz;`ie>^Z%Yz-+Qlx
z|Hpyf^}O(M^l!~&*`w<5>yMv4a&qz1n|=Fv!XCxn)ePY{TP?V;is@LI#6($PQNHE-
zKbEXa*`jvOQ)wEg$(OYxYfbd~H6Hix*Id%l=Zjxjsr5J4qtj@5b-dfX6Fr^h_pV#r
z(XsIA8I`K=bG`5EZrwZO99DR~=i0vfzy`KZM5eQz`X?*x__|ZQE4Td4EtgoDbN26z
zE5<U?GhQz({v^j!nSbd^{keI2{y{q9%dh;I6nbdo&a>L7YpOeQ9;_Aka4()2G5Ank
zHIv6~*4cx_s&=wlmR~9<Wtw#O|JB&}cW)f9(Vp&?wEma<pDQ=FZ?81^y*vEv-i!BF
zxhV7Nr7~arn;54vr`GV=>>{J0rTc##iAu~uv|vBfh2EQab7T4Gvn#h$gA3?q^#z~i
zadNfCm`>DI-x$C2T&=d&^d8}x_wR>Hh+9#9CeLEdy-!Ey3Z<@5`TpzZ%}~LVto?Ny
zus~;c|JCMN`ZS(-8>Pb8FRv7cO3HnAJk5NciQ~fu_d=ikQPG&W|7G<5hnvgXw)tnY
zFE^VOyvAp5ifGZBX+fRr$#q}bUKr{khB_+tv)`SovC(dJbGr69zm>l}B-ND~9b2|$
z=8^(~(%4eJtoueuFW(+{vp4JglW*pWuimftm3`>PqjzD+z3=t(d|%I5>(n>9b+i68
z?@nj?6Eoy)By=J9J+ZqoJ?;3q(`#35`R!XS5_s)7#P957FI~RBvro5P|9|5tn~Q(f
z#;=aLAH8o!ag<tNXwvDRWtyM{#LSI)LNcps{oqZ+9}A|Rd~kTCjP+*O>uhsZZixkr
zH0JL<tl_#zxyAuhM;KeF@9baNwL1Tg<*Ckh`BUzHDZk>fxpbw}dLK~x^KL{k_t!pA
z-^JUbN^JyK`-Bm-r;N|JO+ghq4X38XtF`w(tIJs>JYfa@<!@o7pC`Zg+VTxF$<mWE
z|IO)3(fm47WK2a)ggsW@z2o*a4$E~_^;Y}iW?$mqhOGtgswilBT%3)VoRc~6_uZ{C
zlMWh(Kfdf(t(6;Inf~thv&uE@BAuBZ<Wx^DoqX?jPtN}s%{}Md%xNop3z~hp{?GiI
zS@*N&r{b<gT&e*T`C%q!?`Iv|rBM*$0q;3K5J-zST5BG*{L(v54?a+>DU|(8eNVKd
zD(C&`tM^vd&HK~xuLINvTHpJz-n@9F_S<9UjgwDmJ&CygaO$I60~u*VYOvUG_eW6~
zyT19dOK(m;`S5dn)UFvqmmkQ2CIOB8+?xug{xsUScTQi+zY{xtW#50jHf`3KGElGX
z=4YMyj3-_ZNg1xjyn9cJZ}U3y!q@i0x2-<#$g|i0N@=ONYM^T8>%mtcx8lxN7u%cN
zFL4)4y{poC|JT-4KTn2xtpUy9PL^DI`NI94h+nFbwT0!YH@20F&#qHgH1k{0x%(D}
zKF0a0KWw!3V?l~OKhwir4^zED@5HOM^FOc4d9^3K=}_J6YpYj1Tkepy<<%r}|EmoD
zpXaD6E!tjFxZK5L(v!IBq03iZuKvl^m}6cndq#e3#<FeoE<5@kL_~<dTdI6d>&ms)
z)$SFY>Fr+s;mwh+2ZQds&ojMOGB@5;bnZ^M+4ZH@AK$vZ_(aa^6(3d$EuB2kcZ+e?
zq{W)^UIhtHy>48zbm5M(uJzv2yan~O{hyy^`F?V}zht=bqcY{`(_5=lrMV(PuR3eb
z%6u8SZ$l}lyJz<G7^B2wMDvAj{i*efjwGlZUw8U!#|yK2?>s&E&i~O;`lY71=SuyL
zHL;8GQewj+ckQ*0lkj^T^WLuNSFFjDIrmzE9-X_dKR<qU*zfopo44*y(uL=zAM<kg
z5*Md*>akXF>7%tKNh|+<h}>QN^iIYnhhtYWv<}x6mY-ggcIsU#OL^Mg)ot)9wjcvi
z#i|`Y7t_1C`P!6Q|FYg4f9857FXw^8D)CpxgpO6q*PG0Fb#mIDj}}Ms9;TXpdD-jh
zqWt&li84@W<Z|TDP4U;gyzX1ei!Ygh6V&WVYmd$wuXN+L>^Ba*8n;!C>r9OtVi88N
zrm+uOe9!r1h?G6)@`LMVUj-?z^|8EZt+Z&>tA`sqqdMo_d&(XB_OsL83la6-SMBw4
zaRH6O1}BFqh5w%IuU55SmClvzv!tg~B-k3~f+}|RjrR}!&i@K4QWIplH;PpkW}C6=
zn=3skdwkaJ#k(V0*I!poF5P!r?fsE^bG|c5-PYSAY*}es$-+4wG$2;@G2{0Rm%Lwp
z_ZH=qlqXlK8>`i6yMt%2;{JY&bJ6j&c_z8`)1NbIJ6`mD{tIg4du8V7uUk}6k;w(B
zNM`=@e52O~s^IzpBcvjo4gRf{gtaCOKm$BKp1l6r5o7r&Iept>@MOdGpDFvb_IDXQ
zKlxDqIJjz^dU*|~YBiZ)BP$p<{nHPPb30vfo__Suv7PkKZCax6^@&1Hr~h4N^|@y4
z9*f)gFRDJ@v^Sgg@5lGk;@9}BzrV8De>x{CZpy{`%VGlmZ_!$MYtB#0kgs!R9BZzA
ze2>d?XIsJ?OAYu0PtV#X;l|cwp?N+_L9N>kqdC7fp4^k(RCMbquU*6D0v6G;%6-d%
z{v6zPL)of-lD(PmcF;tMo~z53Y5MPutiO6kz2EiOgLjMHp6C1Z6BHt^PMpno@vtl0
z_Rp!VXDdLeMDlqOrd?M+G_`Ud1Ff)@o!@131<OBm<+)|a%*T%{Rg=<GEvs@5vHiV5
z>uCLj_w)Gs9~p#(nwQP7s;|v<O}qQTZl2)Z-O{&b|G!bO>(>36PqUAF{r7Bg7^q1N
z5?&g@tG<2zniaX0#Z$aG*%uu^9{w;ws=1RU9S$vgUUIs}&)HWtGW2U}a=^j8E|Pm!
zHQAMd(t}yWv*~g9+owpF+0I{e#<8;STm8O@EwS(Na`Nxpy>ai)ql;yl`se=nuY9zd
z?fIS8*ZQ(-9!%f+;tjXxotbynizC`JF7u98xy<x^6npHIi1hsbPd?oJaf#*WmRF#~
zI0v8gtyxv|{!{DPprmCd&q!L@oO(QU*`#0I`wX9jhWdYHTyy4ykLJR^XCJ=_Enkz-
zcWZUK)-{)=NTl|Eid;$gq9Z-4YSKV68OtwyfmRwp*L;Hf76(1Qy6o1fQxn5O=Vyw3
z7y9^k;=3ojU(Jo9*4y9su*&LB%=^ZrN9Nv}TCA)+Yv!HQs~;UikcT^b@(k0%W4Gy<
zFTeDz)05Ahaq5di9@YD6p4m>kZ!0hN@umH|)Hkcv^qU;qr?+(DziXvmkL`Fq^ZDM$
z@FVioeD0E=>GP|F*^Mv%zWnoRWvu-fb42;>^KSM#jYVgcbyYtLijmjxUHVpQ|E%8|
ze{Qqx3EJip<Tn`<t8ONn^g$CppN=Z~ewgEU^oRMLRW)@fVzbsp)W7WArxSl?<*Hxj
zKU?&#7OJ;<wUd4S-m|l=Mps#!MKoD1^cWpZ`H&e}xc~m$E{(%G<!6INS=&F(-#mBO
ztWzfz-)HXIm-J_SbY-WqeHkbwmaTG0KbC)N-}jI1hj&eRXXE>D*Oa{XpIG_T4U1=P
zH9uJJW&1jK>^dmNg>lKBeR5;w>cY|svx07ao`0hh)F=#Le0D`6G$wb=+79{tUw^7k
zi<f(yNwYsY<EFH{lyx2`xo-de?)`NAHB*JkpC$ggwzTAb-Ood_rk*Lh@cYN&hikqm
z`{^S>%S1grLi3N$8b44@-8xhCo%zZmvp7#>1}-X@m9<)Hb7l8oAFbo=F4Jmk7AI!E
z*`a!R>ED0<KA(P`FaO=^-K5)=)3%qZUUO|+tb!O1ezvD$>&#Ft{in~qNZB)n-Vsm#
z@qtlhA*ch}lVg50?)|6MnIR_gU7!A#&b}_~(*0Gd+IveCH-BC?|L@;Vty|YTKEL$H
z#;Vn>nj0sV{)sHIJ|5_HN0_zm%Pa+W31jliv0ObZ^r<m;-pgm{+q*xC-W`7iiun}>
zPIYb%e_J{$YxNX~bF1VxuaJpf)B`F$(=I(cdiR*nYvZJq`+qL^x^Dh=&=`Z&?>|YF
zYSl@ahHGBE+Fw;~mEZp?;#KUv4WW-%_MC0oiL{<6P50T{nX<dJ%$Hqy2O5~$WcEEd
zcsbXaITfMLmM*(>N+WvntK&Ud$Iq|Ze_FhJmd}E_)pco4osa+i(=YySPNe?%SB`B$
zsZ&b-{QP|S`SkQ}35+rohjz6;;8_0@5%G)nz3fYy&NEN@<I4rMQ<ts&1FAja?|#+L
z+EBD<s!;FVlZxJU^9tkJ+^Y}#DV+BA?1^K)sxPq1R>{|!`~fZYI8$Y*bj_=C?#gz{
zQ&rbKK0p7z;^CrIZ_jkET6fK*aq(_BaOH7eO6|vt-Df`iSbF3G$Thu3cw(jR^z}p=
z+qMgx{+L_-<KX$)PhZnq%F?RV{eSZ---2Pzw(3^Dl$^fOw`>d<5ulVd>1oi(Hz`Lh
zEqOat$a-RGgqKZ(#qXrO+iMElr!d~jMNEn_FvL}bhW?#?>J@06&5^jPt3HQrs-9-=
za`IZ;{j)uRnjh~^+!&m?S9Evx;{CCf=0c$j&4{%z3=ALmKt<=iU-MrtVl=3o3U6#M
zFfbIzAey)g3=9t<5M>wx1H*xh8xZvp1H<RF`+qJG-QDe78e3{~>c8GZZ~Ol`##Za=
zx4GoFcFvt{uVWqf>9|npmVl{&pmy{k&NE13S_!W}^>OBsg?EpFCM5$GKi~GTM03@p
zSvwY5m4jAt{Jr#Ub;{*s$(FrOF1wxky7r&B?K?rijXQ4JohzL4>QB|p|7(BL|6hGI
zMJ6qCzhOqsIho6Umwo*C_3t;YlSM02)=Uw<+1GKRr{lzl?=||$)9U^@xTUN~NtrU~
z<I%-$HB{RKKkn$-^zYj)JG1M}NAIo$b^buPYVszvS^M~8f7`z0_@4Bv8_^(4c;&Uy
zOgeM<s`oBO-m0Bn+xI5@<hdiy#SD8op2q(JEm~b!w}0LKk6-pn`6uK&h^fE)f7x-{
zWOeVW_SXvU)Ys*vophVz`1$|e_1&eR>(f@|&7H7TarxG8lca@x`f|DZXWdT~QFRym
zxI=5B=>BTEH@fk6W**J_DsPuPJ?nj1XN<1oT7K2d{iX)`+WX4Ao~+&7Kd*1mlfA3f
zU7O|cBR{LBxV+F(sZBk{*Jsb7U$g!Ho!{~-4b(~4bE4ioGws+^jl~^1G9FY!BSwZ8
zJ}-8;W6}F}-KIPf$y)uS%v;az)c;sBS8{FIvAr_CvmU8Ox@|LFJXvzPm+1Ye;_3gN
zzgzsa{(kM2zmfHyJzr~_TloJ&<ZsXty-fl3ooCL^nib9d=J(o70ro#1UHrD-|A)xi
zJr?^w)2uV+Z~LsRd~DzK8h9InVTQbF@>7#<yFo>`+U?a!{|vrPKDX<n$}io`|0_;*
zEbVzQT|E7N`mN6Upt+*!p?}|ZM9eMR4qnO#T6UOrz;Nz#$?)aZ%kJg8i3&?vZuPn5
zY{$pGY!h&v1QDN=lyCoizuiA|QnjXG&YHC+R)!a>-+WT*<Ifv!?5{1G^yBXRnoGNW
zXZ*fDv+(r_t!?!MYH3@H9$&lL`}XYORdMGRt`pS0EHNFFEOI`a6`#5BUi7{l$wzMV
zBT_|!W$>z(p)YKoNqK)d*K<yA&ikdyq*i%J&iZ-$wtnaR{%!y7x|n_kbz^`1ys7T1
zCTf1?zTe+JZzlgcc3E|C{hl|r_LqM+2b6}cH?yk$w#wSAt32*Ad~}2%Vc!&?<(rzS
zLz7mY{MM&nxP9X{(AwddKR+ufPkXiM-*=VIpb58?eRpj1LT}%{dA%o0cBkgazc+fl
zKl3}L?!5TGH0Q?dqP&zP70<uM!Fz=a&%D#N{JNh%f1k?t`?m6Cx8hEI+v2ws)GJx}
z<VjFc#<lbJrDV-NR>w`cU4QvH+p24qFU)XR_r-j^iCH~psg=>J+xn}8;w4q@S-T^-
z_TQDz;;SXkT|qs8PNOWHHp$DYt>%_a&b2pt{M<in%d4LEe3LWo+^@N`%9#E0q&xrI
z;>BOR@A>s{<M%&4$^4E}&&=-KDw=xb_vN3Z%13@96-G0heZybOU0la6o%8O}mUEj=
zKKZ$7ReRc>JLj&K{r&T%QF#C9&&J!0mi>5eG~~CGHz>(Se@!-$lMJ7owR%d%hhD{%
zRo3$R-f_aZ9}EX-vNk!r-?PFybJMJ!Cc>Swz30W>xodR$d3ajMzl|SDzB<nbEnZYN
zvY-9=-Mu&VHP_5u9Z$Gt`b8iFR9vgw*9e$fxi78c#{(Ndc)zvb=ah-&e$n&Am887C
zo$I+KGPzLNbDq9nG-zZc?f0DZS9_x6z0B6VeszuWMfz%;E8Ba1e7tZ3lmKS!Ik)EK
zc?%9idxD`@%h+o9+NdH>izjH&PL`8L?;d-6z5d6VyCFv(>!fBZo8Pci>SkU1ro#X2
z^Q~rHoO$h|_mMD7!<xVUm)*E~RZXk?@)1*|e7`NzbL}!yQ<C$!P6q8W(vo>`Ne5c{
z7dTvJ_YT}YZONzHat)2*H@6miJ~qERSzE3obP_YeGrzq7>s^jaU%u*cWZT7nOR2Hp
zb3585*KUr>%BfMVGdb;lV$0bbqJr7K`-)G_zWGP-`ldeiz4mkC>#wteg3wes-(+q~
z{C<nwRj<A+eQfa@vaq>2{9Ny`pa1TCHr5Vx7T!EX;@{g(t-6a3Il|(*p?s%R#?ho2
zvA}h1&w{3ORQ$DnQ)kqnk*cjEe<ZKw=eZ{@UN<k*So(kVe*KN2_y27z&-wNH<bpT9
zzyE*ptW)yxex5L;(`!%s$vt#&rcqDFQ|7J3Z(rA?m`vU>rBeT0`SrfkJ<n3#&0F&G
z_sQ$Ce}8|x{xl=Q`!Z#}Xr;`P^2&>6t~wO?@4}atS0%lD@3!b%;dTzL>CybO$?4}~
zX5U7Q|GQoEd^b1!I{g^DB6sEYuu1u#zINxXjaoNVPpvq0>22+wi|o(O-Pezg=<e9M
zTl)6)c-05Dr~A$Dlxv!`h3QZ9=TGx4K3D*2{~oAY#~&82_ATx8*)`v`@9~)u*Jb=P
z?N923-ulw|Xvy_`VJT&GzwauYbGKV&Sn<9>F63Cy5xZoozF!HR=EjNd&N(=L=4!ZH
z`n4nCmVV|pmDQ`NBD}7K7`?kB;`cE~xOa+>b-ncFPevbqfZLkiyf3fH_;-57KA%5z
z$!o81fAuoERwo&n9``3a|L3EH_x!&8eENC&d%IirPIlBK|GxBW^0mbC%_}8dCpL%k
z$LW}w>c`vqFtRJb8mafp!jww3E$VvzNWa<s{p=^_a$;q-#My385Mwydxh4M68_#Q?
z#<F<-Ht9@l<=ep?M{-}}+NWBawfOh8|M^{o{ZF5FJp-+Mf7RodwnZv-^>14Tsi#4~
z`&Wmk{<C=(^Y2gp^Zk2%zj(Q{CuiBLKlSIzl#*WUm)~DC;bB?uTTshuqI#8gr}bl-
z6hXm@{~s>*)4ZByTpgnWsyn~){oLRadv*2AJ4eFz&OQ7#71lUhztb+FYUUlgWvh4|
zy;`6;;rJP+lDM$P><kt&y^ft)`MS6>F}e4xo>|z@y`W-o=aLsSIc4X;Yid^S`nCSj
zhi2uS=MVGus!nlV<NHgkJu83V^^o}2b57kB^gI3sv|zT=C@V)t?A77(8+FWQS=E6y
za=1-(J}U{W0voPR`84nP#_5Sub_g%6kqo>SD5xL3QDQ#l6T{Evj&yAjmb|O6QD&xX
zBNM~3?`7(@K?{tRuRgzY<B`X^)>)mM8*%rBMMz}+%)6T}?=H#<nR-cAb=I19@_*&)
zex>d+-I=#}%KBL^iaR&myTJMPppI0$X5sRK&-kXUxd)o+p7^${Z|}7a(nc1n@Tu##
zpCuRi_P%)Yd$UmaqucxM{d;;ooV`40;~#6I+rMjmxS9N@`l1}1^z%w@W#`r(>E&-P
z+&{fXy!1`5@8&;tM&b7@+rOD_`Ee$mA>&EWj7nprUCWp5kNi}4GEGkJY|nl3(zw!N
zL1tIN-aqcYqkS&o{ioKoyZg7jcX8Rj((L=I`1<}k-4R)ff(kV^e%{Wxdi(xs*P3%4
ztra*Ly+v(f!MCGTfB)p{?=*Kx0k79C1Fd5_Shu(9*sAU3A0MzThgZozZr<DdkGbw<
z=iQpmrMLKZSr^t8sC)6$eg1f+EJk+ABggW6T2pFo%g)>9c>cfjwd?QpD{KC{wLn;K
z_4|(Zx!q^}ur_3BsfIlgQQdL;{XG81M{lMjiC;|l`rDhgclqzx$&WtU&-?%B-Qwlu
zvsY#Ot+M6~JDIoU)_<qH20GlO!oIpQZ6CkZjlc6V>G8`b7qd?a{*WS+{kCxN)=u_P
zug=6^{<wl&@S-k$inrkJKk9dcUjJ5G9d6jOx7=i_gm>YEQ+LAI*IEd#7JQmDCBxOt
zT4~#&BN}3#LF>3{H}rzm=k#7Z@u}G8Y|s=5*JGzY>;1G?7196uZu$TAr_)c~-2b)g
z(TBSEtCOBj-?pAVZ1EK7^}jX=|NrwkW$IQCUvIk7;=h~D#&l^M4o}`J8hY>c_IUl|
zOLe9l`|p?MEdKLv`oBH*+9P+_MRZw(eUm*c6fOAkLBPp7pz30}^u+xt({+xXKdG-O
ze>`c8Y(}4{Y597-sP)&5-_A}GxnJU5SbCvr^G2biF})qv^q)s3iA?-{@8<XBbN6fa
zhp+o5HUG^YtNnbE^S}4rb-b>~;G<w11u6hQBl>kxzixx(B)(s~94O3r=w^;mUU06h
z+3Nm_zqB^W@$NNzu(s|0hX3!i+UFi#y0Q8UXc|{vF4ugM`b<mVV;kartkSvSdv>>U
zVFSzef8TFwFI~7%JMf*P>oIuWvo37W-ugJlf8Y1b|G&(-%b#ts?B`zznqD`1PK3Ga
zn|J*}XHUo8h~C%D@2s`k;$^oy@{v3ew`R|uciFNht_x)wSp_}{tNHZRAnwWh@4h$A
z->5kr`HbB@{FH&xw8yuuH*0MC6&8Q&^YnvWDKGcSOs{$Ev*~lxe!Fh}eR2KbH)|Ki
z@7^dSx&7PgL+fi#Uj4E2(XaEhGp5czzG+Xoj<J>C$D7s1Kc>&;yR|W#EpX9i?>~>W
z{`^{8U0tZXuJ&*0n`d*K_m(Ey*|}T7`}etpcXtS1XMY_y{r#ep-)jwD@A>sOtH$WX
zQTyHTeYW-YZT|l|9kJ){#6P(;`~GI<FWPAR!iuHAGe2|n4k^Lc%a`t#wCpM0>-c;E
zs3Z2W_RqzFMP_n#+0)lZd-AOHs?c~BadzvD@I^COzMuK=cYU{6H1Ct`?vmf%hP=;O
zf5hPP)%Uz-d_dXouDd^Iz`fBDJT870w0^4LwFh(Yrk;OwKM(!Se_uE4mc{nH{r|(1
zEe@|WE^*B2*6t``6>Dy(VBssP%$Oy;K{TCjUcUP`-W^XDo>mi6&Y#2hNz`Q@Q+D_Q
z8=G63xBs~OT9zZ(;jY5MX%mio4}Q8TVvAhq`t;J(o!2+-I;Hc->wY7m5z1hZHtkyG
zM!N~;i$(W|a>Vb5opNig)pP4tFXeZwT{7o=hUTe#lkc56{bEPLp8D^LLs_fTH#<!~
zzSU;KW2v^K8uxF<#2NL!ee`X=AJ<m>^M8-e`d03I_U^gf|BBz|>OI?Y>F<n{Kfi9Z
z*#G;-nms+6X6_FD%+7EiVNF<>-TfKsPHy~t{LL}0U+?$i6_(9?@IQUOpH+X~r$;eq
z+<bRJ6&Ae+OZca>`E`sy{15BjAHTbs?Z3YJ;$GSC^VP6=iGhLP%i-6Z^-Qt%X5L&=
zklFZQ`}xWnA1`@rDRd0{=Q=<7N{QS5gulLqn;(5+4}7>|bJ_djQ!hW>=(BiEc-1`b
z&5MdO3$4DC-+g}VWP|Ej7wOo#vihB~ZJs?|cig1@O8B1S{;IzIo2%Zr&$XO)`LXu=
zcF)I*3=<j`|9$y%cF~&PQ|nIe-1&d=eZxnW{qtWw-_El#FmA^4O#Q{*ZqI+Qs{f((
z{~xh;pPuc}E8%bd`d9GG8~gNc1yBDdLfey|oocsSuV(6Lh1KugHsQx}-y6vfo3B3=
z|JPiq`Ox;{e}lJiQ?nhH1-#Sz{m}a++l5W9g{oe>?tHw{Je5oIb>6GOnf6vMv*cD(
zZhD}gyY1cbZ9A7GO=S;MEG=yKUA$B5NtIS*y4<X_Wl!Gy%`n~j;MVIR+r0*Lw!6LF
zeY0K`yZ6PTM?bFgJ)ZpM=En8qvYXczmtU-W5i9nenc>3gxid3gE|bZwEL`_+oe$T+
z*lDhXzux*ho8a{7;*`L3Cu;<{#q-i_?zyYgv;>|1YBD>!TU6`z?xWmw^RB+v2o-y|
zK;9B5l02+J9H)KSJg@s|^@DpC7V2hXul>uvUt53ik)-s^hi2}#@8GiXs#vr4cX95z
zss8`=iCi^V```P=lSdxs4hKz{u39?%`?R8M3$7=AuGqb+=wG;dOiJb1jL4wS{6njj
zWLdAf*tX={qm-N4dwI>*nScK?QOEG-sar9>Z+%?1t~$^=DE;_1WnJ&8IxTiNFU`k$
zZ6))azsJ4v2z%9WU;pB!e;nD&r|-@?)?=39`T1JAh3dU!0r}Tf9sl_?#`6A4jTUq5
z3{|a6<2Bxs-nqN(6cS5*vC{0incv*?rLr%J50$YpG8izZMX%fQKS<;L&Z~PA+wWYM
zDt2}5{@j=KJ!{@=PA>22R-bu$`5XV5^Iz_LI{D~L+Y(;2Y!jceGFKk`o!K?>S6s}y
zOU|k~i&pOWA5_roeRIj;{R!7D@LR$612QmN*Gw<pDq8nCt1RQ`x_jj_!X&bz)Bo)f
z-F8d%l=ZgL{LdQps9ol-lD>6vew@!z5z(Dl>PO$k_n+4JDSsw;zinFNgqkz#$B+Ju
z-^&{;_rC5`#q>or=@)mYRIYyfx6td)n$wHceBL>G^FM1YHnDk<#m0}1vcJvyIrsSU
zdp2<bA9eRLRTsXjIlA(wYWn$|*AtCD+Pqo%L!O~Q?r8AGPrO!l&U78rf0a}7vig3#
zW=dd<mS^zCkhwZ;`aWSR_WVEe_i2lk{+aDQac7@wFT4CnVZZsEP<{P#A4RyneBaNG
zST?{=;Cp9wde=79xtj0xdMtQ+=xcF3Q|Z3@Q{^u)Uj173HZNZG{pGIJx(g34Ts_gq
zEpg2!g_RGY;{4CBeqWOO&ustBE04ZZ9oN2``SEp9V?*^~<?{3Y|7x-Q+`{776})@X
zHKA?3mU91(XUuPBXz1LXIwk(A^|yz<oq+;JzOFfD^=diu?xQnH^2@_tvz6X=pLV_b
z!3)8_88Kr1sh33WrnEjeYBSIC-;O_`n_KIiqBvS-ZNoP1w@wdQy|@2Xje56Bx%~d|
z%c<Xgav%Tjere0H_nt@Jv}a{l6;63{<H>=)D>U9~rVEKV%z1eu&Z}m=x{g4FtXZl4
zuB><4Hu1Y%n#^V-wtB&lbgmoq)^WFZUUz=9thFnxmb=#<_B46QbcTkDkFJ#jpRU?-
z+;C+?<^QDx!dy#F+t-Ev|9d#jZTpL`9iP^=t<0GD=7_+%?t-g3H9h{GFPheEbnf4+
zl+{ze$H#4ONOD?VTAo*{DQUw1Jr}@qe(jC5Gjn$SkGbgl^7i|iQ{UcQ^u6%!Z?kpg
z_0e-y8%4hmXN7OZWH_)SQ`~p@lYa#nN8bj8-QB+XebHXgZIigS<kncF9zV7G%5jm>
z_fP#Ey^gGszIE2h^3VKO{RJ<~?UtW+?z+v$@VB~j>hFffdFP(a7EqWjHSO%)OK-EQ
z-mh%-jF{6g@xpngj?MeoZ@gq(EWh-MI`7wQ^~-8(ME9?LQxm75e`foPjVFa?>@PUK
z;K1E2HNSoz++6jlUHb0riJV+_;DZ$no*%ro=zLb4Iqm6j*GFkbQgb5X!nKM%)~8$y
zEGjy@%IVbWn<D@3^oNQ5&OPVM;Bc*J@q%Z;g-f4XHy5+^2>&&GA2&TxjP>2o?5g+M
zf64`v=YLuL>G^%t@BfY$hQGdkbf??1?~BwAuauBK^CsYl-ON+=b>a2j61U%cpTs>G
zTnv6H)Z3L~+I>H!Y3ASOXM{F6G{UzHGhFEZ9T-^Xbp7L;Syi%T?EikgJ@n0McfoY0
zThjV_lk4X`;Q3+0V>3zH-_e>OLEuz*9wc_EUf-(T*HE}9zxj^cu9t=PAJ6zS^?N+m
zQ|s+jyQZ%PmmJ2GlLCGof4`$#+EMOyklX&Ext8+G-O}$IkL?#*AtCScKlJD4_Y-Pn
z9f&EhH4VP<-Qw-Kx4ozKf1h@D%F(Z@Pc7m~QAJF2Ff=SVyJ6n1&Fq1SU(?@-&MdR~
zCzDnB;P)P(T#XCXGnc-fzen%8nlKN~E1R0gzy;;UW4~MSGcqtgUbj|z@A}vS70gT`
zDd9)*3kx;gd(L}qb<=K<=CwK{C$^uZ-(uuK7<ZlIdUx>Ld--pRPMv#hV{Bo$ER8Sg
z-QV(m|7Ts6%g~%Wr?~#$8wKqW_$m?x2EF1HO-r76yuIudGAYycWBNPanR_ox$*S6W
z?aJQi)|0q=o>+X`b#I;Smw#raDO#m_?!9{xr@oHal3#xLoOa%sdmq`bFr=hrJzMaM
z-PpGLP3g^5OFk_*{(Q&j+RG`m_4kjxtzI6r{{6{CJGY;dPWk=f=k;&zvcz_(dL9f6
zc)h1I<nE+*k2i0WdVgNW{`S3U!6S}auP+x)U|C<z{dw*E?d7W{ef@fcYqF@;|9jD8
zU-vuQkNp~-f8er{fsF`KL7se4-iuS!<Xvd)y4EAlmu>p5w%q&F<7eTEdi$<3nSNDU
z<CoD;^}47cv&Mp-k>PM~+>CtN-y5QhBmHBSoSm}%Pj&vzKc91QFD0jJ+BN0m<SBXl
zFKy=@fADQ$j=b*Fx#xdY+}E1<N9_5k|Fc38?!9{zCv{_I;wkT_?<*_*e&??a-TdR~
z0;}W69@lqQylVA7+W%Wtoo`RltNO~m)A5GdCxno*Ip=!sFs~nuo-gmN@9tb5^}nBc
zzsslRa#25z`CJd0;y?5FwIgz$|7L`K+^P5AugDU0Th;@6^;TNVT)v}rQs&Op#Wk9z
z$_3{KCH=d*<g);SL5O3{dYcPH>)(HN@P4&X`DaAkRqy$mUM$l4?3DKX`QBgi|Nb&a
z4*U7}{iUrwVed8s#?6rb`TN_cbI)sP3^o_XD9m&0Qxj)ozx+GYe#T0kmm9+FHeXGb
z|0ebB-=pnEcdjxh>zf~S@$;hP=i)inPH>DfKdGGZ&(skyirbL9E-mS?(dYNV+v^2H
zOQr<9cp&v=@y@eCTp4@Tt=;-j?_Jq%4Q~x8zH_3b-a&d>J2GnIy6aZ7EffB%Zn-|G
z{)*xE<=pFHd!Ib3{?|X{kFU{AZkDRZib>Prm+xLROH}A{zV@6u5=;#1LVrHLd293A
zy<zK*ZhIHC?oEwezq4bZJ=6DH(f?K7scDCl**)Lg8~*g~^rq-L<&0ZS&)&~h*>|UT
zZuU-H>od9<wSpf#EHv}ZXM8;5>U!X5>(6WN<-e^u^^B7x_Sw#^G%?%T_f~sUfm)OE
zzhoad68m}Gju)8>`;TAVD|_>~Ids4TG@{?fx|}Qg{D!AT@*cK}i^$8wIZxcWT<o^^
zv2?yGJ~g)AZqL0uDXhW9jrCo0qV~qedm=X~KcBX!=Fy?H%dFRfH9va4GO3#ob>MGi
z()o{D?rdoJ!?mvBUPacy#6SjylmlzN`@Km!CI8l6-@hv7RCh7&_a3p=vd?z?f49wI
z^83okS5JO;9e(rYoce8hw+p^MU$c$p{X?eD9}fMr=b9IH*;F-uS*iVupZo9Izj2-V
zHuhcg@u#!Cf6h7k^lbKj)4H_(mYW;TeC|S;Z#(`?UqkFv<x`)7AOEh<`0RdCx;poR
z?401PMe;7K#_R8P%PlXNDd+3xCGH;lT#4DgbN_PP5Q)f>$LCyr%>DnLZra(&|LcU!
zf{Gv4m23-8{m_2$qx51{roG@gcH&g4bF%)O{so?aiI*yO2<3WA6K7zM+z=5RUNt}S
zWm}8J<m#Cgd|t8n**8TTkH3>Y`QddSD6MYhukN2;d!zO_yYc_@WnbgwPbuik`g#2Q
zEAiZbeZ{L+uJ=#dWw$!-+x5+F_s*@)eZOv!Wb((gA0EvrU*Pq;p2w*V*@xQ>O$&<)
zOWk(sqw(fY-`|_w?aetcb^2<J$WIn&(atw+w@unrB>&5LtxM|8Pe$>V1mp|ncV15n
z*4CGvJNK0C`Z@1kOn<S`XYIE~Oxh)T?(bb`e=RGy^h{dxr<UWVW?$PX<oTBA$0VQE
zo$u}U8ypUusw#5$_&>kzi<fs@ol@husYP$yJ*nM4zMcx5tU5=${olKox~W2+U%$Pz
za*^eF^}O<5HaYq#Gk)~#WN3J(`QIkGdfVRXueScUmU0?Y@JI)A{4o4zxAS?m$^U)r
zYxC1LJ`SGsptbFK(d@Nf@7upwTVC4zBEEk2X2v^ps|0=CPv3p(`OCjWd+ayQDJ=XO
zniOsn`SND_-O`<VxzfJP4?bcutLf$6tUdOd>tZdF#r7wO8BDmNhUhpQ&}<L$d-p+S
ztF=M&%FRE1nXG^98zK9rZ<)x&*`lep0vD8bw*Gp2;BDrsjjUDbm;H(gw=Ge4x_9v#
z--xNpZNlzt(Yx%IRk*u)>*Gwuom2Sg(pYyc`d0DHLiL-z+CQ1|sWana=d@=gGcsH_
zKX<_&ukW)z9z64E$#FG~M^$ctdS5ma-j}^|_o|luxxfc@iGAI-#dqoQ>Fb}_-lVY4
z+UmNL_KeKC{AvH*f9J0beEN4f(`KuvQ{10*jjyiL-mhP6#8~k3eKAu1XwD|lZ7JI(
z#678F{NBcwV{w#&eO1~1{y6`dN>#1iCo+EouRRIZxK*^CFTL;}154TV=W~klw}_|A
z`D~SQN+eFR-u!THr~UExcHf=rHV7yse)PKjeBt&d^I|rX*=unzG|0^?x!SjrU)|O$
zQZzbhy6bCD(_v<bpV|7!HzzN>{^;9fOPSs6$`u}~?L_OBU8rT*FWlFZ9r@zzJN*tj
zwpJ$i&Rm8Ed(0Cb?>Mpd-rw1KmN`eic(Ke@<F44F*-kU}di}ilLhM@Jy4Irld$m9Q
z?lil8Xyf^vTm0V5J$^gj+`DDZZqMFuD|+JZ!hiQfW<PZEcYXKnys-HCoL1eVVsUkH
zQI=nAN~Z33!NgD%8aF3<$F4p37RA4pKl0V^Db<|p_hPF3|9yX|Z#~L+xALyt#G8|+
zwEX*X(tor4m#91cuI6_ahwi_$=*+?&VK4T5wmhHGf1v!(+-TqOtL?KNW&Pb|5w7}6
zVu}n>;V86+Q+krvt=Mz5FLy}n(YX21{z0{Okn_4Wrs}2U*)Ls9+Oss4pL_K1z@%>3
z81C5jkDFhx%l_K6WYQU~x8JLsgPbj^S6xpG_704*G_|&mU#nf4xBd3l?Bca+*e`O+
z{#so2XKhKA`o5#~>H1%))>b}@unaAo@qz!JXW>itTQTMHi$Cv@Uwf+7b6wM!eWE_K
zbHlgm{@ob%I%&@;IhRt|%t$NA^%sKw@hO$Fm)d=qHGTHOHaVA2*{slK+x2bs-;XP(
z`!9Iyi$d0m3)fSl>?D<c+T^5^$uTkH*%V(*sk-y}_alY4sap(hZv6Ob=I<5SUA7ut
z;^Mu>mMu!%aNbei`pH)xpRcP@(4Q{;{8wDc$CSdd$MLs!pFN->b@6a)@Avd+^J{NZ
z|9Z0g=JPZEzH-Ir-)Y-bG40)32@T|Cc6Ux&>B{qd8E^G&f0eV}Y`y;QvJ%hb@AB;T
z-#-5~_5ZJ{cKeFl9-FZ5+rRf*=_K>S&>+*pKWy#)8B6W7Uh(;%R^`pU^KNd1eEK%x
zo9*}+8O-M$4c4#Gs=M=B`tL%uJqK*3*|A0*iTJgz`)pqN#`90*_dk|P@Y%U1bKNY@
z^>t?#Z1}t7zS#3sQ|sSvO$ts~Hu3eex;_3=({ERMA3XE#?&`8N?rhg5%umlgZ}-N`
zH%#K#bJoHD)mIW3eTXSYP&LUQq5sr+`z*b$F+SOwoKmZ|Tb$fDvupXQ$ezbR=7q1U
zr@dP>`Qqc_vAWZ*H{CcT=D$}XJ?2hb(YpUO(cF(7v<IFOHlF(E@67X)>vAP)&DN}Y
zb@kKSXx~S@j*AY+g3X5!$1bm4z31f8_Q^6+%0BKl|1Eo5PcshGbU(3Z^|q7JOFsQD
z48E6gTJFVM|D*Hg*WUR1=l8d~rJw$JCkj~pO(`rpxOCI*sKrwJ=D%OZ-`>4C<@i^Q
zW#3mHKEc2Fhv>y)2R_e4s!KpCP=0XsHQfrm_k7t?X@Pk@UB~p_c;ptU-CcF|t@2Hq
ze?DOoZYIy~vj6`tQD4es;qS@w)8?}q|NcB_m2!2gQMX3Xez~WuKc~&iYW~ABUFxa)
z{?)>{Jb$8`5G^W@zY_jTd4DHs*Xnz(fBS^3_*0#KsQb=lO)2|b3%aXwPAxeQD|g{w
z?WZ-z9Bn4#Jp;96*4v+LD--F-Sy-JQ7W(hcZWpPT!&BdDR9Kz(c=s=B;IV*p%1FbL
zAS;edJ{=$XvbJ%Wnx$T2we94>CGYire0<CEY<=Xu;?<sN{&L1o*>9fRQ}aCRbN0gB
zyXWm%ZR&Mg{`kS&pq|A{gP8ExA6Kq^J$3b0Zs9twDTY(t7a|qCAR8WMW<6U_Hud|?
z>_yf)ri(u}dfD}EQ}?bd-|rs0n^L-|ViRjxAShjIh}mDf`X?x}oP6}=|FL%u7j(_8
zK9?J8XE&qoL__uo%j*kvt+~8c)_JlrqNV~_U@-3#_vf|g@@3g-uU97A_4x^E3HTM6
z$CY0_8}cf>XUq5Sd-a+-j@FhhFMD~p^w^8*^V51aXM9MyZ0-5E`QMz!pLa%8{$DEK
zfAsVud!xvQyZUaYoStg`UvFytpLKp>JRhqcg4&$?yU(t9Zr9PQb@Awi0QkN&kOLSP
zlF!6Or|m6IF~2-%$t#xjXN#}IH}1Zom!^Mz=T#f&Jr<Mu?le}<<&nEl`SHuiM{nHp
zKkIaN%Vl_8%9{2&Y11JC@hLLTUl)6x*S@{mb-LWH%%4_WcOP3sOm~^bKX>nhkdp-m
zvW}MuNGw2Xc>>#e;0GwwU#$yU|K9j!QR?&Jx}e8GEQPj{8-==VCI{bVefKVFs`zuM
zln)u8(KDU@HqpPoF28x9uc`8TPWPs>Tk3R=Z?(AoqqK0{pC`+AR(6+Of4ViXZr@BV
zkoPAhI`8}E`#%0<wPLN@<8T*I=d+3EaeLM$Tr0}<*8I46Hx@kMGuD*z*G$_#_uvJQ
z?fol0&5b^*-o2Uo)CW#>HSLgX<=xk-V(iafoA<}0{CZzg<xczan;3p6y*uc<DeFY>
zUW5C)UVV2u{>QWTQ~&*|omy?3NHrtKyAs7>*{{9c8&{jGG}P2Tv)yL4(x)X!-*mX9
z+E3cK`0e%iX@_;J=j}ETYP|<4a`x+;o7z0{Z)Lfy?3d>|_qdqx&fooS@<o<y9cpd8
z7)C#xpPn85@>ovLMo^Iu^f>9=SDrS@;4^WR|Cc5#tJ&Yo<`|=1>>giW5_)dc<(;Ry
zluPeM%*eNmoO5@>;)Hv#%%_hBzKG*b*z*KFdX?~K<|j}%-hCnQgircuYvnFo&?w3Q
zmH)r8S9wOg{aX7mWRFbB<(D;2j$B&4;Qx+i+VA&^oGQ;Vy{&&_rpT*lpyYS0ZyzWe
z@7uqLeR;?0#L`PE<Q6Y!O_%>BH#<b~NV?2c@h+1S8Vq+Az>7nJk3L$v*saa2*xGlp
zW){rd0SY??<qx~(|K>K2e*1UsKaU`bPD4;3Y$y8NKH%L3g_W9~8&_u3@;w*%b#FrP
z>fop6_j@niwd3JQ|IO$BZ{2&F>&&7v$r{=dJQ;S03cy#GfX$Vte|mIh+v(YR_nl8^
zz0v&0<=B&RYoCQC6~)Q0FAc8Wd-r|CvpDtS<8SU1rG8G?vsl6Y)bU@pAH`f<TJ(&0
zcD=tE;|noaq|qhzK*#pK_Idw~r0pntxTA4am2ep6ABo-aYqi1_KK?pqRh6t6=LOTq
z%E*Z;H(Q)vv&LL8Hi(hIylH2ak?p=i(ei!;5mG^i_D1J7+Q!a_ep5g1jq**aX_X<b
z$|vlo-5(|Wl)3iP<u{)}^;p_p`S+aLZ8TXHL?aI(v}>K%GVfuBw0Pg`ch@3RKO~>|
zyYP$`=gyGnS5zFX9|@Tv^h{Oks0l-Z^q0~V;p^^k-_dPe^j5I%l)LBYTE3tuOHTdP
zXWhQze>FFMM2&gb^J(Tn?@g=apUcPp|9$h@JvXu6Vn-ae);teew!fXl@y``o4a3h2
z>zI)S2S5R9pm?ggxEIs~pB%g4-s}U9+Nv*Hmw@zd`@i*jHLh8|G3MSM)5l3EJo8Tf
z%f8uDT$C3T#=W+<y)<>tg>8Qxmw!!{FPp8Vono|L;|mc7{`+^)ihi|I+D;#QLEWjD
zJS8)<*)Dzm%a^>#YI9TJgw%DLUa&dnYaopef#y?qX6!NK`YkBKYMS;~r~K+~S><mF
zDt7(;HubyfuOmHoUT`11QDUSX&KNTtsWEt<SA2!)_o`F=-IGei6n2=W-n3(qbC`c7
zPV?IFzU#$vRx=oI-MPBSQ0vW}ONOWZS#$jk+*iE%=bOWE&3z}+Yo>&}dL8EcEAHBT
ziAf?${=aLSU2xjU?RjcK;bGg^cBk}AXVfy>MQ#jK2%D+ss{DI%@3gF{*r6MsX$uZH
zgP`X{QxzBvcw~G06=&x^aYVFf_it|FZjasD4qPpGZN4nZ>~($osqSKtU-vG^?7A4E
z+r)sHEUv$-3kg}1dh)-brvA<PCs{B0H(a|cv2Ie#PvgfkqGkp8u0NbM|M!kn5v(Ww
zYu?n(ZTotr|LvD;%bM=keU)slKQ(3g?d6Z>U)y~z-!rP~)2xf1RzCjM&t&SptKrud
zyV>>n+x=~yA81~&AY$p`$N$X4CyA_B>F{;mr<KX_SEt;p7y7<&dhX^8LQ}tNeevn_
z^OOH>7t86nR{E|~vDTYnV;d%B$im=p>FpZ!IY-WY3N~gpwV$!@z~9yXZ?1ox@a)#-
zBeA7w$ua(`b}a4LH8WlJ+X9V=(F|(rNNMgsX@!7j$&-mOsxwvQX0c{W3X3xniKw^}
zYj^YS3XShwf3gGL?JQJz=^=WzI`aCI)=t;0+85h=UdyiEEmpFkt!STe_{Wr->-8#E
zw+c;7x#d}LKUntF&SigN!;fzhc`Cf!RCj((bq4n>uITWt=FFcJt4r7J$vL&QCUfJb
zzZqL?=RG~&^K?>J+&b+IyNmW$)YW%R6MYf;oPW>K?b-il*YNyWU0j@>QT&$O^SHn8
zhM?nS`OcU3zS#KWb^5oTuQ$rCTr_q1`K>#{_L;P~iyyh5D(kuH`=(`@+Un0PyZ)Xb
z5^g<px%S22TseEuhnsTWyC*(MYTk0bTz83H!4E0xxq1=SUn|vK-a9?*PTZU~@spNn
zte+!y`p?9algYK+iN7p48780EbG2}N(bB?Ax^C-p-iz5T-q@tDuHS3NX;{l6TJ7h)
zW6A3iuisz$UwL!mnV%9mmkgITTQ|IWzY<;}FfbUTtlQJ~XZ;bUJL}JMb^V<?ZP62_
z*54Pib}Rg9GTg@-c4^}OrN09=F0VcFv+qom4#TJVj9d2Qg*kz{6>gO4-7ULyf9bzH
z(=BF*ioBTn&VBXt9`U)l0e0qXzx!fZx$R$TtgT-3H29gK?zykt{n@IwCWLt2eg3V^
z-tL~>%NgCDyq`UMlW^Mh`Q^PYKDHK4Rk^&Yu5;Q~?=3Yix2=1z<8f7eSe)DRWA9$?
znR%^$`};4Z(|uo0?=O8dr$#_@hXT`%$nOs7{$Ve@pRu0G6Rx%`yDrvQu2wE}eJ}sw
zEgVdfr`-AXSD~%<@q#Hg6C`Wd8Fok_mmh6s*W3sdTodVdIqGf2U&oLM)k}}_pVj`h
z;`iCTm#PbQ-)g;bS2lX%Z>B13RWajuO};E~cXiQpeb=Awj&0s^hD$teljyc5^THgi
z{=8Y}<=A!msjS^(s}JhuUoJk9-1j%O-1X-3qzln+v}2#gUPzrcYyJ09xpgkmM$vB#
z_lMt>y?=h@xAML7^`~7A<bSTh;KMN8e6!T*Pw)4h*)?hR&$nxiY5o5ZTRSDm&a^n7
zSUh&Jf8NeNzjiNw&L@3_#c!Scy`xRn-sz<*J^1I{tk{P&)9y1esL8V;P1|^UUfMUk
z&t~c4E!&^`i+LBS`S9cWw4>a+r_aB;&ESLc>y-)?hI|*F7J5kQEwrePTD@1iD!!uO
zq-^lyuA90`h2I9cvFg9&KUuCLGUH;=r<iK*ccDAyox02wxMoTvd(md6@5KpAuc*t!
zJaY`$QIXhiUHJUMZ|AR_uX*Pc;`O%f{k;jVS3cRg@TdTT+l`P3v4xA-qfX`M1gjnW
zWXE*(;CXHRGuzLEDF5y&Hkh|6{`vFWS2Xm`Y<|G7YR~^kFKrjh{519L-K1}xv$1-u
zG(&u!-izD}qrVewy}cc3@%cM@pyQ?%C7t}22cB)+8FuYil*Z=PDd%IQ4jtT@!sRa;
zy}3Pi^5cSi40~kTgFaPkD-dE2FOr$W)qPjK%rHE$>fvWg$1KChLv`vRJ9e9I5iR>3
zxo-KaOMCdf?4NXM<?Xrs$x(J&k|nZ??_79xt7i8D>w^z>{@GKZo*nx(S^xI4lC4Vf
z4!5W)*Yy5u{1={oU92SG^U0qXm1pN@w&*N9ck<aS{#!ieU&`L*y(&DS`JTOjb4qG?
zak*}Incerj25Ub(zppx3bkhxW>4Qw=o|__~Q|=e?-P?I}&$+&D&*IX>F6`^K{Zn=K
z<eQaDdEYcn$Nstg?cJ)GM$rs5S^hg13~nJO>UGZN-enoD@t$<Ag?Fc|@11uw<!={n
z;amLei;v-#*&8O_F}+pwI^b1Y=$hR{x+k_Sn6qm7KJ{$@`G;PetYgtUK5ft2?sea^
zb@|q1{l3wk+xGR!yPMCsyMwJyMgP1K6Pg<KE=&G)@q{~`|F@KFtP6VRvG=tl$ZJ+P
zS=u=-bASA4VikUFufCGG?yV2cZR@!)66vvGGj@ag{%&V&&bPg9r!Lh=J8|>w<j)z}
zIZNkF-+2F@Sab0I+FJ|f&Hwq^@zhS?@0&ar7>>=aHuG0E47R&Bzw*v|i$a+->7_Xv
ze;*I*sRRwTmx`74%k18#^f}_!5tavA4j9KuY@QXG{^QiS=X*|SEiQY@UQmo^_A)RS
z<iuTnz4h75>3t#ZSJ_Ve{oUww&0QfbwmWtwg}4sBcRzZLDNVIk^3~g@t<MktR<?-_
zkXx;JI^lNSqX{7$bH&<k?6?2<e(H)TpDcZI*UjzCU9hWf*W9eDDV%o?g)h3~dGSwU
zS7-72Yq1mOsEf|OJ+0*EyJvaxg^Cuc`rGW&v$j%uvv{SZs%ZK5O>aeYTq`3FMZ7!P
z_xV%*hGo@(mv$EZ+;?Whg3EJjwjT<66v0sNxn_z{b=A?ur@rN_-D6R{l<6X<aUEUu
zd(q07&9_#t-Ssime9Eb2-d8(iOO5P&8&UtO?z&Q-c75z`KXAML=f(II!RXbi?}t|H
z`pzd6H0Q3K-_iFfe=mHuV80wV?e6VV8&4*O{&-%b_Ll_XU9tVkM6aodu8H<qer`v%
zQ)`*{+pPEOmz>?tY|(ps*Q49n?`%u>>q*yykNpT^cy~%&Y<0w;iuH%nuD70Qtev7R
zGI^{0?t2^Mm&=yke0t&6ixa=fau=T785LxI)n;$WvNPMdQ-k_Mf*;*@lPK>$-&ynd
zO!q2*t=1RkAF(!JJise{B3tkDlI&eGKW)@m^`<87#a4@Npm7hi)LV0ZTo=^4VA>tO
zlYMo{0+EP21^jLQcIxH-t9l+*eC5$Yxi>M@b#l+dmRx-QAvSJK_Md-=`nL_=-^sH3
zz2UY=q~hcVucPVmW%pSxvp)<K;|0yg{7qQ4s7Jh!#of`D;lkzhh;ozRn0u7sH?J)h
zcdq?!yzz8pc<lDv53=8WX`b<W?N_&J#*Xc^n#+z@FTHW=^`xnKvgTWF@4i3n%bveC
z|J9~{+;M&D*0Q~>Mf{7JlBPcSw_$bi*{pTHPji<Vs<%GL`=TlP+1I{AkIT|FUNbh~
zY?sxg^t;uOlW$J@7J51Ch7iM@f~QA!x?MXu=i|RK&ri*-zpwlMN9^9&-)(N+yKQi}
zYTEIqpTd=8zsv7moi6!(<GF(%M(mP1OWDF1RN{``@~^F$b9a5@HW_&zaqaqlvSrn=
zQ*Pb;^O(6?XSKTe+&@vPerf2vV=&MwEr?}c;PvoyaSTBzJdSlnMty(zb%}WJHeD~N
z&wN$W-dA0ASo@^u**dPj|8HN<+s8LMs`BQG8RqtvZTH=Xygx4}$2McX%W0$ix+|9~
zUjN%7(f4?=XqDBHCCioPlr31btk%|6JvVY)s;~B?z0*yPe)FntDcQhMuzBa+pf=WL
zX{UCxTc6+d{gqz5sjBIz?&9=y_d)5nGRHeFO3vY9T6Wg6geU9YMv7nTE9KhtDou;G
zlFd%2QssZuvhZ~|=Y1!O-pPG_v;FR}J8`UzG1n8<McRdD#QpsIKIn~O;3emBQTD>;
z@;l-TPBT=wBF)J+ocyMi^CIrb&#GHVjc=}&?t8o^(vg2r)4%yqn~o^${uPkCMJV^g
zpNUKU91-2Ze=F?9CH=q^4)68u-<T$v5vi>|yGT3u1>b{Zps9=B2hUVpdpv7p%BD%)
zR`(a)j-AB&Ci<OgWn$fv`Iihklx`V*3zW)htbP!u{>CFHZcet%?R(NE7I9A&O^GV!
zzh)|`9w*IS`Tc#+<LmR&cRpvm@cX+O(ztbl<EFJort^n{_?>k9HaoFaWA`?Zr&~XL
zT3;r9mwVTv-R3inbAzS}q9#;t-aTbQ6Vu+ye>0{&VBFCOnt<48KffipFkE}aP5JI*
zP5pDGF|l>wzB>+F-O=|$xU!~HB>Lf*tuFtvl+K%WpFU&OpdD+E+%#m2;g0=(a%I)x
zq|G8rMe=?ZSgp-#`+DTOk!Y$X>pSN+?`D4X%2KcX-WKDZ`peOXD|pw;=V!N8&OEeE
zoMng7S{KzO_6KU4W;QQ>m(}~f@x@Dvl6?EEhxJd`dH&xVFaPZLPX3=SZ6un#+eQ8U
z|J{Cc=c^@8J5OgnmEW)YoiWA}d9F-2AwqWl@xZ9*CA?dU(_=4vni+m3|Mb-<H*f0R
zwc|_emvdp2%{2X(zVY3w{;ju8-p?-*{PuUniin@<&hIo&3=In9U)036RqLnoOwmjB
z2ju0RvoqY$0F6&>=CAfw4L$Z%;!bG&CJXDZxi6X*gI0&M{+XR``+LJ}oA?wP2YJia
zg)e_<>hFHD-qS*Cx_R@<<_VFk1z)q3KpkT+ZZN#$T>gHk#`>u%u6#^4dNd(-d5HH*
zh3tQ|pN_A-aQnx$sUMO&y)^dmhe&&IBu@?Md%N-<N49V^7i-qCCs*tz#eb8XdG6mt
z_vv-#UT;`=w!nFI_UE_D)t8i&>KDZ_7X;h>%>1_V^zl#D$79zfr2T)l<8ArRb8DCJ
zmruNZ!YHyfV!kL#;oJ`Y6Zwia=h|<#K6n1;&bHn2`f7V()*dJ=-!m_dG2u&HDLdG$
zAj06^JNLP+n=VJa)i`7N*5`zvy7)8|(GTpJM_<&fx^Od?JM>fM`nVettsN&^T6p`-
zojsM_`G+2g%ssl&_1D)<yYNR-n99AiO}5t@+IIig4)Mz4^QUG!KJ#sMVr=`i3$c6*
z2hIxl$hSNWD|ovuOd($4@uRchDf2{j^RHiB^=^VI>*PaI&sOHotI+?KQdpK8BmQsB
zPCLDG6F)Qj+U>4_7)(7N@o~$$%bZ7d&bw4wGwJb!kTY`2j~sk+dFA(|BC8@+K3=-I
z<Y2w5+0%P(l1~5XaNA>IxU+ahkju;~Q~x`L?647^{LFNr^q;UBuU>NUFcdgX5q}na
z@XNnLJ4AN+JAF(u*c-3<dC5w}r*ph{ts?#Tj7^Ot-9by(f;{ZpkLN!;za&PUvFE~H
zE~NZ;?8M7OZ!X`FpZD{3(3I(!mWhXdxg1g4&>wqrVXmd+wB=nV@3-)toXp+-&b9yi
zzVq_2h3j{}IFcd1-v0PG-DweBpMsKNj$aPD;icncu3e%N*AdM1`|lMSRdLJGXLo|8
zgnx1p;c8&GQ}H<HiJj)r*`Oq9QQmP*hp)Ss_xvj9@2%Uz9__Ac+VMqm^~OglD}Fx8
ze)MC`ay?UxJoX8y$g?$tMpMI7a+gkadIRb_hO3-b&)IG&Sjch7YVQ2*!>3Mrq_y^)
zy)*mmqHo4Q$3k4S^_ADUNbmYy<i6>t_S?<nfqU|t-#n08QZm1!zU0!*8dWXL=hmHu
zGWnX%Cx)Ms*<G!wT6X{5{4XYqo14Po+|-k8JGf?j)A%`O$qQbFB^UKyl!V*PxH*6R
zlt;ehxf4q#<$UP2PyXJ|QdPt<FZJ9K{W-e&XSRdKU1R-^KWO@7GvnU!9kLGFu16yc
z==My!o*4Y@>Xi9mCHh6aum7iPo3-QUl&m9;K?!qPl{W76`fIZ}bmlcx?byos|2gzK
z_ih*JddIGwJFy|s(f!w&>WQbfC~tmrWUjkq^~9n#M~#oqi<t24tMTV4-%J=cU!A<M
z?~7$^;t|$Lb_Vk^*PHyhOUotZZr%NG-8Ao~pkZQA;4e8+mGx|a+cD3g-zFa-jt7@A
z**acdd30x+_QOnv@Pti=Hox85+r6!Flf~}DclJB7pL{wITe`X8;q{|CKdHpZGxo5d
zL`rc+>d9(-g#z2FuQym47M{3yS^KDC+~wIDZhibDpXmE8R&2&^QEm&pH(t^5S%2c%
zeOI35oAT~#r&W7gyKn4D>1Eqf!t6d@n!Vvx?Y)vCUw4`v-o?O>KBa!%T2|xVpWjtg
z#kRhCm$mbCrom?W|DgFiVe!XhhFM>iJ&zJN^40Nq;Lmew)zZJVe0(FOF)Q=$_qTVw
zQlA&weXWU|lWh|@C${6RvwY+7|24Wf^_whq2mJeJ{VtV}=b7~^q`9W#H0_*|ISZFB
ziu%6F>~L>q*WuS2G&i@->pFXPwbcfLug@)aSHG-y$6M*e{=s``$?tt%(wU7?6T^?s
z-rPDxUavRzUrw8J(ffr77o)p$eco)Uzw!8|##Zq;IqRnGT)^nC>C>T_*Ptm0gU$Bx
zyW0=HihC2JT*lu#^Y2gf?#<GZ?@YaslzaDwjdV%jy2`nmD?hOq|31I@)uVgogsaya
zzO&Td7c>O{n#`0x^N7{+YN8%P(aMKGH~X3@xo$J^I3ubRwp<bU#Wj~_+%6SQz4G+>
z9(GI9-Q3gm2CeB&;oWtjvnsr@e8vS;s|`<T-Yi}GW%h=JOEVlTZKu_ErfISY#!bG>
zoxAR8wT=DjnX<PRZ2K$L{`0Yg&6LQ8U4<FdvSzm*SGq1sJ?U2(^yS(|3F)X#ug=2V
zZ=xP&ow!u=cG8UHPm?~Smzl3$e|VXki~Wle$|t>^mu*uG_iYcmmUiRPUyYD8hknl8
z_sNbg>Gr)OmE3hxw+iK+{4;UMrJFzPc23On`sUUCEhakg)A!8ZU*${eqo)2od@f?1
zoOkKdoK5qVO=xw{{kc==z=0?hwgW5u9$!6m?)jgK|GpF@l-*vs$n$93@$!|4Zx?;*
z5B?bP_j=FnTzT=vTOP;0J->O&;2UV-B6mu0&Xw=_Cnq1h$?GXSx$0j3uQ@XD)1R$>
z`}y|usk@eJ*t9pgC-wBCJa4U8n)8pQ?^vDp$xWwL>d4lKubHlMJuq@ZOdK|FZWNm8
z_s@FyvtHc=XN~y2FJ6@NRCLAE8#{N0?{_)P^<~}T((lX6u0LCEn&%xDxAU>n!P&Fy
zK{d9&=*RrFuV;=~g(z=zkYgxFo%;6fBBt}l<wTy|=dwQg#sB-a(i=~Br~m!_`h1hZ
zI&bF}_jnl&?^AnMbMCc4_?5s3{crCmDSUqaRGr)Eybf1sWwF+WWqieFi;f+A!%!fK
zJji}v!=37#lW*L;{dcF?^;0Ym*WW2YUe?aQTx1^=`e$qRcKa!7ChUkk7bl<ts!JId
zkn%V~LctyRQ~Szt{HqUayZ*Imt>*@ankC3nWd}@+w1pw{T!R_1?gzVOIPK+>W`WFU
zEYNj_I0S4&Lc|``m5SlcmemWdCr+LL78@l7HUt_D{{BBPazWUufGe*+F7b5rb6Mw<
G&;$UB6$vZ=

diff --git a/SorpLib/Resources/Images/MassTransfer.png b/SorpLib/Resources/Images/MassTransfer.png
deleted file mode 100644
index 03bc419e78a72da2c119d3dcb35d29b71ef6ff63..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 1441
zcmeAS@N?(olHy`uVBq!ia0y~yU|7Y#z|hFS#=yW3Agfr;z`(#*9OUlA<Zz(&C<6ln
zXMsm#F$06R5C}7-&%XrHB3a@ZQ4*Y=R#Ki=l*-_nnOu}#oS#;r;GdS3nVeex*0hj;
zfmPAd#WAGf*4w-KIZBQq$3IS;dSdd4$tQLxX-}Mb;?yaxRaz6(CqDODJ>kSDFBMBy
zKgHEt+Y740D`XSOZrbNRtDXI4QrjDovri`9{rNe~Q%+7!$Z1QvpMrxb%L<kiEeuly
z76>g6VhV9;@M`el2;gMYV$@P}Pz6c1FiZtYGlejP1noII`H9h4)>_7pT!Y`4YMJ*g
zuW?<L$(FhAVz@)D(2GY5=a&A+Y5p;<jydbDM?2Fa4d3gAEHgS^SACHWc<uDd`GK^|
z&TY!;?%v6a{-PZ4y5df?;@!;8TDMAGdM^m;{IYw7!QQHE(wr;Gzo-YSZm|-3U^VY;
z-Lt*i%u_{NZ;9QwSF~kn|3AB0t}DCJe%78Z6YpE9b!>&hT9%bZzP+<9_OH)lxx~6V
z%wa88R(QhfCmGhMN~~9QEwB?ixNT?OZq0z#Ex)FfZ=3%wrhDm{rSG*E13U$n=<eJc
z^1#oESu<dD+pW*C^V6=M+WmflZt#L@jHLxR8|`*i`?-i-HM-rKb-CSPE%&Q00bhf+
z<!mhr2{cS(%6c2{G^y6xVei=jJr~=o>HnCsVm(qj@BKNlB>TubyMWmZTIuhV`^}10
zPhC}a|KB^iwYTp+ziM&T<nLbp<rU6nW9LohWfx1@J@s=?-x9Ivl_yV{`M>tt#QJMb
zTz#4;`x@~pl?ON3RWc=b)YmcoQu9^&EzfXGIQn#<#rs2>-^N~?<WTKkU(BMF(4R1w
z`|o<oTi-svON(Ti#jKSedqb|<Zr^6r)qB5&Hq7f|es!E<gZf6_Zn@&JH)*;IzmDGc
zp>pL-|5nE8l4pANt1g|pSeH}S^NQDG?!)}`-y3&*KF;`CG-~+^*^dV<PF|7zx3ckH
z{&aS&guQ8R9~-MBzK-zz)5T=Vt(EY7gQ(rTHyWS2-)*edyAZU1>DtZ<_Fr<!A4gR8
zKFf;|yAZT6igowRcO^Ev{N<DjWo$c_X)MiIFx6oz+qVM}pXIML-kEzU&d0DQM!v?-
zE7U=|HH&r4;$N9{4DVhyo=;zReNh<i7O@o@n@btqq#SOHK0a}B?3~%0H%uL-I`#^#
zNnZHh_S@1OY7J&grfM5*N-z2zSIBqaQ==J|Dcgp=)_?8|VL$3kI89SF^x6KBb5L%V
zQi?e4vXV7GIl!6mbw%KNnFVYMv)EtX_$R}7#UNyDf-Lvnat78_RvTR7bU6c@156uu
zOBdRQEO2zr70O}Tx_h#B1C!~lRNV%tHm(~Ljc%M*jc!CVy768Wx^bg%R)dsrgtmjP
zV=w0#(*<e^+jy>N1zZkrX3Cb;2$<T;su2)MfY@6V_jjLE{U0WcfWtcu?_&^IvFgCO
zG`aZNEesj~vz@AHczzw)eu5#?IAC7{--=(2|74qsT-a8uYMi!ljcY@cbie^7Q;h`;
ztXTmLjNDfiG%$&+aAaiF320{GidewLDzd?Wch{YBMiIsV$*b5+f99>dvG7>Th8)hE
zEdjcrS7uj8#^eO(%Kz+;%rObDoGfB~<H16vD{MCs7BXECyYXNF(-pNF2@9C6m_>XI
zVC0IpN*r;+=s*~o=z<2_uiloY+PDG^gfVV2S;3$h+GH!O<=`os!0pVcu~IlEZv}&@
zZ^PF%u7FD_Hzo%#dYLrX@`^5SVZGrL!00uLbvDD476!AMeVhzlA<eP6lm9kqJ9Ij2
e(0~2ge#*A`tyV9e6*Dj}FnGH9xvX<aXaWG}fp1&@

diff --git a/SorpLib/Resources/Images/MassTransferDiffusion.png b/SorpLib/Resources/Images/MassTransferDiffusion.png
deleted file mode 100644
index 7868ff175c4550ae1b56296fc7a0da81f1d532b1..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 45873
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

diff --git a/SorpLib/Resources/Images/MassTransferDiffusionFlow.png b/SorpLib/Resources/Images/MassTransferDiffusionFlow.png
deleted file mode 100644
index 10f70ee61dfcc6046f5f326bdb55aba956c5f19b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 56635
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

diff --git a/SorpLib/Resources/Images/OpenAdsorber.png b/SorpLib/Resources/Images/OpenAdsorber.png
deleted file mode 100644
index c8a6f7d9927612ef4f8ae3473eb84812a64762e6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 17310
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
Uliwr>1_lNOPgg&ebxsLQ0E;=X9smFU

diff --git a/SorpLib/Resources/Images/Sorplib_info.png b/SorpLib/Resources/Images/Sorplib_info.png
deleted file mode 100644
index 20455ed1634f49976affd8904b6562fcc5c4310c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 22552
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

diff --git a/SorpLib/Resources/Images/Sorplib_logo.png b/SorpLib/Resources/Images/Sorplib_logo.png
deleted file mode 100644
index 4541898aa3028fb855ec184c91938e2163901e03..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 8109
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

diff --git a/SorpLib/Resources/Images/Wall.png b/SorpLib/Resources/Images/Wall.png
deleted file mode 100644
index 4eec32e050a6eb19686d7cc1ea8624690405f28f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2784
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

diff --git a/SorpLib/Resources/Images/beta.png b/SorpLib/Resources/Images/beta.png
deleted file mode 100644
index 39f7eae8d0108be50c870cfd4d22fdf944aa9475..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 14971
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
MPgg&ebxsLQ0Crig$N&HU

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_iast_n2.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_iast_n2.png
new file mode 100644
index 0000000000000000000000000000000000000000..38ace84c5e9f2ca9d087739e54617d3e228c4acd
GIT binary patch
literal 77325
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_iast_n3.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_iast_n3.png
new file mode 100644
index 0000000000000000000000000000000000000000..b1bea28dadb9880a3523fc80ad40aac8cb5babc2
GIT binary patch
literal 103704
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_langmuir.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_langmuir.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ff2cedc8c6a6b576ee2affba2d4f39109eafa91
GIT binary patch
literal 56102
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
Zre9m7EoN-I$H2hA;OXk;vd$@?2>=<<h+6;v

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_mechanistic_toth_gab.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_mechanistic_toth_gab.png
new file mode 100644
index 0000000000000000000000000000000000000000..1222134f9fc5026dd3c01c181d1068bede1fa82d
GIT binary patch
literal 77749
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_sips.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_sips.png
new file mode 100644
index 0000000000000000000000000000000000000000..29aa6802ef2b467bab056b676e7c128beff04e79
GIT binary patch
literal 72093
zcmeAS@N?(olHy`uVBq!ia0y~yV5(+dU@YfgV_;yoE7x1dz`(#*9OUlAu<o49O9lo8
zmUKs7M+SzC{oH>NSs54@I14-?iy0XB4ude`@%$Aj3=IF5db&7<RK&fR%NiqcR{D57
zd%4M_MGF!V$`i`>mF+3pdo7!tt?c*quUmKT2I1Yp0*<?O-ur*%-l7-U9EWsG@AqqO
zH?H2iefQ?`f0oUgSioW+!Q&>TWMCk0b5m;b#*G^V4kZ{!%oJySn7>Q)(r-mRdApw9
z@0(jEysxZ(uhci;hj;(pRspu=gC`m^m<xZsNR-+CheJy7h4mCi3+KoBwtw{QJwGX$
zq}>1D;Bf=RmV*ff`;HfIIsTaQuA`!gYo2kKv##-h&bihL%T~86>JxKX!zO;M*YUpR
z?Znq9t-PO?Kk8j0@oL&B-6O^lJjc#=c6L6D{<<V+rNE?PCu%oVeUg~-#n9o!Ra*=3
z#CEHtpPZCjoIgrtFYh^MC{>>;f3EH3qPmxRDk^g%-SlqpYZvoHo9DEwamW=pnW<LO
zc`(7CWXa=cww7gU;@O%vF&m`)$oR58vzu4jOwp}_HAzrF^Y8)I+lF~hB;H8f7Fuq$
z_E`2*fwKt)5|S;~pPN5CuzOB~;b~#xblxMEbGr-vZVu{Ty%%$%r#63cvTE;qTaNSF
z^^YFjpdoW>H$R`L?E}Lard?B5zRB3B*EE9yVq)FVd1f5%YeF?bboBQ}uSiH-@psS1
z$kXqIbS~80;3--E_RM=$_Vy-YlctN;R~a-POi1C`6JOU5y6=&}LhElkC*1dFcK@eX
zBXhL<Nc!n$AMyO>Jm$%w?|x_ouCA*+vd6CTw7CC+UF#LILUqr}pHDE5_~^M`*d!@_
zasBQ_4U;lyn^hK0h1J4RzI!|BzvVb(7C)3|Y_OhvVZnc`FEjSZI!ix2{`U6v!aqL>
z6~o-`q<X3N@ES=-3UYIE^T=9>7|rzI_*r}DHcPMaWUJ)nC6au8Zy7T77%qy{zws@)
z|Kr!#A3u^O?@o}tF2TOMR7o^ZzGB;3#@!2de^~yBN9>Ia^K+YX70+e+%KoY?DBStR
zqWqoAx|p4Z>dpDmm?e99xNGaHzrJD>7oY3vq4zTUP2v0pH}{#(`IUEQ!!ApK!b;g&
ze?JSH=GSrlSMhe@J@N2Gr;p6dc(#*m-dXO?iU0on`|;r+^MA{}r>Cbcc53A+C@&Xx
zI-+Q1Htm0QR@SNiqTExxSeFKI7JrtXvT@$U43j?<8s6UCiY_)v%F30F3TcVU0yKVP
zn;8q2&k?azKO6m}>S)WX?iDLmm{jg7etz!h{bY4@b;T#&J@b>^-#K(I;%Pj0^|O*j
zm%oh8(L8PkU%ocjki%#9@6RH;h?mj4)z3<sT|NsQ{wLEJq|E;C-JO#s%>Nj)UEg%*
zZYs0kAGfkUyK9XW?b-YA_3P91=6yFer!S7(U3Ox+{(J!?zAJJPQc_)Y>z@``&W}I3
zZSNJnz-ou}kv@wSFHTHJnW8my;S-0q0$X>gsnzV>oN?h(@3i8i>4jJRU9?gC_WACX
zOkpY0td?oI(OilrTe|js>6{a7yGHVQ{m0U}_s?D>#yqYo-YHS%e|+}l?44@8vkP|1
zwQ?(R8fRbAd3SAX^r5(G4r{}>=O1a^({f0?&~x=?p@*t9LgGm;TKpeP3j1F9<HN%_
z+qZAuFx`lWiOE8Vt!3|)=U+Q##vI<3ydz`R<LZgoG5cA|&xRj79(Zrgth0YFmQB&S
z_ulCGlECVB4^Quod2hd}z<d4cb%(RByR36N?ir)7|9kwgKH1Zim6e>;k0yq_XLntF
zm23VH<+b<vw`}^J=@}JM9Cb4`=;G6Vf4|2k>i=Bwm{aQ5iyPGfi`Jhz+OyMm<Et!|
zUwm))F3<3{*zjM&?sxrxM>8jX413x0V0H9{gnu<_Zq+d<#vlJu%fFWK!mN2WE=1|x
zJ<@iq>e8b<g}T+5jJEnGFCUs`alvM)*mduom|1hC-@Cu1YM)7d>NUL+Oj~y^-gvqC
zi=-*{;^S+bUcNgVc+#^?dO6>tL(cL$uKwcoowN6&d9VCtrlnTj-B&t2y|CSzd(Q0J
zqMx6iZ#q8D{Kf74>Tg<2>RWCd*fEdIaN$o?-5mYB*S4Hk{bi2H`Yv8u{jI-~oX^h|
z``Ptv)sm~9mwpS+d9m5I^RM^yx^Ft&W(N-46b{%{A;~k_PX27SHA9f`jvY^$R<5+Q
z5tBc%i}US7^L#rI%_tGpPgVzK@VX}&NJ#QNo+DwDELe3#x3{WREum_;)Skk!f>XUR
zX3rV|`FMWaw|{Z+c>nP)=S+XDpZea0i(Boh`^7~|4a>eIm8^Pqs@+(E$F1hl)*Fj&
zJkxG>>y=)(Wc60P11H3u-t|6w?3B>Y?r?{#vq~?l2uwD~yCYG$dP<X}a5WE`vU1Wq
z;ZkWcr@vZ9Sq|$oMt6SFc$9VeeQme?zqt?3g)cMPSl{~~PGL8=j=4Yi-BCGExhTQI
z_V{~ZQvbmO0|_2BW#P}>8;@s(baZjJSNu4?J!0t(W>HBVHfNnJTC7U-Nxw^?SwvQ`
zq_rAK@VHqi2HIDjda(M%^*SSyJlBMumsM3vKUBSHb-O%0$>HlCr-)xEzrMU&5xH3{
z>&gnnmJa7TIf@(qZn!wpx@6m=8~-l6&@p+{e&W<AFAhQes2@T1Gn3BUm@@gdPkLHp
z$Df+VX^$_x78TCYQ&Lj8^yFt%MMc7s6BAEN)t)Z!>9@+&^Kmb3*I!)zyC`C+-je9O
zkL)!*JWJ&G7q?$3mrK=z->mk*%a@(^_Es+rSm@-`VG&U6a9u&{Hox>-#Z_0cT)!W7
zdn@p@UUQqg*{l2g&(dFI`}?erU1S!XQ{T3wX7STGH&SJ`)^D*9ua14|+Aa3c&S<uI
zzFvz;zf1JDDTW6x+!8&yqJCQ9%}w)jwJ)w)BfPK0mHU2z!6u0-R~@BxOik!$wlQK*
zt6cq{-hOL+Npv5ZtIkK&IZqkcnkUwIZb|LG9CW`#DnoRBLC*KgA16Hzx<&h*2<J(0
zGccL3=#l)~fLmAR)cD=MoDg|>o<+*mX|`9duD($7i)AvOY>Pl)f^M~@@=D$6Ic}Ug
zCpFuA5$%)N)g{pS;C0s>c4y^ekCe0(m)8h$S$QRDB<=ex8v!z7=QP`(a~J01YklI<
zT$8F_sd8(Ry5WR_SI)2ml`4dtmF;&vA9`Z8x&EhFEeTgIsaE{@DI9iwW^?<$N7fTk
z3@))=*{LST&~v8q$OVpN%a#aqSG3=}tp4Dbc<?<ot5tE2=RbY@@!@A_ojDr?;sOte
zOZ4cp9sDY7u%kBmM)H#INhZ?fS6*}Koch=MH`}H%^yZ%XCTHGWWAJ0uUby6Bwam`%
zK^Bt^o=CcIO@`TQrS0a=KhFk>WLfa-PXGEeH-Y`UsKj@7%O|?A%;zqCFZi`|e}PK#
z#H|xpSRI9Ablw<V()QF^>XTc1(BvEMIa|I<tS-MFobr~RF<bKRb#n<dCH*~rtULBv
zl*nv3?S3ZjsKup6bEa&u%9lx+Ki~HLn#Qe*jYAy!3y(&d+s)*zYKXq4Xkb3+!RP4(
zGfo|Od+Dd_k#}WX%DVR_uK6}^$;n!^RPDP*)YiT;RP}vV%yoX|iy3==?Ag1W_44yM
zt)YC`3OZart-m?zHcyYJ_+a|ayk4p(a>@Q{y!rY0KYqW?y7T(_diUq&<_2!f3Jtuj
zyW}yK#(pX3DYq^d#+KML-$-VCDIsYU=Jux0Xv&Kh8HMMwGdRv3?Y{7<rfE&KxK%=6
z#|3*6{>xw8HXo@~laP=|`0?SPglX2470KWBEj)PFSbIap)z}+W(T<Wr&0WoIi$45*
z9PvG%$@RZ9n|EQmmujbZ{yhZ~lPUlA)ch>!k+l}f%gg&yttECv?!w3Hq<+=K+op@<
zC-sXidCxv~rq|~+GcFkJ`6Ab?_3C7CsQjPl*Hjd8uZ4t2dt9$tHv2}ZOzl1s|4vJ_
z$#$1pxy2VbG&1eCP1E;G(l<H6EyWyuBicpLz=zdaTRWq9&&LzmBB|O_8Vjx79<{3b
zW07}n&&m3IMNhew`OWR(64m-3>7w)KoNC!=B~j*(51qP3nTk%X%Wkkub2`euH|}Cq
z?30;AE^i9w+c{p^s;yFzw$9_iZ=cW8Zk(S!i#w{L>u=4<#HGSK$9kpN)6>%xzkK(c
zcjNJgr`_gfbYc=S1=<csD9oN}nzT3mL8wLhr_?T|I}3k!re9wdTk-FY<^P$t4v1=p
z9k_Zm^a_{$R`!q|9d|c*+~=Pae^hMd6~2qbUAo_1RC~VPI76vL`T9v&ixb_po}bee
z-ExT9cd<ri8}E|uGp9XIvWw5k7uShsNIKfJFmiL6Q-;yPr1#-9b^9h~U){l8{+9dh
z<$~+m&pkOceZ{G>cZ-|*&vTraZQj4T<mIFd>T*lA9nDX2=Ft(Cl+=9F$u6iEQ&F*F
zgSuX3VVvm6;7@CBx7dDEXzT0l=n(jJM0M@F_3iEK&mTWlezUZvp@E@K<kX>i>n{}P
z>+3z7wN2*O-p~twJ>DJR@?V#7a@U<--TFV2jhG%E?|&Y*uSWAtr+Y|9h|#;!SAx>g
zr(NCMxvL*J-sjI^KiYPyI_vvUx55wcewANVY*3eTDOu_%>Hb!4>;9z885fn_U0CRR
zDDIQzB$Km|OGMkYZaVxRjQ7IkaCV>jf2HP~Hb1aASM_1X7yh?i9^5BvpP6s;T>bfy
z*zzqF`l`C?EZ4p(4zt!*U3-q(BVa{T_@7Wsruu97jq_ry6K`IPICFE4q;0mCSfA(r
z3u2vH6jnbCt@6uaKdPpE@A;atds9AmZ(P3HAUWi{E&t}*PmXN7tthd%#`adIzJ?5_
z?wTonk4-9S@!1!m5}}c;!ue+m({Bd-3AB28_aqNnvm#q(m#yy_akI1YdM?g8{LnDR
z;#~c?wn^6>&af^MVB?kQ+I#&Thr5wP&l(0<{+VUP500ptJ&~N|Kd&M1aC_p74}}%W
z3fveEf1hDf!?Ce(ap9|*=?^{Fnh$#HSGl+8_(?%ArYX6XIGfpdk1Pn>T=49atjyhg
zOx(}UyM6BZ*}^Qz<L0K~wazi2h0AfG=WQnCDFK;B-yibO-tsEK#qDIkVrP9GDGP>X
zb^YT{v$t=^e=MXk!&<VG>$yN*ih)GW7w<=>m#$R)@akl6j7=redZtAQS#yP1KU+I?
z<*c~5%(AH4{^6(XiKmx#GS8Krx^$ZN?h;O^eEAsx*R>ZdYPC_5QcK(Qy!ut4#-XGu
zp7Glz?D;D7=~X??6lE1J-sGF>+usLyA1sV2S)J0@q{rv9qGHL>qRgyHj=2359hd*l
zYY`VbI*m`SK>2!}!r4AIS*Zhl7JAADrg;mqXSHv-RFv7({NG7w@}U)(!HO<289&`l
zTW*Vqy5zBGzOCHT^f?xV>|UKR`SQOORIFZ?5pgK6!{@%iMs>bO-!~6`i9T3teqrTi
zfe-Obi$gwehB^J>wsnnn`E}aghRZc$i<D93q3e#^hFiUOm6MfSj%IyOb?Q`GnwvPG
z$8?ox6kqSj@-=5CrEgJEdQp2$D*N$24)I@N?t1phi_C@A%dsu2TE9Qga{G^ceD&;V
z-;OkP+7>1x=~t?FzB$^q@6bHn_J_--9y)ePMktqO&;5Efoi`U3?Pk9ddugHhMfrpz
ze;K1)H@ZW!>MhmYCQpz#F4uM-B#Y(h^4S+!ejnZv;awoKwcv<(QfQRKg!{sBi`!-f
zKFaF<))#c$ckSJ`iJ4B^T`l#UZi}CB8*_7eD+yUzq!}w+*L8U%oTPWCbE9|n^V!pq
z^v^uED|>6#T+qpxqvLyUrSikC|G1ajjJ>$=xr4|?aXz2pprG=3)5$DceNx#o$zQI5
zxmVk~*>kd{#I-3BUFXXU%O2`o$+*q;FyHw?_9>l^Lf`vM{hhXj9^M<5Pjo+Y;mPys
z)gLP@o@8n5X=#vOur}s*9{a&#JtAKFUtIda8@eDz&U;GP)+4P8c7N#mcsyS3Y{!#d
z>la6DZF8P!BeucNKlSi|OaWn8W@DvqM_OiaXT8}p>jrmiA;Z;I-<zxF|9lZ+sh$)+
z_s|Sp^9!qDnQQ8fCw|$}sga|b_i$d!j2ps`aNql6qRPhS<<+9U&i(Dk{hg*fTc9lI
zn!ug1EQa>>-4EikO_pudP&~54AEcwU!*;!bYtz~=d8Q{8MfNkqgSnP69do-ceosnQ
z!FbAndqJnlCtnKNHs8^8rmSV#wpD+-ems73uHyc|*B8!9M67BBb>gaR&PIo9=<o~^
zt@h{hJ^I9Xn#G319Rf@_5*OJoUj6TKV`A@y*T4DMLJEYEE~!HT_|btQai4yCU6IpN
z`K`ua`u+nGt(#^yUf6E&{S5oHX=*=S$Z~iG|J{4!-gm!*r(IJm%8V1u^-nc?-|_i{
z?2+>1lRpHVotbC+TeREAF8<Kei2952(d%k{p5OMa$^P1$?}u-3*WIW%DL=bzlk6Vh
zmad<=7xztKj+(mFZMWCAjQE=mUtinU#cVa<?RzWBi|sjkv!DNXd2M~1-<Gv64sh>`
z&;2-Y^_GBDk>^goxncdh)#`)ZxqY0EzlYAxf4IuuV$;N;tFMbCHqBh(#3=no=ylk-
z1Fzm57t~{^b^oxs<+13&9X0Qmm@Xg7H)=lU@m!^{sqOn^+Zo^XCmU>3*Rpczdvuq5
z@vLWtVzNIQUT#)bSRQ$a`^S<;^`+KsYj!oX`DQ<Qb}?Dw=Xahjt7pb{TwTah*VA~`
z>QQhczfAPE@}^f)x4wBfy(5Bm-Vc|_zt=y_zVhsuSj~>8(+@Q{>)*=%o^P04Vk0e^
z9j4H(slTW$rzAMj!s4dH$0R+?BW~^ouEgA#wodtd-oxA*={(xky*LEfuWg!cRF~d#
z?D6UB4GAYrBc5$&(ei1XrR=8s|FrXsA6GcIm+`bza!uQRt!@9IGl9Z_acfwMYAu?V
z@03cuxuGony6kngJ;&ArP8NvTA{k>h?`ZOJ`wcl2)iXFgK7U@~@|Shrj^E#mPN_^#
z1vQR0OtS^GsX-Y`U*(1DlUsiZPOWpPXz7yhEOx1_>13au9Jtj>(pHyAuDAZzf6n`#
ziZ?C@_q4ff$f@k-xgq`YmG!YFKk;9GV3=qXx1Z0oPtAE_t=Dpv_ASO6r`u$7hxR!A
zp3AV<^69nR9C!W;e2slAJNHULS`G*6&%TWzPUrsSF09ddAvJA-qn*3(r<{MkOL|g;
zKFw`Wsruy6%PDoTwbS;ahxNwgt@odQH!v%2UhB%U@`lHRvxh_&&&xkpdxs_Tl$c=O
z@7j59<oVAtFSFQI%fxf|{lc&Fg)ip+turYwefoI5+#HVcwMH^`?Ks;6`9GwuF8ne3
z$p4AQd5Y$9XN0a-mYWrJaOG+CfJvRUa?qkuV5xMtWC=g>?$U#;{zeh0#z%gdP7YZ7
z^8Sw3>n}~dpq$b4K$>O8lk?}^KPxO`6&K^!Uy=MEbz7xj%CD+3Z|`=<tbcGkMYY9e
zT2odz*Mo2wfxwz0j>ng&9xab@StG^%p6&7d>Vp;~`YnHW5B|ID7*TeMe{=tjgom8>
z*WW(lY}XN1up<7D*w(IFHFsasJzsUxa9L#@Pxc({#j`DvUdW&OW40_Zudb<S>PnHD
zKD_@oFP(Ow+xboP+_3ZJy5~GSSASlnE9A1zwsl=B+oPR#dN}q*$V3>hlv?#2oBiU-
z#)i80e<z+*oqtYY_U(gL&oJokYxz_t^1r-p!x>reeD3gK<~=-%Ue~rKe?4?p<N8_Q
ztDmJNof5Tu@Vq0|;^@R_?>)k*{Wo2z^;=!-bF$<5>?3(Grg{0ZoBo|%w;+Mh+U2;#
zqxTz=FRa<KT3|hU62=gq|K1kXYO_UO_(iw=KJA|T?fIb_ri<D0dDh46?fU!s`)eiE
zyt}(vZ*ERMeE06$^}HRdxs3~#Y+LwLUFt%*|9rWh-qBZjdOQv~%d6k)pPK#Qfiug>
z*jMMYRRa$OM#WURvsBsCepL)$<etg(G}c!k{N<)5uf?v5gSOR(zv{1%-7aQ-eL}3&
z!N$JW#Wy{d26e{mUUK2N*0V}qp41=T59{vf|8V@orL_W!#qtk?gzY*n^6OuZlquKa
zW4+Cri%(r&;#+2}C*Hc)+b#LeyX_j!l$_T@23GWZayffw<>Q!NCzhPMp^(|u9Be(I
zYqh!Cmba|8|GhTcw~t%CKBq{0&10#@54QL<Tw|Z7Vt0IlZid7bVd<K#2lLnMys+<c
zijUn6dDoMREz90WoSSD08l1B(f0yv~*4Bc;!k<~wk2E|BW@cu-7`^LDYIQwpt$oJh
zrW;KS_tLBSU+xv-6&5b|&3|DwkLTyKEjxWXF4&hCDdg_-U8C4;$NbMw#qp^M=OnS*
zz$sowYxiwYE&TWAr$*c!i&>`1-+!9_XuWaSX=%vh-zf*UJBz)m7GJ*Af1~mR%d02G
zkM4&4u}HA}`r+^kzPk@^6brYRpXj{6z4~I|$KW-;$~8Z6xF0D@znO97yLQjqrW=dz
zvMpSAKkMj}qut`4&(6QPD)ce8*Tx00oFc)&vE^spCuMlN|Ga&A#M)~gl5ah#_@*f}
zJ+AF=NE(Axe8c4|0jaf5j>?^#q9ybqCA()?s%%BC1bb~=UzmM$<dzG^yzTqq?^^z1
zy7bO<<LqmiTcn%I=68G*3OZOD@#2_l+&a-MO3$>TCY*d)^snk@%RcKbe}#Vkyp(R0
zbHiYtcF>i)n7$hhq8l59oFz_9xna9cwr#HI;m*ao1G`@Axw5HIeA<_TMeDO}Y+oR)
zxz#=);IpHKWwr9JDVM(H#6(>a_r4!~Y+wDZ$?g9Ioo`nxx^f|IhfS$S$kg43?|v{1
zd%v$IEcySz6?ydzLbB(|&5x!(J2SH;yrPkb)n#kr#fumBJn-7I!B6$YZ^xqzH=Hw8
z$S!&=5`E{=Zy)W%Mc<MH6Ia?4On856>czY}Do?bnI{U+YHC<OXv~k5ecF9qwtbb{+
z_=<{|8kg9!M|SaA55)CiILyt>|MuLxthHxj<-IJMKSFH0=?uZieCOrt8cfnXpKLR7
zI_uYbaowuf1tnRFkDcqBTX<@TwOMa|%Vq9giA(D>-^{x%Z@*3RPMncYv7PwAdpGw!
zI=S%u!nQuHy**ZG`U+01>~VnxO8Q*7338S0hxL6<{%+|G%Lq7fl4l*?v0W9PJbZag
zSG;m#Sr!uGJpG#A)T4I!VbYu3J-dJVcy=3Bf4U$ZVV$ph&&9>rn`QpaMw#z&w(Yt1
zj0zOqmuzM{{K0+Wl=c0uYbzyx>DILNvQIzs@oJ)p#6IC-^IYdl_SnWp#igvjbSwJ4
zvQJk${(5nSMUr@$ZamN91=D{B$#h=WZf=--RPamG20`0bQ;(c~cDh&2R?4>eTT1e`
zFFsMdH@o}#nr5!#RAEypzb<dbBe1dEt+%z|NTs;K@!k3xCmemB^ouvcdzsf-rR#q_
z8~Lrgct|~>F@1hgLf#y!^Ga<T$K70e1J-YuoYBiw_@cC_&E|*Qw)fS&(`v0%cCbC!
z%Y6HzX1(tgjj2V<f0S4Ge>W)l^FLvRvb>Ws?}hS5DIuFUj~tsjJ#cZT`jhR~uO_@(
zJFnyDKh}+zMb}x5#<|T{;FztT7`V&P{NYBaKh@?P|9uYU>Sk;<tSEHf?K6AoR%gH0
z`J1l4u=mbh>B(yx_C;*Q7P0Cr4C0?vQ-n>9DC-`Hn{l1>jkR>|y1lcM7Aot%xxuuq
z$oR_1Y~_|eY_|&D%rO+I-m~_B#MAagw#O4a{wi7Quh&kRvwCqRYxSF1FFRx7rkxOc
z+pbjKd-Ouv(N=xonstl*E_ga)OSXEK>V?h&Y8f5OTb-x5ypinC`IgjigS$g1)sd?`
z;(}b4`M-@jKIq6SE4+MA*x}GgfrrIy;xne5+gi7)E1)JL^4M=1)m4wf&%Lf^-P*Wi
zkLL^7Ws{j#i=Jtlq_^_+Z$V*E$0K_z=Py6%vOY=wR=U2_l{sy*oZFS|pT8%rC-(o}
zW}%<Ua}Ph-mfCvYimT{9$@P1j6Xq{BD4O8IRBB@Pi{;=wO>>==o)ul4E?eBVvQM|{
z_PV_K#^SZbC4$vlrF=0O%Qf#G$en+dqu1*t7yqqE(@&pc30vlAE?07=W5&AhN1(3F
zj2qsPo}$(B-|M+eHrst6FGk<u&yt)+I}~!}ZDc-ME_ZmvshzDC?zh~yY_5OLG5KA`
zp>-uX3hfR4aTjJ-DJ+*YJW%*C?Pj1w|GH{(KEJgN5iUGBYjP(9NS-<}&q5<fDIv#;
zrA?(WscqMaU4QL9ZFdpSR4RDsDq+7wp*{4}5xLyGS}&9OjMj;%*eV)0@@)9~I8s7z
z<MnGx#culVIX%T{r@qH2i&rn~o@Sh|XHC$^dmpN@v3}VSoAV(_{lV=IuiZTTfvfkB
ze_Otwih<d7=butnA7m-N<Mr3eRQ+~f;u(*)Umqfv_k2-3)c@q;c}1?6YT1MJ=RD(l
z#H;5DmTWZl+vLA9{@{^$76u#D<uVn&UD+64@b*mU4_Cp53N5w$j6P?J7Zm+nbs|yi
zQN+so3adM9TWzMDU$4el@>!Mr)>jD`PxbApdC?iGBRnEh*6j<PaDEcY^z=W1RwBzC
z_>6BvdDNeFX58!7>(%(|>E^>HJnq!&`1vzaLfY%%!T?!C7nvEar#|`E%_%jLedE!%
zDKUr3x4+x-to?z6sg6&N=Zsk#f(ugeibHf)XzQHq<(>3INp&Z*ALt&{vG<Him~geC
z;Kcw9Q_gK~E`E$@f6w~a&RN(<a!bjQzK1JMEZ*n7@_O@;1;?elue=DkD|soU$8+)X
zh2D0{PL!-nUhr(mgi}G+HcgMYW^c)=tn_V{*jnwD4p0xXxpQww3)h~_{)Y?RJFD!U
zmwoTevK5ogOSl<vcI~{OP;K@xD+bzEI(Q`R)QOy={xb7<^<rK|s+IR2@BL)bA0%Dy
zzt$rDpqbx-rKjy<Ixp#oY0TFzl=h5%t+g|7w-U=ArnO2!Y;G<IYMZ6amoAwaoT~Qi
zh-1h`@h5*7xs2IwNUT0MGveT!ju|~oc1Pq&Yn{?XFG}6t7wx#g!0^f483E3hmu%6M
z>DY03)svDks|1a_wbQ`edViZs%{M+*|7T<~>)T)uaKK<Tua8k5r%&)k^~r(PwfApp
zlxKb#uwv)>yYsKS{QWJvaf8aXukPOq<(Zz;WJlcGGwtKnd46vuvb+*ERQ||jU?f)F
zA-L5!GLw}T<UW;+;@z{CZ%e%Us<}d4w_Q^Cbi)04%U{@M>2Rg^-+vtP$isJ|JNu=1
zwPJ17@0BW(ov)YW2A<=)>9h3DjP4&7m}XA8z`|P#PjFh_t}L|p{9Y_4s+=iNkJn(~
zYSS{={zEScogb*Y)BbjQ$<!N<LkuUZR-GUzxY0e{H|Wuw{}QdU^OY04WDg2&iMl1l
z-r};d^7)&fM27k)G2MUq)G`7d?KhsAdHvOSnf=EXhMZU!q<*J&wLYjrt@dq_`=nbl
zo#SMVHf`;{I9a0G#_eFix(hr<54}(RcklEe!I|?9aESWZavl6+Jl`;LzWB*ILOd(p
zx1`>^`y=(>CyN<>++P?<^qe_(Jp1;BPXQKfy>FSdeHFaI-ZSie?%ruzp(As!ga4~h
z!M98ey?q?&qK`fP6d&SG{$6uLB*|L+?e7j(^_s+7HP<-y<h#@EwyZa~tSYX)we08)
zF}*)#n``C1teVQa^KH-n&8li&G_G_rHXpn&QDx)u4z9*i7q~3nZgR{@;wnCIK=OiW
zK?}2yVdF%tHMZ~jOU3_w?6~5VEw=60y@jq73&XcA*s)ft=S%x32PW55I|LJ!q%Tr-
zQZU@wzSwkQo!T>lX3i}^qCBdR(E%)izdercyZc+9^`py~vvzNqPr96WyHBv=_`Qo2
z|1_oi?T#)e4t4j*f852nHm1UGdu>8u$?A6<RY!Aw^lrOzRWD0-$*BZ`pxG)Xx6WA_
zy|^@#kNcV4!N=+T2I&#<GF@kz@2$<^c2BWWN;17sr_0do$!ns%((&8c*}{uGd^cC*
zZI1WbpPnLH<i0vk#bn~u=aMs<7Mbo|5EhqzCTfG+dHMUtUO3+UaAG6dzg6L07D}%R
zzJ^+Ci}~B+S#6(mVp@4b<u!h3{hy!juDx>e_k2;A3#-fcc=G3TuNUFZpToQ}XX&2*
zJ9hXUnJC7?);vLF<ML^@7T=yA`D1mdcaPLf@u#b|9N2aBbl@$wiCM3?my0(ozH-CS
z<=z}+I|E~*16#~0FKp@2%{dz>uKRfZ4tA}Jcf9r97#gX|nB4r7{NaXX#`R6Q$Er%4
zckZ&?Sa~vJheYbXbpO3Pcj}}YeW&kBIPq+IMA0i_`<|r{dBr;KrpX8YFL~O&`OBJ_
z%two6e&nls+0tdPD5)fGg#?e=t%)idzyJJc=QC@Q^t;~Zhv)78yZoM}x}oYr{ETgH
zi<SvhuRiy4;onK(dzfEdJX^GQ>h9WUFIJ`fv0Ec;u6^L)&!=C1+;2L);_5ElsQ)+F
z-ey}T6iq)DQTVH~z~@;L*PiL~lMNon=daoOpnviAra*<|nrhoFl^!fxF-P{Tw&j6?
zM#(-Gk_|RldA>eYs>%88tkxE}y<E@vbloOrz5RG#3(LQ(IMYndCCoyz7rHF}rEmYZ
z-TM9FAG5NqXWg8rE9pI1m2Ix1*0VPkEH>S$)XXe=w`JG8HD&j<9A(JMJNlqD)2iz1
zy-wli<qP~K@8i%6V9(8(BGBjg|3u1uu{1_Otv9<QTQu4C6u$D5SS7mYQS03;-zt9^
zp1LwOq-grCQ(2W$=Z4E{dQ=(gWc25aYl7SLs)!#aq@>OB-8UPRygl~i>_X@Ef~TiM
z|9w6?+uX4Dna_^hyPcO_>fN|#b@&mDEjKDmSy*LLSA_dK_iM6x?W6nX+*A?g*|P$~
zHA;l5rR-w6C&d*P{hhv)twhUiZ`{Q=mrp)ByTuRIerjD39qw`B=TW7#?~F~wuiS0C
z@qB3>--_203LhUkc=Ki?$KTqz)92?MlWv}6cI4m&p&NUXxmP_Ey<Yz8{f5fVX*QLM
zvTOI0z81T-CX!iPT>PF{z>C>V;U7M7hdwy6S>i{FM&OCKCb6e)9mN|KtP2d0(w(xz
z>Cf&9f07as6n3rVdNr@(S@_0W{jJVl=6soTwB=s<t9PzG)Ag6Nxkdc_qmsfF^hF~^
zyr{S0@$}29dc3=zXJ=(~{rvoVamB|+8Q0d#6qscrBw8KSs{ilqAAP%%TPK|8QRJ=c
zsW+2x|H^kbz^q-->q=(htfN7B6<=9RUtD=En0j+lYR27NrmI3%9}}NaGKp0-qvm6!
zMV9Dh$FGNOF1T8-XZx2cE_&B{UkX;QRM291aaw;{zh+hb;>C+yzt_4ftXsCCUi;z^
zxyqYYUEXBY+8tbxEnfA}spa27w?4fue(S@1R_t6*CvvoI-<O$u@^*8?Ym$E53~t$f
z@Sm=_fJ@56g=bjiTvt7F^EX3%nS9fqFt!y})|lS;e1p?{x&5C%e|~(QXjJ|#=AWFH
zMnFS--yVJIPDZ(!jsxdjGp>j_!Dh-8eejr*T8Cqw%<+0t*MRy7Aq^d|jtg3iwz_Xw
zAR?UAzT&QE^qY&%eOmixJi0dF$^6jsC3W9c+_+ry=q6|itH|$-QQs~5S<8=zT>TQm
zEw0xxd-m+QIa=AFjyuX;X*G33m~Y+CvU4WurkT=;Rz^%&5{FK%wYXE1*7Neyme78#
zy%x()ZCPfO_nrNUZeFw7(tocv7;p8^UViF}>H??WH%>F9!n597I<<1sjpw1UyI6X+
z^ZTs0AuJdr5&T$hTX3pZ)SYy%D2vcA*WZsmy}aF_&^l{os#y~A%O}j5^N(A03dVF#
zZRuXSqxI~2qqH*;UtU~%ygK-4#L{W=eZBwQ=FNI=#NXpG`<8+wYpasND>73%ZY|zY
zu*&D{x*JLT&pfO8kLI2HVp++;W~4diwV9C95k=j(T9<89m)%(W;_Avxjc4Sp&fey-
zI!rh4f(=u+-u&a8m(vUX{xXf(Rl{qixbe`$m-4Z`q3p41s!mVUe-UxialMniuBXf4
z*Hb}r$eFcu8&9k{AD)x)?A(gmt3;!=<}kXq^6SN0^-oSe|M1w?)jKMln(cGZYE`~$
ze}(Os?Ou<aY|?r^7gy*R^W;BSW4>^D=t-~l%Zs;2`K6rpN^!BCvBccw*I!GX`CA09
zO>5gx@>{iQ>Y47@?d6Xf*H`@gywdT`<Ar?oy1u*tdh370_VTbPKYmzVZGB9~rt!_Q
zqB*<YcNZPaDJ;4#w}(%7{cSDN36dTHi=S-h<k+jly7}Yk|3`Fvk0t!!yQ0i^SK{St
zmCn5l{^bict?k+Ow|c>xwX&bgUv;e9JNxkatHuvIdKx!gVVK`h$fvk<Le){D^lmxl
zlnh?|?yY61t~K}Ww?_VRdvSNOZCAvt1u>idNnBpVbZ>u!y3E9X3wKVjGPzfv%5jxD
zdSTD%9gl4#A%*?)yGvzsl;s{(b@2RrbEx3$qimM8wr1g-=dG4X2yWc|J4|ENlx?lD
zpZSk^=+3xt`pc8k@qAJDS63`6b;whekEwgodSQizhtUMyEe2)>-hQ80Q>J^iMXq_`
zQjbYDjL!$lAFc{Jws-aV3uOuHcj9fC-4EY2*b*)anv?uGyZl|I#+%L)#T&)T!z7eH
zFVc+^npIWWYU`GE^xj_XUnb=T-~Lwok?oKyGs~LQ|7~`X!|6?j1YgQ;6|?ZpN%-oN
z<D1W>yc*On;i_m5SiS2*MyTMlov#vJo;xcMcv?_=y`5;E$N!e283liRS+Ycpny2*Y
zCoB<~vsBe$_m|gI%@eI!_U&X_yeRg<;xtDKk=)+W+vbas>-e6_?-B3w_<upv&}mVq
z#@yMVWs)m9yq4aUcsc9H(RpEwtJ}>IeogU|Fs{-OTNBeMni9P=OVrJOMx(WSX`ZVQ
z)5E}`8m_L^)w0o#r%mj-5P9#_8dG6i?}Z%4XWrE|%>BfY#C$waa$~)ArSuMo#mn>#
zonFxM`Hf{Sm)5O4#}k$)%~`Fz<Ic`jTeqsG;=0vB5fL{JS>^{$(T?Z(dG}7h1_#C+
zJD)ngw_I(o*IV@AjxYU%X6#Q2H;H}&trz0-;7QEP<)7Z98n7*=@QM1jek;|o)A17X
zw9OM-oadh3)#K186?<WOretFOK@Zt2siz&HcWv2l++)3p-Z!3}fL&qUU%t+1=6!9`
z(7*oY(sDWb|4m6#wGMerxyK;t)Z{#2gZb+Cqpwc{?$dQEOHE!a!Q*CRu*qR*TdrZw
zDWNqpZ%ZybKmUW-hm*fGLe>Ovt=!V`Equ`-Cjqg^1=$b%A8##UVQ+slTm9nv<fkDF
zuAgskSM#`O9o$uD%;G7%S^OW<X1AWh+Lvoqgsc?my6u+WvVEP!Up*fSC;yhp<dZFq
z66TdQZ9)fsYQ14s7Jt{g)alQJiJLzfnM~wSpLoDwP3jg29=Bym-!7N-NLmU%-0Ah%
z%s~G;)85^DhxRVGB6VuffwymsKU|-{`QgWI`ENFVbXtx(J}N)+=yChRA9ugk{tUP}
zefbQlB8Fu?pN@Q3x%$EE6X!3k5SgHTa{@D)vi2mEjn99-u(8wfI<(naIb>aoB=0Vs
zBlGpN-q;nzS~$sP6y}@_i3tur+?A>waQctrGTpn*PLD4<I&y2}jzwz@9lyS{rtzis
zH<g&(PfwW7=;mQ-{wTd?M<JVG+1CsEOLOnBZF^(R7^)(_;rAWyhaFQsKD{URC;xl2
zPxL;fZuYRlxBmMcn_a;-n_2G7(KE5@4W}OCU)5M@yzHR4mDum;KF8IU_eFRe`piE6
z;2Yia{Z{?|_1A1VosbebN#$EkESK}=r$XQEe13d=5qEvL@bY-}1rGmg{_JyG%`Yh0
zv6{a&V4s`pCuP+Y!Fz?8-rqm6{a2pAI=c^!JEclnf1Ki|s}P>wazozG%&@hw@rT{U
z7r!c#)-QBFne}|>h0m8*KOa?DeK)<T{_>+eA{*!D*39`N>Tuz7vc+$$Iom7$_4hxD
zYG7+Ex;?p8bfpIu`#-hyd9lqp@w_6NS=OAo-Vi-Sf8DP(u8jw>h4N=?*Xo-5Bj@Sr
z#SKaV;c@qmzx`emvOcs|Cb5N0)ceuhwbC6IYM<ImNX|Bp)?j+G=h1|#=Vo8pI!!eu
zNUSn=&!LV!=MVQb33ORRJIKCjovm+wcx{2^45=B5zFtUN5pA%$pg>EpzPa%&+oA_A
z)=ETO73_+heWBu4>YvT&%w97mRveAy$unp8>7Li<{#7R6-o2h<m-P}p{`1}N>rv}*
z|NZfIlh04w{Nm0w(L1N7JrF-G#=R@T_-Q!zy5(kBTcxz7axGi7%&EiTLbbQJf_U}E
zLa&k%lQU<|xQMdWq`EH_{A+i)_|hI%a08^Hvs3UdXehYuPeomES(%tq{rm$598ykC
z(>?iq>8bx#zrM}v$v7T#;(bC(#Q*6#UW@iFa^-ejwbi}f^KihukKbiQ<>y{vmEPi8
zm=MMOsbH_+qTKu&{4wntOJjfhcpSVtaqcgEnHl#w_oUc;cw@ujch>6B&wqDUm}j%!
z5;tl4Khg5V23?Novh&VAUWZqF{`UK-?Y6h}oaYs5CmuiAS>KoB_?A&urnjf3MWArO
zd-lD4!otFeE;1`*7kyJ$+FD$+@Oz}%WJfL0>yKTcrWQih=xv*R%f4!D5|`aCpXqwB
zU6WM37e#_r-hA>1d6SuBpYZq2)(Y{(jSEBA{6x8TdT}qk##i4j)p+Tg+ma2Jk4i4v
z_TK6%J5Tm~`O3DuV;7|QI(F`3)J?yymXs&jb>XP~6?wx&&h<~Ewg?{1dfM>knA(;Z
zrOev=>)qZwcDE?~Hb+mk@v?e<@`VSA8sYcm>T4Wr>SFA=(bgBITq}5_j&bFU#n*MV
zH7-2?9*h^MzVhHg_BpNZGiPyU-8pKfuWPZ~Z*JGg$?Atsp7iASTRTbXTT=7<gs*?z
zez;t8<iV*0fyW#cK3iZ?bo9hW=ZV*Yc$aobBnO>Xc7$c#oV(1gm8BET_w-E=xNY|5
zeB%kzD&Ds6i=4MF7gr_bR>;1Yc~erTSKO^kqVvz)-49+qTf4%p)Y?kKu<iXp%NP6f
znb^0TKX5rayzue0+<&_Z=h&37T>fXythcVxW&MXs&)r))W?U$r3~z=fb=y|WU#TIm
z`)cPc#jN6^b^D;<Z>~E}-}e5er>7sjd)K$jcQ)5T(4yy-3#%6I;Mbp5<Uil;={(!&
zZ>83I%A~Gu2rPd$t$s_v5<8CPX<ycy@4f$T*8S?;^=#J{9L~_2aeuK(!R9K{2gmYi
zPrl!4Z_%B7p-x2n#QVR~D?dLg3||)``0YsZo`yeaW=~Wfc<{R15T1VGgvZ0lJC+=+
z^lUsdQEKZ3b-jxhf7SdKQd>Lk{f5ND7V`4)iTbH5EGz{_GPtWb7l*YJ=FhYH+0T2&
z>~?eZoji;0YCgI$GmYNmNuM))xzl00@Yj~t0oxV7zrUUT{pY>Di7}JqK9^WuJinvw
z>+Hhi_xC<HR-So8*HZixdwl%6gQoHy_@@V~n_-a1^!?dc=|q2<7r!0v3vX0ZQt>=*
zvDI_+_vTxm1yya+^1sA&^9ojH1|3^E^=|B@6wdM&7Zelqf2wHts<u5l5xhg9OH{jU
zk!yF|-C1Afb^O}twBh{^=Z7A(6L{Z7nIC(s++FbQ6zdwx8hO*(+uPS_F`b{k*I~z<
zNk`0&US8Z?`mz1pBCAgS6B`+FABk-?lV)FAd%-v7(yKjNmbq@<(lBrOlgvbanN7Do
zFa2)5c3ytep8aiZVFlV@f9%aRe14Isv8b}G`Fe0VYp>8(D<%IUu4nGo3;q^c-?lBO
z_)6i%hV!?@e>{+HeDu{yA^wW!8Rd_^#n(6OigCVjCR!p_YRci6Z$B5j{luBG_gVL`
zx6z6V`)Y3~O%yw?w|cK~W-9aMTeau1p8ICb`}MZW!#!D&$%(nu_V0shDH=A>;)kYw
zo*uB^Do0OtBwIk+ql0_fIeM=u#XmkMadjDo{QUJt3wm;=7G7JKVjv+YschlZcs}vq
zp}JEBMLPW_h1nGzU39gXKK0-pPv!*8%a0C!Zm)PN%%$93G{eME{C`Lk*JpM9mWeDH
zcS~h{g>64_^Rs#2-sdV`)=qTym<ZYv^6_@k`);S+H)ec?=IxuXpz5~b45Lb}s_iS*
za2u7oKF?bsmb3Wx%d59|o<07b7s>kQe1D>WM5M6lz7?tko4odxPL%cf*O+;ES;C}r
z{~aF=Pv8kyT<LC7QvUSuTW_-?B|`Q$H;c#Y<C|&XI{96)LFK8Ck~PsW9LWX}J?}k3
z-W1M~sMuT8`276*`t5UX?-UUKt8?*F|D;0`dDxmK{=A@}{NWw@Z};uar=LGqx`km@
z_$5w5(2BG3Dq7#RoYJ@0TFh;hfA7!TvM+HuYPzv)T9)<quQD_rOjuGrWukmx#p&<g
z`t!tV-)>Ae$|SN$w0xO*^TC8ae4d{-Pv@LrS8J7ZZB3_?X%>g#BZt~g0Y|>IyDdL_
zdF793)24xH6vrijfq@$~Z4z=iqHJR`r+m5Mve%+kFXr-H+qywu`y=P`o}b0`#u+Yr
zrlh2#<O^Po=+-CG8MCv9Q*pn4(cd?zY&N#G7k8KEi)e*-a0s$z@vra}*m(Er5#Lk7
zx7Ag)I$x3Nc*~?}WHjmg`J~;m7M69~irM)0?nT6gicc{)^=;i^x=#CQeqPv9S*)m1
z`RCgVTejwdptb65zuG&Y>>eK;;c6a;_)G~kP{S0Y#>mj;jiCfsJSAyU&yB^KTaV0H
zD#>oWzGBJIotIx#ZN610sj0sDsbpDPVZw9K_9^p>gS%~CsVU_x4*u{`%-*Nx?12Lf
z_v^%#pYL^A{_nqz-+k%1lm2ZksLlVfC&@nf7t^w%pO;2Q*~C}XUw-w|Xp;Y*-_yg)
zCOixNHSdp(-~8yPy|XjF)*abd^)qsg-S#zM$Ch5LUG_fD>%^71Z{ObDZtoV?|1|&o
zot@0->FE}hmLGp735tju`M-7h_UHe*SikOc`5XQ8%*<d8LH1YQU!0z<e`2onb^#^1
zd-v}BG489DJgT6h)ARlNlNT>ES~{4&DvHU-%+a!YK8gA3;uo)9bBl|ME4tXsv#D%q
zX6HY2?OGVe&)Q90^Y?DezW(UqV)sAKUteFp*khv7hK(B^em{EX{{8vi52|g;KX&0l
zz={y9l=JgqIRx3|<>jB8n8<82(}zQ_{rr6U&y`U*^XG5rS$yc$IlZsb_<XoBLyy(|
z`qH^SY~x?9OW!MAU0JyzczK_|BpaixHx{=V)ZWxAes;!jYu43(ty!UU@j7O?w~qXO
zdvCAx|8O0>_<d)%?|M#F<5Ya)5Z_Yy`B~z}M@K>FFUKb1g2F$`?#wrRGL}u-^Y16!
z*pLX4P~DwzZ<clWIsqlVD?9q+Y^6?5(|ydlXGV{tF<bKSzNf6UUMIDZ^v}ICPd(Ja
z`Q!Ea{Q(Oc80+G7R@iEUt&xy2&(mq?U|##?a@X?%jm)hAg%U<79P|B;iYW#!^Ktz9
z>#M8&<7?~V&s!J0yR~(-fD)g$Ud(~5+1G#6=&D`$cQIQxF6PeG71Q<O`xd!&gPR*3
zMhlblwGC>2mApGORr}DqiV5P4_m8y2Y41(jsF>8Rd@S^au(;B<9W!P~B>Kzn$yyyb
zJKsM3hH$^Qeq6zk7aY}(1Z8E<etmm8{D!bNKR^Gu<Hy}^cuO)eGRg=#9g4el;PU0k
z)qj6&-JmYFIsN>zJ~>;hH=W1-{r$aDR6C5L`jKJ60fuw;?}JQS8N9sc`uceBZ%2~P
z&N7u*S;1BPsPN+>*Suprl85G1^hg*sRsZ_3a)Y{Dx0vpu)3fiZp7yz*aDCPzyZ84S
z^`0tyE7F^?W20q~^YOfnyQ#hluX~x_I;){pa&yj>2rHen^Ym?(H#a-anmhaB?+d@D
zi<w=xbt~$No<7&!Yg=~2W&J;r_jMU)6V21vH)4-Z*|Mo|3wQXNrI$1`_g>Rc{+2O4
zFQ&Y0#+JOhvtYrqFgf%{URZx~S!CzmPnSOm+g5!M_;#dO%BpH_lJj-Rxi*zWvqaLq
zR9#+Va9U@{)xV2hf4sIT)cb}ozg0_npQ708PGR*=qDmVVev5l^N^fcI?QI!1H!a<u
zE|(d4?4s#1ZZRE=H=XQfPitN@h;)0ibLY;brw+V(;-t>qVVS7FSGD%btfOsR4O>=x
z4R}$(w(-1gw9(~9KQGPNa)bNU@rhyQr~By%R2%+1<MQxOYvo2gvoC)ayzjhmp({Pg
zM`h7__o$Gz6?>PjU6C|7ELA2q@$`KA{UEEq)_i_)a`K{+ZZoTzK!wtuo;5~}paMxF
za#<>DqmA~Y#OQBV6!i`A?+N{AJ2i267(dUe0OpU@6;~FnH>kg-RKqp#@K(2So|hrQ
zY<A@jEz8&zZMHmY;rC3+V!`HicCFo~3bG!@yxA?!!o9mm!YEDP)2!w8x;1r&{}<RT
zWBF&kqE%p#@}HB2J+Wm1F+GY|yfZt#z1#WW-5ocdh(fMymTv{GztAbx=$*K@>fp@~
zaiM>2SdOjV+dFZyy0X93E5%^8y@wY4{QOW>v$1gAD+%iz+HW5J-}k~lVrPNeyq`x8
zEp!p?d2yRbEb+a;#bOIP&*FnIQsqadWn4?=keViPN1<ThjK`Lo>vC-_E}Zlu)@Hxb
zx389eHosQ>H}4AfN9i}A7Y|0*m#VCDpW!Sh*m_N__~JgNGMPvdk?8ksO1rntEKqq6
zwUF0l_titq&fSLT-<5CNo@7xh{zck~<>=f?(dHQ%*L)*+udk~Ou>b%4u+Ac;`3YAi
z`TmfQVv4-CY=+$r|06bc+9wv59kyAnysu0qRl8-PFq`uBKVoj*;u|E|-%OZTwWj*?
zzaOjP1RpMVf09SHdgJ`O#8-c|c60?TzA^vs$MVIKI_@8odtJ<ZS!|7~N^kz#M!Q~b
z<wqwyEBvClS0<m!KR)Y;<Nu4!fjZGVW$R`%o_?>C_%=#Xxvi{u@5BP1U5?$hpN~Ci
zE)MQ_7ZS^H`Qy)5Wj*orqCw2cTjWf6d$}SX-kY~`#@6?SMJfNU?VYKcU)m#ePwrY%
z=ZAfpct7{EC%syeC~%!Q@zIf*J*|@5;fgT_5AG_F?s<1rWZK7=?<<?;e@=by+<-Nn
zjZZCAVNYJ-l^r)bHg?4yOLd=~=p3NAzJPy`eZrp|t}9Fnv|fpe?7wYZShJzz5Z@Ge
z8;Pm1`)`^Qcm;hsd*oGj-HBy<O~H>7XWZB-wddTr!#_gP6Q@6pmQ0_rm*<$@8`j|U
zmp{mC6g-jXp3`dhszk2o+SJ(A#h3V}U(-A0eLU;M?LBh@7CB1`_tee~fB4DRzC~hZ
z!m}TWCzQV){qgYdL-o_Fn=4Xdy7wsu?BAg{t^doBw;sX~lfGZu7Lx4qZ}&%YYtN%`
z$CR6*pI&Txz5fZ1__P0A(iiq=Zh!K|TCq>)<XX9V(_U|XVIpt8!8thZ=+^UdejQC*
zm(_af4(oaYJsq9A?gt`Sy5CFgo2)w;FTA7QQSr{bm3w#e1)CLSDQ^AZbmaHq7)S4d
zceU5K6s<xQ_U}BHJFDole(i&OHb16k-&$o{Za?GkyLGb1LbIP9{8_vAnt`5;(k$ia
z+5!i9SH3-RaHZsTtJung0Y$6ZwmtawCFXo<Yt1vYuQ?}p<HheUZJ2c1ey#QO)JuGN
zIwxk&zOvZT{ON<@BFpj}RZs8k+}pqZNcFylb7FqJ^}H8*yFVn)XUEOsN6Q^2YDlSm
zfA>mmU0r7Qxve?&?=}m_9A9eMyrXMtb+P}SLpxr-ZYx$@Rrctf%gUWQV^<a1K9}n#
z-<uedVp2OJ@Xn-vZ+9B*e*gJ?_>p4;tMd8nVg+7*pE28Rg<g7N&7EuEDu<6bOMmW@
zzP{Uf`|CuOo1Y)EnXEbexA>j$_jfOJ))oETzoY!)I&&SHuJf1k`OiF>^>xnC*30i#
zKZ)syIlBC-vC*E_qD$?~=RWz}xm&I%QT|=Q+^DS&%4|6VlsHf6-}zr<_WaoU9sZBr
z7tW2|{@`D&^ikG%@ux!9+?!P`BlZ8EYmrv(wB0*uIKDrhpc>=g!LYp~!#eN4CSj+f
zm+j}xuNPcndl2>aeRa5A;JxQN^K}0|;j{Vr+-_dv;lCFX8J<fYF8uG8b>8$(^|$TW
zs?ilGJj(_59oM{9G?zQNNbSko-*)WFOa<>uIaj*Fj=QfoG5%h`-&<Forpb2YZ&unN
zDwn&H(ffR1Vx9g^qk^-(^?qM-?BkEce(C#O^V3N0UDwt-8#T{%@|HX*v*8gsbcs1i
z@7H19yo%>qb2z<<k2CM9H+PoHf1WjU<+0rQ2d69V-#Z$rAKiKTk3rAw&50J_f6ph*
zssHob`;<l1*79q8kN$m$I2x$EAn?@A2-ja)7q4z?ymPSB*)n`3=lAbj#ZDPAUU}F5
zvlS#?yZhk#w!T+KN@s0o@8;Zh_^ST%b8oAK1m6F=WYib4@q6St-^uIlYz_Ftx^`A~
z=ih&FX=n28OgL`wKdAAU@9Tr7HY!9-JJG29T<>wVaOw-;IrW0wX}+&tKk~ME_-g0u
z4ioeCty^u2tRg?YGb)*_+QTDiQT$KsQ+O_KxV5xNW|(}Ux&8y+s;tjXls4pkO`NfN
zs`Ep6wJKH{tLE#snlfUQ`8Q4f$2>LVpvB)K@@+Ra9XxlB(Q;qhYSB%RvknHV5U}}G
zuAO&u$09GyY>lJySIps%QCjqLL)jT#?b&k*wwb&8luQwD52!n`vU=Z&+dEj-yeWEo
zKFjsvgFBWj($a^uX4@87r1pQW*?cf!+3MRGwd)d}ZuHj(-lpQS^yL~y>rcwx=I&|o
zD*f;B^U<~+9}A~sS#r7at#|w=6Sm^cPIIo+_aD_Q5K4O%w&DCd<$GVF4jwuqF~R+S
zzLkvO`*(@g*WIm<)@wC+cW^nk$&TW80)NhEEpooh74UBYqqBV6G3%|SI*0Nn-LGej
zeYVE2-)oz~Q<KVP-wL|Q_lDg(^V8<-*O$g7w*+KvZ{=2(uW4FYc*{pckh%4H=$%j7
z9bUUFO_;je=HH3jmd(@OacwO8I4$Gu4xUbZ??=6b-#!(u(Aj+O*t9$LuYY_$&lJ?G
zFlWy%8PQk&IoYMzw`2uyzSo;~P+W0uN#h~*Z1Xs$c|oZYPk;IydGvk$9H$MwswR5R
zIIdTn4bb?cd+wLZ;Uky2ZXEdWt>K0PcW~mLNn+2<@(;3qR$38ug2n3l@0YBihmuWC
zynDj6`pwTyUUMfOpB@2sh13T}uW#X5!@OFiwIuby&*%=L?G0D`Pg~p-b+@zaI&1z!
zBYK|#&!y1i^JK*RWgFGPbGKv$$#DJr?tj?E-!{j(RA#Q1wc_^b>OU{j8g}RJYcSsS
z;Izf@ALpk}Dg2VP_s@QZ#UGB_CGqR+<7n!f_+zq%kn)5nx0lb8TI{`in!(?~jZ;sA
z@AzfJQ#nWE$iKHuv6m-CSZz||QF>~yd6RPL9OpgHy-!;(vsC_8aML>8J$d(r*GG5{
zJoz2h-J|)9sab$Ict+~ww^lbI6?Al1HtveuRmZ((Xa2{Vtra`3@pPU4ZkXG_Zevq&
zd&A6Z0Rb^yR}psO>bd$F!Q9*uMTQ@^pOs%`{r+9=i1OqpiOXBft{C3meW&9Sck8i3
zT!prJeB0bU{1xI_InnT5oOO@mp{<wR)=T?+a`Syy%&6U0b8N#$<q5&7RMPZq6I=9Z
ze>;^{YudDZId)P({7a5(e&>u23N9KwiFu2)&%Dji6%-cj^I$c6^zi)0^D7R<ufLvr
z$j0X5ayMPJ>}f(9uhfamnp(iHlJnzzU-Jmj11ny78?2pdeMReQ{k-<6&UqFQFOJ+=
z$a?wXt$kXro*A`<2z44qKd;{%x9RPkSH4?96#mqBJUpN&Ao`W{wb+>>Z~Y(b*7T5Y
z4ta0Gc=|a{^WvQ>URS?|%RKrlSN>k`;HN9yf9mqr#BGz(cj8IRPi4CQ`}w}z_dK=v
z9377=KEK>SLL;Q3uj|m+z1|xiZpoXu;Y`OQ3H8>Asy;3A*1ai9JMyOWMH$B_eUp2S
zviB_BD`_}e@q)w*#V1cgd%DX1AJe(lyyAk!kyA?z#DC@Hb~prRD+|u)+jQn-DYro2
z3S~A^JyzE@-|ck{>C3R0g*i2*aYTDN*L>=4o7u_uZvMS*v2~GKzFXCYJeX{IqwYS(
zWB2cEtx@yN<t)%;<9X5Z{I~jnWQS@S)0I7byk4AzEc<v&ey`(Ma{BN|(<ME>OXP#u
z>v!LKXdL!1S;f-hb${#W?~nTb2?t!gD#BG-wJRyu<lS$3omm%U!;VF*xN@I6Q2F$m
zg0c%gSO2X^)C}8i;<j2#&%ik3@ztw`C1l?JJa?yrPbQE#PTo0TLC~kw|K{BN#Q!a(
z_ISPh-U*A7+}FfduuqL$EAZR7@(Am%hd&SR-cj+B@Bi=q{P^a>+wBj}*fV{WK-4kb
zpH+M1g#RC$?ZFp+qFiKQ)}qu!59;4*Jkzo7$WXNPIwn%h#<pwad8fJu7I&Mj$Lk+!
zcyoNVl&`jdN!;qNLpSy@?BbK_oTyxSyJOzk&P0W;8nfQ-f2RMdaoNh--r0xZ<{h{r
zyZ++S_hB2Zx=rd?*y8p1t?SeauT|?G*V)zEpZKcn$yTHn$0~Pd>!r2j-C7e){oPP-
ztH{Fqb)(hKr8U}8xsgAserEPsaafzZYfAoFCt;aolNHUHe0p8-k5`7>G15DqtiSO5
z^mBGy%R`q$bAR*vuG*{2UeY{Uw*B_(=MR!XI7_mh_TAXPp&{y(ap^2;y>gdG5@-01
ztrq*Y$h*y*oOJO}<_6^`b0<aTpTFMji`BpRPh)O#NUL|!-I?AIHhBtF-{qLfZ4RBf
zJH4gklHjWhJN@I;v6Y9M4<$}MEz8XQMQwjQ%Pgxs$7eNf7vM~`5Yy>y{J3s={q3kF
zRS6w=o68=Z=xf~*zdca*&W7Z#ZZ!h;MHgBGNPGORt9@B&rpM<Qv!~%4o0o^HQ)iCe
z(TnLvw*NL?l3c6QW%9tcYl58nK81+^)~j#(XWPZ!?+O)v^5X7d#gvVSOExWQvHHjD
zvwr%YXZhQm)0H!r0~x<p#jl^5H}}=_CbKuDY5()hwaVW2UHX>w>7J%%tFmk;!{XWv
znU^`IWE*oSANP0sIAi&Z!XLk`zkYn$;@9`rpOt>A_^b{*Xi?2rBK_%YRr~iWW_4rM
zKHWKvTAg1n?wcsBba-*a{@hy?+YMp`WDnb4Z}~L${M674(?t2Ia}iCq{M1|?ocbSp
z>}yU~qfKpa#Tv_=zuD;@z9l$p&577uCEau>Qg;3#g{i;g*N02WvaUVDDBBsfaDROg
zxA>bIyZGY*+YGjrxz7HP8uMSTz;N<{h|?P_s$Vj&O?YhUR(j;Ma(3aPtJl>w@MwLL
zkxA&&n3Pz$dp`4_gyiJ!xlL_*mCvZE*oAEOe!SLmPwT{4A%Z#+j_Zo=Z?M__bVK`<
z3zLpWD;POk50#LW;}c!UXuWju#a;i_&sPdrdgx!}yofFDx#q=KcDxn8&$ZFzzQs*v
zAwj0t*y+vj1v*8S9aqkgQoH%)fmr$4l+%gstC|$$Kk8Ws#XY~C{Nu{hil4tYujN~H
zZ1@s%k-NH)+uv@n)8u1M%%8hHzvWu+{Z?fQ=fw@@{IcqcTG(IC`n8{>?a-M^Y+-3q
z8N6pEYRB)(KY#tC;4&lLxIMM(zCWaWWG#7?%kMwDF*m#5x_a!_SoJ<LHumRb$9H%i
zyRo&JJ4^IJ<(lgmya|tI{J#Bl(%EB&I93_R@2PtJd27Lfe^;-3+}(J|@@DZ<waTj>
zUt8xUXS3>=iEUxZ@tIfp$7b&3gIyBeCH7Q*<xzBM?mu#c$!$r|av$|1)vbnQMGYI3
zcrH3!y=$%@baQik^v+`%?7jT%cV4hdz4v&ttaG7Mkg@iY(|_OovrOII*tk-6jm{Mg
z{tKdfj*5u}Cg<4NON<;JKVJR3BhWqZ?32VBCEpa^$=q*J{=UD|DB3#GSyo2rNx3M~
z;n0G!nVv`b*~HBHK<V}7+Ovw^Ydie|wQTO#@+bel*%*F4FX`_&ZV&xZ=69D%V?Ks0
z%$w|W;%SV?+f&w$9!))cf7dKonZ$3&k{RBoEsBo#pR!Q)G>NPE!LszdZqG-FZt3;+
z63-tit@ydt(BkgrUoUD(<`xO;O@Djv#IjwbnWiplXGPsqtl#r|_Th7rTv{HVJuTiL
za%AqpovJ)jHwL5&R41h5^Dm#XbE0oScV<#9vv6OShsV)~w7xq(Kh;(5^Shat<56;`
zefbXw4G9P5<hn^oYyLzpoM(7+Ua6*uZgQ`!b@}1fPkm)7<hp+KzH-v-KQg^RAY-l9
zg3QS1H+Q#o_uv0-(sCrcxiUnhiP?U#&jVKd^*hc=D;`lWQ@j7aAX8gz-|vptYX3t!
z{epKao!k?+W2d^G?Cs{ApZ_^t-=#WneNA%7+E@m|hX*-$dYhbI9@EJE#W$PJ?!fEf
z-38Y#i28b2If%-&>F>K&@%3xe$!C8h4Zls@@a=%+n!o9MYW(j!j6&nSytpWJ?WL-D
zgt#lOxwp*iUCn=<ncpaQ#OM{il3zQNXI~9xQ&&uUw-jqZ(SNmyz4bk@;rA9~U3S~h
zGgaB-iSfOCb)Vl>ofLE7`5%9I`@;v{rq0-(Aay79ZQyq2{2kBz>XUa_Y-O4lXy`P3
zl9-|+V@FTmqhq%oN^H6)J^5H~<K|=HadveRgq@f5@wT5ozWsjed-eYcC!FIFKb<&e
zQSsWAv%0OF(QQTScBc7Rznr>foX|MYs;6qXav>{=`-Jc7IlH{>C4Jwy{K<FwBQuY0
zToJln=1k~9760E4Qun<6`sr7T$4(jcaKB?up1S|o;C(%Qk;B%g6O%pfzL0#nuF<M8
z^v15&Hhbje96PCRWU?}xu`A=#Irdi0k6uFc(~itP=xOh4vM!pXZHbcfgZJIn<saX-
zmv1>9wJ`NB*N)N><$E<X&9cYy7p6Q;6R3Z9cz*EG<2rNxluJK5^Pm0f>F2H+t>#|X
zGe>#l1$HG1C9$8YP1}o~@aF9O#Kr&p%>nk~Mi~#1xGG&V{?ynV+a0D~QU9rZNkQ=&
zyE2i}&(1Wbe?L}Gq}w@f?(3T87Zr6UK3Uh*waxIx=D9ZZ>)CG<U1h)OQ8(?#)WU13
z7k7y0GJl_7^sa3k&!5FyXO!yWj<p_}k^E#+^Nr1Qf?__>y-G_qU04;JFCth!xADkB
zlMc0S4w@#GZj+7lG;G)o@^4>!_Co54o9SXvV$UA<uIuc}T=LDRVM^ip$F}kNdL|!F
z`fTHW=4MGJ|L&sm(o3_iyM8NKQ8C3ZutV&aM%L7eHImCuM)L8VihT59+2cR&|9?MH
zE3zs`eBHDn7S<mVjowwymKPCh4o^2v`fy|CpMRgbuOED>*`MXQ|7?cY947(0bcGa+
z$Zab3V(&E?Uzb~0GF$LP;Bp2f`+LXMP4*Ai6QemrJ3dOh{;QzZUrV05*-x6omNv-?
z^83r#9eEpVUiew<ZeHW*K%UU7tIe@TV&B*laek5sHMqA}S?ALA3cq{aJGHE2j#+ju
zC|dcaqVTJM-u}P^IVXb(^i$d&SC>8db~&I#&Q^44(M%`R{sX_azyJ8)VC|hp>!;>?
zk5f)x$yKmvic?Yo2lHAX!K~nrm4U2bFI|62%vhLo_0*4wN@KtH+K!CtyJo!nsJ`Uj
z`3-L$m_E^tlv=74=5XV0vqjZIxuUD@Iu&)j4hO7te6U=+;@=O=cQv*9%mq{Du`m5(
zIjKeUiJX_9pitMJr>hnlto*s$+~U)w_JdNQTGJFvze~)yv77(mvU34HY+ZLOls$Cs
z?vbOXuNS<2=)NO#Mbn#G=PSNF5|z8N`}5bT`9F^=N_spkBjN<p@9l4nY`xtdu<vt5
z$*MW8cdy%9!f5#J;lhn4qSrBfij;o*cW<!8PXm^xr*|xlTDoV)j&k91vHQAfeAyS3
zudTUo#O)#T$;<t6Hb15<&$nxi?cDWabE@r+xLXdNj>x(^Ti0t?8+}NpuD;&pMMC+j
zGS#(V%$|m9%L??Lw#`1i?ZKzF+gDsqXNsDBvh%$E`NtQ&`fJ4RV!7ijejrz<{^d96
zD?h7kqQuVgO%3Yve}Dhs$G<<mzh|`nxH@X?FM}TiT)+MAHdLORCUJE!W6!0?wuNQ}
zW=bq(KTj{NNld?Ex0AiU>1@C*7s)B-R1dz(W&e0VT*9Kzi0h`u!amM}ueZPd@Zg{A
z!>Ig6=Yr#ROkICucahNoZTl5Tg4&zix2}46srN>+j`Yd@M+@KINQ>F?ljB(G?c|{K
zRvo`8xOe;6I-e|34V;&guXl86<Kd6tTlZX8G3CdbuYCUdwIAnAHd?3AWf6V(Uu_Y;
zDhGGB<3}yi2U(NPWjW8`TKF(aq-=dd%(Eby-9;ScdzThGvwK{)!0^oC`wuTIJ-wsw
zv!2hVa2G*$<~_AP+w>nln)m)}b^e6iLCRZxE>@Z+8{Zoo{_fxg7ww9&wak%LBGnro
zE;KkD&6DaWDf;@q$nF1o9Z&5jTH$l*$p&`z4eyVrx;$Cc+F2`oIApa`!+GzZW41rn
z^>lAL(f(}ht%G)7w6@9a>Nu`AO~U3DbKVoVV+X@7Bp66U@@)eR*`M%AIg=Ly8oM`;
z;BlLjfH)rO@Db>#S#D}=*ry-Oq^B<opTf9)W7birnlP!CSz>d9)`jj`kiYp-O-+@9
z<OhMz&vM(>qzIen2{c>B1(jspXZTap`s#ed<|N}oyqldL{}p;B8lCL$`jkg{T&2Xx
zmb1rFJ6w;nTSx3m<5yBKy7yIZ`Nc&ci|@S%IPF{RV5RWqZt9uHN)f%Qw-z-`6^}de
z#Ob-()Rq&|XKa5KFERV3;+fZ?G1A|T#FuuzdL$vqc5Tz~3)+VB<&uy8>(;opLiW~H
z<>=F07N*G-&tz-$WF~%dso&FdSN;7Wm#s=1JIh(5zt6vFX*%t9;>{O|7UCJrYG1Pz
z`yXkV{jL6ads8kCTk}Wmrg`y4-vxgUT)Xxh+qRq;^3v{n2bSHgJ0zIt|KM`6MZrtu
zJExx>o^8B)!{;Ztu`VyHeWaguPG_sUxS%dKqHbT`+9y#GlKg7lBz_$|AW-I48Mv<~
zbBdntwyxZZulcp_RD9sr-k*1T$3bSpk~>B}R*UY~lF3!YE7kOl+3n$_=v_IJh06Qa
zI^Ab<He3>K?h{kX<S2M?$G&>OUpz{Q_2q}w$X*u|D&Xf%U)NwBtEu))aoV}qzS;ir
zNmpMa{;0lS@n-k){uAZTA6(pS-uC4`xAFG)!{yvdB|RR#n8bhdv(=$HH$=k9ZYG{_
zO}^dZS@G}==j>(Qoi8^14BW9nI!7nMTcG)%hn0}C<fh$E+>aVrNk?ovcmK!cCbsZ*
z_6MK7)ix};pitp=zlS5#gilYZv(C9~!SfH96@Ofh>QAmH`(5)z)`rEos`SX5yW0ia
z#E;!K5dPcFcW{B++>L*Zc(d%Y@BaCDTjRQU%RcOHIm&JR@LlukAL%~?zQ|cgKDT!{
z^#7gQm$z5to2$Mb_>_FU#NN*#DWN5%l6yf$p7o4bGY;OevtID+_@b4;0?{{xU%PE_
zf7q0#5u>25<NMQ&-;J%g)3&W{qJ+chY05vmRg{!ZihYrAe}80A)zw86_1^{bDxV*@
z@i6wo(+f;z>}1+Fi=QR?2v_UO+9<MKe*S?ctm+ri9_gH!|Bh4K*?!NC4Z^|K@3_6s
z+-z9i#h#ON|KZ`~<vR*zN;s~15K_0J@~PRMKk<pT4_0Sfs^^e;#(QAJ!r}@0|Eips
z|B!Qky?El)pZ&Y;A6I5ve)UDvn-n#J?vKZM80(XsF;}0FzbCcqkD*J|Dx(WgyLi}?
zYZDR}dX2;y1+And-qdnFkCRyJCn|o&a=W~~X{te0g7%$QYe8xG+mGr$KVKZ*DRE}b
zUdjBtHwVt>`WqG;lQ}crg5zeA-GhVsPj7s%LEi1`yl%_I)eMd2KVJMTx-P!@#QL|Z
z`+gm$|Ms=A<E^^gg6As~HBu|24<E~QjO~}4Vf|A7PL#25^?a7sb@HxCjbV$Q<t{jK
zLS)kdcZsW8Rm)sMkF0rTx^LZ{#X;QNXN`<xeBKy-=~{S3qUitg2%}P+V|}W(TYjGS
z`MiQ>RWO$fPvFKp<tH1qAA1^{zF<S~k<Z2IAL8<u_FG#Q7@px2l~uX1F+<YtF0Vs(
zo^9aXGR+;Unl~n%w3<^V)!Vms*P<9dNgiLHL=Rn|l?!Lho;^`&qZsR{P=~2WmI)u8
zi0J*6KBV)>&@bk*o7tYD`<TUBT`%uH9<uCMZ}9JrH&=3Xx!pUuDtLXX1ZZuEosqI~
z%ig{1Hy@Xn6&(8FyTYb`&uZ!!er99u5Jj^K_pULdpNnlib5P9OZ;r!;M$MHs@(w32
zUZlZUzb1AY=koZ~7ni!ThpY{g;$zg`Saa1c=1)rBy}MC|&(2c*8e$wb#gnHuF)`0;
z^@cx_GDPRT6{z|uA$KH-QGWfyH;+ALxZFMVZZUtU{Rj3lJc|o{-QWA5YvTQ{k1Wb;
zI7E^pBqi0pNmRKmo^trgN|j@0qT5nWpV*egt@d@zIsdu<;jN<EOIErqZVVG`_MdO}
zFnI%O+xZ!-%ckBj%>3?Vax%NGUH$q3=imP-^oozqdi*-@?m-6g?`Peo$NfLN*+W@k
zVhc}Z-n2`m^($v8%b$#o;t$mhNr`X1zz|>a>0iU4++)et8h*uRul^W#L}S8ouV|e)
z7M!QmOb`AlbT0hZoHsEG6nuJGtxVfmwGw{?&E<{RS*C1rYl^}*cSbAQpmgS|7bbA6
zauZ~X&tkq>X_$E}<x27TCfD|`!*{*9S6inosQtc@<J4t=-F-Taf{P{QMA}N-J-+6+
zdavdFciM9;(o`m2I>#k<*g|?mh_Lhurv>-be^k^ut*zT^urF5fuA{v||HTC<kN?du
zPc(Y=MZZ(hx$U9n3W1X+HW+L?enERqSnrL9pZ?JoR|rfw{nEjDLD1H&6M0$vdCY7{
z4&Rq;FrDV~_P5Y+KO3jZb<Bo^=R6|X_Z_;c&0p|l6TcO|OvnGTQe5v2%kJSfciiz_
zx`wBt_54%s9e*Dhs|fKG6~(DqZmhidYQ>wB#-^`T2?{^sEZvn0Ce8P>by#`r(2+@3
z8aORqRVAcJNB2k>aM^M3xdnaOWgyY>WZ~5n0^V=$)cf#FjOVfxIpW87GhlC!W<>O^
zMe-X1|3-(qn$1)^bl>LC#q9VCy)9?|-FH}FfA9F-)#Zh6W(w`~xY2a-uHcUkT7Ra7
z{rL1xvL-pCqUf299IHU-vCN9w-nuz`r%VH`9b<WF{YBkugFRQ2=fS^6=3Sh>B0zZd
z%(Ij3>t9QiVw=u+?83rgL8mDzeU|%3N(zKk8Gh-yaz@OxORVXpf6dez&-FTNEYJQt
zKh>(w)p+^x7dPt#etnf_GG5=Dkde}Mft~$A_5lSRxg9J|fBPJhKf3loajNkyex*d^
z?TgPfY+Mn$i>s=%^!Trn&W8Vc_)kq+%TS$d{X~BPdr;8Yskg$9w<z{*Ot0bRQMx~S
z<3F8{8si7%DniWnE<~o3yB@T$+}Cya+2Uu5`aTw~xltzQ#clkosP$li3b*iU8I33l
z`;`AHKT0X3-*YP1W~?-y_rj9<CQ~NLJMt$juKFg`e*53X2{R)e+`U=)!u1eauXRV-
z;$@2$b+gLJNA>J8$$4kG<+Dt4R;u&@@5OUwyftKzmeUN_7~*;3mc=36{l@Pj59|ua
z?s*j@!~N^KlGz6SX|g*Ge{VR_e#@aNcio>8?{kjVv-Mmke<t(fZ;4cN-#yh?S9&_z
zc(^`qKJF2IV)5by3m?DpS;=@s(EG58QN)be*__hCqO5Bd3hF$PUEa~#cI1eR8)t}}
zWvI>~QK=b`5jE)>obvQtn;n-M=D+8=Qnd9?KI<F-X~DK)?q3PJ!YyO&nEZOZgxBp@
z%g>w1OTt&=HlGnmJ9dB7G^^@#pEt30d?NTR244JA`0QifWOsMxtUSJz8~!Uxx$-21
z%IN5nOnqZ<?~k=qt~hJb?SrWrdC6)mb^aw48fAUC?Y7hEAAXsm=cJ*$_<)O*a%^H!
z-p9EY7SEWp;fGVd6KizMLU%(m--s81Dn|^W{wRFWNVD`_?6fb(qVR*xio?_A3x0hm
z=T|Mg&~IuGr&JKAFwnfR?WlN_$lSf%??1UP6$^>QzX<dZ608z&PTu^V!?tT}wCI!*
zD-SI^Y+h>TR`2xS^XDC+sr^;&SX%|$+?uw&F_h@hVb8vqY#<TId2Q2i(3&^4=82t&
zL^Vd0Pb*IJNJuzvM!xyr2`LXIX6BnYF>K8fmv(e^K1_ckC1qrOlZQ?DvvOx|Zz{;d
z6ip{*=fu1`KIO&lYfX(Lc-+!JfovcV*|%VU!oBlypcQt?+6UOy8i3rj_VK1Fz2<`_
zv<x<q=rYhk7zvbBdM|IEpBL5`94+?X$YO>R{TS)y|9On3D?WvYe&q9BeztA;F`12N
zdJ?u-9G{{+TO-(-5B{)hY;4>!-*#7*Th+tUZ~xBN^^<GKvTrXe%XqwQ*XEyQdM9&W
zitqHFKjf0#7WeGsiRqCy)0^AB{GV2Y=(=vfz0n7nbh!>C7}P1mZhvEY!%}$lx|J96
z3+g58?s)M$R8?#fYTlas`(eC%`WM+7{5$Ps58a=4T2S){C|KMSUp=<$nY)?WbQiD7
zaV0OGITpf>MT(OI-j+5VdGAsxbbsXvuE}cW+@?fzGk<n_xFDR5NAiyN#p_`S$NF|3
zGMC_Cdo2Aj;!W$L3ol=5e0Db%ITy|`cUIWJ$&cFw6^<~qWmpv0eOoiXX;EIQVO;{h
zMqJ!6_EzXY=;_b-6;JFFvkK8^I5pS$@Vm36bH4M5CwcxkS}&Lp&MfO$v-DhS!vA+_
zdaP}Szk3U8+PzcRe_xWu<m+tnYwbDjCm2Zd<S)6O7xUDbC(~Zwr+dz^3t4>~dp8Q6
zO}~3!(cbKUH}<yrfe|0di|3f+v@)+|JFH+Om6(|5G>0!ZIC#a?tQ8?ziYlcOJyib0
z*WUG;_HX^d=Ls*>ecb%-U%E8ueU&forD*eaA0_J(7w-}L=J%c<V~@ciU;8H#`^4s5
zE&lj%dD^!Fw`Tmh@qNEv!!>E;|8KaLZ`^$$w2F1!XY)fRRmJbs1ty<ZQXinZ-cU(N
zNkH;vt$q8<nUW%0tR_;u0+V)Kc<z5OTrT0II-j?Fp;6T@H8r&jTetqLn)hT<-O+iE
zblC(qh94;AZVM}I`SZ-pWNslZ_xE+qoWc(!=4s^2y~4a%{@I~>U;i&y(aaLQF6Q9B
zzrR~6WcB0rH0<4LD<dP*GT}-qm*+159^S9U32jUNXRnwr-D~Ne$}f!G_Jv>O{%hx#
z-;jD*EFv-zw92(gxcd0A(!*?}$#3Sn9i3+`SY11z_C-|Bx~a4K?G69xuL(9g^6zEH
zo1X_Z=f+#`M|aJcF7~)>iOnu^y{^l%!xi=<sQbK)=U4BSJ9=|-`p@^rKK}Ta{N(KH
z>EdU9HQ3evs*{#@vHWny()kvWwzXl$RL{*e&o`+1QxUQ<$d$uWE#%Eof2N%u=e{mB
z=CAx*J>OsNnba1!Q?<{&vrJLEqjg>_W~!dB#d{A$9mZw8vya8@F7v(NU3;Qiq2?05
z&fj=pX=!aR>&V6OU(M|N&-U!u)3SGppn$-ElTV8h_22H?wafl`(SxkJeSdhbudZ{>
zd;MA9uHD05w;E$kGisMwcWu9O-#4n5eVyE6E7LVc-&QQ;=CiZuUVWqH!gn(xIc2w=
z2lw{Z>%UoQ_iNw$Uw-im132b?VfMB!jF6me0a|~^Cu5=TMpgc=$Cr?Ua=fcWkIudP
zTTn#qO#l7U!HeaJilmMlJGJnlOVa5d>mvSL5zYQTvtiDq440!P7K-lsYrNvqHSr??
zA7fR1IrV&bxlI4dT)WnL@{^Xg?!DsP^JVL;BSi(LPP}+|S&X%ItJV@z*KCuPGrw)l
z)pH!(J-Pj(W_sb3Q@PAbZN#{yvbnA@Z@9R;+rs_P{rNUb`PJrEG@|5=ZuTyGdLz@t
zt?j{&-sdO67jdlt9VEWZN@J>5qW;%~=i}#_O<U&A6_Tj`RZzLM_Wu8#Ir}71=j^+D
zJzdiM^t>rsq?To$j@)~k#bir;Bj;na2YYLoecs;|>G;*)D_wr*b+Ce+yJx@&$EL5w
zHV+MpOw#o3cRT#$0UaXFvo|q#hvc!6;^VV29~=I@k=`@QN^+-;iN*GM<G#BU{I8vS
zJ!@FksD9ks_bcJblaCuVpX^)se>VT`>#q&U-c-zaek$SIiZTPyOQ7RJEiP@Jzc(c1
z7t&GOOY{N*11FqJsgh<^ar;%WM^u(&75|sHcB(cubL88Xt~X3hTH=2^_~q)aT8o#z
zfB3L*qO!YExZd3*ty3n*{eAON+TY**%e%YMtz4o)PC?>Unk{}z3*YawTk!I7XW13L
zSIkxmTW_h?F7y99d*Z~20+V*7eEAY7ISUl)NUOP1&e;h<2U*zoLG=q}-O$-(>nGZz
z-TpoC^)ufaTVAH$PJ45wSmb@v;?{i7*vvCW(Z}tZf0ren_J1pXcU!{sdzU}-Ub?U2
z3a)`WyY@=_-z;HT!4>D~nUIii!vFW*y5NNCQvxGu-YxyW3%W_ehQ;o7r{H1nL-Dg4
zcuhEtoeEUm_;%xdu%t)5iq^L!Vy%WL$8>t+eu(cXecQF}|IJ?s&mQf}2-0bXD3aYV
zL!zMSOZQZfGsPiCW>juA*p$v>w&8ZbnOG~{(7D0slID9So6gZUkm!;32zeuUdy30(
zy|W1-72LMj)7_W0y*13ZpuqF$n$Ww@tOdpA_ZP;-3h;JYa)V3j`_7*qsZLq$|9N)J
zU$!GYbJ>nQ({;+Zl`wU;mescPy&J;SFD%N6ypnUVcY9;)?f;D5rM_O=`d*-B%gUCl
zb(}km{L%xqYX}NnsQahGVj$78#$l3L#)_wbKNcCfpEoStm~v7`C(?jB^z)5HIn8br
z`*MZ0-QyGiojMyS_NxAaxE;sVefuu_`tianKmWw`T<0@uZl=s;z1sVF*AM@F6GGRs
zeU3CvytI4zhqGH;MTNTpJj;4!>}%NG*!`@}{o)(56&E+KozwYr<R!mk${nLxJ1@~G
z?)^@+@8v2Leno$5Ihe3Sev-<!LpAdlw~1cdxNUXbNu_qB6_3;U7idU!S$KUsayr^#
z(!qq3$PDp?7kpRjt7ZSB8@=Gh*4g);+%9);G~czqSX^ZH_YaAeoLUp^?32BD>+q6v
z{~2FiIR5+Aka)1^h?U^yCF<;FPaggMH~7X5Q<u+^`1bIcl&<abx|z!He9gr3L4E4;
zn_HDHTb5WFR9j1wzvH=j)O*7FJDhrEVI3(35;Lc&L<Sw7<ojUWYhE|Mn+@L6^&Vb2
zCwk*~e$S*btvPif4PC4;Ey|bmuYBHRw{W%Ai|kZZF7N->Q@&&`$b6msmD4M0$@<EF
zGPibrU$D1+{(Y0}`OaIb&6Cvq*~E0)lHSF9s^r=tf6w{V1lcyeZ-3NE3mQ!P<!1Cr
z@Ldj^XCQ0Il$Lzl;nh37!!<vDybXWx`QHDoL!r?JU5f-4i@kZ2`{3kP<HDmCSbv(#
zFT5Jv>!rtcXyQxpx~B{e<-E?E{h6K^vWVr$<}~Mx6`TTsCy)QtOWGr^^S34OrMh35
zhrOyw^3E*+Zz6WEy<hy&>H4-8FDx0B_4hx1qi$T17s|bVzs>r87KM*kAg6WL{4`ny
zIj#Fe>c;F{4ko%DU$=$`c>lkC!F5Gu<FfVQdWV<gCoy&Ue4GEp@{`Yw28M!<yFc~x
zD17|Z*0V?7z*w2_W1V+^LejlGt!;apg+9e{srR>T2}<?o7HMnR6YloJ=8LpYcDBch
z?~l)L+p1ggi~p^@JGbPScI><CJ39&s%KUyxJiH&J=lisEYw`96-0tgKr*YT1mAl`V
zdAFj0DI<RWnu35|NuYDRKR#kboa-$r)w`j?qVir$hK7lXyu>_PcIB;7tEx&Dsvf#?
z;o7wNx<AI=PKJ)+GnbzZT)M?+qJT+lmVHLt1$LdkpvrMgkGI4wmfKCN+yQGM3{A4H
z`EdBkc?wnAt@nR$=k1#p_m<8PV0ts(Ty)>he+MSmYjY{S<k#2N|MBzZ$NA=YcRJ3^
zwO*Wcb=7^ISS=xGZ!X(U6TWU;w@BjU<>?XeujO7@*Ls;~PC0Y-ETraod27*rq3TH~
z_nfUhI{tlPIOR#`^phPk9$$XGU|+esj9>wq-~A)P=^k9K8XRU!)8{`Nv~=I)Dj_Yd
z&(GVh9a5?@@a%NBr@6~a<?r7s4?Z#(aWW~cykOGKFW(oq*lp>-TRWm`_J7uw`#sH}
zeHv@ahKx0HKiEr{ziG_7%FUJdvj6(}cx4rpmj8Q-o_ax#h<7RHW}5$mm2>CzCr?|R
zoEG<}sTFkAI&tcBxWej4<~CNY11sWe?`|v<aQqR=>e%osK1$=IH_wGHFF#)jPm~oF
zK73n!+Q0J`%YUum@s;?sTU;-ugXu}_pSxQNC#!s0wExb52m5Uj@20V}g?1kLB3N7~
z@4Df`{F5u<RF)Tn{7U=w=H`l^rCi`EB$nu15xD5Hq@UeaP`P&2!bw*zP2>U9`+7(6
zQ&UynEVZlhw>J{HsiV7JILN;F^T&sGCke2sv<PgGnd096;*jqn-pC7C3o3tdZCVwo
zu>B01@XRl>XQ<paT;<PIq*N8eTvflK!RzZZPey)z{vH`iBi<u&0-s)SRDGG-uO-)g
zLG8G)&x}1X`>vU8%(#~^rF5fUpV$3>h1d61mxFgXc}nOCcD~wOzHnEOs8F`Hgixc#
z>M&V_pT`v%^}cs>aO^W$qQBAo^75&iS?*sL*RBcJxa$0u%(~0dZ=87Xa<h?1p_qPL
z&z{Q9ufpGaY_W0qzD>5!?hL20?eZj#_ADotV+oKteA&Gta<zgPZkMh%iz(O63S7DI
zGW##T`HS*5E}Z@)^ZK%=v)neb_Nj_iha5TiG(b-6k?%@{MSdDKmb#V6ya!xeKmB{2
zaXm+7PS+Ae)0V>9WemA<yW5Xk5fS>d`|!!t^Ln>E;dr>x_s;v}YYToU=pL1G{rgd7
z*7ldp=5DTrd8d57WCS>MoRqkb_u<~&YIV;ywXIM5-%i)R(AMTu`AB6;{(YyUWalIC
zbrP4I+Mk6#lyjR<ljHVjdPsj#f8X9~({FUBOx4Yr|7E7#+5BHZ(x9eoo7%ZWuH6&*
zL$-WT`eqTT@h*06_kjpe%?KaCzmEjk^eubmCI5F+P3J5U)$LExD?4=YrL@{NA@}=|
zq4!?~FH$<3m^abx=)70gbmI;LZd}&9r|ikqVEZ~AJqrl~qi4r!E~M*R%<6D3Zr;+g
z`&|X|!<sLls?Vo|u3dH8U+tGz^31?DE0gv;c(=8kBRDf5Bd6&=w)BIYk9FOIH-?|^
z;@(~)`f%FaAPcM7&(TTm*)1luUoC&<Q2JGBe!l9HTC;-UW=FmB3zmDQeSM{xd+mPy
zfg^E`3^q=;klf32b@h$QNA?{3l$kB?cnW{tv|~p)yaj{>+cK6;n_|zV5&Pf&isr;<
z3#;10N8%p6uwD!*3j#bO-sG%VV7}2kPE>o6ne2vhf{D(4Dn|r7<}__PGV#NXX?${4
zc2i=^-*PR!yR0NfgunLfmM96+JQijvfq6^5&W%`<xx9#*Q@HxR$Eq9MoO}9JjmsRv
zRw(57E;;fpQ&3c}FGAGarI&Nnw!HSP%D1hHFPpDa{I;+8S?;8E)AjMrm0z`{sGOH_
zJANQwvD%^l#>dli6*pe?{bW#3B((3#Z;;n~-l+Py={tYb`nF}``wfK`>yB7iDY}~p
z-*{T+{`S*4r<`L=oqLa5EO)zF{>w!Cyxkk#ez$W5rd~Te7TsNP>aluB-N}||TO)!R
zW;QgxIuj`&rpCI=ByOQYzjCYmS4sCPeF7c}@~2-BXsi7E>YK3Q9Fep=5ncL9!Gdbv
z_Du}gC@%d+Vs@Bpdt*2E8=u|@t1Em%wC4P~yXH?%h<LTVfMd)2kH7gR6h*DbyVLOP
ztF*#wRecWL;^)`)iVHEHcy+C@(fQMRMd9jBP^hPTF$!6qq~EuEdf($p2a_bHnh#G}
z%}os4cUJKRoZZXw$ttbKRB`4FZ<*TkklN+`#vgas#?82KOEitMXZ^LBKPz4v^<Ga}
zrkZ%FdwRly8FSy%3P;9daNOUerd+AE?)B7jZpKqRE9VzndUW*XhAS$IyEmTE_*SA(
z`20y>O-G30o&U1)_I_4py2p0)Uq;KRr{0HdM%h<dZN0erhH}!Go;#Q4@2z_^+k7D}
zPt&iX+!=fKBsk1hEWI7PQHW>L<nsPLW78>4QAQ67CkVRa%y<>qW4Lj;fzKP&zI~@H
z0*~AaH<|e3g(%0`L=nBW7Mzbi@m^e6r>STJPj1?^`>dySaL?*im;K#jSem0?T_h0I
zI%)of1=byZ7Ee|<Vds9hcfX{zo|e?5tWZVWAd`L99xt3M^+<T##RFdc&F3{iDIv=L
z!h?zJ5B@$k_@pSIzI{$}@#JqA5C6RmyZxm>BT1igbE;($cSg3n?6n2EDw$_Z*Drn7
zlCe)wRL5`a!|0Ql*{cHQ-g+Ya<>(Uu$A9Mj4nE7+eBP+?30HS6es2^avQb>NfctOs
z-`?lXTm#o;@FiWfe|T?shDcGd<HS|<3;lm<ZMbs&_rxqvy8Lx+g{JTPa~vV}_nozF
zd>W|rQ?lund4A>dy;ojOU*2fH%q3c3_CmoWzO!rY&-LOG&%C**Ch^nm07GZiCOh>8
zgN@S-GBv+7#mPEv*IO(w^Rn#IPm#`|AH@6*Ezy{wFMjI!`}TKdyAMa$-&DHlp`WC0
zXmWnu$H@*EZ+p49n_t~3{d8{fq1JPL<>y!@%UC8jeD7p1SrtBAo_}@}$aRo-xiF>6
z_OK?)!{R25=J<ry6Wd?>+;1xJw_N&9;A)$=*xfBPytfW~zhT9)`-;oUm|w+av!w#w
zf2{oU<l)}qubHhTPx>|8t8<|@kKv`|ty}J0QfE3jVNc4(;N{sxm-0exS-J21QLLy~
zW4=1+y55R&^PlgoyK;TKbLl&o{TX)mYuwpewMDM16kM{@`|u8D_PUETyXFS$b9}tt
z?ZBEc**b?Ej_2mwH?wlEX;td2ny|dhDL$!x>3j=y|9MYpQ-dZ>3(A;o^LMT1+4q9?
zwr~90B(J6u+1wZ#wJ32a(~ioIdRnIWO}B4fKe(ladB@Ec%LRON&&{!H-n8UUa{l`H
zoT^`bUOr@^nl!)c<)`<0H(wNRMy{Rp<nB7Y$hWrwR$o1!E<d+8zje}f!BwBd7wjwL
zUbXr84^PD_wu1ToO--F^13sTVq$--loLP5a`h16Jb&oE5`5JrdrFCuXw1p+62GY{A
z@2^{<`f@GL_gc<#t4yLo&MoBLaIW2J=UM@Y%nm2MAe-+WFSfqs{HL0pV)LR{*o-+S
zIecvd=g(`oyK?VZX>7}DO?q#q!7qC)_rKhu+Db{&9FEEBViWJI6yAUF=*QmOrOk!Y
z^$hZEhi#vD{*uuB{`V6Lj&P_ZhcGoy4B1yx!>B!7DkH$-c}VoE%d$(?sB&CQagO7*
zocHr(*h&w>DAW61a~1Y?oj;OsdP?KP`1*r8Vy!m`N?+K??ekBmtnpUIJlhIu;dFly
z_HWJ`)AgT7n+sKM7X5TKTH*di=9rWx<z+9e&z#x!Ird~iirS<ro6_^9GvE9EJ>mJ%
zgc%u5AKtwZd{ZghEp>G6hxZe+Gp=nF=SpAxI%Ap9M#meU&a<q!SIY7H{m(@etwkr)
ze&??~*nIc&#)n=4t9FTd1nk{3ZSN6J&$TX}KQf#2&v$tJnp;=!-<GX@t}e4by)ayn
zcem};Ez=dAXQRE;&7KstHcl1g*_7J6#!FPfG?ORtsn@QxUa2Rv!dOaOosOUO)X^=K
z{`*H;*~jHxCx3b1`KcltZNGN9uX(ClXjFW9-rBvo@8WND3HysqI8t-)a`5c}txIfI
z=crgzeAM0b@2cp|O-ohoXMXr}!;5F$R!Mcf`Hh(yPo2n@-f!J;L_WUtpt1Qwl}>Zb
zD9OCC`;QjK&pXsmxH@1%81oJF3*J)&qrM3_J4S!@yj7^{UGn2txV7UyDKVV|*{n;p
zEr~Kc;Wd>>T#%7jT6*r;jT=<VUTWNzTCuB8SSv^^z|q5qaSLPof~w!s)@|g>?31Yy
zti5vV(jT$!zk_F=nXqr)X^YzB^XEl>n`G#yEW{qR?(l67(Vx>~t@z%vzHFYn<BzKJ
zEwh!2*xhHz=;_HfrLONz_`62$hV@eYyk{>OwjPeIk#%1m>hkE%K2`~%7xFvG;+urI
zcXJ#5Z|%M5J?F?V=?fo=masgxU#%D4`0VWL{JY9Umiu4W#!llt_GPz<^~#V5rWpsy
z=N}XF?VBvvyn24T|5my7gU`d0%6jK*nD8?F42$&U=@v69&&csVZ(sXAr*Xa;Q|CtR
zD*m?(3yOb#@QLEk&0dyc+B+fr_r>x%j6AXXxb*tXAHA1-zp?D8(hiP)vz+5(T=pCO
zHkfhbdF3X_z1#L3ymhtvL6+y|B#vdKdhI8-e|os_y5*D&7iyoo8y%Xl_lSq+b?qZ&
zN8_(gw`yPJeOU1D@$OK~opak%=FN8zN<V)kYu|Q9C)c7q<@4ve&f&Q+WABlZXHqk=
zCR{SC_S|&JPQO3t>aOD%ck3ng3;fhLpSQyzS*NUSgH!ch4qGpSb20U;pT5pId`d@p
z*0t44^H+;MP(Knh<z9KgtBo>uca=GmWgm9gZ61`OFo{8w;g=Aj$lm4t*Y~K*4Eg;<
zb4vBM7rR2fziTZz&Zm(v{q?f50Xa7~&hD)?SQjpStls2G?%7#~mW2Dy`0|>4vfSOD
zdf}7pY7=It^S_Vz@!IXZz2UN7O7HHy_$(I~@vC$3`!AQ-bm!f@)9hRAbfNS}#yz$w
zzT6I7<+jJGwzzb)%02ygwK!n+6{oE+(+XBzmsrQRzTjo>3IXmtd#c1%-7yWAd*u1L
z>l~F$aSxmL=Zf;!Snm<NzWDP3FH36;&sZD9FRF(gO@8-Te53Qnx03?zS{b}tzd5$;
z@2^8k^5Z48XEHxt=F2MmoxMle{Mm6<t!qNoJ7(TE=sSDCjUAk)?jG@bcYFQjsqFlp
z?j8@&Y8C#=qQ&$@Ws1g^doMo!+x$h?z2{4?)1;_xNlfn(D*6)*{v_M9h4mfmG3@?u
zY>|%GIobX$)=A;JJ&n4yOI*oQ;Oe>6v@ldwasN(E-}IQHhiqR5DBZJqKV^CLvE*IT
zrOVE}ILLioKYrhX!|nXLJQ{nY%@-9vKer-ktCmU0gnBJuY3b9_!L^;Io-EPtynaUR
zzj5sap`v`1`S#7ihmv1BVGl~a)|3)*%V)m+`gK?Pq*SNQ`rhs;e$ii~$bM)1o#0=;
zGlh5AWwkz;KKcIoqZ_=l4Hv(PuQ?qzNqWs>#@H9L^uDaq&-k?^)g_)yS$VmCG<Q3{
z{5kHmTQY8PS64Ib{e8~q<Gsxn)s7eY%-bmU@Eq^Pf@cO(3a<4&_U1gktn?^bsqmZm
z*BbZu-;=nwjbDas{m~h>c8PZR`TXa8J%x8;eU<tm+u8>|)AcPX-nA{i9nB-LTlVa2
z;g36WblY<68o11sG`)Mw93LP5Z+GFEn4Ln&$NO4m&z9cuF=~4d_pd*htK0VN`kC?T
zOXW-NEtl5SX3bAowxq$+NiJ-j_4?1ZJ!5SGtDW~PuKX+}<JlfIukyRmlkc;xuRY#<
zMk0y1w<l%7#K#ts+AZ1J*Y6DxxtH|!NZ%*jiJlwMH*Pe1V&Yb{-~N}Ez3tS6`<v}f
zTR=O~tXv%r()E9t{@R||>io~ru=JMApSx>%1Qx1?yf@tPm*I)@Hc98z)=J-wxow$I
zD$M<Tt=mTVcTeZ0E;hWs{zLf2^55TbWvt75#5Em`zww=GB`T^F($KZ8Y{ID*yZ75&
z{L<O@*Xme{1e>nriITcCTLNS(9D4k9RGw6S37kElCu2!i^WuHaJgQbjZ9Op2$=`Q(
z^2zI|eSH%mj=W}H<kYw4iKgrQ@9lB7Ph?9QY)wj!IOWs%(5H5zy88DHF|%Jn-a3C<
z7P?I-bMBKi=R0@qoYRZ<pQG>Y_-B4$SE{(p1d-!!D*rF2-TKGL<&>r2Vr#P_{~B%o
zzh>w>#;yGCP5&I_>j^2Qb2r$Uu4cdHdiD4`$+-#_s}65|o3NwGr}^N&n;**LJ2~Gu
zW?W8Jbj!Exn6=Zl@ZX!rn4Lwf|MO(7u&s;O*d)JwO+VNAd&l2g%nM7h|DvikdA41=
z=D&wgTem3rYMtC;s9Ly%N!Pl5p8UH-DrMIvSoNtr?Qi06Vg2c?y-K9dYKB_s<Sh{!
z-?ym6R?m=E6P6b`Ke43#jb^9x<Y{s5{EIv<8<~h+NdL7(XluejCK2VIiz7FuIc0#3
zs483~aL1xrwC<vpM~~0KnsTY+Y4cs!`y*GpP;s1RbTvS2{k~~@T!*i`d)uJ4+HhxX
zT!sA1{{7p3CI6oH^G9LD$Nr@E>1XEK&lj)yCAHZ-d+wDBFSBi!eea(*)3aXmU&ptf
z+!=fKW^|so&T!R#p1|Wp3g`PJSU#2X&N6LnNpb3v5O>b<dDLymXtm7Gt8V|sd2uPf
ze!ujdu;!5I%nOFq#aZ8)W-hFo$0%z&MQSp$P}9=+7Kht-4|fPEyX4*sKKkR~tC_Po
z0zn<-t`F7LhGoyac_eK`S=VmW2wJMv^~B?+>HT{qBL8;>GPH;DGbP0@iZ13iiQmYc
z%k|>YzRjr;%i_;=AI@%@Q2txAYKvU=vB$O_5*{nD%zE0Y^Mki9zOJc?d3o}+4!wdO
zo{x{Va0*}8njOBk_vYf{T^Xm>?K{HYJHPMd<?uw`<1rVVLgQb$PwMS^wy3|&Pv+vj
zijP|-`OV#zZC~a1_l>6g$Ch@EB3@48tQ!xi54yX?E<7~h$?tnJzdw7uP-FgirlUnK
zmOt&fC;w~Ti`A(<Jw_q-U%uYl6TPRx@YA!itL5#hqn?V#SeCLjZqz#B*6N%)jr(g>
zNZU>`rofAa8%{oDb2sMfnAh5)S3Y^wj00gG1#kD?b-8%x=Em~VWjD-UG(J1}=Hp3o
zhM-{YBEPvGKJKgGNO#J)_>%wo`&maH7r(n>x%d3BtJ!NC(*pAIC0bgVxOtmDoe;d6
zb6tCS>D>(*H|{YG@>|@>S?V3M+bm^kmSfm%vG<$3oNCWrbTVq}S*LP;seeHJ{`m9X
z+pk6T)$eHDrML8}nRIy1G{dZph+p>Vx@nKKl=l?8JR{pOu`8$~#Ude`<Ll~ajSG#Y
zNR+F}d=_umx=>7tS#!xDsZ;x#d*@2(y}R8Qu>28+^<GhNUasVb*}FP8f3;|A71=pw
zZDHkqKbGe@eI3TP3;gD?AKq2&xcS=Ki+ci{uV`enEq*@l@aOrh8ah6&eoPcr_e*(m
zbH~dysroxLIwMR~-n046?-O70ZN{zCduG<wpG6B_`3FR;ot3vbZtnKGv;6n{Ic2}4
zy*2O3z3hAYn?KzsT=D*1<F8}95^*~llFv6yIDL}o99NKBOZ&%t-Y;9GJozEz!&6oN
zBLDjBzb6mq=8M!WUw{4Pj*IjAlAb(yEwQ^!Ev99|`-#bw_wRkke$)AX>xJW+GPz_T
zjfKVUyC|n`+$C{muVByOd&zgdd9V1IF23XD>nsU*{Wr&7evtXGJM}8d(YUr*z25Sj
z8#Mdmp4y(&-Wug`B3|=kz?VkJtLyohv$mY<YkYlvzF*OW?><Vk%l$VS&hDLUkz@AG
zeA2B=&;J)NFI&TR@Xu7`kDoo){hM*A(&A0qnS&3yc6}_}fBLw#wPF2zTZ!4v9nJ?H
z4m>mK@Xfu^0<U9)&#rpXeEn+djP2j`I?G-7&kJhgeST}F{da!i*K^z%*U|+(sRV4>
zd~-*qb2Q(|+DqxbO!hDJIxUpTxg^<$x8%_2hRaE>Hcwvh?*ntz37G|pMEQf#F2u=Y
z{wy-su=R2O;sP$qB}ctKJiPz0`@30a{eORtt43ecJ0|Y4J8iL7Z~8KxosEujmpM#a
z&Y)BO>tEJ~mrv78=Is)wUG+@(&?WVkv2QY+oqjBBda>wt$zBha;~&-*luYHA)T|J$
zl@PUEFGVt>=cRS6+P6Ah$nX<)Z9NNf_1cEWi+>D$zDy2(@OLxEpS@MAQKEms7A$k0
zal?BKkLtI&LsxEF2kduH4cYiJOf1-OMcua;^F)`1;8j1acA1>_tW4G_kvx9vz=n)K
zi6?5J({{YRUNm9G<mZu_RQ5~nmyVL}P&_u{hPR0B6T^)c{(RBk?D0&S`0Dt!<ytR&
z-+Y{`!Exo}@@x0y+03^6k+8NhJ3NE$z>=2&fsX7if)*WcTo!aV!oSS}JeX*_@q6}+
z8^7H)sbv&^rk^u!ei!CRNJ`^Mbn)EP*17k{$qz~IkCok9SrfW^k(0-x3s1EkFRuJ0
zvg&sEzG;><rys11c42tdbmSbLSL>wrZPO-|-|1LqEBD^+;>LEN)l<%Ti97eCrf!_h
zvf8J2rseyhNBg6X2~@pgy?WI9&#v{KbfX1#mq<R5HvhO)ZSk?*#5)UZec1V*P3K(P
z<nPpT>-zLQA<?t@Yk1h4Q&idvd@r!2@hm)^@P{M**pb^y-n}!BwQzWDJ~glYd)v=T
zss{fy^Y*;D(zqmz*F*YB`<f<e5$iIieQCN+UYk4Y%QF2RUio6ex#tTu{8^gxJ}#rK
zpz)Z8^^6d2-Hhz>{JK&ldst%ESf`x|IdWzeZ>|G_yq<0-*R#vZ4&_WyU-I<S$KU^F
z#(}Q6=W&yAa$S)4F{ws;{gM<<2@!oh=b*TmeG+_|3zHMgszlDH^|Zfy;P_wjzs9QK
z=K{u+TuIN)Jl&pgJ}}_T9oDm-pU0bjy}Z1}nXUAvtNJ>FFV03s;uy;G=Jl%H)_-*N
zv$RF|?^c0x3j(gIb@aBrdgOXUFOKKut<pcgHr(1!Fyq24p_Qs1yUWX8I2@Uq$HUTm
z@PtLd#`hbih1|L(yQ?|8U+>YU<b1`pgD03YL`qJr-0+#%NU~>^X>;IdF@vm&bME)t
z-qz~*{hfiN$%pLhg@w=kE>zS$kqy#5|Jv;8%F6+3?lYY2ni{Y!j``=WuN|=)nPz=|
z|8w259laBcCaHWg3CuT4e^X-f>Eq#pZ+8nOa=n>vEO>j}4-WT~*c~T4H2US)w`ZGA
zxxDPNar)BKQw~u}jeOiI5A7(`mawpRk#^2VqKBvR(0e{LpNO9Cb@CgFk2_|Zc@klq
zr_*Q8FW#46Ao1T(>u=P*i@kmpCep@j`J5)QDmlt+&QaU>0uJ!9xpp7g5K*}Aqe|IF
zp(A=ROKzu~YpJ=MrqO8-61#)p>CDXm_xEbgX_+W8N#)xgIr-zf`R)}wuR3kY9M0{T
zdU4SL&c4{)$}$s=UdZ~nk)x~jx1zeK;M#uvD?dLUu6V{1v^kSAvRBH={{;`5a`1;w
zzZ~~WoPO}bzO@tYHaS0Js$Vdz)}rrjr5fl4);jUSH9r#qw(Ie%4sTu)<XX43wEJjx
zhk?x6+spi(9v8`~wRik|vp;87<gtz1|9);e8_)1{^70E+)su~8$~=GiwbolD)<=Q6
zTv*-nO=_`LOHNk)otjT#S{{NQzHxrD|JPuo+Qsdj!uw)|_0Klm3Hf(UlwbDJIg{u!
zd*$zMPp|j?J-Q{WZQetbmHSylnjH&Eba^~~aNntP<r3@^c^@Bp(DS`Vh{mtKT5LRQ
zkIfgJF1obt(T@uc0}rX`hKZ=zmc|}btN-h|EzjWB=C9?_b8U6*?_=(=-Tkw3!l$#d
zPi|xFiru|1a=YBE$?B~wo8>%(t1G3FzI_SXv8mjgiOD|c+zibVcQd8hOf@xRChokr
zr}lLEv=@fS3%`DDUsF{&<8s&@`+p6Md(UkbvtRZgJT6C~%7y84ht`CGUxmL9oVfKw
z<G$$S_GyPF%C-x<`pqJIOxKb3yy}nBw#y4xnhy#{AGWF7ms|Py(2{cf8NIU1mj#s*
z%nF%Oc%?qvJuYM&?Xk()VPC#|(lTG?GixF{W?FQ19NHUjf6vKs&eiWz-pxCu(z$oS
zg6$X5vO8F#%O2gh=zPO7@5X~umW9918K<PBE8JS3uy6J>KV@?T$)ia(gJ$%~vmb7X
zbbgX%l5$GM<&B}eM9&qs?(_5SA2O@AUUO$R|M7mgBkTTFU(}n<wte0{@xDX@iI=?2
z;o%adnQNj8S5+3z(2Zxi{P1w1RRxESd;g>9YZmWgz54y#<hOE3;p<%9EIRr}#ry2(
z=?{K9^*kvisJLWCq35I<!EASrKiI$P(VTu3qm@kQ;l3_w#r_tYw$?iM^yDS!lZ8_}
zk3Z1dmis)N<KoQC%MRNpEUs&NB(}njq1N(tZ}Zam1}2$)i;}*-5KsB?<uV)RqWg2*
zw&yW_Fo|MYnaJ_&ynIhp?D0pg9!#5sFDw2kDwC0)RxjMXbiPHEuYK1G(Or6mr5}?L
z&;6fzv2%(u+u<eo@^y0-6fSl%SQX3dwl&MK_N~+t@99qal2}Eq>^^pJae$m1)76)k
zoto}D-#zvr&hm?k*Lz=~unP+^3d(<ne2Fa*WWDo7VD*VkyT`{Cc;1|{{^TluJ~^8X
z@9BCU=jY$w*9*PjFMh)h>l409_<AhYim}Z$6I7LFbG@i!urA#Hx$2yC?yEg(Y-V^Z
zWs0?Qi0^jU{6)BJAM=&_U(O`Q8|-OhKGVbd<<erm&%OKh+z-z9wIyhge)IH+mzO)G
zURe<+VV);5XYSnA3-{F{wKG1rJpOU%qQvIMrd>NvEZCsK$M5fdMPtgo^qcuNHZb<f
z+ds3vzq6SA^|iIl-QC<*vP|Wt&FYxAKf~_AbuQg2Zh^n22wpayDwTX{?%NelW0<ZM
zi!}#L{&haQ=lA0EMop8Ze5tgrFTC!4UvQzq!zV>^uk%h~3*<K7=4@+u;=YPsL{z&;
z`B32E00+0f0#Q*-%J=`i(ra5b@eotzIv?Zue>EcNFU=Qg=lo^cFHjw&A*xkipx|~<
z;Q6$Fz2{cjC;fgXykhowj;!8kSBk!Veh}QeVS_;(r|_vqN4tN{4p|#zT6BN^{*+bU
zLe29WD!*#=XooyV|2tv#>F)hY?3TQEk#X<BOK+ZziFT$-enok?-G6!cxXI53^J6BZ
zYDxa~$C~uYQyjBftF+E!{3;1$tChUmGskZ4^TTbtkEj0;D&1+)cf(=Vv=v7Ljv0x5
z^T}cFH%_xCEHU@8EKpDrXe+t+v&5^Qz#ysB33Tb5gjI<Kmx#s(dFdHa0ny&mjX}MX
z%gen3U#@PQbW3BF{Fj+_Tkl`#TW-eo<nN54V(C{qFFd`}_44V@SD(KJXZ(7(il;aK
z`N`++-_!+6@Z*`Z;fAvNk9Toe>v=ma7>8(9s$bc(D)i^qw=4H8P;vMF!?ATG?9zs7
z$F3gPb99rY_Xn#eX6KcHI=-qE|6V9AvGi7$K9%R{?XS+SPvwDTPqSXExbXYttsPlP
zU#{rKeL8(WLg?uq>yC}@=Iy(@+)Z!sx?b;@8@?+a+kS#KSoyDrS;^b*)gtTu&ydK;
zy>rB~duw4b)BEI$TfTm{>Xo2j+&0yx@ppgx0X2V3iwRtbkL{QP_j??hvBa?IOU9Qs
zHz%*{oz1Xi)1-;lkIk+BrJ5ynhVQ%0HYbl)i{9U#fARE%j7^2*?+;lh3B|Zr*s}#l
zORz+~y=8FbF<0i%u3gOalc%if{oOsymM?3n)SN~UwpAWK*j$8|Guu2qT{_w0o0yfz
zsa+iW@Wz+3UtV4g+?;myf5+Y#H;WS{SeyIY+WuJ9;h&zQ?c!I_pqA;ZZuNJ+I||Ph
zzh0Z#-zBLf@a5{J<458iEor^6ShqTBE1SzpM`>ZE{Q<0NbbC*3bvt<Dh)CMaH6E%F
z_O0<*&e5*b-`|}*633KMvT^&19rmk4x4HbRdFJHt>d=w6M;~5BM?A=Wr6qc$U;eYO
zgG$=62Zs**bd^|P&VRV3vhwaknINrib%|3|Crp~H9PFNO^vOaAvm%38+uyhC{4d?@
z#w(S4{H^|>LP>tB-EF^4Po6RR;F9Ea5l&mS=82vYB|ey4P&g&M*`251dB?wudmr=9
z%(fEwDz)wS%kmsnUbkNk&(lqee;@bwe_>;7ykc4Ny4w6(`{mz@UszFTEU`V8Sywh{
zW0vT9=75dK>^m}UsjaA=6vFzweh)Xhd_=;*o<fb-8?wUF);sn`xe7=MD$7jVxWIds
zCZ9}8<6>nWcK&6ukDPcwN61bW7dL-UR8Xih&q|`TJM{P;Q|*h3O8i<{j~l-O9bL<C
zg?~ZfLZ?4MtDYIBIYcdDQ4yQAXZQ3K2b~w}stUCTvRCnZnz1D-W%H)C+Qvg0_`e@z
zpUNr~uEX?RT)$P>NI>Seb(qPSr#y>~^|m^I*6~TK4P(yEwocIx5qMVj{-f(GX5Ox+
zM{bA9w<t^SuqnUvI6duY^lzWv{10Mxugtsir1sCsb#ae(Hw4dC>9k#*<Qw4fjYV4j
z_o6ae_ct?a#HICWT{z4C_WZpdE_5qYT9lR9+S=o#k0i({CRgo$oWCbrzVW@sd97EF
z&fHxB?Q!l4eK@zpNHrh)QTrmm=y8~C;xkJjx88pZ&yI2*`LlV#`**&+ldjcgPUHT2
ztj}#_PEg4EM~$~y*930JW8boJ;>II#Uu&7Yz5gBa@-aSkM2M|<;x~^?;?2izEIg5&
z((>$Y+u|*gE$>8^xj#1YJ0u7SLZb}x^(XJ|O}w+uc7N6Mr1$so|NRO&p?`Fq+uB33
zwWT*EU6&5gm@BWfRX6JEJLco!yAAW6YChBet!L~h*u%T0xInQiuFtX6sV_kKnbY(A
zzZISx3G%sL?{Cp}Fu@>*{ne_YB^MkdA|ji)`2?MU-5w?R3pY2PKA!yP&ej`SYc<=d
zDiWqVH{kg!(e<@|QNa45%7>tsIMH&1CGqr~hcmX8Xm49PyZfNr;fIz<5;it$4+9oh
zN=?yKk~xuJAhEJtCEDzS)RlI}byL<$xOm3Ak({+K_5aI=O>;W-+Riqd%CXn6nJw`{
z$HyDx3D&oES#z<!67)5xvHz*0weV_uhr-jx!Sy!E%?D4snsIaS=@UOAc2zN#y^U%A
zc$n?8*@fgUB{H}6vXyd2aIr7rbFAC<f#3JW>4W}{MIZk7^3wRp%KaHk%?D4Y{MjTO
zo|VGWZnN}(Ms1tr|LBINr>7_XJJK1k<+YAdYx0*?vlqJ0dL)}>eojle(Xp~ZW`#gf
zNx{MQ2KjFi&df0HKH`6Hal`w^l00n6sU8Z-W(MUCizc+j9O{weu9UV&eq)hiQ7LY}
zX471zq=L%7Dqke6r603>IsR<6eCr2`q{7O>Pu72&o%bS*QQPkB(Hnx!2KDbmc;xqU
z$Sco$lx!gJU)59C#3@ep*qWc>7bZ&Vs{i+sU0baG@b0(98{Tx}HRk?ZaPZ;P%O6hc
zP@JY8*Qa*VKIzz`xqp5YTbWpFN|So$`FisG%{*s|ek44bB>VA^WMuFCn6e26f2iKO
zZkF(HTe-xx6wQ3*>F3|H7IV8Lzt+`%*fHf{dA9m9xlf1pn0jwadLn<rtePvXrKWho
z>+*E*XMbOJ?^LOKy5iUk!*r`XN{ct9pUi0yebejeeQiO?8`CrQDkkl`dUjF3@8doS
z%8HXzz9l&|C%%gjS(?+Dx?)XC;PxCw7WGSaCloOieqL#RDs1hs_o3@!1Rwgpe{8(p
zo%7IHb(4Ko`@`3E>D^OryyG|h;Kl1kej>YmY~LrwuzbT8;r4Y2ZkMNfeXZvG6{Xed
zboqL@+}RT^Uw^*$zw5(;fRyv$Qa@X+{_B}@YH`*=84ixctHqYgxn7=k*rGo4iMi6Y
zRVl6_6WAZ@dcVE#X8yZ7O@aHg3Y0${Q`K6qz>4R3+}*>q@}{doil6tdd>qGg@B4d|
z8;_l)@4WQ=^Y!aNnIg07?tXD?^PhjiPII?C=cJ35{a^0>-MzK2G~>{_1+ja-O)!&a
z)|*<a^y({XPxKCM-?lT3YirCjA~%b1Sw(QTFBke`E^#4Gfvfjs*TPVlg*&!#_AZY<
zW?yZ#V2WgC_@1K+%9tnIFXnCwJ<a&^?b!^Iw@lOC-DferU%sRIf1{pkW9{#63#-4s
zTM@93$z;|Q!wVlLo_@M#;pOQYg+WWazHZf9vhVWpA1rQ%Zr)>Js}f>0G&KBkYyPjM
zW&YRyU75b(<cXKT&gO}SSbXMK2>SVHmX}X@vbB(P(S2FR$6?9=OFoB~Xl6C)mw!um
z^z8Nv+cYjO%NvWF4o4Mi{PWk;yx-?tQ*TBWbFj5Q^Xp#0-0H)553G7tzdm$ae*PuV
z*IRlE5~9={UNfIR=ltNx66Sfbcbb1~E?ZFRnEXS2W;5Syrj6y_Ygp`RyPoUsFR$8P
z{M-+;bg=UCv(~WLzuwkw+_>@2-z(D>EO{AxaMgOI(4H?V|6ZQX`<=Vf&CFPN#_Siz
zkG=Z+eY25CV#X}*>3Xg+jZ!ac$qZIBsZ{wDRy0fE$DZ2W<?EROx0Pi->8R>5PCxe`
zZ-J@W*}v?mYZrff>aCD8rRs&v)KdvM%KCE+J~}PFHYuvxkn{4}`tIwQp}lR7ANzLf
zT{`pA>FN6Sb3r!|p9o$VQg!o6)>r?-!P&_#|5t5RxAOTr`NNf4FHAM2o|=Db>9J#%
z{A(_^JNy)tN>#DjSJj$+&+AIg1)gL3%qygSbZNKkEM9i#szT3==?N#UYQA<bR%+cc
zWy!(ihcY|gPCa<#&+Hcy{z|N$bm+=Ckz+xemecH8?$k$V2uOR_xx2gnJ<b+nxXxeN
z!@Sn6zBd2Yw!mM0_m8zqX}oaX(&*RUlP_K_-!f6_;xt>|H`Qxq?`3;08kDkmTgyTN
zr3aT+muuYlk<XJA-FW{x|HK)8%cWhe#5B!}<$8E_-~Yr52PNLzvlG5nQzP>1TW0fv
zEN;W)(Sm!d4Vam~xh5X(i`?+|@&5FGe}1kASt+zC^l~Zpa<h=D!C%*|k6I}4GW|)E
zsH&D0mzdbfJBMWWr`0`rVg2{v;r7qb>tc4cOt`PUQnz}eWB<mYcVR3ZzKK)M%D6;*
ze3(DK&SCDoc`rgv_ulu{<S*+x)N+~6V%x>ZcTOD7xL;(lYu(-UWtC@t{%GIrp8SV1
zTIRONERCJZUtGwN`L!mpp?h-Mfo-?TDz0okdNtMA@PDY?n;0t*`(jD|Xt&JwZL_0a
z{dp#T@`djGEfX8~zF$oL^(*h^nG@jUk{PGxtzNA?%RFDNMTH-<rsi|K!GxO&YTj0@
zh+of_B{0#YRp{=ku+n3X43h<C?pHgt<HeHjSIIpwY7=j4dd;A-mS<!6d(A2DOe9KU
zdOtk4s68WM_ksnfCfnZKa(}e+#`fnbUL_JOzgX+v@jbh<v-nT%qS<x}_-9FR)^@4Z
zF84pV;$`roo{9T<x7uA^e%C|i@BHFNM>s=P2DOT3YPNE*|I(?SDxaFxw<2ag<EyJ{
zdtZIbNjUqcZH7saRn8shg$duLtUs1K|1#ru{`^C-J9+o;=O6xU^VMKUrs|J<RUHnk
zhFoGrM-MB{F7(dhoxk|@2eWY9iY=@9Wlr%&?EcTQX|`+f@r$=tT))lyZfAX6{fobg
z?>c<@_RY!TmD7BCU5~GtW*NVJ>8yE~pZ@Z{jNzr_+nT2?w10lAS9-(7jgAYQ_HQq`
znZI}HF}|l4R_x%-v#n5UdC_je%a-6YovWhgz2T`csqTrr-OR5%_SAi46Xep3dG-D1
zkvvh)Kgv^HnXoOMHBDgO$piz5Ux!yEFkdOS^yt=S`Pe0Y<cxk_nqiX4!n0TYQSmpa
z2!nm*XO>3Q{QJOW$2f7q&8bIRg!ENE?kl^xA>q*d1+HEjzb$@v@dRu6yZtVU8!um2
zTy!cLbXnN5$J<vYu*t}(PyZz>TX$sd&HH~AJkqP5a+P()Q@7uJxev0|{(kv%_Nzy`
z{{{BlPdAX@`MdaO?t-Y<Rc05K73lUzn~N=GFLmPES9pLSRC>GX-A%hZrLMJRy?Vr6
z?sjf{@`2uf?S})Bn2#?Ez1rj?(R?tW=6rsat$oaYfi5A}FUH@R4<;B~G8H^us2<R~
z>1U}^4~TEv*=4)-4!gD3*`sSBH}AV`v#Y<&vz70~od@54^?}+6$_o6oonJTa-(Fwx
z`gS^B*OpiP&z^4Pb_eYo{G}SWQQdHh%R{5558u7}clX+&^BQO7-;n<HOS1iJf`P<K
zCg)^nk>3aZU0l2QxrvYb1)*QFt51R2Q|^zF{L^|jnZ8~Sx3}tk?$*^J&)M0HL3=dY
z&K+AD^1b@E`*x|PTpaG8Eiu2In;(bWdthM1gmeeOj2p=Y;QJ6x96{Q)dD1AUUvKiF
z^{F))Cb`q<4!y9h<?@Y>_bv@Q;t@apyT;<>>(5uu7fmoTD2({kdH9mQOzradLBG`>
zavXZ@(;l_<->y@~&&)Iq+*?&zcbVO5>7@D#zoNwbd%k3*E#h{4&D`pAaQ(^^>+kz7
z%ocuC{5A?)s?_@X`}fG%N}W4*&gsN^VF`&7>o<DW=cl<X4RTz4_0#;9Ue2~vUmOlL
z{ff+N-uL)Q-HX)+7XS2~&wcaqegC(U?Ji$m&MWfx`)lLcur{@GmzH|}EG?XEnyuEN
z((j`SzFUD?T<^pD_xJXm78kNCe)i;h@NED2b_XwA5(*0o17(rR+c#`z*t&JAz@%M2
ze*HRh=1fm~Mx=brzdw>{;5~(+PC@g(zrU~SKhLI0J167Ux^?TSjLS@F#l^+<N-7&(
zIzQKX`@NpKlhyq{yx;$SnU~xtt)%?7x3*UN_@Maz=dZ7?HKMkxxR-O{c)$Ea+v>7=
zeJ_~x_4RMuzJ2)4ofr<!*o<FgWo3KjUS+>`@7|u;rB7SzE|mYWv$L!D>2_bbcENk2
zDbor~-ltqK`ttGd@flX7TCc9GREBsjV|852+OlIkk}Coix7~~S_V4@t|J%#O7y?!6
zW&Z1Vmuq%3Mrf#sm6dP*x7Ygdn`7_Z`Mr7fF7HiVpn%J+>d0;P>(jnhip^u(z5P+m
zyLo%eKPRQ%J5ydKoS!DPDr{}nudlB^>)qteow+7pA(NDO-kIGg`k$YlcRx8v_2ME|
z?t7}$ky|nZyTo+6uC0v*sq{U@%*J!zP%HOVwX(mzzlR^6yzNNGzq(m{8I6m1*?6T|
zGA}Pv3||+s$NQVpd;82wDr-YmfG!I$Og^R%zi*BHxBt5(s<)Is-g~59+MKWc|KIJ`
zqQ1HHO0~YbyL)lT%S#}A(WSdfUNZUn``=ToUik6yzS`=qOK#pucyy#Q<K7-i(9NB@
zQ}idR`@1c6>)jG|EYP`m+QQP;*Ph015|47LuB=@7eB%|ilBctao}OBmd3o6$?{AwD
z4l+&A2z<0W`rf{yU834oQZrVEt*w|Y?_4c=rivlAap78?lErH!-+$k_@#1f3Y3cM=
z(`9Gt)zzoHySX*<_dk<&nQObY$)!D;FDvcqf5qa&8GUQB-23zQHOK$_cPlIK?8%xr
z?=${nMlZhccmKZ3-~Vo1+doI(|ID4~*OztwPH&aTeN)S`_HNc@!O3Ou8LO)so!+ls
zE2iDG?Y)2W<SkeK_*ed~yTAQO7V|CFm1{p{h}=qAx>hfPOZM1;x4*M5D_l<d_gD5p
z*}sCq!i!nnnz@F{j`eI?@ZH?l_;LRx`KtQd(!$_-*$cK66ct^nl01Iu!urWq%V#g%
zU1;BCw(zpvwfS$~r@b&Yk^KJZD);H>`q#7ClK+%{d41h~ZvV?2hu3`CUGli@%!7l?
zh6N8CzV5JfJJ(#-aCwQR@RfD3v&$2osJswZq~zMQqFw3_&wk(2a<cu))^7CT`P<N!
zc_u5^+_`>X^42XkjV4{zjNY~;Ec&|Sf88xTi{&>M6seW0$qh?W`jH#;4YU{9c7O6|
zIZ)U7<VM}<qMc3mPtVE!Y5YaHHRjy=)V@hSE?XWG@p{`EnDl4+3DH@WCXzFir~j}1
zQ*(O$!uvI=c@|4~ng*;)dTVJpF@I{~{K=oAzFj)>aC3@W+_4i052Iw0_v}`_etc?q
zAWNA3%x>|ENA^3I_DJ4)99-X4r|fxXUFhZqzr%Qp+l3_T$_%)o>Q-znc=TN2dbU+k
z?%V{wIo;RZvc2bv+oS*Zx?`WMahh|~>-rag$LE$`R_Ls2iTqqUVTxX}_t$qH-rZxc
zw_0PZzWvQf;lCRa?isl(JN4kjO*!T2?JZy3@1H#(9H02`&(aQ$iHA4lNcX(C{Y$vM
zt?uyB)`RIEZGId*mGCr-dvW_;R`=w4lP3t)$}0cXZ?nmdlW=a}TFd_Ey<5(lXX}q$
zW?o%rV`YDgKeN-HP2E$-Q_><jn9Zsx;m8cfg1;+x{zzG_N%il1Y!_S@946W=rtfg?
zgYb;KUxn-<Hfzm^FlD{28khCIX5w;#;?qa_|49Biw^nv@fq{knGyOOgeVYSUMA_{s
z>oxt~JrwOq`X?p-<HwH#kLb5&W*)sDcj<}4ntA`&+x%kt1U{y(6^}8x<}<(X%cR;3
zDF=02=0<k)iZ@mGvrXvB-Mn1s%u?lPI&+v`_I`~h{3H3^T`>9gos}Gg?;2FQpE=Z3
zD^HWJKK0x1i@a*z+8Ir^Pf11W$zUvEmp}OCZMgl#11D~q3qB1AUR!TxxB9}~y25+y
zAGHs7y6)If%=Yhvz1(%?qz{$0Z=RL;O73Ww(l|BbyFu#HgYP#b7ERlD-1Why!v$9|
z?(jTI+m;c!+lDDG#?|OOugil=%?4L8uEe~(zp0FM&(1nl&prCi_dSm-jn)rbm#2MW
zX5@m*!?!wiKkp8>H(f|hs*NYoq%Z$w&)xL*P6}rdzs|hhFoAvgLw)^TyV%(c!8K`b
zj@lnRTki1rSZG4h>#k|4u?45Uv%Np*a4Y-AKC#7xkJ$`17CFA|YW?uwmFb_$50#bv
zt#`?A`K$YRLFiJY3Xeajd(55B2ev-Ew3y>c&J~`tXJr|or-lDrU#HOeeOZfJi?a^b
z!E<M47rwaV%`ubhU(ks|@(&Jm^OXEvtv%;0@5h%8OZZb4=xQ?0HeJ&?!#dnvlX<_}
zIWN{sPmi+#hwg-3evz4;&6(+@HR;}Qv5)>I4O({It*+<xP&qQ6H}<D#z!D`@QG?Cb
zzeL`Mh;&%#<G#kD)+0dC!bou09LY01J%Yu*8N~ATe~3&=d|`c5>dVnjk&^>Y922;7
z{@B#QjUNTLPyBuwzNKi3xpPpFk;*J*Hzy_+FX0)tGoCe<Y}oFQm1T74s(Z^3mkyC5
z_kU^s<N2#*`th>SnR7ytk3>}dD;G&th|lBlb~c_NA$|D&7q&Hab^YIy|8UI^S=apY
z^Rq>vGw+<3pk<f4b@Jr$zmbwFCM{QfH{a;P>nA$N{Z|rN*j$eMXgNP|KO5U2{<8~?
z-2cE`@655)++R=GT5!U5?|8BQ|3YNgnHekh|KF3qyhUaslRDq}WAgR?Iv?6*A1?o{
zcE|h4UdjCeNhhXi)fl#KRjj;!r8nHcPc^{*$(dVv6<0ng2V_gPDsTIw{?XZV(y#sf
z`_KQC{B>45RpR0S|5FCWU*>F=ZQph_Jo`b%wxfj^kHc8fKHTexZ{vwnlYdYX#&*eH
zkLAj-pM8egEw%fjEe>6a>01)vYiqBiCwEM2+lG31ui{twe~;T+=?SXI|2F<2tymep
z&7o+^GO5WE9M)JUdq4S^eyQ5>p3Uy|^3EF1v=lC34u${o7<qf*nH=-fBUW6RaH#(*
zN4IZFbF;FY)ck+d$?sXT6Rjo*o9Hfjs8W~nM#iq@fYV=I`ycK{)DHYgu5YVLp80#S
zkxthh`(SPB8-J7EEPed+@$ZgDv$HIdizk_f1Z*(UOHat)W|w|9-^ieEO5>c3qI32q
zKb$TzjpfsV*u$T8RAtEiiL*U)j$1!qZ>V;}NmmZ;?gp2aJ>Pn@4~4(|KjVkJ^VYDn
z2bW3y4c*}KI<55Mqc?0eRbPc}_y1Uwvf1p!;wcI?Ix;VfRNu)*cYiDnJAD7X{66vb
zhnITAPAPt%pZ>?GU_!^G6V_L+<fXp!<lyaZymU@@t@f?t@84uU)R%C&GpS@;TeR<&
z4BNpwvTw6Q4or-de(?W|)i>KN*TrGJjGkPb`!h7obkv`1ve=bv`)B_B1N+(yv+B)6
zf9f|KV0|lH@#xgS(u$|w1+4XdFLZl7ZNrp{MtVX)twQ2uItQ*it-c~v@o<*B%_}n(
zMYG38^xK`3+@h@P9b9J~oL(4~ae0qiJlnnl-xgmF*yS3X^s`3#p$XIe`N}8a*BP<A
zU-w|k`{W&0esLeR4r84z(^7jpPa*!}rVk%haV4HeowLX5Pxhb2hjULD*6TX|FVuO*
zdV9%li>iluXS}x_*%9ZPpwfF}Ve|9Ew_$Rn(&p`s7d&P5*T`R-mTHjpBYwluyK+78
zd^01MmJ6i@D)sYDx_9^Z#MSu$$2N=DXjdxzIj0y?`=I|-?C}NJrs02HNQ-qJeU%wr
zbgxU>X-D{qjwQ?03qJPApV}(h7Weh;M8Tgt?B{HqKW<tYcx<)Nq|X1XxAg<JofY_!
z74WD1asS8rfd?*g-?@F-qV}yJ*OhmjiEp)?r;2p^J)W;rzw*?I`#TsXy?=Z7rgXoe
z?hS_I-&<NVs}Js%@mk5!=GPjq(}i&YPfv5Z{-JAYO}fHY_?<dXZQ*vxq5INWgJt25
z-@m$<pq*hL(Q_Yi(&CS~3AR7MSF{;OSW2Y9`YlfqW^9C=E7P2K40h%sUz;TCo;Q%<
zm$F4MH}}chuD$=^c)Yt<1#fqFuJaLl?)a>UE7T*lmGJ(#{NwR^1=}Bb>-Kj%>aUyE
z^Mn1yjw*4beH+!prVF<68nY)~F_GW%x0AKsGEgJ$er;38Cq6y-J8icaZ*K3n^0`>r
zAfv;a?|$9s-G3zhnU^KMKG^>1Z}|4}j}PrFfAv@X>BF6GZ)|$2@Qh!+OEbIgp>^2J
zM1v9^t-f{9O^5pz|9rfD@{bQJV(aX`oV>N+mXlC{D0g_Sdx#phbWLx|b@PJPzSrtw
zgFd9LiLVzqd4Gnr^HhO`qmS8=zbu;j;Cbvn#gNW_J3bzemt2)H=f+Oi^U6P$N^R;9
zGXJJ~=)uC|!k4K$@4qGAvER!1`y6}LH~qQCboX0){nxM9{C?uu8{7UeEaR1KV%=T)
zk$L^+>1~qLRqagt=ieM&>7MxK<MoG&;*-uFyxeiwHOrUt*ulT<0!q*N_cuSj-H{N_
z@vOg2F7lJMjCBQH;eCUw!}H}1tSj!!xVTg`=557sd4*3;6Ln(CS|l9WR)p+lJtboB
zw06_E&#QlbP_dL>HT?uAwBFB~bNHq9`YXS`*Z3=19FE!hf3eNZ5&`}snZWHD1y7#1
z2CXrY_~m9*)Bo;R=>PodH;kIzC0yUA{iD(9h5un!+y9Px&mMSpwY%_TB2)dJ&r96w
z4s2Y!PoOq=-=63Dq6_{kWcZ&QFTb<iY2Tl9`G;TeiZ2w3SQxhXnZ_jT-D)o;KR$Q!
zFNfGPx1CLWdv5nXEdOkwcdvWN)~cA@Rbqv!=3jKM%$s|oyL{E66-m;)wdr|+pWlCP
zIJ<dyxyOc8{_J~JnoGUqegF7DFAK-hlOCHjIzAd7U({eCBQ18mC4P}WM^*3aPeB${
zHLPdy-W~bT8=j~pa(L-K4xb<Ku5+SnS&#pnq!3WB<XLv##mmnY?b$5A+25D6>3pDs
zgjPcELiJ@|*Y-a@J}u$&PYsF5JtFxD%@2*!7W8ClmFds#iWbzGp~CVosfT&nyjz`%
z9Mui$ZZdN4gl^Eg&U^Wn`H|C)y*K`>QRxYl^e{Wwniu;j;p~NbAI#Tvwq`$H<mjm`
zw9VvAq!DZQVVwj`Z<j@xc~|tOvVWJeYdv9LuXaYZUrBA{jomp`dV8ie85bVgF!69;
zRDoDM&yJ=@_Hah=T7%m2+%t-mro1wdYmTnSSmZ0$nX0@i`KzktFJH+<n?n79&y_51
zy37wucqh6s|6|S`PvuhS_96-Mb^M=ZaS6WKEqi%;O!G`h_I9PX4Sd#prOO{*$bTnd
zadclp?NrB%XPKQ3x?dX<zD~X|YjwcBw-#UWX7RI6^F7uZAiTn8k-~|1VPp3ahc9pU
zMr``b+2bKGVY$^YzIUB}{xm&hU$*_I;6a5qaudaam+7{iP|#QDbljjD$K2X#Sn))h
zqur~1V);det`)mym}Ki7VM?AMn%A_l`PQSG>ki&{6EFWd{rbT!$<+^Tp5b2pO@@u9
zSXot1U|p!xK{ZQ;^KtBpU1oEB$cvU*S-0GSx8A<z3`@bP8`6)ft{qtT^8ew_HNgg}
z9#n3*Ezx<m`dR(;H?J*u&CbuW6K?LDyX)W<{)?;2j~CqYXY~_e4xQIE!)l|xj_19&
zjVYXmjvPC|QP(&9n{Pqk@f4SNF^x0X;|?}?yU$z~Y`CG*xa{oguI!0L98Zcm&U{LI
z*27t_S!L?-)6oXCzjbFwcLXl@=+W~wMoxUY-{FnNjU-M@o{$#GA)Mahwy!5(jry&R
zTAmzwpG5PtPCfYX@u`8D+r<`N^NxGVl<N-*N?c#6v@U0U<6(ZIgcTlbR}RX?&K5iR
z<)5>{sq2i|*Ztg%GKDo5aji~2f8cb8x<uDvg{|66QmnoO&tGz{cylWGSI@r_s=Y1e
z??hJ2OJJDlYv?0)RbEU{+8`lL=i1wuUFOx#6J9>em~m2d#r<llUDqCHPsn7Hxc|D|
z;+L9uo4+he^8e}`f6WA0waXpOi|yP{`7g=Ev&BI7j(~7`S=(B{cJbq32?r-$-yotD
zu)!&`<6X|Nf9}U5HW!G5tdCz*@p|HlK#$gT_UQ@tUIyHlC9xoL`^k*(&<0-P^hc>(
zx+$898$Q12=-m72!PA$$5%p#QX{%UfOv~xMSZj62bFbKZ7H#(JM`mw2y<tryliT^*
ztjvqvuPkId5x-OLO)&G-TcKNyX7s#yz!`WTvL|u_JKHk00-ft~TUPV=o%<`i{Y-m;
zqrbFHWF1rJtDO%Y{L?lNjZ(JL<4S#Xt^Lp4<UL$nPG{@5FDx#rJ96({XW;7fhh}Be
zTs(Hza7%6B8i`AsY`)hPMLu%+vUeuC`n5iVrOD^ox4wC)$|Nz#=*8K;**m_U6G~1y
z@APha`-Xo9a^K7`7u&wWYKC#Tnb*@GMNLEAM;*&&SY(?^^~H3BdaEhCxnLwyCByK)
zeR+Z50UqJBbB^NICC<d{Vn3PLIKw8>)az?ZL#XyMr^-@Wv-`YGJ|CQ8YIP1yh};}#
z_gJc?Eaphyd`}CRFqX~F&p4h<3hU_aVxQD(P<zQs<bSqY*xEVVcW!j>Zf6qw{Z3HN
z-sAX#nVTQZtP{Qc{@CKe?x+=aKlxuNI)Aj?yU%^P-{Zs{<zwe&ao&C&z45~qj^O8K
zTo$g_98vv8bDn%;TkLsVgHD^x>)nOidLkMWHgf9do)!4~!f4r=9WC=dhb2Azb8pAy
zI<vk#URUniIw9#Bb=CEyQSXJtrOtQkD@7z(qmpy>AG6qAWf>B>XJgJk36=P$#;@YZ
z3w(CAPn^8%!0PWJXJ#7mxXQc@+~&s{vf={I-C5Ti5A>eq@G@#Jc_nmgy+!A>#c2u8
zeq6J#IW4{XUhAWuQ@uIb*q5D?Xcf87dt=jkjkI%j`)?(SC0||Dy5coki+cSnmIaG!
zl`d7t+%FY+Hg$KxwHsy@n+mv?=H5=ecE$cf#&@BZD(T*{E-#L%?wVX~BOAtVmhkDF
zw!n;Nr;L=QEfbD+Y}8{dKb-L9W+kVp74Ly9^PX<VdF3N<RkG(L^DBXmQ9a@d6C-TO
zEkA9S=(gN^T)F0c$(kL1M3#xUTnq6!@sw*rl$>+D;DHkned^QolpMlXg4252zdUn$
zWAUBEPWZUOo&)n$>U|o!4J4B~c?=uF4Jx0SewnqOOZ(Z^BWp`P7wBs6eAkyhbU4NQ
zj7pm)@4?zLarJ^HIm->|-YIUGwL!+N+g&l^eUc0(*YVxQ%|9xfnf2nWj|Gd&fi~yz
zjkV__?wGD{pJ&RgDl^5yPfXGFjiK7Pd+p1Tryoi`X|d<_ev$TjEy_<``rhHb_+snb
z)3z2;IUUb<_gvUgTt4Njw~kNghD(KSZxrq^)o9J!?56zhic(JfQx}smE*|-Jhsy2?
z{K%Wv+N~)!!_j2J%$LeMvo;BGDu||J8~=#6Zn50mWKj50OGomu1iRRo17{`n?LN9m
zVAl3Eokde`Jv^`WwBXqRPK&VDy$fT#liyD&J#jyiQSAH=>ALFl#|OA2FWr|ryn;3T
zV%-~`GjpympEKJTxU;S_WYslJ+1FDKEj~S6P}kVu(q`Kk`yLyz`ORrwxz}c6(Hir2
zZbu)!JNa4Q>DvC8!PSqR9!$Ma{z2i{kC=n;#nTe6Zi>`M*LS*;uAG>0ds2`{7xQkt
z1qH9|X53rORkO^uebp<6GZMEr(y!?sn|z@_XYO8>K3?~U74tiG9NxU)%b#S4=!gRW
z87)5+Joh;NmQ(yA_nUk5{9oDn4}N%NHp48_((B8NmXES`Hzsf8Z*u-)kb99Y<h`>=
zU6g-JydBr>d3#%T?&P$X%2d>vR{P>UYucNansb6!le67TvhK=NzL5!7=oR_kr|z9^
z;R}7|f7`HaoAdVl{~Fi@CpKs=FSNfYu}FORhTmJ{c`nU=^y1|0hTOtG7gy_ZJ=x^;
znom}twwCky`N_qPEj66hCw+ftz2um5i?DjFqSCRT!)CI97w)k=%?fMzd0Tx)mAxSE
z?>~&z+1XoO|5DcyIo*3<_VWVeAjZ%irElyixY@cA=GYXnX14h~`Q=wotZ+SCm)UqC
zk5jVn3?b#CH$K!FJx)lQ&)(}fqiC{$Xi>TQR;#ZM65cYHmsc-g-*@2R=kI~r0{M4L
zOb^SvFSYaN`VSxG%9t%{xIcCChslwOpKdYA?2+RO{o^aMSKz??+YD*XmKm6tHSe6s
z`6lMmq19QT5s?v#3U_}i@ThI$<qm&Pxk`eqD2Vgh?pBfKTCYl7))r4a7=PFLfHJ=z
zV<V@Ik8fgD8lQAAW7B#$$3@P}B^uME`SN-%E?FaFzMlQyss`&>rum%5V_Y9Zp5f#Y
z4!@%Fw5fSX!Hv!TrEH|WJB4mP|2xoP#gn2Z+TpxsU+p?<H(%JRYMS#^FS!k;r_1}5
zDY!iojo~yq_TTEN;`<wtb8k&|d~x{r61O}iV`D|8dHbB+DdiccPK&y@iudA%BDp6g
z=Zil*RlTq%Q`|zlw6(X8O)k#9_qdYzpR2c+uWftx;);p<yt`FxCQ~_YyejO8XI$#U
z%B>zg>3r0|iwAk1o}TV-YVGNYNfWr|R$o*8d6>0!cezuYHsicFo8IeQ+Acrd9bYId
z7;r4^_{7cU6Q}OCsrqwQcBhQ&g|)uIEqAS3XQ!Wg9NMNiNnZB&yU+Ow9@Q<2m%l%J
z;GU@Om8#brpF&SLc=l|+ozLQue|uv3&BgB9|1aFp&HAVFo}GuO>#NI?Z`6J>Wm%+d
zQT0sj;%%m^+{IO~>yip3mY(X6lRVs$F=66_^Cd3Vb3ci?eimDskUpQ=)q9%5SE;Ru
z$#cb7xh8Ra?fz}y_GM|^>vt!7O*Z`eFLk&f<XQYNsY8Am2mf+E7s$(L7FRES{H9x_
zqxt-!Bc*k3W*rE~Js~lB#^Ebh1kUBP2JT#>u5(7_!m?!P2X9l?#BCB(Oww#IQeD(h
zm>sZ(bJo-Xm0Mx5cmHKHGMPCYxWFT(=E8hdHzAqHW@iCY+fnNUd5PIiR^Q+X{jB=n
z)?W{c=^tD+w{3keVZDXd^UZ9}Be<@9mP$OlW#*0ISCU!VUUvrVG_`*#-?7nMdzS0!
zEAES5{d_RzK5Odf(6;cKdrrjeV94=RsVMrZBe&$q@%UWt$rbud=XALq9etbb5jtZ6
z7ejl4c>aX_ORRfN)Ouad?X+rrJ7K$n-IUcavZ7qK7Z-Fg8BAAy{B3D6hw193bz3`*
z?Y`nL`_;1@<)`Jjm>=ISs&q(u^U~17vB+y*sfR*~qUO@f*Ap%{e7?0}0!J&`l4*-t
zE(CB)4Pu+=($nTFmX!2;R)8nVhHZvH^SN7@yo&UvPEvk8>2>Inm`p3J()q1B_s%-3
zpzQkA|Dnew1Euo;lZtuoMYFlNy()FNdOpa0a-4qK^ZCXG`{T7a_V0*Wu<ocNhn;WI
zk*WN`D<5i3eU;4hv(mss>G`B=miNU<Hy8eXAHBdrs6xtbX$;%Sh*rJH*AtW4gZAj>
zS}K2k7P8>~%KSu!mTvC@jl8D|9%b4Th39pOg?6pt7X136wO(#X<1WrCdGdE&{(VvT
zzP{N(R`2Xmtx^k*w-c1Nx;$2Tu|37OZM#nUk_FN)uJ4px$L4J+Ufa}ggwJqW=F*^L
z3W<x(EByAdEL43T;lbndHByS@Rk^Qx21jrui`@R;1A7Y;h1Po&$&02uNf8yat+L~^
z+o`@Wg_lQBWP(AR2;Z;Wtgjqu3X%=J$j<s~^0Vhj=2o_>OO|JEiQMA#H|+}Rv(I2|
zUpF}{$z!%qz=__(+@+S03nvKo2COP|(olIGwD-&jhs}bg4Hnj#Y8+Ae7s>KTN6X!-
zXx%~ks_aGA;#M`bz5hBb=KhUp&Wj6Y1*A=Qy>dd}iLXwdc8C1WIK^()()r5p>|2xM
zQztjGJlXf;pM19PPw($nq!#`=eXzqOT5+<Xb5iHR?rjU|=khZf+GQw&CVo=+b@}Q0
z4W(zfVz|BBH~xAXaC$RCCwDJf-M`x}w#M(e*j`@{{QGjb!@r9z;ye4j_!h>p_T1bi
zTVJ_T@zce`lJ|ei<&J;0|6{zOOz@`C{@xd&JMY@xaxL*&8!I2X?4q8KUeXfD^gTx>
zb0kmEo5s%dN$!f2$GL@UDwe)~H@5b?Smlth;@fW*=BxW>ALD=jVfI4Lqda?^rYW|y
zsKo6wVHR4sY-OaDSJRb+EUzkNJvy+9S-|sB;fn)yHdV7Zw$JJfI2y<?eU<FR#qRu1
zCaEj+K9Tm5YGc0rO)*mG;6vu$i2*CvvP`miPMu5JpnWx@cHL@)nLoTcBfL5)CUkQY
z6>?oV^J#J7S{sYqh3t=x2*ud$lHWeR{ou*fj9E{&H_UZU{`$4GMbqQd1c8Z)*V8lB
zg`Y5*;AkZC_itce;E@fL^LJZ#7++FU-0H<;>SMe_s&I;MvSDYj)8?wFAHH15bD41e
z&yO3PE|Q|IJO4P8Ok#1(Hg&Po=6iQ`*W~o_M%OBxOC1?|+q?4J+In6IRQ5>(iF)3P
zF_QavbkV{1zZci_G3UkaXrHh|C1UCduI>}o7M1!^lfD!PO?UrbWyQSGvry&TrIY!}
zza<-@*IwJuxw|EJ{iKOvg`&^pRtMbFwy%_5IpLJ)`Dv%7PMCb_`^UrX4{t5AX6uu0
zQaU7I!~6G7cAS<O*OKMSg%>Kd&k;&0v^w#WMfFm!aN?^d;nKTHEDGM3sZ4T_vHQcK
zmwH-hd#A+4^?wDXtaEtSbWP>crIWQr9diUbE-YK#{j*wY!mLS6HcMw6xco`?+g#oz
z7nvUC<<0?jR;w6FO!k;FS=e5<gw45rftBMY{gr|jYkt_xPhFzs5V1jN)vjep$A5WG
zNKr|6ey^FMWAdTJdCF5Z1}v;7Ud1~%QLV3CqHTi8zC-us9`D$;H0k!j%LU(ZT3+?O
zUf8pifi<gC@p)PMUK7TZM?5aS5L>@J({qCLG?%+Y$1HYyW4NTMBy(p!zkl=OfE8iN
z6_yeT@x6YpUdx{Rnt3E6@I+@^{gT`e@fG)6U5~Hmb>r2VB!Bs*L7@sy2*2sW$;;Fo
zbD~&uSBW0GI(hfiU9}GnuzJk(UbI8`V$ei}d8MxxPEcfDf6n&8<9;=VA`#B#?5|xl
z>(@V)x#+Y=_lmcWXWe#@T=svxZSR<3_Sf(~T$%JlGhVc4fAJ21DO{d=?7zucHGU9b
zo%ASKA<W~-dxfbHL8-6JoA3PR$ZPi&`29vFuQlTE>C23nD>Jw3^9opbSozcbzQgY8
z7JQn2*RaT`{>IY1M`v63-mr7v35Z*N<>;aGTT`da>bavTy|^h?;@f;a1u2OxXZ8Dw
zBAy0q5K2?{bW^#7`%J)*ivmSL$6qeVS+xD3NKnVU*9)E6QiS#;#jOo+C=zdfcWlCk
zyT?DyUa8@)^;<?WdkI(8i%XO1<y$Uu{IPS^4^TYxU(}~7+{rOftHtkW;Km)cNzQRX
z$?MgAmE^Zh@Ls*~{T6+vjuV!ZA&$?_y$#eY=bEM;+kATZ`G^0aEni(<-Pf_({iB9U
z&-MOw4_({1)%+wIoxbgS80pY(R(txxLrb-H{L^79mAcyInPsu$+R}inbGRod{}s%S
zkgBaJZ~F1jFUPh@GT&)(!t*%6+}$M(&5PP@Y)R5QH~IB?+fL`)qP;UUgoM2LLq4DB
zp7MfWiNthgS^nZV7L`nWOS2Yq2+M9(I=(x6ePZ+?J1x<TP8A1?CB)Y>zLM+fsQb+$
zRIUGKeR1%K`1uE(H9s%3zQrZHyw@>uw}?%puG{2!^$YhDDm>G_+qPP~@38(kmeQ=s
zg9i^q$QDnUQqZD$b3xhMpbnL`iNPypX-qU1|1?`Y;rFuGBN4ssGmBIeef=D+K9dc&
zAKK>odi%la-;EymcrU1|)!(zLN}y3o`pHI-Ln|{xr|1PTJ<WN%A?In{ojpH!uKu6b
znRhi-@XICso!(bl-R+!P*!Q`udt~}>Mv3U=u=nlnZ+4%!y+Hq$i9WNjbMK-bKi?hB
zc1$f<^RPplv2#Vtdd5!@s*j(pj+nCgF3UQzmlc2i$aY=(Cx6Sl<mgY??1Fcj^pCjS
zN^-kDE#T<>w)!m$?^L}Py0s=9Y2!V-IwJW>b_DY@$%_?YO76XFr4Kt;Y(D$DTs50}
zMSl95nB7w0>*HEu-zrL6UTO7+c|N0FXn@y?_P_p@E-rL-j#yd$@O^89PS|#?i`TN+
z_9;4VxG()gE1q{}$HlbZEo@#pXDNL;TRdaecE|I2p&uVS2$Hd`XAVqqexe^NeAjA=
zyWv86F`e6etHu2f=wIY2&7O96wRihRt*Ey2?|Mp?b}23EdBrGR9X@44@6l7KuRG)B
z9Xwp_b!B}#bJvXoiKnZ3xZahy<i|Tq+iiC7_B4)tFPwS!7j6GoWHEJ3lipnG1zpZc
z)AW{JpMSJDf%TR73ck=c))Koyf?k)#yznk~Qnh|hrbX2&sjiTftu@=!j%W!gAJCUz
z)i!nX6o0VxzV;KXy8=(|`Ut-A|FR*#`Rnv8g68E(?>kRdEYxVK6lPagufU}5)N^s=
z^Z6%cmkAe#%eTE>xtQbeoWRvtl{aQ&Md`a1<_oUZXo$MX_2BL41d)|7@~m@<m8aVX
zM4QPUdz_$ps``m~+eDe(S>;ZZw>f^Sx!W(jZ(o2wY)0H!+3n|LoSK#j%k;Dq=!SC3
zxfI_CS-&yiu;864iKf1L#TOT?QH`_bc1sNUssF^`-u2fBBC7(VIV@U^M)yDb^zydG
z=lv631T9wZx#H`^b;o)yd*?ad3ul@ScL#`OnXh4uj?|gQ>K(AwvG$3X$Dz;Rg)8oC
z5}p;l>FB<%s|#;_*V0+dci_kWt1ekLyjj#|EbyuHuc+MNC?nlc{^(9d%z7KcD(8pu
z6Z(Gfu09ka(we@I%j91?`xR}4*7K*<?kIe#=T$PNg^|}=@yk`?8)EBum$$sO5Y6jd
zr@N}@{r^)JH>@wL4-{FV_AAwKX^{E(>^qkY*JkG)xpJo^wARb%$I+cKmeb4JYj$r4
zo|K;YwCdK>#1G9^HEzi!eb`!E>{V*6@z(2S-V4(?%cMPOJ<QJPE4}0L{eH4K<9b))
zhs|#9&#(Kh<;7}w{=wwmfo1*q9a}Hz7N(@uTSR2_T+UzEd0(C*dD(^UM{0jnPf5BH
zXDU;xKjXojlcEZ#=knQqOMSnte)-SAiGP+a`8jh}`=b2G*G}AiZ=$yCjO!h{>%z0X
zXWsj<t*tgX|37bE#)1d!$4{lL+ieq)e&w)T-GgOXtRZY$swaPPWL&vB>bBi3@!ZZO
zcQ4F$I2XKXcjV8<>m9a6yPo^~<*LVq7w@BXyffgsonEGJ?B({BDU&+O{)%kbv*6)l
ze$F{2qVCH}kH7hFYR9%@o8MB?7w%8dGq`f1;=P_rYt`F;y)A#kS(>>XZFli<4qN{}
z(7FFpsB^#5@ppe#2p;MGUU|Mf-sSz*OtT+{E-bDo`x`DOH1YHkm;P641FxKr51&_C
z{qM;4l)D!e*JPatatT~tXvdIoYr(bro2!nWkW86nzhdIY{@tuurn&6ro6?Tx8rv?c
z{QuiT=ksT~Yq#qkALq3_70zqRb#<n^;TMhn5>-?B*QvgnfB!YNbN?ba?lbTIbBFBS
zUt{XFB4WL1(ek?o{~mZhm*=PV+h3L^s{g(Deq?WL!|aoN8L|5><zHOoo~T>R!}fT4
z^H$K!756*e7|fQ0PV7~28H1MkfL2r%8JvMHLOf`Y+<y>!t%WlC;T~JI=8v}>(=XTW
zH)3i&nDC^8W#h(;Z?a?9nm<N=tP4url_Lfb7V2yP%>q8&uB55SDJCZN>g!TT9yaCW
zho6D&%GfXa@#Du=mEXYghjr{X7Knn)eZ6DNyweE=b>d)g&?3l*xaSoOLGlL^p5T~-
zbld;@X7G~7KaR0lyr0g{u4MYqc7yR7o=W>Bm4~8YzB8LOn5CCUK0UaDbMeE6C!U>6
zGLZQ17ZWq5YM$+`uC{#wb;;t(^7b<)2S<OIVIUZHZrPsxwhyzb4RUYmO3b{m$ok{@
zNykM_T?tqdy-VO9r&ol?x?V$OtHaYg6`BwJ;MtpZbNBXQv2AvShhG#XC;Wb<uq<!i
ziQfT7Zdhb;tn2VfesbfYhW4(ee~ZHvT7BmpO)#i43~D}?^yg7>hG_-QugaMTzn(;P
z2!5W|vSs^o!@`e&TNM8NT|F!D*pr(cQ?&~d4o1xJ*68~9*zMqhlVWFXmA3D1I+$Q!
zx8V4(I3>Thx`t1^|JlQ*GrhR7#_G@c`EES#xg{2T)sTM^Z_d{GX=hT!d;0|(yIKV#
z--Fh)?&r{7KhI@VaqJeo$?{LFN}4|JX5S$*?aXhX`umeT&c$-)cGO2cny>yvaNV(G
z3Wln@eXKSQ-UM+R{d`l&(5??^_5Qm%HYxDDG!bxh%RRn9%5TD*n@!U;=O?~w<kk3^
z`JPRY(|GsRL%Fy27bLjGYXk*dxoaYyoR-G6Gls9#>EP}R{ziudn{WOs{i+k&<~jYz
zk#g6Qo#z+bUAMFN`Lq5_ZTm_e&zpBsc6O?7VL_U>gJjc0*<XiGR@)xCa&G-Md+Xio
zW@#pe4o1c@hHAKNeb4=T<L?WXzlgb=jb~>U7vJM8lJsPY>WWucEiEl9Uw`eFPtMEZ
zTN%Q&H0b2+jQ%+@{zd#dE2Z;qQ`^dwnlT=B<_14@n(d0ee<N5m>Fo@;2<a%P_G{<e
z5~CkHJ3HH==m|%CQ=7W~yaP9HM()iNp6a#KOrvz;Gqu{%D-BnVZhldmp(M=Jx~KbF
zMg9b7sX7yfVD1-2|1^wd^0>LVWffjf+tp>yWh#>~Yx%=VX6xhj9$FW>J0aWKs8a0b
z)!w}qW!aVfe^A|EyIsORM`}U+>q!=y%M_hHmmjftpSGjmmx*5dzBT*4*?xb2-+g1!
z(S+pW!@D!sXUS#ky5KtN!qR&|YZv_bzPa`7_d};9tXX*4;N_=C{rG)Hetdi!xH?St
z-cxo(`!N5`=W2g%Hq0(naj6w4tkS%`Vz0UQTDwPr#|ymMO`g2^GWYn=lNH<78&rSG
zdH3$_?mrXD6eXwLzig+n@MCq)e8=e@kKYTuCSjH%AuhD&V)GgyY3b9RDnkEW?0<f(
z%`xURW3~zVB!+eA&ByMnyY4wF`OsV6=AGC6)|#+iGLKoG_IAf&bN}N1*)i?6g%=e1
zSy|3seJRU8e5K`|Cd1@o1q&B01X*}YZvXPylBL@%4SlA}S>bJI_%Cc-%t=|hni=-L
z3cpmGna4cqx^DmP^fF}~H5vAEcbqn|`954SNm*4@w8)j~TK~%?-o|$kmbnZ)t{*)-
zypCSC(#Y_g++kh6#5SW>$JTbP{UyCEY%5l$ce*IeJtFU_Bc`mZ+-!eIPUY`woqrl%
zBEQVdl$I*r#U=h$Y)Phbc*gF~r~4PB%zb9izoTWczVgRECm3CJPjlb<XPbw=ccX?g
zU;nMMiGr1^>K*^PmDvSfK5DdDs<qfDE;z=ff~Bxf@J9Vp&O4{Cx5?I@Kff@u|Cw&C
zbM%JNssBn=ZvSGrB;k4g7WUe<b%$I|yT;mfzhb${oxAw7!OKlN%Q9`X*Dk7BJ12CP
zufuMqz!~P*dXMhjN=RGprgFSB;rzVA9Q{5ny9)C{PNa9N<yK3+bVV{^*G~(fE%q|4
z2NMi7iN03yHQeYQ`zGFueRY0^Vdb$Di`m+Rf1kv~R0uG=KICh#FyB^2;os_Y%M&kc
z`M6<Y*?|W)PX}mx6G%HZr&~R2t6{xQb&cVYnFka8e0%ZTruyay&}#DCWpC%dfB(;K
z#aG|#^CdPDwk_P+wPlOR+WvzJFGNYoGP|*NW=Tucm&8c_UEwzS!jk#3X04k1WATzD
zOAeem<@I`P@Rrp6WxU+n-1l6oFU+#a?cA_s%ahnG?c2ATyY))7*8KeRQO~~L?%d|(
zxo-V(z4!K3AHI8cZuvz%kUs8N*S7ZReVvx2d(}R--*w5)&S#0SEuGt%0&}m2N;*CE
zyIuLN_H>+|cJp*yWzpSEtru2>YTtW${KU*!C1{<;V~V|^`@BB+n?<FJo}5+l0};cJ
zc+1l#uE<@TZR+~*&Mo=*6Gd;#*t_Q7u{Wu*W@-A_f5el&r7SX-V_hORQ8Fk+uaQY&
zw$<Xg-)aS0FTMX*pK~VeT0-)-O>EMer<-oEO7oW~<(zz6*QsZrt&FU!@lBnAs*5FS
zc0D>D52|J@+b#D0onexyyu>X2vIC!Wy3et9>GEPlDFzZewU6U_ZIxdeN$k!LZ2SJI
zg-_OM#rCqdw-(CozrXOX{EVlYWn@o1eY*a~-Ul9U9qS&e)gMVPD3ZGNGb`y<*H4Kr
z`~6Kf{I!?5!OVSK-=#ME?iM~{37%u;Kde7CZ{u3_TV)w6i+Ak)u{ugKB;x`n=n%0D
zd20i<C5e{2yvaU&@|=Lvw*2)+-?OR<IhH+Sf|wnqH}&GSQr;y$<~v>Pl3Q_a(d;PZ
z-{n~yMxj}c`}Zk7NDq*i`uXp?V{+<Z&Z1JM<P9ZwYM<_A<3D+HrH5Hz+xIt9BX&;8
zSv_rW=E^@GvTku5WKU1JJ@@_=?!yNdn2L-4H5^QM5|Xk=#bZrZ(yvLOS-dfOlk`^Y
zc<Q?M8E--DS(Z7Rm+opQ{c6$D;kope{f9DJ^TPEt(>G2R`YEOLx+vr2(<Ox)%9_LN
zw2v(147_rYWBsASrr_<*%$>ZItgHW+UR*FE?ZWm8JC#n|U^wZey(7x&q4?YtW&htU
zke7a$AXvfHJkfOD=^Lkm*NJ9{a31_nxVrG$o5(qL_prDN<vz%q-?;g_aKPdU$A3P5
zU8UnEUeb4a`OR?V&P?uaYd}SBU{TVJlD}*IcL|wVFIw@^muL1~*R_r9;l4*@KQGcy
z;Xle7bbW20fqDJ1e@Sat7wc^PzW%kz#LM%h3Lkd4cy)78(hQBr+H>W))7|_999kA<
zn?LfMCBww*Uh?rB=flUvJLJ-P`FvN`&A+-L*>9dr=WKIR`G5=iH>aI-dU|T=)nMin
z$*9G>-OX9g^(1;E{Puqjv%c)V@ns3aErDz27q0JXa~1ctyZDkJBWdyF^%>Gq^&+u0
z-F|`#SF3J*u{mScg>4oWek{&(z8&lm@WO=M<ZSluNE6))E1lJRW;E=n-2Bh+#(CZ8
zV$E~Cw<&j}ls0y1SMk4X*>Sr4LHdinYg@fOK7S#;yX@_uZgKr9zqjYzJ#=epcHjaB
z#;?_<jY<N)ndcvf-NSP5fn&)z(XGaN&F_{hY}|Dvdev4F*{teUOXkG1UD$E@RMNlu
z%)G+2VSZiqR=hVK9qkU>l;XK1=jNpHzlQrx-{7vUWl~>%JJDgj)Shmh+sl0&_qb>G
zya<_Ee%W40Sy@nCe*L}p?Rm0R<?ni4U0uD}ICz>OtC>3&&&_MO29ma2`%1SOi&}QN
zEShY2?#1fGpE+M9^%+}D7ZtUNO;M1lzoKxdjO|kDpTHM3!6va8w{I+VQ}um(Yu@q+
zPOek)o<+&+_Tuh*c(^_J%nZZ-2XF1r+Owya;rqR*F6Z^$_wHiRku?-HTg(37{jFPb
zx9e%|ss8R~J6)yq+-29t>pdnaz1lKA)x#=GFxkKGolQ?W&$6(tTan?JO^dwuE|v25
z>VJD`K-P<kHfy>K0_QGxcqvrUNxSvdI*CgL7c04ngCu=;pDgvBz9{43B758O_sS)!
zB|q{T>}faWk@9aT-&%4;YBNvcHPMYZ4_QL=7X7~~K4oX|^Hsci-^>Y_soa)wY}r`@
zdF!_Fiyi&z)Jm4D_Y0rQ^g7GQhwJQ$D+-s6vYabflpO1~%I9+HwqDz)9~VnjaBp0^
zHEP$>E1pyDPnM|=+xz>R+sS*MFB+cr_L;epGm~{z(o32ADMdd`_Z^Wn&y%V8_GaeV
z$y%$Km=$en+0vZbKj=v%_b+pd^;xyXd+*Z8&o6OJ(d)5|^%e2uRgU#L<KLT_Yc6rY
z;9~mIEk+eTKRqodF1~zj$*K2-#cMjY{x)m2w&g0VTJP%ne(H|Wl$-j=F9I{zPURVG
zp1l8X**UY4pE_OZ=DE*b+@1c?>Ys+CZp?pInSbIp#4?+jcZ)yx*|q;d(IL;0c^jq0
zxB2}|<+0^5?b$T@%)NR)zxrJja^3saObmXkzxw>I@MM2g{{wG})eE0|P?XvCg>9>}
zX+vR@M3Ylf=WRh7zP`ujK{qzdX}7WE+Na+4_`^bHiz<7;wX;K7O$?b1GOjQ9@qu$s
zm)}E>GM>Lr<9luW=5<t0U$3ZPCTdhD#iAE#n0zQ>2iIajQPJitJvl!vG#*Sa_#(2?
zf@{0pJ(r3uiAi5fW{BkXStkEF=qA<lVnxIf@6G$Sf_ArUnq6=DjfF`uM`lif%7q%)
zl)2}H@BVw&%gD@@^kBii6;D4_>rFnEU{J@;!sb>`P}ndbc!lYOofW=cUR-Uzejske
zi>&kW!8-y^@0Y4(OKZK5e8$5>JDg)%S(!&|vE1T4dmp~FWt`0)dtkQ4wbn$AyJt2Y
zPB19xpXr?WMb=u%lzaDqzKnz$cWYnqyY6xKJ^U{Cy5OW42cc$`*DeUWvRW_7B)^Yu
z?yjT<4-QJ$tTE<cl7D<|GQ+=~`y$NDE|Mn%RlNf8HG|H6QMsnJYv!rug9$H~7*Acv
z?0M$GY+d?OxVe*!@8x}-mHc@RA7*dU(`i0<p?=@#8{YkUoApGy7uK9^jM!Rb8g_n0
zpXu`R4^M66ow50&(WIq+I`>O@1q-h+?>)N5y4vvlH$9yl^$gMT<{q4tuD<c<(aN04
zDz58?O@(I}N%X`||8ZSCaKBIDm7m2rVZyvIR+U=YV)nOP-aRe(=sxxnC)!q8OY*Qe
zN7qc>xLjztLryeH@U%6DC#iaGNa^LDC3d>kh&M{{Xt^$*UC*QQfA$J2OHZh(iqpwA
z;5aSKcl1QpTZie=h5{T4A`&aY<z|)?OSi?vbS|8JJ!4z3_r^yT4Q)DVTG=l$&gy-0
zJUv6rF4aKdSG$fbW5KEhSG(-1QaiG~DutX&?tkSgb@=^*q!=zQaI)k1`*?TH-Yqj6
zG|t`)T)t-Qv4bZ3URJXd^g<cTs}-4)wr0Os+I{J2+vIzS3at$f4(o3=-|BRJlkdg#
zCB`M%HyP@u=k^u9O;1j`YHzsl)PIxc-gg?4PxBsU%6kxTLH4XzfvlasUjm;Y&+|KX
zm*0H%=3vk5-GcMP*eAvu%9j*4ZEv#pQYh=1-mUiDw#^@RPZp5l;C{}vBCcWni`(l|
zxMrW4xMYKaU9lw7qe-UkB3-6U?CYtYDfA`!9}ipeM9KT9Z=PyiXZz~ymVD#GQBXgs
z@5h;go*RX=ZgdwsbLDz9t>p3fGife?5$4GPZauP{3x%gETIhbx<jc#C>^OP4&rx2@
zaY6i>rCyhRDkq6cOC3IWh|llYwpnKn$(4SZe(;P{t-<Ch^Rr>g_1UK7HfmLRFZ7!C
zXx7=KER$3+XH=CcAB(-c=H`iiEz;2&@Bf$T6G;9jaI@@Z{IQ+o{6Ci)O7P?cEGiS9
zvT0{K<K(c_rUlmzeXMvBz}BjoU#NVGW9!{bRtNXU`19!<lK<<L_~8EE!ZYtbTlze$
zsLD8L|Ia=C$ftKwLGxr?r`xj~?k^QEkm&LGp_klme6m}xc>5!LfA5yoc4emk4({pa
z-LL-n_QEz(Y}T|5kI$d+vzT+=fLA>Dbn?-zrz?8cXFMyGkmv6WOjUXK<CozJ!x}ZY
zR#oTSr?s=E$2>Dz5x#-xm8iz){HGhX<k{zBS;}d@=Dm=^%a$B>cAkggv6P4?nM0Q!
z2~MBLw7(^wXXiG~#p~7`*SOz1>+K`0H_C2_2}u@Ala)=QgIMk@bNTF_Vjyw9`@%kz
zXKQYCwEdjIp)NHeC7d_=nQw!;oO;g;OJ>neDY=pdcPwu=sQqo+6TOS+b9L3B^j{%+
zeE(j^7Wn_iU|D{3)5at92k(nMFizHL3cC0Ec;dm1gEz|W$)9>3RKnK$arejAO9KC1
zX-r$UqwUz;Ux_a!C`#CDkmT!=>ypjaxv(j(^52>_YJB1HEQ^EYsu>8*T2MH5RmZ+^
zX8Cf7(@OIm#VrwK`}&W&?^=^T&%yH-k5$!_^j<!H-SX@i-PL>ctKZG=PMmM#Yq-TJ
znrHO|w!_*bD$&tjv~TnLJ+<}1pQX|tgA29RRF{ano;UYmj=%rJ{mVB#`dIkG#*S^i
zy1MD@!_GV8KE9Wq6d^J5(3G5A4$_4)BzIMvs|K~+ey;h?CmMI}R_oPhri<(T3-BzI
zy0O}3+L!nJtLIoth3Xxf|NZlxeNVX^58hhwAfe^XRp|q|mJ-(wPp*hRF#pHlt!i3A
z|6{JcUR>a1P*eF|oqgLwPOpVwtkxd?Q|DFZ>Nw25`TKh6tP`E*Pjx0Pdhsd})Y)BQ
z=YF8}cvJSIBkB^Lzb7mSmF0W?D(TG34Qv~KW+mUeb5UdUT2EKie1jFA6-1;rGap`M
z?O0T<9d%|;pDMfA!XC+bzVn|;g$<0iXnZ^OZsoQ(WhEs6fe$aY7+9CRap;$`4Okns
z^-ZMmBo`ZTarU3v-Wtf+cCFjDrfk{wX<kbW%&-58u=@4tMbpg^!K!3t=TEa&EI!u%
z&+e<6@{`BrYaSImIqU23MCj4_jbDR}gEk!gZ{>C4=~8CKt9fou4n6o{@kJ+6ey5J?
zgozUw7hYgcYirZUnJxY^*XaGWpi}np0WLiSexBR%)i&2J_~<UYZJYR+Wfxqp=<4YF
zP=4z)-}Q3qwxf<}lUIr}o10$USLi3cce%6p3#N~^TKfEDEsIo+^~rYcsoZQgvs&il
z?vjNi!js=;PxR*9*HTxzT&ezf=8G4P+A}|wJ3hE5=e>;IW#gU5`B^WYeA&Oj^`=aF
zT8ZLJ4H0GQZ;g*1^h(6*@4xl`OHbYnmHZ}W<K2^NWZEvuRw-UTQ7iHCSvzBJ--G&k
zvtz%GW*a0OPYl__dT(EC_k;-oU$?%$xuZ~7&3|6cp;qqIm))l+zHh1i%+^)>Jkcb@
zK-7M#u`j<#Y=*UOK*`GOA<Qe)I9qSMb-t83Bg1OJ!%MAfm!4l(d2&nO%O4U_YMm~N
zE*nMM{^<U=r%vM8yLWxlbfZ75vp-fYS)C=4C~<M0W!e7XLx)sXe+aKFzvt|IqWR(7
zN`^aa`G+^m@;k9(E9=_lcMooAe*NI%Ox}X}s}VX~T79;AHhzC_ka>=Ex!>cH#ZOO(
z`ph(9ovIxk#vM3qp_`zlL5Owv!Gt3p>RbBMOsf9B*LB&%R9m_w;s348`_e)pq=E(i
zUE%VXwnWkS<HN`N#tRMCx$HgA{lh^*Vy2VY)Po%<AxpiwCg;m9ZrseSa>t#uEr_pJ
z*!zptRgdJ9PZC1SmyVtiY<p5S-(j8T$s>ObF27)K@xEWH<L!XJt4DV)x{!YHkkjpB
za=JO0w=Qg35tMPz#XMK~nTalFuleKS{r~-YY)w!4U)-8neJ5nfK`nXtEjshtzn`#5
zfBxl&TA}ir`CsihrYO2(vn#xR!7C9ND}3$q=YPlAw*0zb|C^s9WTC{}LJcmy*-SU*
z-RxLpCid7S`9kUgubx{~9AEFQDR}!z^v<qQ@7lN3E7;b>>=atJZr!W$X{jqNI``OK
zZS6K#a7^yxc9GbnoLzcfr@a#LZQt@}q3@TKJSY8L6t7sgCO0{9dg7(4n=_7PUR>m=
z5xHqeS&yxs9RK~v(*-B`^)NUaYaCvm_-dAM#@%`;t(_bJTZ(E!^j;mAKlkpEgtYU0
z0Va{nFXwVUzPs_~i|y8oyT9u;FxMZewln``)a)i=`X%e?s-wG8m^nF5+}I+SmhASK
zZ&r_2bitZ6YbwOwPMS4qmEM*ud|Ue~Z#VY+Uo79xVJBuQ^lt0<^9L?9q&(^8*}dY4
z#*>ZbTrYLAzjso29yK#+QK+K+y@$aTJA;x1B(uUpG_AVro7T;9&E9Gv`)W~|cWa-R
z&#nwf3A>sdyGr%r_toq<eg5;_WAkimnWp>4xzF+8Ti7XiM87ZT)I9MQk8K5Aa~q6G
zr5BdOZJO-*E?>S+@;djUBW;NdH~8zfNi~*b^Dl@M?CrC;V<~ib-Lu1;y-Sj2ew4a<
z%im%4N#&0<)A<+membOJ$FRI+{=$a~B4-#s;(v1L$hr9@nL_`5z1A;%?ND}*mCdQ(
znT<h;!h0tL)vl%xK3?C_<To$9@?DiC?z(W*^|V~B?j_e586W3Qo3>0icG3IJFo&(N
zoC^{cz1Lbk_2B90`t7r4OGj<ZI=cIh#Gy=<y8qlEmn81&`^E6mNjT{Cl!FJ3@t&2s
z+Pt{4N5zA$kCp3ioQ6AFI*0J$H|H3Zomks-q%S%ALD&Vc-{tSz|4pmCc;+r!{(ZLt
zCl0Y4YnvrDDd2vx#r%YR`&l7D-&4|#E%lxrupz;*bgkL$fQd&|SNxH1GhOvrZ&uH$
z)lrh7R=1*-bicC-Z1ebQ6SaA1@R=uDOIo^H54ZQqY}blm_3dE1z9ivj{Whz0PbX>#
zI{K{(T`}d4n){}Zp4j#49^`zeom2aLLJt3x-{Ma54@?kN@YHfzqau3orROZ)DGZNz
zv`bf~d~<Mh4FBl9&~1iZ)VGXZixV%qp61GRy%MT@?&jw7tA`CXIY(qBdVPMeJ*q!7
zbK#E4w~``HV*C`FHwJrd$q100*2JR`%2uEm#PN)a^U0E?WSu`hPjx!$W#6&bBb;dF
zDo|g>{w}KG(C%1S759CvU3WTOgz4R}+QhARt#x8Wo_e0-)Q0l!dKs5C*+!XUw)|3E
zQ~2kRcTem#mUr<Rcb}hQ+5GA0>BAQ<PAorZwdsn8&A0jv3v=;F{*$j(n(C;EEnG5*
z-B~fmXG=6Ec=-B)>**=$P76dOUIrJHVS%~dZ|va@_S0^De`n|7xJ@6^wX^@<+N929
z-IkbKYnb<1NaU=~=}^sxOPkG;Zu=bAvu)m<<g!Hve!lH4cv{L8<7IxN;s4d<g&Gpk
z-|sq{HH!_n;TT-YySI=jJb3Ph@Xe><O~0j`o6~t~Yj%3}>3Ldue3Q;bC)kzoykDgG
zC&O_OxA%NClPK-Y8&6i9KD2#-sp>4x&BlT5LCk&k>-qn#NI89Zv&ZyKMU#ITo3)<o
zkohU}_KwzMrzeZkxP{o&+?KtF+r;S88gG_<fj?>=oA0kJVavL~gP<$2XWx3qwkSC{
z<JJY&Y-v%eD1(cIi*L29^R&*oqA_>d8&})7{*T&88#7L;q+}^+Ivei0T<}D0E6?H8
zS;wyb)e-#Om+<mnwZXPC-Sd>$7Oz+;G@bvwQ=7N1$@)iaCw{wcd~zUGB68P*_kzwH
z_VtR6VxOgM^WArN{BCdH18v@2Tcr1tzrT0$)~4xF!i}uI#hji-woOr+RpQ$#s(8^+
z*_b<GMf5Lwtvge>Zp^y<NWcHr%&e`PCvP{cU-e`9i=h0K*Mk0D{`P@m*8B{)Ypye1
z>|S(h-D;zjV{^Cl8c3<#>Y8!+)PvO1(-sCSbh5v@>HGR)^K5>~xqX|_YVw?E!-*>r
z;Y!bPnP&ONHps=XR+|59k*tn%mOgebeBu3y3q_BOXTJz_l5h%M)bZQhG<#Cb(>X%Z
zo#r{Ln~-@dXkWWbyZ5CF-4aa#H8s43Ej?$iT)w>`eTC`ee>WVsjK6I<R-gE0=^ktD
z_y1NWM(kklG1}_rA;mpq(f0E}TQt@z?Z3K-GgqQo>pz3UoZT!uvIlm5n2@6?c;cb-
zryraDta7qCIeohG{8isS7HV&g;Yz=4qwzYRA?9=BypWTDivFBCBI@iq+V8k6YB&(`
zyK;tPb!0Qh?W>R7s}4ER@blL8=v#S{&g#wBINh`)^UcK{i(}{7e=?mvNknF*>QmXe
z=@aKn{FC``VUUyOJ9%|K#i!jYZt~synjJB3KQEpcebk>@iEHQHofA2WW`EW``A6Z*
zjnh*9TQ`1}Q$2ZoCb#O}2_C!eR^4nh>#==0+kC=YOYY4Joh!tB%jdQ{(av7IK3hTd
z+(b!6PeBXuirFGM^S7SRUgDv8z2m5ge!U5+i0^Z*nIdz&%^Qr*PM3ckxrn_@<^J={
zr{?8lr@cw#1>w08)s~DPMy>g`y0&o6g&wLOzn^r7OEPKedQ@ol;oNjqzK_)c!X3wc
zdLKS$G?}SIqATv_=>x{)iT54`FHth|(J3`{WikHtZ|?kGQs2ehryrB^6~AfgFwaj-
zexjJS*INE#rn)y?9#;@wG+)um^x5S8!x>BcG)$Ui_ZnZ(p8EOjng0u>EZ!HbDzY@#
zua^B3k7P?)yu8??Sc7E!Y=dO|;u#yKv(DJKT(%_jO`ysV2IIes%x`jwMC4q4HU6%U
z5%TxRlIdf!ckpcgGk=>wfJjlunNXQl+0Qk%)*emv;aYS`PxZ&*H3xh4<{$3a`^Itl
zvAAUuE_rL6Yv??Bee0tWv!f?yrp7-xY5q}hhwN9W);AtizixDkbe5DZ`oHsfQ}@^Q
zpDru)F7i)&p~C3;hWo%xCuwbW!({!{AgArSe<Qdp`Sc;)j<cb%Yqe)jbUH6}Hf!2b
z+pqFzZ&G{bWW2e!Wd2?Gj1&zIM|bXN=M{J6yg#koA$Z(*!bx}K^T|w!ZagOr_08<9
zU0Q6Jx}bF9ER9c7!#I+Y9HOK?yJ^c7JDSV(Z1^#^$JX^#_L|5o>>4*YzIJyBF4Sph
zn`)GQ^s0N&qK(r-_lllYov_kwK8M^6$%pOLiRTsmym(!&$tix-VWAh_xd}_8tqlJ@
zU(L00$_A5-4%;X3D*V}_I<ftnM#7h$Gmf11@b+z<y7k-Re#z=c<>QjoAy1y2iD2B>
zshVf&d32HK-VHaa`E1&Cj@~c*`ulLtcWAu4UU9@oVn+HsUYBr*N`bFZOC%n~+C2^2
zV*jpfZ^PWH)0wYmF6<Q4n7rG-rbt|=Rd*-%@?Rk#o{CpatQC?uv&lU6pWd-Jw;#Gb
zksHLHsr<apwe`TNoxBFw7pk_*-_DkM>c#hV$@huJ;>0FS+>^N`lgVdN#{+TsKdIWb
zCyyruJ+%J$P48m*)9Jc@jtEpv6zSXVeWf)q?X>@-*SamsGUjZ*vwvGynm8yoS)RMW
zy?>`n^Ytakf8RWlu+G$d_9mkFx$wUuVz0N|FkWX{KdtU?&t6axS+n>ozll>&a-rUf
zzFpOk>&(7cNX)KDiO>?|5Lb6r@nh^U5{!P7pPJR$_s;aE+}iV8nx;}KHNIB9R?d~U
z=&1duKJ$&OrG;E^jdy}?eL7EE5$kTVvqzuJ)BUjHT*Z%){|4um*@5hG+&b-*ylKRy
zLr*WLztVf+zidJk|HUu0jMoFNoRNDLHnT){a?Pwo6OsyUJ~LRhwmaV8)7}dlNB0%W
zD7nvb-+I@J{p0bTy=xW<C;N+3aXKG+>pHotwD8LZU!M6Fn6urg7x#QG<H`S%U6Kro
ztQW7c@2oF<tmf_NF>y)#&07oFoM-7c+g>zXo;UHt8}qCshwhz`a?+A!YkRdmWa^We
z$NtY;rYx#c)SptKv7oNMZDvp4AIX2-$@<?u%2nuBcKDs`PP)ERz~}3_X3xXV7hPVo
z_eE4(^lFY&eNd3!Onp<^%`=nbV4>iK6DI#G-hAHQ_hU=Mq`yWNlO~Dtc5F<~Pjlt|
zzW!PARIkQ!s;>^6JkzJ|Y}ajHv~t3e=w_d-kDezSi@SE==8U~RCTK@k<TA${^G--k
z>nMudW4I}H>v}!^W%)3#J(;pHJkM>9%O;hnE7}9@wysuql=ZD}SAf<B8%>$S!u*Gi
zUUYTF{eNt`=~%sOn*NiUhB~u0^BzoMj+ia6_}zk)FM`#7^Qh;7qGh3Wa)0nDg_9Ew
z=y1osn_vBX!V~YK;aX)4`8R@H)Z7mpyA=3$-@XV&cg^<Row`|1bv^m^rF|&OYTmFg
zyYk<U`xCoVRo?L=I+*1i>e+kdr(UwY-80c3mDa!;U!9vezE^iF_iS4cz4wiN;s--W
z>Gt}`k;-pZdTWbR6aJ*Wo*Sa5{QhD?MQZ<!|K-Q#aXnnPUeVy2LtOg3PJyELY)-v%
z12)G5-gDib2nwC48<($MUnr`@nxgV=#kTZijT;}Oys0g1HJ30p{PE(>GL`zvnuQ@p
zEY9RiV>H!L4RQIrOMD%3aj>z(Kkq-1lhQ5IjS9c@FL=~z8(ZT0+#*@u?18{9zB}Fb
zvdb2@25R={&Fk}wmRodx&QXaws~&~Ft*cD}UHlxmS<U!colqKRLUd)(wIA<$Z226`
zuO&TL^LxhLY-6okZV9*7XwIlN;SvtlJuZK>o;NxF&5eyee!t&8bL02PPfU{g53RJ=
zx-I?b>G=Ok3QCXqC5xmnUA+0WZn~nF>fsAlm=4uPI$LR3dfArUcrC5lb)_LEbPHS2
z?DR!<k3{?Q*cN-geI4It{7pl@?~Lnt%i|M{n~M9Kxno#yNaBj#$3#A*+9wwlI)C{3
zHT3=c-R1n;Vmb~>y{2ACnv$B)=*z{EcRi1zt@`q|<gLcFKSLTyHX7K}mWD`_eAM|R
zleHwHTCjkt*PhE%Z>#UJSc#}6yKXU&D-*7&nf%MRb)jsb%feVS=+sz`q%oVYnvcW1
zJ@?Ij{JH<*V_uBrx|}&JiP`TL1=MlRc)q%8;^OwjPK<A*O(GL7FY~SV^<`z%|AWo!
zuO2h8a{ZZnd=tyr`HYMY^x~M<_?sH8heB3${JOmKUJ&n+U(4T~y0t#6ZN+t!|82`8
zr6rtnrcT%)Ji+46u638M9SL^azHmv{$?#lT#-0<OnN&ZXn6R9A{@PBzbhCgO8MUQ6
zPi5~0-cS-ZGMbt8T=>M+Fg39cMVgGw>wV^aww%OcDB|>~d4H1U#jp4FpFZ(R{LI<2
z8#68{P0<SF(v9BsB(}b%-u#;d>!r(=7CzufNXu%GmTq78`qlLtMITh8#0{IK7`M#a
z_>KF?{8qE4m!yPJKR!B|acj%UU8V2uH~mq*FwOSmw6zA(#<R*Vifs8ZbJvQiL4gal
z8pU2=$c(wf6n?uoThrv<3dbdH!(3+ZWvulP|LDGOZO0Z?pWCgiE=qyRd9?&?wQYNF
z!DM}R*pY{a+gI;aD!sYs_{t{&OFI_|aU|xgIkIu5t-+HmjD52A+PQW<b$Qa8xaj!l
zr58=U?<=yd{Z+yvXCvX-ofhw{l6!OVd|US5Tbqu*)~c1eTXON%YVW;Eqr5M7gZfXP
z)@+I8zFxcbV|VvUPP1RstF)6vsCCMl+APsa1{bg0tAEtL<h1d7IR%Y(vO9d9S^Q;L
zG<*8t`3tkwIc+$x=IRGyi=8}`I>n18v%fVwbH{4wXRW&R4}X|uRC+{z;}X|fGk2Qp
zQVRjQ%i&52v7SBY!V%FDkKSh6AK0hyDMET-Rr|h-=%?3zNKG$&oW^^tcXnxndET`j
z`nw8`7WQw<d8X#Fip9Xhtg*L~YyF@52bBB^Ehc=qx#YToiN?o^4tBO}rH|8k=iKP^
z=2c$xc9)iO#+}T)2OA<xB3~Z!ov`F#XpF&*_ZKp)iX8)DROF7bKj>arvLe&<)W(yc
zyZ(KtdL_Sjb6(7eO9C<zU5qx&tSZYFHZGnK9eFs6J-arI{S9+3xLO32jUVIddsqAT
zyLiM{<>>TGoTR4q^0JJW*|rU4*Xy#&%MRFGI3Wcp`*#_AE4dlvdGYG3=aHu0_N~7n
zsGe}}MV*B0HR-ih-w%9hoqTaeUGke<(#Pi?NHCDF6t4_YP~&~o{4tq*@m2Z18<Wm)
zTv>ac@p)6wPh$z5WAEA4hIqf2equkv{nR(E`);&v{^u95Gec_6sgQ$5Ors5!RI+vi
z&A1?0Q1UH`t$E_)%Gy$Cxs;G&uPl`Vm*vRn+}a^oe?_C^Ns3`T8))W9|9<M5i#s>1
z(LI|Gx4=MV(%}zoDLqy5Tm_^)wAnxY-tw*fH1C$%OU@@4{Hx|^aaz>)Y=d5i#IuQw
z9PP4M;%8eIm@EDPEuvhwzh?Tz>C02Nr)>Um{Ml*6j0-yUWj-_dwuU<ethAcT{rtP?
z#S>DmV`hJJ2d#vB6u4CR)3Vru`_zj})}*#Aef;b}fCJmAY5IregBF7PI$bVVJ*QCb
zk8PFBD(mP)UdJD1M6cD*GJW6mZ0emK#&!Nvm=q`VY_aD6t;yNG;tf~whaVR;a+4d?
zYTXy-MTTE_c|o?+=1cXuz+B}gAqK&hUg}HmwAp>;P3~_tQI^%$&p$9pxBp?>8OfJP
z$|kQai5@FAOTIJf^PkH7>P$lRZFAC$QrVg(GAkbIanU)n_AmFwpCu+<Pqw@5IwF?)
z@4Do~-_MhuJ#_!mxnKR`F|!?s@m=;w1`@wc?U$}T#WUxIfoyTun*$pUOB?2WvGAE^
zBB$)ebNrux^Okkdt@aZSCKwbcNOIoToMSUB$D*NmcX-m58y{!b6zW_&Ah<*8eD}4u
z{o5A`Cnt4x@7$NKSi{!*@&3p6$L3v-dE0*G_$*%Qf-gVhe55T|{{H@c{6OO4jp^sr
zwrD*+F@J^Yl9L=<JWh+AXkTVLwW3}@$ar7=F3_>)Kl08LFFgK3G-7|Ld7s?9u8+>_
zt4s?%tdO+WP|KRNEA{!GD6JND_D8WLT=jn}-~XNbGnseQ7Yi1lUZ2x#q8I8!uJxWy
z_#;(Qd`52Wooj0Th7!x~9eH!}^oGR4Y&x^eI6rTj<FIL3x@@4^@5E;j`8x4?nHIbI
z9BS4$dnx^W;ITc2bRO-``RdgpWhwYw+5T&~fke+5CsTuP$MTLQzoct-LbG`1m?!eo
z^xbP{u~$D`pcE5fD|a|;-JvxPn>W0>m2NC6@V`4-EosHAdV_0myaCqfEcXw+2vpv9
zEM3s8Z+<^RZnshM!5^wW*YTS?`rDT<@x1Myy$P0LdNCcLtJ4*}y%1Vs@ok2^v$RG*
z#a*2rx3?YaQayd~oGIJqus4U=Uvf{i*j6X@XH8V1>c{sX26CULzyEV0-h4$wvr_ZK
z$Cc%|#@A%J4(_;m`ij(!yo&;NKF{n~Yu^0Rc$3?Yx3LjbdaS3-bPw<1%q_^cShC0C
zhk=~Mqjz~awzF4!i??4X%cnoHcl*lB8=JEfm!z^Ke!OJ*;gGY=of@uPCf`^5G2~4#
z_%i>!(YGawOd_6YHZ6K@Z(~~Q_H~o%1ifp|j&l}P{IFu27rOU~d#HAJ(~GOYF01-A
zK305q)x3YY_{Z<{T^rVO@W)nZ@1DNWXwm8RnKf4D<zj<;G_IUI^uokuSCv>TAMb3v
z3s*O1boZ`%)bBKZ>D#53G<Nwk@2U~2jsGwDGE?b^-iyAPngG_mrGYCW;+CYQod3;J
z^F!cS>uM!?&P5w4Dn+KMKPq!kde6;bTf?&1DKwzrhxCr>Lvw{6PW!KH)BPY|saNDz
z%dMxTyZzYg{^M52_mY{b-uTrYb8}(t{cp{C<>}@Z#U%^9cku=Lb=!j$xTY3_eSTNI
zw)gZ>JD20TWEZTl7OD>^Y}0tarMBLx<ymvu;wnbzkc=A=a_4T^uy(32FkADvZTx8c
zAoeWhrQOjNbC&5(dvm{OQ^|~;C%kOsQZ0v)w<TBbrk{A9?>zbC^o^e`n9XSU@%Y-^
z>RG=($XJ*0?5+Ch1ZwqUKTl=%3R>!WHsH{?N6t*kzAwvm&Z>?L=c+9&;dL!8e!Kp(
z`b3W_ol&=6I|XI@3GC_Zy;{GuRqt`X)AbKaUOL@&<L<SWGFz)};kO`r@+IHf*=oTH
zXWLX7E%TYlBrYy~@9XoQ7q=D~H~BC0T)j}^PNC7P$_S-r2N`|tf92Tg=G)M|mpN-o
z7LWPt`Tg&Oga028+j8XL%h-;NmZX&9aRm}PIEAG|0)Ee*^-bJt<*Y{^de${)@htu?
z(PVRW_ks5(7)|DEm!8`_OX1g(nv$Dx?aaT$6<?i9wyFK+RQt9XbaRjAWVM9}2b*4{
z&fCPib5e7}s+QiL?7UY(XDtAYTCoNFy<GNi-D!iB(|;?0*VOdd=1SL?_>|;6n-juz
zxnz6RRjn!d@p8IRTONQKJ*J|TOF0_P&wuppu|b8|3l{TAhML;ik2+^ryRYRqy#3=e
zN#kii-R-zPg*`qASxPMq>vnE;TG+Jk!jvmYSKI&pc)WN2oL{pK_Pkg-X;03qNV|I(
zY>V{Otj(E&(w=WJI&;NeT-x`_%$@&VMf>rJ-z|!|Q6f3-KhshZ$@TMX4%YrRxsrKH
z?iy$R6)B0ND9-FKeMimcteDe|Nsap-JvZ2B(5QIP=xeM+k$J1(na*u{jz_#bZ{PZ3
z^%J)ZCsG-Mof$3a-gGrxnb_0Y={D)_cecaFXPe!dDmXEr`t*N4=9}NLbAA4A+Lqc{
zpL;VnjV1Z?qq7z2rY%!@S?^s>cZ%QV^v~+9!LI7ud#=(Q8#ctV9|@0c`gzy(L)HBf
z9_y6{{>d6AF8=0!{L#O+f^WBSa92-rI?y;%qROZ1u66psxVQf`yTx>!rfP)-EOz6)
z=UTmF`SQbu4mH_d(o>qqF>TtkKNG)Q2wmIb#I1Jg*V67Vm)N87uHok=o$mbT=;9%+
zTYY84g7cSMwa<Ncc-XM$iN}-E)BDSRR_@!Ls;~Ue(oE-OvxReTMD)zZwX@g!e;oed
zSFuHv`Pq3Z!{@z|Z~wSFr!ecb1xL{Q1<AWV{-}PeXrj9!)3Bnffa#e0_CqJ%K34Ro
zZu5Jqo_yh$>JFnygEhO}9XN5U??bGe#ObE)<nx;jW;MSr&R87>nlN3`Q5ODpL8gEB
zT33<SmuuHWJ<FWvGk>b^X@S@+JwZiDl6#7tdhOV?Yf<Rxusx^y73a7;_`d(ZffIaB
zv#&buttt&z9Az5vc>A%^?u55XK6VtZZR}!w`(yKF>Es<zUK^6H%W?RMSd@IxT2&_9
z7WI>5NA-VJAK5z(5|<x1cXxNkey;Yu7`N0%@!JcYT|OAItHe__u;jAZmfuZM+PgF|
z?su=!<BIwv)1}vAdyB=N)&KS}x!N{RQ8)W{=JhRly9!qdE_<6-z-9U+W7hSfo6pU&
zU42bHYe}kT)Qn3uzt(=qNqNVz{@2&Q^?A7=|2>$c!?qkcbMbOw;6BbS>(sj|3QJBl
zKUd#=$owKpe*b%?lFn%och)F1&A;!w<%o!!T<gb2SIlDk3>*zU_G?{ZagMs?8mGtf
z`up65sg6S5=GXT<`@1Lbp6X{s)AVz58ka9umyz9Sohs%lTynXU?Nw0z%CHwnJ=63K
zyOcJ)TD$I)z^d9?dd~OSHJ494xIO=V+uXUbckbS;oG$-(x!WJf8&h1I`K@hgUY*~a
z(Oy$po$Pj>jiXw+D{AkuB#*<7w(Jy~C>VHR!s-V>%h}VuWPAK^4tV@tQ{r034`T_Q
zwrPgNYg?uCTpIp5S4>}%m=P{CIo;1;-Ij6z@!Y<nkN-8z3}`)a!{f;E6o-u0jh@EG
z4tM?%&+9t+c=yWcs5`fN5AEn%Dkve-{7pISaer5(i8*K`SpSJj&t?B#VxE&bCG&^6
z8;^V=U#VA?%$d&%bK9?-$Y1>P<x=U4Ki1b$y}ubq@WeW9>HjysS1KcP1=k+;o&y`=
zavv_p`(x@bwJkSb_nKw5Z++TZ|Guo?kNeKn758@Ow+Zv+L~T@fe=Na3V*aP%WAl_)
zt}_V-Zc8z|2U<2(rz|A*IB$*6)UJ$u(^5gpgrCLt+D=trxh;0)$d{Lw?QgPuoxyS3
z%J!o>^IN_zsRj}~|Ajmk$zMD3Bjo>!Z{HhIS6nEyh?;W#D0B(eeyM6EXX}s^ml=4a
zYIc=MTZ(>m`_GwMI}6+_ZCF^D7xLHV{|mE(S2jMsc6%<1-)khn)3)y;Z}NGmrCQ;x
zUte9dzq!Yz`=2o@BWN>F2#>F9;JRDOf4Oh>QjPqs+kEgx>5rX;urmUC;+Y7ZDEMr<
z;kOq?<|UWSN;G9-*Zg(Ac=VF(`-`bNO1|psD(PQ$$YtUAQ<<3o)6ZY}W>jn`8@u%T
zoLT=$zOI=gq1Lr--cs-)`g2(~6(5vr<T+N)65BmxouNnMhJ=Im@s~1%cZJPcca3Z5
z`o49JD_5Halx|$7*m_Lf_4awt!q1GTC9nTx-OgC}(f#nUw_95^OJu!fJuCgVhErH=
z#r8dwpFio@`-3(P^~T1ong281={m!*%sEDtpHfO*U*mP{77LZn=8j#)8T(4N*F9=O
z_U=Q=P8+<m`d5-D^D^jq>CZJ+SBEbSSs9dZbCc@(PsvX*lHXrg=)9xoX%~24prEiY
zF#lFdS9V0i4S)TxKgt(e#6(0|9v$7fU#-BygF{D0XUo10D^(>WCta?}PZ{NN{i8Hk
zSy&dhbPDb1F01_dYU-{9SGNgD%gV0xlm7Yn`SaK<?ny~XlO|6NToIsn&$Zg7{-2C{
zpG@Q4y|(W^eg30&?B20n>5orN3V;2#HhTMmhYuN}qocoW+_vDQqM{;WE4TQw*e&i=
zRlB0}yF@Sl%kpb%Y&<d7db`!#4B?3$Eh|=Ntd)K$vNELW!GnakQxx;>?+abN_sxm@
z|Jib%aPsnAjg<7c+^TnK!gBxltJF)@hp(4=|EW13`F(l9vokaAY|Xy@L;3B)_wUd1
z%34jazofV1z#}#ui39SP(|>+`Uaamn=RyCL)4NJv@6e6j_QCyDvxrE{{e88TLA#&E
zZt>n<_tzpw;FJ5U<n!}v?{tZ3|4@Eg^zaaCABRBwlGrw0>0=YSMCzxQCM73ZcDfvr
z|0~xcXB)NF|5n?pH&0GZ{;B--)2FB2=WgGgZGTBG`FP*ccXxLmm(S!+np3Ro-uI+`
z3-?)nW_CUh<0|JW@mp#d8XoDX1}opJDvcG_iQd*@UG_$z{>$S(X35_&c-yu;$&kL~
zy1e^c_xB5F6|oM7m#p5%sS>-&Ja)nB@}=Dc7r!s*epklD+rRFTf^v2M@0Fvw7p?uY
z>rD8rOI)`?m%r7!^ZkXE&n}(yB}?mf@myZNq<(+z#_$CWjBCyJ2bWCs)ZF55-SxX<
zYnyj?VsTMXQ2F$X+20>t4Be5jeVQImTI@b;X=&-XCE~`L{0=s;CT6Yr%X+V5=D#y%
z&RltTiFFs(^qo6*`W;@Py}~bG?*+46Ji=FtV|l_Cq?pF+@7;KPxxf4r{rGwIm*lp5
zozQptGHc17!!rz%e<;6In&@%mv2cmwY_r@8dn$|nc~oCGvv_s6tE6?A&YCrAeki|n
zv}akk)?(L!qNk@`TwN_*za;j>?xeLH_UAu5JY1UOa)I%G$(<>B1;xe9+qaw7FNw{V
zk#S=Suk32`loJB~Ja%9BvqYPBiIwA5r`s=#e6Cb1-L;N;Qxw~Ovt#qtEzrMz`gFJb
zDa$E(u~x^oKDe;#->T5nS$|(g#5zY;mwvt2skbs{Y1c1h#kM-<=x4UJwm%ooac<=j
zouD1A_fI3;;j{4Ba7)gph37g`4gLyE{}%91$MP3w3**5PJ@=o284ET{+dJPyQ&idZ
z@oBZt!d)EkCSSBw1v*PFubmcpL`iTT$J7|7L%*KBpWfj*;UCxDEH0t{FNOX+h}Jl<
zbJy!zXSswXT~moyF|%}8R8sR#bCS~}zKw6fS6rX?L%de<|Ev4@e{Di!E_p^o=6>Dp
zsJHC>6K}=^mlxLj^Rtk=cv@e0wcMhh=kw1yyMB$+`RTX!x^u>#?jy4-)Ax6Jd7b+k
zxA)KcfQjWwr<U;esi)o$_w@BV{Dph^!B_YHKehfj(P+ljH-8PZe$2nuRLP!y&}W&$
zNqe_N{+Epmrl}?FKc6$Fax!D`;}{8pN|{rZvy@K0mr>KZ&B|Pq_iq`q;hJLJjQWl*
z{fm8ikM%v>T%gP*a7eCpS)cpSn6w?ctL2`(t7@|8Gg7g*etc6W^TQ<FgICXf-uNs`
zMu%1HNAahSE4mB*Hg30f{?Z&gV{@W;Wj2#V=uhE$cV{1XRV(T~wdW->+rec=BPzD*
zFlU|-J~MASQ>Ua>#MF$oi_KOC<ILr^{*%}gGUw(7hTHSi5BnrF@I79>VCHV+C7p^l
zc2)|@?e}(wXfs{rC)NHb&y2(3Y4geIc?ahNFZ|dc`69@1_h<2cIx7|XH>8|2I-=d1
zIBPwdTlM#b$tz{}zv~`sdhEC%?8xFL@tX~IxN=H#DQztKm}Ao!dg#PD7Pmgxrl$XU
zZsZ@1`nHKd{pjAk+8ZC$2>7HHU6HimtPj!UaEubUraQOQ-Ox+ow%G9xh0cK;dnT{A
zU2RzRH*!+gRE?{(I={>{T}|BnPdKtyIWtS_UPq7O2A!Tn;XQ#@qB=LPRy+K>NavG;
zt7F_U>uEiI<lpcF7i3)3ne##X@DUC1U;dKp{)@i<I<fooZiDLYtTRqb)wq+!!M0`X
zpM^Z9I2z0Ee_Uab!T4{*B>t6-`(|v);1)5`oRjtSP{%vo1@+A87A*5_x9$ABe&Uzq
zE!E2tUtHg0<CAi7M@@-(UtD$X3>U*$-zEC<db^ZVA1JBm-E=Go=9~WOufd=GTLzEc
zFY#Y-DQRQzQJ)`fg#xQ`E_6>h80R;wqrQe|a@f1Jg^cXV{oiI-tWcKmH7cmR?X+fx
z7_+v-!q-bOGah{F{b{^%<MAJLOFGMU%JtqZVvk>17<0&UUE$rdJFNzS;uR@c*FU|F
zjG5$fGB(O;Mz(pHtome^;>Z85Pnlh>))K6`@8Pbkna6T>OCP-NxqrvzTBYmjj@$UT
zd|SUx=7i~s-IIjXZJz&I5!@VIsM$05=>CVlOjjM@y;U=vyK+x!_SHlV@kz^`#J!(=
z()5*OWB2r|cZ<U{4(}|KjV|Q&V=J7aH0SlrMRwa?nB06`x#jNckP?<VGi?1&PMi{L
zyhYbM<Ep8js_z4}?->VuZ+;IbUNldzF4^|_rlSgaGmcc=xY-&rRjhd@%gUD9mOI7G
zOZ(^lniIVFcVWHXz0*hCVxR8X^5RHr--!p4-o1S&we{^m+y2R`&tKGcxfAtX@6H2N
z@ss;nX5ZbcX<qSHwy%5lxvQU7ot;~${nY5*oJUe7?+@5|PAV`D<9%S&ck76!h)~|`
zAM0ZJE7>iVK6AT&^u5LTxUz{t6_Z|HSfO369Cyq!?(OreEAJ2O^_f;=UdvV_>y{U?
zfAU-5e-Enktj=i${oT1QH>%*aoNCdf57IHSr{(S_Zq)oU_X{U$dCftFb+1pXRgqn}
zW3KS70$DZrCn^)C?-0BCy6|_rO5w|e-*=RSY8Pxi&sMbF@BG84Z!;V}&7HJ+Q;o*;
zsvkv@vcB@SzL31WJ~BJ+^<S4h@9HC4*Ib`)`>(>Z?@xDpF18lp-SV(zoqN$7t;X5+
z)=HW`J)rG3RqEK+*B4qo?-V*Sf2IA2V7a2bv$s9`W~csA<EPp6EqTK4LJG9LzdIuH
z?)=5sSD&j0^yXYTG@D!4wczsqtaE3r#Ez_-)Vy>5ZPTY_ch1b)X|;Jad-bxy+<$Y<
zE}isuc6NKw*DAdSBCAC5DpqIRxgpzcp{Lv?ePN^C_CHxH)4x<0U*B`rK~E#}AgkQG
z<EHP-+PeR`F{RwyVc)SZ)Kll)cILO;(MqazqHM>OZD^A*&$Dygm~}QWJEdV3?<>cr
z|0VjH@{}B&w5XYKIV6O$^v0|$c)Kmlth#n_$n1$XwxyY@JgPZCYvROPS}S8CM4Qfc
zewGN*m+z73TCg>}?nvw2BY&m8KM2?*$Q2=VU~iuCjn+K}_AYt<M(KholY39(cIL&i
z#G7n1CFdMqSaxidihlQ=X5Qt=0ehoFBP1`EwQb)aso~trW~ykg&HeKy*N;z*oz<Ux
z`749_dA}PQ%Qd;Am^(9*W<=dOpzv1qUAu>8uRe#Jot?+(E9}zhTOFTVoh)D(?pP`w
zd?RdC@1#u{F`Qiw-!Ji>vFP*_(+Ha_b`vJDt@L6w4&KEwkzv`hX9hxC2?{2SJ6ly(
z9$fzLRC7Yes@p7TN7fd;UDdIxocZD`X~Qi&mHVP1>Jx-lSxYDyYVsaiCT0*mvApQN
zuGY1O_dVxkc~q3J`~R&K%ze_=Hm}U!T(qQVuIP?G8WZ+Uwo7cVs!dOReCM4(K&pdI
z@PUXGO&j-$m(8<p?o&-@X)|G9kZkmHaSX{#oVQ<S)~?%1f9?j~+3}ajb(LAO?ZwHj
zT;7Z7zdPv9fAr9SEe6lt-0FNM`c}cqqp@+JVh^vW{F0^nY+B!zhq^GIp0GiRNz?y>
z#yKwES0e2PwB%=rp6-n{f4}<tRrQu<M>i&X_bbs$?F|WH<Mx!yIqg~Swu+%>_pAi*
zi~IjBtlU_6J?2T*?rwI@Z5dI!1z5~jFD{v&n|G(`$bHZK8W(FM%5o&wwO35gnkM+y
zSn(CR#LQWTuXOB@Zxl#-Hf@7Z(4qb*zT1{cEt)V@pf%gPC3%VbJC#4x*R74e)d?^=
zbKkffq44ON9gnQ3^f5W#z(Xem0yhdt+|Jz9(sSml$3Ye68>b^q_?}5Tv|ZBrhP1Ms
zVr21x^oWR?2QQiMR!{Fawx{-A#;rx1J-ufVlUM%ym<hUw;ig7OMhyF@6)Z`6J~bMd
zwXN*rxoB8ram+b^$=W*m1k?IM)i)ycn0|G6+_mnAbCa(2^#gkkb8OLn?!v=8Y3U^)
zg&?WJJ@X}xo;xR#nR(LVy38w4wP$7<HX0n+8vEIx?qFd^_B~FqOBptMtGUbPw;a5A
zQ?j3L{n2Tc&oA_u+_ZU9KsVdURR?CZ=o?x2)-H+XNKDS=ejH+dM#hv!{gBLsRokpL
z=4dBZY;Kxio~7`Me{TDsvsH_CEN0s1={4h4)~_3D*Pc~WXM142rEj9I#H@&e=WdDA
zrC(3{u_RO@U@z~dD6bRNfd{X=J8T`O<;wBVn<YKdF=!rJb+q!4Bg;Ox|7u|fGb=NA
zth6!hm%y4`6Z_20t`_Fp*wDK(?e66c@6#JUtW?}}WfenUiB`|Qi`Bs#tVu_Xyu9C`
z(Rg9bk)5iK<YkXu5WK8Vy0$y(s4SzNn0DBE*XDo1f#=Uo3d!o!6qwGi@xYXjbtczu
zP5z*&ruOpg441}*mTz)&1!~_jwDr#6Y^)Zpcw*QnZ@8njR{n6$i}^MWY@V&LYy8qu
z;^AreZ6D9FL@y7IUr9d8>=N=)y-z(Tk%_QtlX!9d;)=>-363=vSG!Bw*cym7vwwGS
zc~_MYqi3(=JXvAO(|8fh=CeK`9lzWp&-Cn_uadv?TEyPx23kktk6*eQo|u*FoYk^t
zd6)7f#g>V!f;^u8o>!DlZ91p(KknNXLFp|o?S+4beLcL=Rk*;`@AF|{`M0jSAD+IL
zbB3$rOHp&kss@LX+|sh2PD&m+;gan4LRqbKb>hFayDwrjWH#6GJvjLBs)b)xoo=?c
zTT+Zt&}5;B3q>Z}T6?g)e5p#S)XKN79^X*nWeUl)7qRBoalP>`@<xpwL)f`@FW%WQ
zyuH2s_=|7vENXvnG^I>4P+#x%d7DLnmtv3a7mM4sMUQu|N^jVcET=PPt56-kUqW-f
z)iV9~mZRFolzu&sim4Fe<K|v;@6YZ>9#JL+1}g8pi_cu(J^H%z@UrIWgwlLnvk6_T
zOHEgX)co;daWmLv(llYmUjKTnN#}d6=)SD#+Q?lcF!#3oLdI+Uv%9YU+3s|3dia93
zSCS<x>Q%F*7Bq&qF@614t+>hC$+aipUj%=l&TSFxa#<JWtED=(3OU2gbdNeax|*zd
z({tlTii$Ar6oIYAW&$-!8kr=dBtMF}{yn_2MtjYzT8^u(>4xQZ4Lw?SUfh#zzeV|%
z`H|hmNqKU|b}DGD>9xC7>MOZs|I(?VQD0~F?S0+$;L$3{9Up&5UdyxUW@8phcy}pO
zL#|r(w*Q@m3+JTTj+_fvtk>MR_hYZo49RNy4wHNG`?k+>O3d)$l1Z-+GjdNTvC5J0
zohUPNiJkkDDGZ$HOy4K5CQO*v5Hj(W<ol#a6OMcS)^`45A=4!H`;q5{jw`QpCZ6BS
zvu3A@OE-@|dA{_n{&;tuy>Dk+-n!^lPP@%CkM6GU_sX`So<`0hXO4!?{lZzOk{7eT
zHAUj^r8`n_sWAewA`J@)1mE}sZ^(KUGN=BR*!I462bv9vpBSBXNZR9e@bIF?3CZ)h
zYwmik@8I0g9DQE->e=6A>ry9Px8dEWRs5v<lxt7HSxcv&sisCIO}UKhCmto4mI<o6
zrgZVN&Ut&~`3uoiAvQY-MHgnWsl?A*>~%D0f|~1te_yjbPCV|+s?14vevRR&&f|yD
zN==KK8HE;`NNQW@@i`esTfEF`U3Y)hl@H5zl-V<|9ZTD=p}5^$?t$+fu5a6#>hF2-
zRI1PEG`-{fq|wNdZ<gjXR*p{LgQoq9e|hYm@bKte?F!MgEi+qL?`ThJX|xdIRIzWJ
z6WI~>`F!$=N6iw~HfUI0XXxA6+i_2Q)p`-(z2^-Knpe;LH&dW%iNcS26&#%xSj3j~
zt$6XUBf;LDMg3Hwa((yD;N_3E)pMMCce_tK$o&Rq(1bJQd-iqvwFqAnsWm>E%9;P5
z`m^DaBfGX4oaa5SG_AwSqjmFY>7L5p>}|&kgt-!5J>m(DR0;|*J!j%`ZVAt|{pLp%
zf4nrcshZ6tT+F?rVp{9mi4ywn<J#w+;4#e-Yn+<OxJ73&clo^iO_6r)9g82COrK<A
z5tzlWJ%7r<Lzygf^FPXJ2>mrYSuJyDZPx*xSN)5h-&>Tp-Z3L6pl|MOzJnLnGMsyV
zhb?rf-;1#QW<m0@2RB}45;;-Pw08UA3w!J1ciemxz4FMzpPi;Nc72n%)BUvZ{?W%A
zM(aB6T@`(CXA`?j)LEzfv-mnV_}gblY&`lo`r(_#y#dcOo6_6O9>*?Zlen^ispZ$S
z<|m#JW@QrVj^9+?zLCSdKfb+s^1BzG!_~KB-<9c|ZFcl_clE<dWj4ReR<b1C(0#M(
zAKTG4t~ZLlu)X>&)Ai}+njf=Y@*DE^CtSJmwLl|Oq|^WWqpAg}Y(6hoXLndzd{>Y>
zH;rqKO@Yj_saB89UwiuD!-2FtMrF-UUd6?Pi5&Z|&Np#oxo1EVGxzc2-*Z(&&ZV|&
zKJIsTQH^>@{@cFOugw(~I(TZtzdL@;+USq%67xMii#PtfkSd~;(OtWnZ-K+<eHl?k
z`t_UhozrhDkAL(ki}&Fimt(u5B`mYdo~%=CJTcp%RGoJ&+jqy%;!l2jaZS>d>c7k1
zwR?Zwml3~LsY(BBOa2<>9OrXM@e3H5fBoa%dG^cMmVgJZw(X3l`M_xtlUw-v3g?pN
z`AvMRO&4|?t_YFcAd=f%%)#HU;MT@#BNK9?{DFoH*RDs0*5w9-z3j=0JNl#gCBIi7
zM_P{rYdv##gtl|RlPlaIZ!gK$m%nW=)1AG@^RiS$!54*9ytDfILTx8}e8j_NC%SNg
zg1~Hj_65cF9W|b<i1(e=HO0Y4){advtu;}vx_NQ>pTPb1IZQMsbR2Gfr{r%ZZDU(4
zu|8DQU_rRG#=N<Q7K#^%g#1W+-7E0t;(mLs+nKwbedXM5{Ms<{siuhbJn{AVa}Q)k
z8uCcqV4Rr#{b8DjA;Z~wiC_C(e|TjelDo?4(V4!t6DAn__&RYd$BA%u=h-1`AL3`d
zzi~y|-tkd({F-}3Y)L|!uUc0wuC(;czI*qucEO7}6Tt?r7x&leUYR`c$o^wN^LsnI
z&E3xKZ(Ep|ss456ua5WcS}lGnaUR>*op|7aTmjF=qapJr8*JGUQs3n-+~s~(@5kmu
z$vr#w$Y!74-!|1b@Qds{VZExTv{T7($!BNzc1)98RPi_O2*dx1R8GF<W$RiORRo)?
zkC+f5`FO+Obj`S<S`RKRu>QBkpUc?x>C>OOH_E>9wxspFxRo#A^<1r0UH#C?-0T8l
z1x~Z0uM;Y^yDgX`_Wuo!*xL`R>9e@&dnG!9s%~sp?l!4ouHEMc(-SzJ7xiA;ADsL3
zJ^$WXiR`|6>>*4c?_c$b%`@45vM}$qQp{KXR&U9oyy;dy1b<KU-8;$j&^y_~Q9&Du
z+LmSf`tET>$4C9egvWor9o_NCidAo^^rHL!U#+}9-{gs&*cw}wjdz&NviH06Hcfj~
z{X)KIPK>$qcBhmLMXP%j?!E2s?~O!S?rv7?Y-5kqS^XEZw!dpOi_1IW@#)~d-GUp+
z*LE=ey`A|bj^DGoTHH>Wzu7D=G|N~dSGzt$GpMt$;&YnCwO371M`aqPB>Y$t)!Gr_
zTv001b4~PX@zo_y8fJgE>BCdR%(!Zcd|R04oU88`!^@IRv)UJ!t$T5QzdYBa>65;&
zoep2?+;c+U>VNZ|Dc65leieCo?A}p}uR4rweXbXF$NP(H5O5ItDzy4qj^iFDhV-CD
z`CDO|pTs=4Iya*D7{3@_>&4@{#Xr>_u1f{oHT2_c0+^bcko*mD6qrE~zH`e!vll%w
zJV=L}y~&Poo7VAlf6vrxe}^TL6jfb$jI*O9xX)hPb3edD<KKN><HM;fkDu+`Ua&fb
zyK=M1{bH$a`ZL?O^JOlSI~d=wt`@txtG{8n@ZWQD53h|a-k^IzY^iAe2aS_*i_?4?
z+xMM2c;E;7H&Z?3-4)f}HLkt++8U$i=rxOH+O}&3A{Gzo7q>6mbh_T$f4Pw+!@l#A
zA4aY<`Vso3jxW^Yn$O%e^+}r~exzH*Se1+CvQ;h?n48OPBolAUEFSb}k;kLpACglJ
zESY(D!hGL?b>$nT*}6^JP`tL|pR!wm%lBCwd|ggk?N9z&v2cYikL}VJHdnP!&Y6Gy
zS~;i0e|vhW+vw-?yg5#6miwQaW#7?%E_7mbZA7Qdt^X#|bS)b~cD=h9{_{uGuV|Cc
z8MR(gc`;V}!RNz1obYXVdmyo8N%p3*cYTEopC{?uDu2`Ar+fPG)wA3cbH5zzPce|N
zoUv!=s|1OQ2O8Jf2nfyTddA$z*7vTT>&S&*0pFiNf*oO+_jXVEtKZW5>eBRGu3t@r
z!;?}zt()^`@oNi~J9nEyv(GzCIvFbe<3*LzGAWJTgHN^10~h#JiwL?sKCy7}g*8hw
z53X#zcjM0`j{35<4SuEE5BuJ$x@1iAPJAJ`CbfT}t;$`u_4{65EWRstWyAExUsiG6
z_~*m3n8$DyUsS`osX>ONKT=#cxef=&a7|szZd0uNLFWN4PfT>;zVg&HlJ=bb#yW{h
zg&e1>7MkWG%fg;4xh{8RZ|L<$iK^aiNA1%S9WLA4FfLU(x6j-4-zMLS`@KEi#2N7~
z3`#z+_H@#-BlC7_c%bidQ?6y+<}`))GqMs>W!vmuJv}yY>g0)!?n#;X_dU9CI%CI_
zyq?azs}m2u;rt*Tt;AX;VO%J5YUhkkjNONB=*1>ne=Kn<l-Ke0w`9Yr^PV?i;`?rf
zADLlPZq#+zGU@R81!wPffBfF|IOFN5R{_8HvTr7*n0J{UzmR)L)#vVRrgt$?WoM<E
zxdquKbTsZie%5vIo%Mz_cZ^P)>2jF*iEUY4oJP{5mgz3cZ?(Q3UgF0$!@ADSiRIe{
z6}D-o_VSALzGUKF)P6k7_h6j8W{afI7AX_?xqB?uNLz}Udpy0g*e(6f%>zQx;_I9i
z9b#Z(l}^6(;n)qEExgxa0uNLltl;?jZjr<0lNoVgZMwzJ4s0q@_wdg@_)|mk&g!xw
z9oO_`nAeJRoKoujvv20)w!>Ga#XnVfY*|$%(`8k>Zo%%GnI@8(c(eQR-Cul@ydg4$
zojaW;Oh5F5?cLtC$Now0?%iFHvUcZ`h4veQIw#tm5Di#qAt5OJ^6tx{5p|xOqOWT=
zlsO5@#MsE6KfI{$`=3&Ysafqux!E5-ou|4Z{R)G(c)#PPr==DJk6G8nTCs;N+!nE^
zK#t3G?y*bB`T}2b^q;-uKkQSqp0~UDQ2AMzJ6)ZJ7PD_ph-;H5ah~<))3L7`GL3jw
zPxEux^`2|ZzFAGz>bE$x7V%!(9c-+!r>0^1#-Oj~dw6OZFWg|cv%8vk+0uVUwj}Bn
zR@~FDG01H+wX>6mbZnE{Y^LyW@+mX+rA^xyqz=TaIHWrNVTN6ac2xD}Ho4Xx`{Sq2
zI+*aM?!-zqfx8A`1v~ava+R^~NRqucCH3yzhsM>aOu|WpZ@=h1$-cwhy{zou&8wdU
z<M*hGoqyXa&OZI&o5$um3chj8$^Lfq(of^W4+ZSo?(w)?aFt)PQ|-vA(kJg<?7CrF
zulHwCQsLic%p%!FGK+UjJ)AgyuEynb-mo)oyBq#)F8DB2)$0FxPOXZq?)_q0KfL=`
z>!K3e7^LvzE4PdKk%zB(cNb(^h$Qc-K9v4PLS?E9hy47lFWv|=cy{wUeCnJR$gA>S
ziX-t{=f>(N`;vJtyX}Nc+T>gp2CTaNB>jc@nH$L|@=VM#PKH(#e3hEi!&8v<*-d7L
zcwdXTc)`Cgo=;Q1xE!{cXRvvz)5cAzflHH8C1zVIY-bkut0$@_xAkNC@?QoU3*D~o
zO8xNW6=%%u0`7@yZaX#?3vZiS%^WyG|J<EA_Tx;ffeW21C8TFA^!&X|VBhYZ)Zk~2
zDrbqX8S%BbxfzH^9Xb)fksNG1W5RuBLo?I%iH!_qe&;mahfa-=Z}$HFXF-r#^5tW_
z6;hMC#JBf74&C$Xi@%|XW7LD(n4VL;j(1ljonG?N<KG_kwu1?O_6eLdoPM(K@2yym
zo|GGVGnLQn?{mMgIe5n>72cy-q0WC-{Y-qA&^_s?P2fr&#~DwHTIROOOkDU<<JDD(
z|Jjj3$98rt3RV@rV^z*KeVv`ds*Q|(LbkSF6u1f*pBMadl!>|9y(mYsd{N=HjN2Po
zC%t=r{Lf4~j>%dI3Q`#<IUI^t9X8Dr;59K@(mkC!At{Yd(ePf;&RqvLH?j9D$uD^6
zsxf8d`VEDT)mYTkAK$xrndADEetSoU64O^FO>G3G96pd%xv}I?R+61j9qWvZ$4|s{
z%;R8TnlUr-;HgtwX=1JhwO`ZzgkF_<DH(K&!7V`Ov6pLB<CUOAx=Cy<Q(6p+HmO_>
ztanhFxT4pcIcdhsnURyKBM;p<!>K$i|9FEHtKzu{4Z;$WR;9^oTN~A)ttfLx`fum7
zIM)-#Ay4K#x%Z{&7faCNkdK~s8~!ZREeQE$VKuKm#C4@YRK%@S_3M3KZo9FqRP|Ka
zwz@S<5|jMoKFl+aT>Siuqvu6Uo|po!$L?95dDxl{3jP%qSZHXzy>07KQJ=Y5$v4}!
zW<*{QcqwH0mSy20mZ@E@rlieR{*~fja^c94Nja}>3-C@^^?va+hvG$zPvX+99W|)_
zYgV#0#rvJ>y2YE+c#phF_5P@GQY7?Nx$|11pNi9qU;XChY5AX_;QmFxK<U?-X|{_R
zWiC2Aa^d6Q<xR{?U4HFmP3f=1>$_f_n0}Ij-A}F6b)uJq`AO;EFyHo@lX)dJzukAM
z|6c#X{TW^kY|5((xH?>wmIxJo%DTa@Gev1i-aW~=ucx~CJkVCro_fMV-0`z*n^4jw
zebpuxc8&Co%L|316zx8+mA%>5GG&Lu8tcCTPhW3$oO^8R!&6HSZ`IowzWS9%)$4Yb
zokE*<43~H<idq%2r*3x7tK3}+93vIi&E4I6VF`<bKw@_{m+PDeu3%@?d3W~r{dlq5
zqV$*4r5+x|<=2Iq1)KI{L~Z5?F;d?0>W-x8Cn<#&z5*igHGAFWtG2tiW}Wh~V!A0<
z9DdgM(7KN^ihrq!JX@w?Y$&nca83|kVV2e<p5B1<b-ptup33E2q`6k>iED)egNw{X
z+rVAVoQ)Svf0+`$?4McFt3)f7V`?0g6=KzW`y9M(DCg`I?20-&YhhsXstwbZERI=y
z?nTIL=0L{v6TEmVIWPKdZ8??nP=2Aq;dQYAcHvs<V)k{fxRSDUqJ-!-zLPG`ctkQQ
z{=DEzx_9@;P3`X!9ZdqXmPvW!C4@4a)e>pq;d|jzm!H`kvZqqot;hM-ZM!Bp?bIhT
z-2^VZw`e)KvFK>Voq6UQv*p_y9ZWua_Llh7Tp-nWKi!~Cu9f5cq051bf_OzfuVDE7
zWOl@^p9bsZ>~7$BUbG@|sX&sGP{5`tXOS&u59~I-sPXD5$I&8f0Wp!jKS#S1KHcPX
zS+e58i)WS*6<-hRu+KhlZY2xX0shn1-yD6)oi30bBJp)qm6M1d-}6aV1J0<5-^mHu
zSp7QhPW99_t*crNs$R}Zt$YQ3e=v|!-MJuq{jZ9$1ZzDumV@_p@~jH|-n3RrcBgkp
z<L++DuJAQI9oe%t{QXcl$NIa-&#Y^%k>=tOE2nz5bhGmxyz{w!MW6%+PnYA(sIL>x
zpAvA2HlI@Hb#&g|^CyZwKYrC(t#Nq|_nq9CPhMIl1zot<Z=BK1);v*mg^DLfC%aAO
zJ`w#;)~4;pH&$KujIpVeRa4Dgu&Q18kn++MG0V-0q?ajbsE9tzGIOZ&Hf*}DwkRV|
zd{1SKwBbpmJG;yHTBG`o9Y|aH@WCt2+efk^c0J|Lo4=POQqKR1Mm$UB!a|Lpjb>a=
z%G}}-CCYMa8=eQMtq5GGu_TBw>)M*e@O|xqNpBkG#h!Zj>Rav(Sux({dr|}Uy1C8}
zV&0VSb5_AtbLX2~OFusO;q}J8kW+je>!HPk$x{k8w*M05b=B#Uwdr>HTD@RStQM2f
zkrhGP^<;V&jh|mC5N3IFU}r|i>V#I~>3;*4*IGYGy>I(c_Dyz7Tit{=-D+o#Exdi}
z_KT>t^2^*xhD#!ymt2o*O+EbTz%3PHXTR1H+OIEOs%BS{+uc{j8Yw-0-{F17QeQ}~
zGT$Ar`8MAf%Nnt*pFi~dayS-Tvf@6g>o2(jPxgBqZ2Ir<J$MPnEqng8Vt0=}>sEhw
zbl<V7))6a@T;T8dyfF6pIgMur<X`h%%eb+MdCj6cMGd{V<-d7Sh1T8Sb-AjR8+fWQ
zRg<mx<Ku#Dsuz}eOYfNRneSIqCwJ7gJie2sy*s@A8cctAe1*$Ji~lN;y;0lT{^|H8
zoxdQqCbj=y!k@AY(`?zAKUyE0r3mXY=^Xgac;3p9CrY;XGXnzygQu&X%Q~loCIA`D
BN0a~n

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_toth.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_toth.png
new file mode 100644
index 0000000000000000000000000000000000000000..9852bc283787abb921c607ac6435c9ba6be1c532
GIT binary patch
literal 63255
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
Y+N~h4UOeLw0|Nttr>mdKI;Vst0A>r_F#rGn

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_toth_gab_s.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_toth_gab_s.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad930849a0c1fd5bca15d1343fcac8dd125eedcd
GIT binary patch
literal 64711
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
UFCd_Xfq{X+)78&qol`;+0OZpElK=n!

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_toth_gab_sb.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_toth_gab_sb.png
new file mode 100644
index 0000000000000000000000000000000000000000..4053983586df769c68d107ad4983065315953223
GIT binary patch
literal 78760
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
bfBmnoy!=!4k=O?e3=9mOu6{1-oD!M<=OAnp

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_multi_wads_toth_gab.png b/SorpLib/Resources/doc/media_functions_equilibria_multi_wads_toth_gab.png
new file mode 100644
index 0000000000000000000000000000000000000000..a25cf8459f43f07278a5b88fcdf07bae6756296d
GIT binary patch
literal 66371
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_bet.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_bet.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae00a2440cbd894111eb2b564a8724956e53c98c
GIT binary patch
literal 82032
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
P7#KWV{an^LB{Ts5Ax4~I

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_bi_langmuir.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_bi_langmuir.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce5512c27ebaeb1706fd24c999a2681fbd2b9d6f
GIT binary patch
literal 42434
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
A9RL6T

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_astakhov.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_astakhov.png
new file mode 100644
index 0000000000000000000000000000000000000000..955a4ee34ba7c26e10bbbd09fa6643f2081031a3
GIT binary patch
literal 56108
zcmeAS@N?(olHy`uVBq!ia0y~yU{YXUV0^*B#=yW(a4RH&fq{XsILO_JVcj{ImkbOH
zEa{HEjtmSN`?>!lvNA9*a29w(7BevL9R^{><M}I67#MCH^mK6ysfc?smo-7e{r<7}
zF-3*qN)s3q58hSXv0Eg6VZ=g<Dch#(i_i?Za~A}fRaF!@3;p$q>VBWgF;k7;RNd}*
z^3T5f_+6W4|9*ew+@I%?Hzk?-7}%N*CKyQY2u|eqZzRD3;&r$+zF_3!;yU#6^Ye+*
zrm3|UfW$wZzj5o<qUh~;8#Zkca+28T*(jh;{OruZO{u3Z?5QkPYylb5Q=fLcPj*M$
zU#nGNYqeSoiY7BDIxO>_-*@DQi%!G_2aZILS&!#u-q~T8c6L_lt*zPIiamFhIGkae
z=%EszA#z9(?40>-Yr_s7IN)HB{KPCrNDC~+b1{(#Yza@>3j@YU>;+M#A}=)qUbZm!
zN=*t1QV8dMZe@BYr6|MB%G$lP<%Wlg+tEkeY||`6pLmIyM4ta>9+jfvretHo#3`wz
z*weD?n6i<QjNrsVk2>K$k`pSlrv_xV26HWMjhe{U>SnS0!VmSMidsfZHq0BvMf-dD
z)sMAb)Ku&~`RDhF6xL1uW_kC!vUG-r#0YsF)wwc3)#c;IUca+doRI|=Ry}=kcTaBo
zYA^M~UHj|Jw+E<Qe9qyXl4JDb{a*1&p($T}8eew#_I>fHiL<``$!9wGyX)EEB%#z3
z^Y;9d+&X6p^HeqCSkHSCmLFBtw0-@ubjh6)o^rn`a;CiG?BMBlxfCs_^}NRDtdWPL
z!gb|j;d@Wy*UETaG+BS~%l~jzW-DJdqkAWltwP!6i|yLqY?)ycBp~j4I?cjTY2u7!
zDl0!#zSwlip~mQ>CDSb)m5)zVg*N2~UOy%L<Byo+Y^I~T+e)~WOfLU;O~<Ks(jIwM
zkBcW_uNWP1o%p=F!|hi)*IX;v&M#KA>?`w?K0N!md8+!S=#P>6r`|q)@`ud}l`HG#
zN*bpXIJfhOp8F)1`hqv_?U8SHW~qPiIn65nYi{<n1;*RI)ydS`zI&II_h7}`m=!_C
z=kM>GHF@sb)21sU`?TX1YMB@2i!2veS0fjt_vXO*I}I<Rcc_1K5^!DpV9~p`kJ`3r
z9uHj^)R}FcCHh^%@uX&ud~xxwYmZljt~(UEE@=8|qvt%+R|)-7bAPd8M{s>nv%3D%
zb*>zaQ&{TXy}7mV&MNmqma1PAzQ?}Kidp$->Ph2}hp)_JPs(zJa*G!?XieR{KcDOR
zz980r@AuyBf9&^rdGV<$8F^p*OLusMY879dUHbUi-3b#zE);FL9lb;TR>-5ruW!~0
zmD^g(z06_1l+*6$-><g=@(%j$6qw|B;oikNXM_*V(RqDL-*vg7XJLo*#Wg(t&pgfA
z{`}we?~>}*xvq15+97@CN}lPCRZpsxX7TQLKP~p@6RA&szHcvfwhmFP51*<1^KHqy
zI2X3*6F)S~HeR75AGZFoK;Hk!A(M(f*?*tD^?BX>y1Cv;|JU}`pYVMfH1)OBUz6j@
z>u!bS-CAE?7_HZGdGq%GxBHL8{#=-&9luoPdfgkfcb=D?rv&IO@A&pKjlX7c+V7hC
ze#W^`Cff^ZoG1O8x^q>pRe`qN(ju);uJYQ){xPRN&8&ZZHP@(I+2Zm0Ka+(^HkR)U
z75-fqeEw3ze#KueD)OE+{*GDV#1Y_LxcvFI2VB)tpMUn4s@1#m{`R|%C$*lobet=4
zL{~a;a{aYgYpaT9zh6>lm8<nV<Nf=X_FY?eraWiU-*N2dYLhu?$}P8lW@iV*dDN}B
zI&Job*M`%7l{cN(IotbpF>~1cQ(|si_ZI8kIaR8?gFDd4A#Z`llXL4|oHt$Pc4@Cy
zXx^V`40^t^&zheS-f4Wg?#ZkvOV7to{QS;%cD2;<CsQO7@679z{qcN#z;<QxmkZ>V
zdrU73zsC1yR_J<{y46D8Kes)PS@q1h&TMkk*H?wx^X>|rli11on(-ua&)PK!S&w_B
zFI@RVN2q+U_rgtA_|hhEoaj*Muc=_2v??{g<5%NJ|6S=3md^#F{_bM^9meDO;?UC_
zYem-8vaMR-9kI1Sd)?2ahds1df<g>;$O~|O{^wr!|6pWEH{X$)cl$s5`sr$;Wy@5p
zA9r-Ato`Ccn<FEBPWaF4^5gEYoyE@!K1TX%i)-C}QRVLOWlLWd{0cmE`<n&t6iK6$
zl>EFj6@^tk`Dbp|bMwpD9Qa!7ec{?&j~z3Zh5i;ioyv4|x%|PatIap8`WF1gx<KZ<
ze9W=6kAe$--jjVJcbmsw{k_YSXRKy&b*)DBGHTo2B`2RXxKsH_s_2*Xt(2JCdjwYZ
zvrOLh{I;v>>IoCC&Hv`h&#~O8sLJGzy#0Z<#m@_m>dQ#ptgf<S&2;^Je{buObE{7p
z#~+?}Ut96z8>KlM)tB#d?<y8Mzxscl@RMIRP5%ZyIjAJ_h4;X^TK@-kGPNuJS<g_i
z?TA%>r}*Kc?w%F<gv#aa96BTxx8vh;I~UIVljj%e1~EBa)V#22tH-$x#~?3mlPz^!
z(^cwU$lZ6Hw3Ts=_YThTbam14Z*pz%MeZ^?_DGk;#~hz{`MllY_JH0Q;^7~++?s8&
z+cMW&b8dbB`<z3p)8h*sor{&3dySPb*i6yjDW{(6%*9t1O@6XB_Sm9H;v4^c@Kw1y
zZL5xexW`V5`nQ5jsWbO~wDbD$F0w;)_k8D%esveMf+wyEaGpJtHDqPSq+N?{{iv<k
zS@GckQ`(nxT-gslEx)LE^}S7A)%hb|f0u7a4Y0MDwM+QptLYZP!4h-D;?(x<WR|n$
zd$cK@<4>Oak<7COca*m2oyq0>y}-CaPiN_rvUKHVYi(K|SeWwg8XvAODN0F6X%Ok%
ze{rRdpom<@@+C1bd;T#vuACoiz+q@!=yH)^|NEVdzs<!M>en9Ix+KR>|C87`^_>g8
z-!gt8JLj;^^TQF<Px$7=**5)Mzx$z9<v-`-Jp!c#rgE%y$0c25du}_{y*_8;@qGQ^
zsXs~{wo4=>TTE5>^F93Z)z#sOlTTjQmK&|8(r;+&QdFYzM=om7Mt>8zJ!UQ|4`p%$
zSRT51R8aBu`GZTV%|i-J4p$4QypjsDGjQD<_cmZ{i)zxlH*ITb!i&}iIBG2__<bod
zW>=y7zJ2>X)P7^ivd-TTnZEjfXrjfQJozS}$(<K6yVOKaFPgBk;Oq%D)zjA<yM?lB
zcI@C@{;p8t_7<~OW;wliUr!%CcST}Z5bL~HE|&1chFweJj$0||_{Ht)-CQoeIG}Tt
z#;X*@#c%l6bshehyZhsZP@N^FQVZf*wF=IEn)RuI#a3OkyW09nk?5gG^OMi7-0k5%
zQSswed#1@g58gdwc)aGm%Kq;!ZduORU8Zl`x6gk<;#1CW>&HGb6JEC6`Z{Z2qGz;(
zw6x>zFN}FBY%eT{HUF~yediQ)^$qXOC`(kCxP^W{zT>Sp!`z+Li{kG%xqX$tus+am
zhCsS(UA6hPH+5{gt?m_Q-V`ady{EB!$@1eLk1Vl!HEl~XXTFKd@ojpC<Ac8+et*tT
z=dOHX(AKPjw{M12w0j+~+uzo_d_Cv+H{BeqmUCj?82^t;;`!cn_QF!Pz)xp_B9^#4
zd^Xu+$F+>6O?)%=Cp^C^aQD^JHr2g;T6f&TofBi$@|}v%6c86`y6{0kCHqd`&PwMi
zYeMB?S6M5+Ip_Fh{|~NhswX%95^2=@@BLF;TV3?rTQ8TVS$Y?a+;f}}Dk(B~l1;!4
zMVWPRPA#5>SMuW+w;lRhznJs*(%1VsH19FpH(kNvd7^I5lwFH+o=)2E=zc%f$GYnU
z53bDq!hhbtQ8C<o#;5DO3BhaFtgcr~PBT;Wj5|9m%}sCW#hqoI8u4=u-n(4BV8fcu
zw)-YduYdUl+`ink$6Q#$<LJKwdw8TOW<L7&?dpvB2Rd>wd;7xYh-yvy*7Vfc%IfD)
z$2D=)@@1xX5})1`^4)u;MSIDl@Al2?ySi4y?K1fBXtl5Ffw#pLZ)bC?{&KxSY645L
zd%8tb%HI`Yn-)ahsDAY6ej$%1qs-koiRZdmm}iKtY}4D?rTFio;TzlUEk{<GWo=v2
z{LD0aL02Tlxw&`Se=Dj!xO|J7(>(0q(qP#cEccFjdq$ePyd^7|bK?AxJBLrTE?-bQ
z$sv3fuT@A{v*G+UmmC-SLw`L?xu&k{6*_b)b|s^=Va^w|Jv%BSX7k4$`21y4#@pZ-
zOLj118qBdM<=g(={?YuOt_31KF?$|NnEJu&UPkD0qpp-6k3M`{%;B-7Bh6Op&`A#i
zuRqb7*?K)9w<)|oAhT(<`NP)%oL~38S=iC*;u0djbcp9c+)_0y)9jvermGjM_@vn<
zXV0{MM^VPD#X?+?>EVI-H#Q_PM{UdLRC4X&Q0%$$WbUJYf*aM=e1%55J$7^67x7MQ
zbKb4>P2<^=yI*fF*s#)ePSU!EuS}&igj6+d?h&l%KdPYjLuQ?OxI_5vHC?Y|7by!q
zN#Hbo^oECLO~UI>T<eoOgjY@}n7hU7kLT;}tKx&6?Yts#$tX8)E62|H{2tB^b{_t)
zHNRzF^V<!!5lo+g-z#??cpE%jAbJT;&RxqBo{L>iEf2NeJAc1j;`Y5CJF|4k`tLTZ
z4t)3G+9mFT?P>`h=UJ`zm(FkT+1@Eo@y#v6JC~-qufKTC;@gzP{a?;YNFCJpX1Q)&
zhg-u`!<<z!7pKMMN2Kl5?&Udn{@sI5ha(gnm~uPCR>a*2vZ!}{@>TXm$sxwK%dfc>
zYE_jKwb)v8ORt}F@sqo(P;<~kfdb~nI<<-!AGs2rO;0c_waU8f_Tb9Zh$~X|oV(h8
z3*>%Vmh?kGrSNK<mPodhn0DH=ga6{}l^;|xT+$9>{~t0(>SUsS!Ou<l_0~&gI0lBS
ze8l>?{L=!fZ+e2I{ttq-b4OKi`<YqK3cq3epXG_(+>6^*F)u1H^RTPt2+z|DJhfag
z>vlv6m*G?%Msxp%fty5R_cI!as64M#dTV-qo@4Q2wuE0Rr+;bH2sQYk!<RW(&8eZm
zxiX|XzRh}x(3V}Y9YSkoA9|Fj5@)}oPx@kzgxDuH#fR6ndw4tQWY(UxdGj;4{SfDb
zrD{rZ&8Acqu64}%VLa(y&34)T-RF8a<_2vzIq%=iOKY6NC#4llO3U9{C8{Jp|M=DC
zfh(?G7T~(osTs0G@%i<{<69@aFy1f36PI^jy>#5d%M;QJ_$_)DSN}U?IDeYNi>a0R
z{;TBs<i0td+!%b}!B49@hSm1}_pxe<tF20Dxo_JUyYa}1P}3RJ)16Q5ukGfO4Al3K
z$>)6D;9V*mvL;TD?`E}Z=}V5i<!svz8(rA5o~7s(V}fIx=at|&c5k>j1!INgGA1?8
zQ?_`?@=cvxIp*ZUxHB9+FGBhMRrf2dec3Ou;9iTVl<|z(MPe71u1=g2BBs19xAp7H
z-iWQggyOQY7bS)5TJHMb-rCh1-e=y}n-*$0&fBfJ=YHVKl?S&M{@P+cr-R{XM*pSi
z$dL91VeP^Pfudi2F0|sxW=_m57d&1*x9!MI9;<8l4BoeXI=xxedhg)NVEu&KYj}7r
z@gA7?qyEBuqc5k}_e395Q1Rp3e}ZRE&!pF17nog|^8Q?jk<-LSt`9<gbN0<KZ`^rG
zRMks3R8E5NX18_4-Cb;Z&e#Pp-nenl(wTW{7;oQ}RZ~}<+pzguSP9SBz!PgFyryVO
ztgNV-BsS^c>_byOalAImIeszr_lD&2f^+U|<eTkh@BVA|-bH?)208y2*JSG*{%7m{
z&|h}#FH19@8O`3Dsuz;Ogd>)#DPB`xHe3~PXLm7srl{M($^Nb_vh$idA0JQt^Mv(A
z$u}mx_xF0{-tJHQ|IXH8Q#JcGx!vtc>SwK9KE*k3DSuk7Wt($5U&7}l-wIC0d3yLH
zzJK&lt?x;}rb+uAJ4~r4Ofvm9tCU&Qt<?E*R^H5+u}OWe{!UAHe@O8{Tud+T_sNRa
zcPu#k|5?KKh0Ztb+OV;oyMOTPUT?$Xx21RPY!`a{Ek;4~M48RGOV;u(?B|Y(nVs9R
z&A6@fB9Dg2lM{P9_RLm1lXJ5A+_y8XbJpDd@`~d`C&OIZJl&+z<}TY6O*g;VW`060
z;pq9#h0|Ae$OX?{6!1cIO?17`vAf}ux7=!ERC{ia_&D^)#qXJKI?|Rr-B}-GyvJ&n
zh&q$K?c+XgucmKLy<adjf2qn~?&w{?&&yT0C~P*%o*usAkJ;l^#I56)qZ9M6;+w&|
zDaDP>M}vMW5HT@Tb~+>?wu$GTiS1FTXKK?7e(ruW^}vy1PuG4aFW*$D|9A89$P*J)
zEyTX$9W-!jy;r=k`l!CaZZqN8a+gic9%%mCZBYKOIAq=h+0wmpIzIIt%hpznn_ToU
z=3(b8*<%ZQzC^B>?Rkn-Q(Aai%+b4xy+1tPmAzwkzGT?DeNDl;uRU<PvHRPmh0~Oe
zu40k;vuWm@*UlDON`<VZoEM3iDdCXy_D`6MZOo>s7n>9}I=yw&-jMGnzhtgr;m6Z5
zj}0}iixyvhf85~o;fS&yYH{k4ivqsZMY!k8opoO@O>ueQw?BqD_X@hE^ly#W_*+OX
zH@-!8`=cNG{~O3yC@XvH<^EWCvtxzmWhc)3>Gi_WJH)^K`90INTdb{jV}Y(TpWWdN
zRk!O*{3H5Q#Sh)*ssFU(!L@Id5gR_4zVdzDE0xDqQB+}Ornc>v*{46!Zequ8mS%7K
zoB8ZQZ|q#fh@DRvZY^DN?9pb$C0~p_H8E*B)MbXVc<<A1th`_K>TATc^W0CnQ+o6F
z99-g|DDp_8LPCadZh7USYdHZsb4<Ry*~KU=9zJ8nzSokhcf1#TF^+F>JGsD%>(Jic
z_cY>^Zf8F+IpN{&=yhuL<G1TgyB4JOuX_=4Uhq|jss%Iiqir2)b&6MI#8}re%$DN}
zRp*>8A$cg^n^gPqcSp02r%CLuVK{a1w{LIanlgv8&-N#t-BlWKVXH*f<!4JKvIza!
zEyT&g!*y_ZZTOeGhfKXbM{g@P&fNdkzu-tA=l`E_Dt%pFuH+P|C_P$hvFy>!k9%)y
zvS#yL?(6*jnX038rHDRX^0CeZXQFvjFTA=^P+HVnyHm?ReAmWMDXn)s0V`sHd87j*
z)3OrhvG<-|E*E{=arx49J<ZduD3>rU-v7Vli2Gun^WV;BdQ8>+xNO%&Mbj5jVSf8L
zUi;ZU`W_$kc<)R;&V4rwUJ6X|Dm&Ejb8o;Teii?84c3nzZCY*DOwj9gcro?xjQYS8
z4>r%UWk0F+^<(4FJ39^jC$Ea*@4mS?@zdMwO;@*TMqLx$czwO{2A9Yk6U?8#OzgYf
z`26F8m2C4;?@dmbIm7DkT;;8|a_uKA<N6V2-a4_9`^~1Uf3~jb`F`pDS#dQj7ki6_
zo6k2dja-)W)L%2}|Kk~zcl1BEJSk*$PL7aR{_y3&*c-JmeSDwO7o@*E^e44<r>V``
z*$HBr;;Y5KxqFMV_UN3r@9|={fx=Vf4H~z27Pnt(v^6|9k^SN4)AoCnKdt#v_`mMS
zcZHwt=USY)wE4Lq-=^j5hMz+`o~=}@<kJ+)^Q^m3`-mqmg)?VTxbKo<8iC8Wcw$>)
zPGl~;s-a;1)uG=}HehdysY#LVvi~O>_dPPP+BfO?#EPOhit_*WUtBR^)~{zXgHtl|
z&nh~8Db=wn;XN3s=V|ccnfjxG<kNgIJ9He+Kizy`W0NdruwXUYl8lrz24!|}kF_BI
zdv`SPs;_&Py39|sPMcjY;YBOcMv>oVW*YxIe=TfHgksAR_9r`bZ;?NiV{-V0@azj$
zTc;d;Jvm^{)6$+jTcr1gsjpqZKZ)yq>STk8^UM;jo;>*{I>UG+n@r2<`A4^Uz9?U8
zqt^F^(f?^}&g_3eTmNOTKE2sHW5*K#6}4{<-o$)(+c7`zT)tFPeYsR#tkl9Cja)^y
zg<e?ZNxeFjd-#f^wLn%{_mLD`HvgC=$Fp6^)&1}9+sx@#R6l#6{(`}kbFbX}D;g*7
z7E@kuPOInCtvtm7?I@nOCYN)Pt~osk84nxQ?O*G%o=ZMMtd^nlit3+x8@aEwPj|Y!
z%ypr6=z+CwEqpQ(T7DL*9ne2G?FGN)sqMezlC8~MUVQyJWB*SbLBpUK6;lpAn7DsY
z=l0lT(O$dTL%pv#UCS}8TYK`qjsJtbgEz8%N*~+$RirJTX+!0)DjSoWcGvw^4{i*s
z{kY(j1JCR09DRS{YnXDS`g~XPt}7PJxU$}CP4K0JfK95${@-K$RGL09Y`Nl_cs}>r
zb>9P5xjT!ftxXJFSS0b|a>kALnY|~Y-yJw~PVQn5`=39r{|B6Zq^kDsBfHR)a{->d
z7Z=<X`110CMC(_ZO_QWwJmOEtcpJZ9ZlUb!stHXK3x(~sOLQ5lsz3PDCb!_~>E8t&
zH8l*yYU>Wjc1pQjy7r^;n}Lab;^f1xT$`6HS2rlTrK7TX&O)`!XO~MYewAr7i+lS!
z1TMClRdqb^)0O)lbdE_KbNM*+t%bzlS1$|}d+W;tgt#oer57-n>;C4~B0jl!ZIdq_
zd)%+Uyd&+%;dKWU{+RBRx3QnnTDpE?{y~>J>vzd*p0!8QGLYRpdFrcZo_7((pZBhe
zOa8y+p~Mz*Uf#VgQg{~RET3<<te>AN^}XUB4H=`j*dzYI%M@&;R`4h-SXC<1A-GoS
z(XDxz5v3LqX=2L^KCkJxxY+%$G~<l@35@gFS1m9zbe}AD_+#$zssh0r*EdoP@t2P$
zygtxXf7;}0^Vf(%ZP8S#UPtb@-4nilN-(XPvGnkry@wNO5^clsD*K+TezrK!?{m_n
zVx7nz?0$DnHLPq^l+iLd;(xgPu-OwPy|}GTZ|5b>2zu@wvuR!1uc<N%PF+|~vwx;U
zpc2pI|KEk3R8$jITv?d0yK%;qeLQ|SznQD`mQL6qb#PsbZI6thRA@|({S5z_4u$#l
z^>$fTSE;rb6bY+2e3~$2gE|K%`<?8t23y@LnTb38YVf+Qs#>_=C;RFTJ|==Y3SL<~
znj*I1;xb(udqdlY$r+EBAE<A3FyuF%k*)NwT9eT=Dzss-n&iLhevj*xh&`KEdSO#p
z;fuJ~gT2!|CoH`n`A+5ZjN6Ny?uM-h@MwL|KE2?#s|}Cs>xH#z7yXEM-m9l6QP(N7
zLqw13x6bp)A7s?abPk=~m2I$WmcX)(qmOrg7Z8}qB)U=6(9C`3ueX5*E#2d$ar9-_
zRM$u!?9578a&ekKLhvfNSs~h7=iaOI*?2IeKkUisowZ2i>*G}!clH;t{@W;J5ti31
zmb#hOPFv`sm6DXy@1PG`s*~*#ek<f`oYN40YpMWChfJX2L>D=$MJa~TNA}mWg=m|L
z6mI>!L84lGu2kZ_^p6%!tvr*CeOaua?5_XAM2GwAUWFAlT?d_hO87Gw-EZvLHbd7_
zMrx9UMEj$2OQSh_E*(0tT5;DkoipJah5Y=F-f&y0d^;MrK2UbYfA%Bnt(R3FJl(o{
z!nCiA%auK2^h6c+DS8-`JE!KeTebWb4B@CQ<29E%esFD?aGi!qy5%$8k1A)+r7Vqf
zo|Kj*$+7F3kkq8~z1_DRe||FQyX)U@>k4D&?5!@Do)U6*>KhDZT{j9@vWxZ2X;Zgu
zuXPhtY>)1{yzjycQMaRPyn){ipX#(JlUj7Bd16+ql&b7z&I!!Q8=bz&*1ZYw7U<Jb
zVY4~%RbA0T)NW>>Rxp35wrK0o*?qJ8Cw+P&;b$|AQKkM`&J~T~O&OoOV|M>ySRY(k
zu<jP0uXp-6A^*xkvE%Z`4qjNPB4x6I?|RPXqnDKCDMf^{q;}o-XZtdywqAGIT_4w*
zdiD#KUZ`B;*V_=!!M>i$)nk^6l8u(^x21a%ze}D!<9h$_%-4)A0n&?R_=jKlI>A9q
zuHk`zu*k|4&M%nbTU0eCDlT`v%vP}Ol92DI8_NGaI?kzAV^4qDD8*ajP&!-h8RNP5
z@9uM)nEH3cJ_vsESak}gz~4hG9(Jl954!cp?c>tFFEwY2<7vbChtK2Ye|{Njr+$!s
z`8OTcgtt#60$n+N^9yXr*4P&Lr)y(w*M9TPDGS|0_C**z<ImaWKc(6%=JfX?Pg0Wu
zzs7fc{Nr(D;l_x?uX-J2v;L@8t<!kbF1_(pnU+_%MC&v8Us1p8*@P8-wQ^3V=~A;5
zJGg$4V*Ts45(lrX)!?#@swq3Ici$=M-={4imll<@l%8{o_{92ZOT`k;oW$h3kOK9f
zr>rq-i<%D$%>MT6k@>M_eFfi3ey^F=@TbpAnbGK+(6wi3CA*H*Gx<&J3Snhm*=ib_
z`@o(bY@q;XYSX}u0mL!A2b$45n9$+ZD4<|9mv7mxxQI^B{AIjo(8?+ArmM{{ESk+^
z$YPv)jOWe0z0$S6zll15wfsoWxLf$_jO3LSfzBL>Pt;hQ8t&|^7LVSZ=UQcTyQBkT
zh~?p1x1{#}|7SgCj@>pr;m6(@0?>&|w|`B(PN|?N&}Ky|p9V1Fpn$BJ1K8|@4nAQ8
z@C>YhOFJjTy%LKKvv5GCKYwc39}d-;YEkk+;7XQheO_7`o3pd?lBG*OK2J(Wn6R^Y
z%8iq=#mgdNzV^E)J<RROG}q4wS`oXeYU2zMk=Y_*;eRKIo2`sr)IOuEx3~A<+qb=1
zq5uAxJ&Rw;F!5xHgjI>glOoIdcduV}_w?{wSr<FoUYuF0F5}Xr=_+bkQ@hT0lyD|)
zJi$F%M9XC51`{JAA*V0?aW|F(?7pJ5RacCwwdwr+D+{|k<8FxFR{P5PW$vsQGydpi
z9aYeO^DHzbGu5Yd@{HRBPg;Gu!dADsEq-`8LgxkB`jUm)il3k3RGjbM7}1gQ@K9^T
z-(RNx^&h`(Op7&?l~M(HAz3(@BVf7OvIi%dtb#VO#yM{E)buDk+if!^{Ha@xeBswu
zp+58NWS9HT7jv?cFSL!4bF6k+!6ZKU%9W5MOO|k?KXT0Nvb^GQl6&@)B}-KHrF;9V
zIJ;(^so}!1qvsA^QOiBs$-C8CTgOoFwwmasD{5=k9BBy)x}x_tTxU~G*WGJN_g=WN
zZpM>VU#_pbNw=4l-kEN8jH`tKJeS=(aeo3NcB|aqEc90HWaK%is8*Rcd6KwUF*7)3
z7dI#<icZ})k@5ffhzpgRZA+GUhG$GzccrWB#FMBcT6Q(Q@$PXq&RG5H7U}R@VVr*M
zN&1_05gVO2F4~vW^z_x<x^aU;@sY#x<O`eu)22;x>i7rp$dMy1b=!9C+__U=QT+<v
zUy<gvM^qFQ8~x)A({~;}e*E+1J4gRb($>@CD=RBo<QFA!Tdj1rN$uOWZ(ZkZkeI&6
zr6fjaW48LO7T2i5Ec^NnzPWrd;I&6~?2>r`vyMg06?1EQ^mOr_4VvnmQO9m_6z|%7
z=+rSkj;r?Sesc~?QuQu)bwyM0$>&5S7k>lBMfEcnF6#R<yqL}t$#iC|Y|Cc<&o)ZV
zGfw=>*ZOc~{q{8Z%H9hWmS=oj|M<i&Zl1i9rFj2mHPOun_gDR@Z;o24SQl}u+Xj@h
zOuP%CM16Rs9LYQP`SSEbEFOG`OfLIjHYDBR>6rGobPtnc=E@D5w*5-+ZwWiD=)3S}
z+iAmq?9%^Pd*a>e4o|o-^Y&_uoL-}ZJk>aUj<3xpJv%ktM0s!sa{4t-c_MP-MrXL@
z^G@F;zr{{LURp9TGZ;>m8!#@4pTTg^9^{ET8(#jln)`m~f?^%Jwy47o&#eym;hJ{9
zWl{6QD=#KbHlCWr_m1ya#IL>61wN@3c&JpKoVR|(kyqUd%pNDEzt?!>67tJa=c{jD
zUmql@M1D!?#d0-rPN?Ak6+WB-e-E>C)OGgvD^G2kT=32A`Fz#Kkrh@xJ$84p7X-W(
zn7QWA>k3sJU;BHTCoH`3uzs#hz_tyRmx6^75}kLyI=XtwO8-TbonawK-x>mDZwX3c
za<Q*j%G9E9z2WqY{hwu+f~WqtaLH6?rD|7bR=b?-D#ty6>(4iXOZ<+1pzur)Fx>Dd
zOX|`Th0344s-ANfcXe=E@i^@-FfjjDuypRiONlAm=2MDJC&sDdO<$%zS6e|b)m;Y?
z$2D^EPc#<ou_<PW7LRcgDrCE&xTn@*!i##=+3IpmD?W(xur*JV_w)%)zVb|==k7PI
z$D3r6x3N9EUTZjEweeB*xychtQ`WvV*cB?M^ZI$K<z8F+iVNA6V)86nIh**{7BBeJ
zDJNk1C~lwAnlo}wSJkhn4r2TNS+F24ifx;dM_u#Rh8N=3m>1PY@OzxI{AVC|d)@H^
zXMXseZ*p4NJbCLB`CkjN6H@ZqUw3d{(J(exQ_896@;_kv?5oU9r~4u{$O-&CROMjT
zFLRFZ;)9FVB7bCGc0H0&I&;-sheO-Na=N!2e)2UruyenD{UMf)x<n?I{|1bo5``|A
zNbJ;P;4=MtN_lh9Zdn!Q<5_$easSTF;*gSM7mrT9@^zb-(>=GT(-@qMr6=_tmHc+n
zn9-?^Wm3EBiwpi~6Yibd^wJ}zOWnRhLgC+Zab^|$PS>~_OEgTSmI&^SU&#>o_~fg`
z8I@C=_rCiZcrB=XiS_J{xBogx1l|-`U(#!s8)V!Oef61)n!^`vVTE7I6*wnMSyFN1
z#w|tXR0k>RneRHQR@Rn3+W4`^B<GB=Ym?XEgD3CtG|%4EnAN}Ln5n2zsIAXOOYPVr
zs_KW&T@y<>YqfA=m%7>8PG2p1i-~5TOYAzICDy&`?66h1qPAA%=sU)VCsP)MovKWn
zEXJqhaOvd7saz9WWd5hJ$ysbYvVQ+IhWAXu{s}qv+doJ?ZqnYIDp6IY<MsLbGrm<{
zSdOTjN__T!hy8Q^P9fP4E!7es;~D>&pC>@`@xC%fCFMAcP`)^iB}-JCvojh!e;=N(
z?!u?f29usjeOVRD;d^Q_SM-aQ54J>kBrgg$G<8X*z&G<O*^*l_JIoqeT3l}2x+Eu1
zSf#w;wy%#*lWy!p6Dzito6}OYGz7I?G;NZ#_f6h)d&7*f&xh1RxH7z|nrB-G@-5lZ
z)!M=2($4<cJ@Ig?w#lD;?0e2yoRE`0w&%54Mzp4&dEBpri;wzFto2h5y<@v(u8p8}
ze*59Y?>x@@SZu$_V$XY)sr}m%Px-}9`TI@(%i0fxrstt4<j-{04m~}-Nlz*cL}Yjf
z^e?VWf8Q1QeDQ{_Sv+gb_Wa1parf4=-#NMNo7d_TEC0jiE_Lk5esp8y@kM#wOPjJT
zCTTpLe86*mPO5*e+uWTs+cI=Z`qoe3y}BexFOVrsxK24Sq#-5ls<_PCUJtLPy>n%G
zTwXE$ysakNB)E~?#kpF!Lw;G=Q6>GHOPdxbWzO+C#UL9c%q_^u;o7Fnt(Nrc-foXZ
zK^f`(ql@P6EvUSfb7Xs5OZ@DbKhnR>EAwu@cJ^qS@V6h8-r6#6ZRKCy|I<)-|9V4f
z0efq3%i{w(&Pmj6H~DvK59|G@KP!%<F+mFBPc97_q8kiPnoV(xDtk41`-^u;^VeuB
z{Sq7|?0id|H)emEb@e)hAiamyS~?yTy+UF6e_NuwwNh>+J2GV+)lt>;&<_6e{g7|T
zEseRy9mBsoQT#3u5qU7_8P9~4lRUqfR@_+RY|y5(HD=}QrSGTAf9-U1vd7_=KQ%p1
zQY<Fy=(1vOxly8Gwt0VXt#gsw``I$CUk+9#PF|#vYTUc;`ubuHHRgr-NePc)Wc2nN
z2zq>U<Kv2T8a=;avlYU{Z(MClIRA-v$AWhap^sNR{`N+`;Ls{lHolik{cG+8&Xqau
zxAyoiQFg(&lkB;>{f~X0YIm=6SH?x9AHRPmKRq?ospH>5<4G$S7V3H!E_~b{!V?jZ
zGClhjsF^a!V|5pofZ<Vwt)6cKcPBZu@{20`lHj{I$HMc}lxY>s+gGd1)L~6?x#QWp
z<bg?6!KRQE`f)0+nnGsCXPgWwOmq`}sPundU*Ll;lT#$LjS|etOy2Fd?vfB7)5D|s
zp}^o+Q=Dt-{;K&)p13Hn9f=Lq=v%UWhOn{bm1Q@CjWtUqt)Cp6XDU(b7I$Nbv*MOL
zT|ZsD;%+Qi5u&y4oZ#l?tz7(3+q;a|pZt25yra%iB<Q@;hOLhTYF<e>Ewz)_{?R?;
z%-O`?o5DKLn>nxFX-f{z_h-rb%clJ}I_biKgBr=M`2or|-z%BPaXa0#Ix1N7o=qp(
z_we?mKlUG+rW-9FEj_zZso>wA%8JU$kDaR1PqzmAb+YeX<f&cex->xJ$H~+rKbbS!
zv#0d*@C1o_{dCs(bV#lB*3y^17j8^tR_fsCV5s4LG(qL}x72^%+js5j+<ax_Rgb;(
z^ZN?-l=ruEu<kqF_$1j+u|09;Cj<Has|!qpyL0LnD;|GlZL~zQbiz{YhthLASlShz
zWETCoxY9sNRGD?g9~oJ{h1}(}Jtd#+g#37tF-b-6=T66}Dl2`RqqAmsE;P%0KX=Aq
zp)2Ya_oytpt1~;vJYa>yf_<JoyDJkXJ5}?p<PcnKKI7LSW%s^>ySqx0cn>n1?_YcH
z)mQJ0uL2Bnrpdbc#|b<!TE&nPxl=OSrz+uYzvzdG$oe<V-e2VJ2+!M6clp@kD|7xy
zY&puacUE@c=X==}+vYY^D&IPInr((zuGFDJhm7jIA6#7Qz9M)zpO{X>fz>XC3pOvz
zywnw|dD+K9wtI$X3aE)a(Y-qE$ea(Zxk1%e*3Agm9dv2e!`-j%JJ$X*nsU7Fqmv4E
z)T)<Hd{3|W_I3AU6U{7M3w8Glx1I&s1*!i6%~nL1EB>6`uU)xcMpi0t(y4B~UXGld
zGKcHGWvMN-l^62p(XC*7^f<Nep4}3MRmSzku?ruz2W<MGzTR2ZLN-fibCRBh8K}|W
z>9af1>}X!kMY)VuvyW_<EpDb6@*_Y{>6(CU@BN2|+c#!jR-0o}8N~6o#!k_pq~oJ)
z=UeIXk3=<ftTZz-Tjw18wRob&)m@UWroQW#SX{OEjD60&FF#ctKe}XjqjbH{wA^<s
zw)gvvbpN{laJsy7O5L;5Cj|>K#lPL<ajiO$98)LQ>6E)X>D+~D8XqSnZa>;Be)#<P
ze%^yGIL%lV*9&ztPt=QN%nVUcIIEUrd@1ok2nSo63qy)O`y&?BR&M88dv^<b_<6yS
zYi4}g9>EI5k6LFe#rT3(GVb3oeRb@!%@_28W!5f{xN~Es{ePj1a$DKcVw=sC*5`EX
zwGeORJ@}%3k5tn_-Z-oGAGD>L0uPtJ?q6}eoLQ%)?ZNhaR}(y=EVfNsa;ek1>DUsc
zTVHY;ly=^dxT5&-XQ9rYT0_0pAqHkyeTBtti&8&&y!rD~Z%_UEKB>N@#l1FtFQxSs
zdQ9K>BHYaQh4Ti_6~9`2ozBK?Ss&+USIy^9-1febL4C_At?))gQM;Q}H5N;mg697+
z&<PFVIB7d2vvb0%sE6D4KJ4%c`}8`m!eYjP9g`*ZKVI#%*ty@zuVBNOyYuv;B0Kkr
z_uMdBdHd|-))O86iw*_(Y@C`JoU?JN`07c|T79|RCjR0IcX~QO?za%X9J}I=d%Q6_
z-?yjO?U6f{FWD_s_4#*}%g?(<wz?Y@th~ig>TPv+Ligdzn<sAguF1W9O{wFhWC4-6
zOp~4NX(WC9*mD+KH$J(q9KVfc)@ySIB}JALhoC#cm#j)VE(mC;1vy;~O5O14isYp=
z{*hnLJPH=HC^Bd3Gh6l|<}#<6OF>3y!}QIXTH;sVSEn(#)I(b5KW&O^*j<FbbM0$1
z4EU5TXkl8bEGJ=d_)GH7YRNJ#aNBwU|KXJ(SCl#TO2}+sY&<c;PL{1CPJr{V(WS&o
zo7GiZyZ_mCPSIPZsu{x3HgDdaN-@qO2O}nN9afqC{N{y|3$CyR=ocLIZ@cLp|GEG6
z@#CzjZ%hn~44eHkC+_!1WOB)eyF|mG<8w&%0;P!|nO80p8nxK*we@Un$-X)1L&>&h
z(}mBiho}_1kg;HKd_v%Hzpkk@Ke;k$=QBKe61P*PE%o$)E&m(Lg`GVAJ!o~~)3SYa
zAoJI=V=9}U@bCsbjncSc^=F@Ti~V$A#Y<cE@K#+p_h-eu(=%;08%Z7$D_OR)!l~g9
zOUFM*tLjtblYoXLkDoo7D6#no)1@`CiD?>*F3QeZ&aoVgl}@;^>E?@fxq838zp-rP
z6!;sofQ6%Q$+IPw49-6D*jiWjM_g%^y8nV(`;?0lb*6GX+y95hlXJb#!G(_#60(?@
z>n$~Zdb4`Wa_T-HVOc4{oU>1=dA5G4#+!sD%e`HP@7$PRVrWtKP=A+4gjnH{rY$F1
zrv})It2umOheXJE<#x*p9Ae9+W&F6ykz-da8ooa6&_UPcfOYp2{@mFwq4%#;!0^yq
zo@3#>E0<i^x9>vCUaqfOUk6M)G~JOU@7MeN%$q_Y-rnY3eRg)j)?)UaS63RBOb}K%
zB6+d?|Jolvg!J}%9Nf9wGosv33e?Y7{&xL^t;>}4eAaa29`;(eW3uL)+$9AY4ePvX
z0zPFoHyuo<k$n=-kn-TFv1;I%)PQpn%j{<_E_nH<pjwVqvhc*RK+XxA<wg?m%DYx*
zXncR$ez1}GLf(D8qqDXKtciAaIbj-+dy{FlvU`G6iUE(0Z=%EX2!WT?fA|akMH+33
z??2jh`eH<(p3vuh_XGD%aZFbWJG7HiG~oDcsbxW&`_FSVA53^6YWc;XY{jLM+;>*X
z{<y!za)xob*}s?)X|}c8%D*0I9=W!Pr~IKG+v9A<jiuTmugx7c7Kw_ul&m;Ehq3&Z
z$(eSZ#;4bGH{9AHD0X={clmQ$@s1A>6-G?$@6{i?ILzXrqP4L)MRJZzyj*SVzM5J-
zw&sH;e2ea|Xx(}u&hz%7KwBas2M0&vo<HRgpQFt~^a6Qpt3ur0)l4~&@I?1i?e7U6
zpO>6?ezyJHRqYo}&I@_@+O|ZMMy!kET@%H+w!OWe{NIDR0;#&2-?-A}t9<-yllEPw
zFIM?fLeTU6_uCI87)Vt5^09gdy_>VEY09K#!}7OLYhrhctaU1Xv^?;6z@zq$FCwD$
zcsB63<t^S<C!3jkT&ea?zDvQLXXeqy1tl#%r)V0?|HiKK>`dF1!o_E12M7IFAA6+j
z-0>53_4;<9y@IouJ|4a`-J(Q)-u>FLl+%YI?w#jOJC>8tdNAQhebI}RJ`W#E>Y8l)
zd%<P%yB9WJXNfT`asAnqXK;mUyMe@i#gc~)J^mJI1pWTn-o_!Ym`gMvVx5dnJAd=f
z{Ktv6-d8_7_ouP7lf}&?<<Bl-iC8h)<6D~72cA64G_^Z&QTbk{88=s3+-XU@D9OY2
zc)tT5Yloy)NM75#!@n2yy4&=<t>XAS@328efbx##&siNLdU6V~OfS{{W8IW@S22DU
zkJ{VYhj)0V&-n6=_c9}M!maK6_MImCH-7O^iPGnBTmO`Cg%gYWdMm#_ADxB6dGg=2
z8Re~EpL8(c&-WiK3>THYoRZ@Cva<WuR_VvT<NqCcm;KOS<ENu@__kiybC}6SV88jS
zgC``dWOr;aDR}wv#0(?Rm3#NM7T(@wAZ;zSteI`n|2*c&e6k9fK`uX<|1idGR-P)e
zJMY-SZ}0hkC{8^o8*8v=C%3-MuB%0l_NOEoNc8+SnlGThR-kd0>#^9{quXMwH&h;u
z%CRV5)o-dP{Ca~iC&H3LwAVr-=t+WA%f$Ev^Uu6eQeJpxU-SF769gYBt_|lG+nn~X
z*m6nf>jM{VNAIxyFEDk@BXN$`dp=msI$zbafkpKizxL7kgF)v{%X~d;aPeS*!9F=V
zMF)|J%2y26&f7E=v@&rOowyu4Va9}>D?FB$QVv?|u2XX>k7Koes4vm8$LaNZ{;xkj
zdq|r~t!%DiSRR<J$F(g_cZu$-!xvV!6r}%CRPt<fUzoW=d`{cJY~~FQy-c?8>-Rd_
zPd$2KTAoJuk*52VX0Gd6gH{Uv>pGZV@b7nxQ-j3eYi9*6F03}#7jOTi`uU6d^&HFA
z*>$?CcM>QU%wubI5dUjr-u~^S@rv_v-G6PdUuad$7j}Ewp<f5;W=yj2GB2BKVaZuP
z!QR8``iIq%FO^z9ljT3Y;;iG0avdJ&wkb!t{@v3^nY+_SGge23dz+SK^T8jtPJGPU
z@jvxOoWU>E_1~H%-rddKd_Y0s-d^t9Dk~jv-7CLUE}g&0`#p9_mTcMmuE*_B>wZi$
znJn?3Kfmjfu($ou>F-!S=P#(98nJnA!WX97+;0Cj>`nO6-BEq;&-RTQHay_oGvh*&
zT3X_1CH*&Dxs&zymMKZjx2}=6)5>k|zm{oD*jkaN+|%lXufH{awDCiT%Cxz?$1b*e
zekj^_;A8x$$0v3aSqjOEWCgF`Qns#4ocw9)aZ_#nPTBK1)k(L`Zc<&=zo298wkdly
zcrGma-~IA;=(mO?ldpYP6S=t})MIDqYq3=!E1Ouk#T1m4oB1!BYfbGEw@um>p=ol?
zM7ir`*45R%pLVl_g&BBwH9c(OZE#{->ek+Kf}`O6x3<b=HUpLS(ouzCOBQ}!kfHrE
zSvU39(XJ_ZuiR=5PSZYFA-UEisf#DGh*wK=>wz8L-d$L6;`8Lk#S>0Ht@+h;GwK}o
zY>_CpmwLyOtco}02HkhK9R8*v?dDS3ilop8a8o~SMgA}Iy;J{B+q1#*qR@Z$*D@R5
zT&j9|Vxsa5hni0(C#$z!IRD(ZXrGvWx&EOW^6kk-cUD{MPE?mWqS=!DvwO{{0IjK?
z+HdfgtQXuoA${U%vzPf34<EQR>HZbnzxDr}kIk=Vato4}@ICX+62moN>zlSDxxNq*
zauJr7Z$6*zCKM6vRrt-*s7j}%kMZ;$0Ri3ir7IQ1>cW|#-KHMhvF)9Q@8z0pKTddm
zQqmV?*>q{E!czUy-aX|f3;8`h+>DIatIo2XN&oPo%OWLaoJW8D_$2W^TYAUS&r9cv
z>&Nlf+uN^+*%<^HO}6P<m1xzbr)D&>M?9wFhNsS#)L_qhv#<SE?O7Gx+&Ei$$=WE+
za3fDIuSd}nlD3(x@XhMKb=EInjnMwL6|F_@rWI_PddMTGA^)}IL7VBP*ydIzrKTR`
z&f2)3SR^Mm*L7~U<HFB|N9HVcIH^55>3sKsfZcvd{%6i{&)yQ=FfH8hc`|4aeQveW
zbJ<Ilu1Sv1>vW>Fc=T8*cvjR{NCds#Ct<ioY>$j=z|LZ43E7>k43+=l8C&>HcEp}o
zx$gABZKp#&9m>nQ9g=sKEAsg{g{7QsvQ`Hw4m5l}!mg_SD2suw?WUJ+$tEt_Y5N?e
zvz`~2zUt6--Z=(aR&v*6yqS~zsM+bUC+pf9Pg;FXU6;GQrbfHWX7iiQO!L#zZls33
z*|HSmx~;$CeeTOtd2m~ZURJby$@(XLnUb!m;6w9w2e+?a&RN2mUC})8_l2uoFWU+>
z>BTC%z92Zqi+A(<`nHqX?;qL`>iuxtpT;QeC8xGZ?ENbG%D=kj<L)NIU8#v{WFEBs
zO+LM7NASPsQ*#d{7<^K;6j3;~!upl@m8W`1XMeHZ*!{!5XRdIcyg0v;YO$Jw#DBin
z92t{-dFN}J#Y5819Z33?6LDs?cZ+*|-P53s8?yiWGfHI+2~YjA@rjdB)cNo3$5(xe
zFuovtd6$^;-AUK}JWSBM_W?A0^ym7?h3(<a)1I}Y?O$_@cRz#8ciaB2n|B|uj%+I_
ztge-aXWZ4n5m&L~|1WNl)!~P;9<$B(|A~9Q&920glYVA7TkP_Bc}}|U#ojyo_w~NF
zFQ3cTer%f4<f3gF!8c@FWsm+n1)4tFCsw54FsbnU7sWRb<t*3p?zg|+yxU^W1AiZh
z?XvnNK8*%NY<K6o*8XF9;yq0v`C9yjAFuTz^y1E}5AoVxaZ>+I_0%q7|4AFZm)RW4
z;dOGEB$Qsay5aKvsqV+KzG<YKtokd#!}i$w<U)o*r^|8o7tHx;tTXR}tkjho4Ubm$
zKm2hrKG6A;-P)uY89%-DPY)bH&9|h}VJD{RKHa`=`@OBgLgL~MN7h^Y>r8(rd85u&
z?DxAP$zOkJ=-5a${yw;Jhsj2vW82H0Pj_9;KKJyRq(!qqmC+1;4gp!AxVVGQEQ<}w
z-(}fc*|9KBQoUf8^$n9`qiO5*HC(UU&BClKzc^wyUzch2kJ_j!>E|47Enr;JDPgD+
z>a{~TztcN3Sx``l+uudtqhRx5exZV6=A57RYd22bKkazDZ8vxMKF24W&v@9HKVJQG
zQcfVWis=v&v!H-X*M|=tOT;q!GmG69?bB_aGKD8&hI`rs8wc~&(@q=9bdA!^wU}AV
zxX*L0=%-P{y2!Kn&GY4F)SB=-E@w-=`O;%g*Hq;WnZ2*X4y~J*x*=_X`I@sg1h|_I
zCcK#K&mq7Wv%2J%%cZW^&5y!Ov@$u?Mzw}m{R}yL@Jh!YOX<eM8@HS`mg`@t|Hb)o
zvRb3JXXBBZtYXIL2bP5EKU}sa^=zvKPt<Rr$J_Qlsy6glB6LM3u~qecbz-Ewen^3M
z{zEg+jO&vMJ`b&TdNbPJvMUSzs?c7yx1&Yt4PRP37sK*It|beSOFk$p(T_W@qJ~vs
zs_yCa4->5l8VXF`FA(<JANfUQ@ASP6yPS^a{|UQ%nQMP(!SOBYTrY0xs#whi+N}CG
zw@Aa`lHi9k45CtfN49X<2JF3CF7fwy{tNAkO0G-A-X)5dTq%FAv^BQ+guGo-$qj=U
zJTLUK`q^XO&5^sw*%i3pa?|q+v)7z?Y$q=4&QmN||F$LZY^>p)ozhiT1j{WmKt8CM
zA;TrWUNOa}IY^v?**M>ZyQcH`M9vL-{w_&!y0)hU#Qj!23D>#m>Y`M7fMLm&_Y7Y<
zCma0EwNd%IuRZLDEr&));f5tVx<ON)1Z4btD7wq&<(uThA4_8eecrukRP>Gg=<DlV
zvg+Ll{+*x+Vdei5oY(8P-pzmQB=((2d}`>$>mN*(@y%_!z&Q6|vhKZY?|BLzig49k
zG}u+=er!wTgwof2J@(5E{ka~WXjv}@YRFFP=jVC(d`r>J58=O*vrR8u=k!`*A>BG}
zwbR9HSAi<s&xae_^!}V$5>jzRJF}N<Y3_rh!=KbZJ(KXFJ<@v9wVd}H;_&nPlFiQ7
zwWUJknB;+VE11vRd&%~{$YRM+c4Y$}HfjERk>U*%`Ri6|neyl}2`4;z!{=|#{^xSt
zT;ud}E)^9P;3aD><aZe>-d%J2*fBQ_!S*RrMC#I`PU}b9@c#VA@@^)_tk>5U+SEv}
zsVy^DZYw))-k-7`Y}>XSnmhAJ+u8C?pCCoQWzWp(E>Dz^QVveMx3R!Z{)9*rPv)bx
zX{o&nE=e7{bBCud?9m!^r}CvscR%df$*ivmo&psX{umawboawccjxr>9u+Mrc^+bI
zZ5>$tP!uu?`tse<EpIwlzj~VJckcY0Kh1Yz`M;&sM}qFFJUh1qG?E;m^;7o7%WBbX
zVRgTRlao|`-Q^9RDbvL+UX~a%|KX3?Lq#$+wNmNl;tu@0{Q6_@^wu5I=iT1@u;>KG
z{<f+1yl(pw?<b!)pIvAi<mYsMfmdZC^JKRNw-+)S6#U?ksdm$<ekk?$^F^CVuCG(I
z|2T^Cp8ip6b?LvkAlnhe%ca(9%HFmFu8o?hJ#C+|T@ka@oT7)3MtZjAZO+;H9%>SP
z_#?AgK<ypxL4E7^hcEuR$Vi6swVy0}STA~UyQ5-+l=OkCVOq0(Bp68WxV`)6$v8>w
zCr5jj-tl|h>4o1eDdybV!YOUO=J2)Ha)p;6!g0@bzWsCg!-E%@EE?61&YZpcLaDm%
zvbwx-><+Id>`w3J9NT%^wBW-r)*kIuM}Ou%7toK<{jg`V+VR~5ot^>jZnIyVs2m_`
z$8&X|b3oo*rlY@j|17NjDRj-c{J^shiZe>y^D$p~wCuQjqLyjH(xc0x`~C$M<?I$~
z-n;$rKfAI!9Y=3<gFDQt^<9#AEvL=vb6LO3&*FcztIV&JGJgH*8&vO4fAGBULUa7Y
zDSzZ*Cx)y|eSN_|g6CNML>az=FCNr?(aF14&$+Z)@V;u^qnkp^QB_>miv_=Gzlqr?
zIDLm+gzYY_ce)ZSi`CW|BzT02EG?a*Cusg%@9-aWyBp?vIho4+j!l~$_QK?!c*x%q
za%r2zb&qU*kdPC($A#mf{mLf`_8L9nJ8&Vkn&Go_c!G=!gT#JinJK5v?3DWV?}?gH
z(2Lc}CwHj(E9rl^Z~yZ01eZDW6W!`A{aJka(21*2D$6njM3md7zLegm6#hEk<YA`8
z(H7i_mhNhk4_>(vaz&9TYck({57#)Sd1bGoA|pGm<@$O0`8{hFIQqtH`GrJ1D-%UE
z)}v}m6^>4QmKbgO<<>vp%EZZh#TOIn4cq^mpJUm~$}LuNQNX9~d4mf3n`5_rvVU+$
z<jxkp^yx~(ft_E=e=H3Sy&?T{QS+pqNjGPm-SNy!W_MM!Qo(EU2+8Y0&2<tzMqy8O
zX-TDTKXc5aQa(mDQgq|;x}%3~M{SWZljoh=@bmL?Wg{b_&)ZqH_|IFkccVzDw5gcW
zmwvCMOz!{AKZzAwkgjqe;r&&QJKR34D?i?zDmq=U{mODVpZ&k}f@?S~tdF*MyFWho
z|Bc5YOH__5s7mDXdfWclX_r%X9q*irix$O}UEY(haIZw>lVA5I9GLUOtJUdX|IKd8
za0SrPk65j$BXjf>)RU%mSsUgCt%$X{?&`B~YPi|T2C?7=f#v?6C(S6^oYQ5S-xYSM
zB(G%#Xxh)!`;YnDdZ+uVB?9(4v>tC{W-s{k#8dIh=aUN=JP$s+m|S>vnesB9*Bo`L
z5?_Rsy!yjrA3Lv&Eo|qDo~w>G_9Y4HN!K--Dr-GHxTw)WCAX8YdG}(8+>%#91<B`)
z&eUHN`29blWx?Ia8;_o6lC78SU$tai{Jt8?MT-_0)q5*Ee(1bK!EZ}qH)y3s;L0gA
z2aOE{%d;z+zlhAyyC~v+XZ695#Uf6uFH#a&E7yH7XO7z0=(X1A^dz<w57NE_GCKJ#
z*DMKGVXsqCG>QBEQU%Tldjyy(12uz<jEpMS_0o>U1mpzGce%eB<nc>#L57+cOf6<r
zM>ow@b@=x7wt5>w;Gy!XB5U}I4`1+H95Cz3%2ndh7mDYJoWB0GF?-#!WXW|p^Lulz
zdndi?<GXRa*2Zb}_rv=3S6JUNC{BA=UuF61Okm=vpA##7eg0o?=>q%z*?)Ose!PBf
zT)ohMW%H5*o`W|Wn49bW=xI#9xWw_a<iP-~bvKfn4SuO=YIeT&65HIgWP_r_-=GPP
zygnQJ-R0@?>Cm(KQVzBDdp_PGIUIiLelyQ~ZSJ(#?a2!>QT6pY4(r`?FTP)1%OU*k
zPtlryt-it{kGCzzJe+nz^Q+rtv#ALyzaBkyaCM>aJ%*!MTU{Pc3ct9oF8R!->x=5n
zt7)kG`PzO#=xgrElW*6T+A*HwS#nLl@5teX8$SNQ9O;iHO!E8G9`xjkYQ_ocrS0G~
zJX<|?M;ujI9UY#tB6j2Dh@9D5?z-n*a`wq^b<Mq0e^lvoTHmc*J2}qoPFkK1ntR!u
zG=1is4c|E#7rCA|D*7V&GJEaw`R)-pN`KzP9(#IvdSUQQ0qro|gJ0~`6J7ROo!Gm+
zpEn_Lk73)n=qA^Cy<?Lqn*;Z6VC7M9z4+t!GmXq#4&mFIUYI2-hMk$wuG+1>pjdSG
z94$>yQ^P>wXM_Kh+d@0SUU#jWz3t(NrMEwD^SWx(vm_R8mw2;ta^Ef9nt;7YiBI0W
zn8#Aqdir4dpR&mC*=O{%d2#~QtWuY0>71(e?cR#(3+z@^>}p!e1X_>AbF9AGpF@Co
zMud1%`pr!mPoH)!l9T)JfZxC7@?K+|^4KGyGre|92P<V$PXF_IB6ntDzQ|=Jtz8<R
z&I72hP5-c-)#KFP$vZMrnb=qE$YudGRhkd}c>kG`aglS=|J0mcul4_Yy=KU)JpHcg
z$%$_RZu;E$Dgas6_UHT06#fn^Tfv9x;~rj(cGtKQb@srad!~wiuh(io7QAt3&7Z(8
zv?J_oPiOYEgtOMin*_hQ#;0_H9d+zF<LmvP>Wqz?Wpl`<h8zN$;#|Vj!mx3}hK7|Z
zR~D%8g@uJ}*eF=P(k$!prAt8;!tHxDcy8Rjy?y7-ods%qSC-A3IkP}bj*pMez|c_e
z+>ypxCT3=0=Z-YrGBpw^?`GeaD<vWE!Hk#p=v{AbrHLQPUhYqtm^%4bq|cHd&HQj5
z&_w4iwvBJ2qNAH1@5?ccV*bP&f46Mg%9SgB{CqxNar)_>pVj^6DJUy5Z_T>;=={+J
zE3v2tCQ`iuN_<y3FNLqVn$;@sce1#d=9P7R%OCTD)=7!Hx{(nlw0TF+>@Rc0rtA=7
znSDk5qRpDH)likJn(IQIT(olc*)1q2So8SbiHXWiC!T)}<q~LhYSfM1=CCyA<MZ@$
za~z9`jCPg3KR3Vo;K640iIXNZ)&2d&srYC^;bXUbQ}1m|c2{)yzb1aaoS&cHiwg^z
z1(f)@#dMvvW?c=~UstQ>@?R%nLxcFHudl8OI~_^<_2uP@OG~*=P1DtGc`@Jq{~zJI
zyGos3URv5J@Ynh7#V02x8|K_F*s*ID*TP?|U29ebFHbtsAy`mWCg${&d#h#YDUlv2
zQ?6DnQ6Z<V{XS}k-`w2%asU6n{#))jzhZxWW@dAzuzJ_6>L0(pX5Taa`|-HEQ^!9}
zUf!c^ywWaPJuCnGF!Y;a(a0&R#-aG@`OVGg9NgT8Hzpr%nNZItst|9@Ew1<ESf8x+
zoX*34etzCr`1lxS`Xk53o{zQF7Q6R96Vs2=nbYZhexB{lzrVk8r$2JgN_qF;;o(Cw
zD@^k5&DmZ5e_w$b-`QEFkLB!YH0E@=-`!QZ^Tmsdhdwf|uB<$K^ypE}^hW`^%X0M;
z6&)>v*)M54&bqcnb53V-&`OcJYN{$KEuTMr6g+q2;nmgQi*7H8*<IF~eRtQ^0yVzy
zbuka4wqz*I`D@K}L`J~sk5jelk(O;Hmo8muG5)x~?4`gIP|@X8Rb_R5myqzS)zie^
zPkoknt6Lqk(va_az-~`ZPtekY!wN~am&883vhK#q*)wLGI39YYXmaZ0UoM6VGriw}
zmS!#q_^<tK1OHiP6aIS6H`)@mj_NON+`7dDS|WLgb3@W3aWl=5OQN#PIvf^OR$X?S
zrusQSFD9_ax{FWVvtg$Ag-RxqbtUVXB0xhWbCZ>yeGpUC&v_>L<uKnX<$W#di}+6L
zzOXUOD$Moxvm;I`Lq0venN(lvTwRsnD8Bj83GUe<w=OMUohO%cagi%`&F{C{fBgIX
zzEz-b!CqUF+M{b!R{GAWKl(4I`PR~6)+2v{oO5Px*&4MnNVSe>{`Be71y<Fs@L%+_
z?c9F>Zvn6i(w%E3&*%k@I({|)ohbDB`g(4~U+v%OF33I9pXnW<P~~7_Ya6)CNAjVM
zOh&5WwjT=uW+!nsg2pK&<9$9lt_)h*l`&a)v$O218@eS~!8sot7nU6rkr&yRd#P(j
z+1p!-d|A#m-C9~G8q5K*^6c&_khP$1J6FW*-32Nk<ZCnk=?d6F*Y182XI;b&IjG3(
zUlV*C@8_x90+xTy>$v^j_t&8Cu&2wWgKEd@C$(gs?tkc*A!Ky@Ux?C^OI$oZ_Q}^p
zR|>4(ELP>ar}L#fzsr6`<wBhZ4rilxvVXY$dc@7%_uERSHNef$nfd<O$%apU?|WhW
zLH*2b8RZuD$7hy#s?>iuekfRff?kW(pKlM_>;8Utyri{a##hzdRsy%h|FzWJ=Rfc(
z+EAdpHqmXL<LpN3*X)b)@4q)pJE!&|b=_*tCAP;dtvq~T{e6cwb<@6{TrZ=4Uhm=S
zUH{iwe_Xb%dv}*+@~_4BAIvY%^5Hn`UUQVmrG19G`^L(1r8h!#+dB6C-k5sbxMQ~z
z$K(CZOy|x>bT%qae~>nbtz=isqW_sWvkDofiFPah`;nM)=Z{F1lI}UbNY?u<))f)Q
z6EEjm3-~x4UN3jxn`r;TpuGlhYi@VWUEbuOv3SA6f@IBOvV1MxKWD9Yrg;4A)yajH
zp6v^mqc`S<OLT>8J$|-wcHtd!F|T)$+a~^*{4Po+?cnweMbA=~IJUBDUwiZ<)zap)
zM`6t=w-_Gb^1nQ8b`8M~zE0(xQE^scYgTyM%hT)@JAQ}>u6wz|tXg#4{wa%g>}J}n
zp3}NMs&R+7`o`36p*O-b+g32MZ>U@@Kk?8<3)4*AxD<<p9iA*^em8m<9zOrf9lw#m
z^Z4uOj2#8P**+ilIofYm=27vFA@Z#t+hbm@JGU!X)}N6L*jVIw;c7IG$H(5fm+cPi
zeKXASxZKQ&-Dmx0KC-m^K~99?7pdRu%g)O6b8X_T5R~p`*l&<B<z4fBx3doay`o(9
zR5+^eE?$rrw}n&fY*d$hon+(1$;THqyPN3QR`jL+>)f!)oTa{JW`Ewhixp4hn|54y
zzGKyzR{M0{ga6sKx21kiZP83B_`Osr)w=KKll#vWO`WMfk4;q|@{mS=gv7yZDZ)N~
zi#gl)rMu-qyOdr!YHZ;++R9*TBK^U7*&j>h(ks_L{wbA-`^~O&XX=&G<mE{j%+)GC
zZQWvCY0v4@>Z#lBcl^uC<N&RIA~ngMt{WV<uI+GTrH6;FYfPyAKGWAxZrm$9ITl4G
zH+_@~nv!uz$hN({J*w=Q!IcY)5|)!DO%{k<tMa05gWo+igUy_-J^2z$-r~)Bdo?v}
z&uN7I6jiEuEU+|4achv_zw0(yCl)?dnxOEnsiVi{*qQ=WlMl;wPb%uz@mZj8z0~65
zn<XqBDi@{{K7Rjk)vT71NS;UY-4&NqWnQ?Ot|PNH@W$j2rT)bNF(<^19ewM$!qh92
z-#umy4_D!L=9DLvZX5Js#7gfzDkumt{!{QpQ|tdF9<hu1AFkYG4QqYz?y;Umu(C*?
z{v*NJQ`&Z9#nrUF3-V%5?!Ml!bl)nULW?LNezj7!lb`ejr6%n+x^!LJ!J;qzT4eSN
zN!Lyn_ZX(THz(Vt8f;Q*j14ruAvN1!b%4|H_2CB^FK2rGI~lY4!TUdpuQ@6&Of-p?
zbVyp!7Uuj(YP#+EiN7s$e^&pS68IoM@y$U!o&S%ey#CrrOnuw4;KHi~!q+4xN~FCr
zIFq^c!UUVc&((g}vq`-OQIWs6Cw)TcdbTLp*?YngCR!}I*sr~@DkHKbHomi(G0nit
zP~a2$S9_KE3wypU+~w!{IegjwMc<_Y;-{Xk33?`6-zyP)=-?@~bN<dhFW*o|E_k&_
zBjxaXBMJG29d%lE6;BhmqNA&K*zzhabg1c2ypk!W5wg)>Pn@gcG(Gk2stQjkId@Dg
zZs_im%!zOLykF>LK5MeG`Hjx~a)Qd|0~KGr($ksom*ML3b8hcXJyX%Xc{rAL21^<r
zL%UsR%hXcE8`FziKdK+>P)~g6DcQmQxhXp}UBvrLgI?1+@5y}+)K$(~Mjd?e`s<Y*
z{zc6;mO|@;coM^JNMBtg;$D@a(&Q1RB|n{~lId>07T@}s?t@#GFwc3j=Kht^^*sxN
zcN|`sBv`@fq7b=GX`L?P`oG=>4=dNFE?I989lfaF;-P{s_C2oc=84Crx=4txW0<bv
zcp_m>yI9v1o)uT5E;SjrElfHZ@Z+kXj>QJa+vkM~AI31Y=5#NdS7^|e6W7gq`r3na
zi_G@iof~lHu-v8g-y2@th<dYgb@SS4Pm4`^!X9|++|5zD?<Pm+-7W*({XN0r>kis4
z6gVYr>U`?z+#3}soP2vXG<zEcIZpZDc6G|?h+S32W^Z;iWSoxru%XCR)SdN@U(V5M
zcex9+4oSxyeWUQt>Tr)uYp~L<cX>Q>ZJO_=)t{eeZLs01!^*Cy0e6+8u7Arr@~qUm
zKy@eA9-Fxj;_mSJ{d3<i;achR$BLzz?M~m0K1>$r_$z%q;cb_1#fsJaoAQ31)|B*9
z<@o=1s$%2TYD0?|Ka#%AGB(J(z<Ibnhjse;`u&>6_PaH<1ekXHn9|(dY^f9L@%qp!
z%aiu%2Sf8)1sC5s=$h5I>8elRvj=`Ll}hf@BaJWIIm+^Fo}5A8y+glx!yjCDSk3cy
zo!*;>)msk;)_u2-Q&UwsbYFaXUd-`c@rN7M-eAm)5^cBnBeU(@F81~R78`8vm5lJd
z6R<6XDQxYX?gDOoo|$GmsXDz60<VfL?C(qXe{%W?(>$SHSBjX6qgi>FHQ#Veb~|%<
zX~dS-R&v_57vCQ5T=8C`HC@#D&h8E3%h$OtIC|yfi<moXVe4EUYFsJ3R3&Rz6TvNF
zw8?4bsvw!WdwI>9ExydLl|9S#RDb!AX-Vne4v?bNn%-m3KE({^h7d*4clIE<C>vT&
zNbt1X^WfUmeVwaXL_e14TANdX-T_6)^>WJ(tSk|Xn9X6o#`oxI_V5Dp0}`UOUI!H(
zNxox0;;`~z!m|J|UF&O1cay*6hH&hwV=6yf`r%t<`>EF6pJyLR@U;C)1hr9|^IK$Q
zHCdkiuHc}@@<fQOt3AT>zs@4ln@^l>73W0R@$T2#-*e$bbi}vgIXd^Y$gBIw9NgAg
zpLpw_!=C>VQZDv8drXC^la5Z!C_0v4aO9EpJ?^%H2{mTBB<}3|$q?TE?#RDd_JXKq
zeQl|8KU_T5-QgXvt3tC(eqV?Bv7>?8E#4-39Blsk*`WNj?H-;gmUC;ZUYV`sJbKb~
z#^x;kzW7Rp(2Y_Wsrf7`4j0xPXVSS{BGMny8nAMTwolOf#}78X-cg#Nt!L-QE_12i
z^#j8>_8WMA|5>6Dz0qJ%*|`Jrt2-_j=(JUtb|0SeYQmLp3(1@oDf>VC_E$WQb#jME
z>`dT1#{aHUZCzu;zVOC(vaugC-ZPzvFPE6^bX6m2lZ@8YY}WjvoG!ac9R6P7%egPg
z=ByII&(VDFgd58_omu^*?r~1psV(fU)f1kdwOG-*I)7nBAMfe@L;7c#^jaqs<oz;i
zDO$;4Tg-4;{C->GRGEj34>|k|n?J6eJ)`iC<bxMn)klqU{=Zd7n$VSgdt373Y0oD_
zy)4LnsP)GFyVRx|yCXjT7K-UJZf)Hu_OJa~(!)i@9$U6JJ?XT(QS*UKsAo<>ZWdc{
z@MCkoGY1%i)^c@SF>zSEboqssC4W?P)f-nPD!rR;-JpB?(Svu1%?o7J3;tcww#$<&
z(zP)AaVVjK3$(#ZS(?pYi%t()ZQb!Loy8kA%;Z}Bp55`^!i}6OZMC+q;x4bWnP*qs
z+p@rY$9ws%>hJ3h?>KIB=KtS%iQ8Mb=IBhhka9%%nXACOy&s&T&dM9+W|T&(aw@!L
z&!iTcmiTQ;>yN#4EH(3OT|#z=&e>aIP;pF!NAd#Gx;dg=rtjM|_xm2+<)|v~K}q0P
z=&Xf)bKgna+%EU#{^ukY4-cONkunM4U)vpbm#sBSc;<ZN#XX6mdsZ*-i)7#P>8o?h
z3tJn`-bd}JJu|)~K=;UfWSh%oWo>S8)9Yt2w|RL+sn@NAAM6V2EVlhs6WW`#IJW(k
zM%GHltPrV7yjM5qzdm#SQP3IQb!CzP6(-02NbX-;E-K6S&qV0)_caG&<9SW`(hQ0W
zAHUzK<<-*ADWugaxMbbC4bPV!KfPefhUQ#F>wWcyj@;vITgG<6!>=hw)jg`M>)sc>
zC;XPWCD&9hE{QGw^4gqZ@iLzy=hwyv6uwgNV~bu;c)V;y;2o(sK79YgL8Sy_ci%@g
zXJL=S@{bShRp*%O`ta1#;{~M!O`RJHY^^mLEvBb*aPi(+>|JQwaw3>9-CSgQf%A(t
zTMl2(18<A_1s~+MJ=tAt_}x)xRlT+F?&<uExkof(x}OIGEo*%ANY`a~%Y$c;#xo9y
zUYq8naY;1b^J4X527Xn&3#_+)@R`>1Iy~Qbm2vytxvU{Cjg~AqHPQ0KC%!qeIK=Z!
zUjESCRrZ(d?X0k-UL(GLh6g)zu8GXOHJxp_xBCvS<8u_6C%SLgbUeY}-h#^qS40S^
z#LQ~`mwPLr?UOZ6cCcCTr02V*WOeQP#u#yJy=2zfx}G32O^@lj7nfa^TcH@+*XLW6
zcyMb(#FUNB6Q$l>G)y+$mw#PS`T1MdpqKM6Zcnt_@@JdnoyBR3d?))^y!^@g>&v>{
zLqUAk%BD^DWL9cWQrxQcjOpKtJ1q8bU!7*3lMUE4g?rB7{>SHMwhMmS&h+qrXOF_t
ztdkdbzHL)`FeUSlX;Wd~m9?>4({8gby4G;>!}S*dPKz3vVvLL@9%%SB$3TMTV#4bN
z1Bo8<jJ)JmFAf{5y~t?4MVB$c>cBw-xw`Xl%AwQmhDsdT=D}HULqfqema%swYYxwe
z(qQiy5)<bKswjFcYZVk^UiK`_V5(Q*f@zA1k&L=Oql2}pBW4G+9(0^JuVqS!?wK6f
zgjAnfE>@;bv<@6`;p%i`;nRz3ek^#^;Pv!d1_s+&n@wX^JF_qKX)8G=VP^JhX8cQ)
zn4|i}*B)>6uGjguQ7xyJH__#dlw?}4f0XE@$(;d{Bn~@yt&^5iG(9E1``?R>2D9e|
z%Xf?Wv_wntwAF#Dls%5WnPyMF*WkMK+KZ_Bz5J&>+;5)Wrq{S$>32fA<tzR<ZJf-n
z4~21D<o~#1+kcIB%R&#{c(2W!DDNoOA-nl_^3BL}p6Ea9`&PeGiTR;!R8aU$;Ea`2
zi(0+R(e=Kv5!(%#6@`$tv3`>T59W2?-^L1dnSliO6kphQ94J?S#tId!*ot<}S<4I+
z58-igcAg2VSG96fLm;E1iw-{{b@MF3R*{bL1)^N6j~+i>7__oQ0Bqtv$>88%3v27c
z7cK-qxAlTXy@HqfJvA0;1`R@5KK%On`i`QfTwc@lbde4=o-jdR4QQ_>cr)nZ`5!-i
zJUB_!8#D~0*fMdp2nVB4@iQM67ng*epPo8FMpOU${QdRSF#n#-l~tkMVB6A!vKTK!
zf&%Y^YsB7#@i)Q^Kpa>Z2eN<BVHOX$1znYW!O?1uV=A6ip4z+hN9CUsna|$O&tG=d
zPdYhib4O79lHdAoRNTJ4Z77TVm9TxjAIG1Xkn`V@zAp6U@DpTWDKX^V`0sgH#_esg
zby3A)7yl%mD5!iWP?C9DEZ3U<z!TxbKYQmhi&yZx=AU!ma)n~UB&o*s<<}pjY$)*S
z+~50i|2Nm;-@ZuRT6B7QaG_q1a?BaYlm2{(S?ka2fB#|s+YjQ8D(Y+Nw<ssx=lLls
zo@{(rppy0Tv9f26Z$DiBxML#s!zojyTU2N0^4WxQG0t>}k8Za8o}}>q`^o=uyS^~I
z`LR>@|CzV@{>yK(_Y+>1GO^*Z@qTyrs=c@Sf4p`oNh|nLsv~v1wf<jU{agp0|641q
z^z`1GYOnqNy5^4m)Awh-|B#>8@;3bMiOa&5oHkaUWB8LlTYt-!IoyZtl~xyi+b8h8
z{G!`~A6*xp{M~juKYHEdE5CfMY}$U=N3A6tw4DEi%ccF78wxFCCrXM{S8E?D7yWeW
zi*rZC_pP;Dl_Ghv(T#8U@Bcfz#CrCI=WYr@SDhO4So^>G9X6kP>+`l-+upYBY@hew
zbKF{~?cv`a{@?ezLvx4Ll%rSNZ-1zcmumkuqh4>y9oGjzh54r?_U+m7+MIKD&HcK4
zH(qCNc(cadXp^XK?g!R67R5~clUo{Ml%5@m`SXLfvv~Kr8y^%d`=_b@xs=uOa?Z=m
zR_Cp|RsPL<Qn8^{=Kr6!zkQGJJ^Y!xUgyAvyf63iH+*|%eXd_o%ctQ9W819|7W@6(
z#dTYPypNo{%~?_UhV#*shYL#GZ+w;AF@s}<7tfF1_tjXc|7{n|)Z@LdY8C6Z|JxYP
z|2u1-D&BC`cv;fNb?zRg|9$T=m}61M(0);>xxJ+I<;%|&l~?2smS0b}WvdzWUAAN2
z*|`Fna+&y8IqRJ-ye#?g{5Z$)eXW-bs{it;q+b_0rP5-%w@JP5kfrKF&AvTmE-%Gu
zKR)iaPYSpnrjhwqGSc*$-L*G&nvdtbH7t0bFr{{{T=e%?#|vxs{&+l5x{Ci@|Fm~e
zb7mFscy=6FC_7y+@!pghzvNWq&K%qo{BNeHLZ!66zs|w@$=eS1@9BTDgeC6S-U%Tq
z>;y9XzU#+zsPS(9rh919j;<#&*%y^QOqg?j1H<;sH+e00GSu5`b`LMw>z*rYbKgq#
zdff2`Ki(B{OfyqEf1m&8`}4<^E$09D=#k%<%1}moo_}&zw**>Py*AnOC9JNkyRvI>
zdGkcaNdeRT2#J@eIR5)3R_WdH{CUB<o5Cs{YkpMUck4`N-}d;0plQ_i{GJ_WcW?au
zNBc?4HZ8%jT;(*jH2=-P`AcVh`WW`7?l#|CHeQG0n~qu7f0a1&C_m}uJ7Es}n^X5}
z->31hMDdzjZHtH^cfppJKgnee1WIdl>!kOKeOKBv#Z67};Ppa%4Y8Mz69bMNHh-WR
zXJz{QH0#;*zFIpDx$O9pS>my4uV8RZ_ab{u=3dz+7KVRKE=}RzIOWOAC!1^yQ#^$C
z%-b$(?zC9&-y0FLx!Vtw9|?=z?l9-}7LoGFt@FF~cSJr;PdNW|#r7=0*g5j^Y`(hw
z_$}2K^Th6<vK>=qfv=?~>-4l*!zaJHDt_$$x<mW)wq=)B2hZ62Ug(nccZK&0r0={t
zbL5z@zQC6UDnGCD>^=E;yW;u!vddaF^;P1<=UWc1OO)r43=!Qo+3Z2sB&Q#WZ8t!N
zyGvN@UhFbeEr9)^T8PFY8STZz%Y{7pdmMN4IQuj(`Q8q1dfR?&pXay3ttS2@e-l~U
zdj2trmWF@O(TX;nb6G*zx9!Q3l!qRTfA-E3F_p`)?r2Yx+@SlAEA!jwV|^=bRvAq5
zk?iY}opr!FtKrEDksB4|M<-Qo{^;DV_rh?6ywuL6kDg_VZuzu4!g3$GlxY^re8JNX
zr5FEfn0)c!(TT}BKB|aqTWWi6TY3V=%9X4>y)DIZ&NFt0JKR-UdvRT?^_I*?X}M`P
zH)(Y)wy~|2nLKgfscCFxsu%tqpBZ78&9STGWl#LA=`J1>2AAf%ez?9f_`>dF_8%b{
zd@f5BG+*(_sV!Yx(=LBuUu^oH{BK-eJ{Go1{*;XTAS-jTOjb>FPoiF>by(XmF$3di
z5Ar)#bRTN%UTyGZ_Prn5{Cq?H)(O7b6S}bAg2v_hRnM;Qh<-geQ)1R4pU;LjHe^Uu
zKGT!<S1WBXIqQ4ok=YfZtFFnf7XQ;~_oQmR<KBR~c9P$ll_$*5bDdap)+1`Gqww}a
z22;EqL~Ill^O@P=CwqH=TcNndVPX5lM(3>e%qnZkT*NfX<&)p#$q(<X(|%>y^1v)}
zrTQKZr_M`916J;7EhsO0^g+o&^3trmhI?N7zX-FFy?F58iB<acbN+c{{I6RZG%0QF
z#)_<MCfwd9-f#*`5X(ODe16?r>xGG-`7h#H749w*`PDnKSM~DmiQlg=+ixvsudiU4
z!ex4>-`AZvNKb0pyY~I(TJ}|5zZr1M{@B8+=?MY5Saf>s=M{MLob{A5K6L-Bz@ikM
zH8Brj7jwqz-P)Spnx!g}s1viS@X9KqdtHllVkheM2}MlHY5h5Q`GV}@-&RClW0sm!
zKdHy|V)22BGcw<0tx8s~t4n$=Kcd2N&ziS#ZrlsUoUhW~#s8TvGWUwQbl>yHN>yvY
z)GX#`_toa94M{17^zXTDdT@V9yX?^&osSKd`RQKCxWT($o=<QcN5)i-se3D*r9^5?
zshK{#A=$J?&X!ZS?VH2uG}A;u+4c~nH~)?;)pGk|#s7KP7sdAvs(Z3tu-p${=;7tj
zaB7v%tx3=G<Myg`NoFo6`F`j@qOf713;&kPIO#CMj~-Xk%#R67X3}<8G%1v$GyFm6
zo}l&a9&?yJy_u?f^n%>FW7`b&*0P^x{xd<(-{EB1Rl(m@f)_8E7yPaYoKj|7zdIpa
zP>jj`ywZlv2CA)h1&@0FRyHxY{a)Sv$fwS~oyspKRF=H$EZv@Z)1^^NlK=a|iZ#5i
zzQ1XFl_#Xcze&;1Sy8-PB>3K;FYm1q7I&IvZPnwHzMZ7;+)H*pQ(b!gqfi&=FRNvn
zowdszE<D99tmflje%5V`Wr^TT_Xv$s;_3xT0i9m9zZXwzSJ`a+cfLa3^)LV2dS2gS
zxVrkf)8~uUAFQh1&V1Is*0_C7XL7q=M3vz$-_*pU?j*UR9#X<9r+$)P=exByZ>iP?
zy?1S!&RNAof6@J=Yu6{V-?XtZL4!xMyddjg#*dKoz0bJUJ3Gs0hzRbe`(|Pk)$e%!
z)wBy<OAhtdvvdkwRG+VKa*?E3Ze)v}pyQ5u{e~se7^Ztgy{J#Ce#R%U{g=t1&2qO6
zaFpfU)5vxI7cJe*-F_%B=?;sp*FMcf&sz5coSV6={PM>iSDcR=z3TpWmg>bt`LzY%
z$0l#dYCgU6_k!xhmkNqBnvA}2TG%XAJ|<J!^GR9i;5%l~2fGVauDr0fjyJYqM;(8b
z^1r)toHmtwEYhg_F8Hp!P3ghA+8w5P?7_y?livRQ_+X;cq%TPYzb~xz@O5B0dpq^c
zkKq1Ko*v;x6rR2ppU^kmJ#FvQf63Eiop0Rd&Ez~IV-s-gq3^7z(pM$E-Q;RNa!mGV
zY)?UbsC~`v=XpE+U6E_`jQsZHLj!ZA@2Vr#78PqGZe3G*q>`eqmVfquLXe)@)=dXj
zJ5MeMk=XQ8x>V_%?EUT!Y=;dG92XQi?El0tNG~Uqafe0ol-sYa2JStXk+XmP-q!)G
z9h<rDcRk)<X)QQGF-Fbft&N9V(4$9t<RrFyW7>1fO#SB}wt21G2VdQEtGQpLFmLPH
z_O5k)6ZY<E?wNl3!ps|=URsK}A6mM>@R2}in(VooW{&Iowm!_7>#I=9Qko;d)R%ps
z<g}L0yCA_#>vM`0)p0ylU53oN|NlK>+xDmH^1?%=U6G1YG;`Xw6dQLOkm$eSm>YOe
zCwhN>rQ(z?8a&dU=6C&AZBe#LB<kwwmLk(zi_^EZ|7f%M|HAp@3i~zsUbk-?ynR-#
zt9$cD-{bQq+}Llb6@BR$o3ehz>bsE>ek9jx#JQbLoE5w3bz{j=zWT2^ZC3ZLIdL2n
zaqSj!pQ&}c@P&u(j)~J;X1Y!N_~1g~5{qAtT^CoqNdGv|DKUY8bNX5Bq9vm9?lR60
zcYhssIB;F-gG%1sfIGL}^v(#hJ$&oz@{gC+h`yTQ<$B|;`UmdpzDe7*8JzlO-Dld-
zY}em+yzY3PGke12dWKVx%O0Ivx%S2m8<F1db1ssH(=FsYxc;bG{&^?m>^`Nn+EYRG
zg!p>lsTU+?9h?^Oqx`$f!LvJdNjwv7oIHKrVS5v~t8-)%KW$tRetO}W8_dDGYum$?
z>Le;`ZOHvLCo4*VclVzTrLUWQRq{TFyC?R(Ok%0)-NVl~vjwAfYPW4&&roc4MPzGT
zM02y9c)^!bIyuIgZ3mvO)G)2k3A<K);PBS_iGM#Dy+|qK_U`xmaF}1}j-_Om$@A$R
zYhu{Gxy-JScog_n=HbI2!BnqM^`>;=cgv1_cDDR8Ut-3=y<y>h(k?g5`*=fSEkk>`
zw}POZdidHyGu8QC?A@i^wg3A5c|E&-n<qWrrm`i<TvGJub%V;2f*P~W9eEk~ZO7gc
zjc4z+9o-`T>VV&)mTC6y9iRT*z2Wg0o;iA3MCNw=EzVuIuR^fvYBs}be%|6IN|`SW
zK7DNb`6IrSfzeacBx8$=`61_onv0xguZg)!t-O-UFMlLA-&~|n?{v7ydq=KDM%$K;
ze17idH-8N{$dYHe>%sQ>uehG8biI4};78uC{gcy{&zZKc_~V<*v=*=0>5m-d&bBD|
zkp8CNez&6N$!N~qZM^$)+7=z<mw54*_2|Z_7B$~_n3UEtY}p#OM=t7^%K>{up^`5L
z4xE!cchTCQc)8HtI+eFw-hv#a^?fsLU45AIabmg4sn#>AEME2fWS#wcikiJr>(S`<
zCpo@Ny*1GyOz<3|cX<Aeebd`@0^c9+wTSpH@@?KPdA?n_j`BfyyxQN6JbEkpA>+8f
z8e7**#Vce!wysJz{Br(+eOsko>**bLeZ9?M=R-*!sVQw%x`Kj%{SV}0yEvxxi}LWz
zS!lTC^c1(JL7|CK|C##d*|_eQq~dvP{*Dm$|A}D}P8!cvb9+{%@%G67=g}4>GQGN~
z)sH?cON^+j)K=T7p%Sz3#RQ2W&eip|I3LF)U))-x$nxfoZ2ixx59ZsyJ?6D0ev`yX
z`?GGxl^SyY3f|bVSAAWcRF9~*c~VfextYuac996iO>5?h-&g$=_H-@#3VRcyn)@AF
zXY<a<5#IRO&1%>6^*q_k;#0PD9qY~ZKX^5d-FR~U8`}qgGE15D6cl?ocveTS*l2ft
zdb~+=ZjZp6dz-nA%W>!`Cv%s~jp1H8x7T=X;ij&TD~25VcF9ccZ&mO}<9a+v_rj7n
z{?8`#o5?<WIMHM4S2xLM_7IJv<`>g7J^aHTeSP}&#s+;(S@ZL5%C8iRL_Cc3Tg~iy
zkM5E`<sewZ?>NW$kblpiFLMP0W>hbV>(5)E>gjN0@z)tOraX<FLQ6z5+rp;aez4fC
z+ahOftFX<Uu7ei?IZpQ}35D~oJ^C#>($|agmd}cwORZ;F)fYK>{cz5iy^;B3>92?1
z6-$2<7UeoIyj!+=@wRqZuIYMwhc6!&^nLUoaIsw0RsEy4S3OAVK0EQG$Hu-ErJr(Q
ze*TUXB|1wut1q5RH<~5(l($AgD~;D^?uu&@9%~=j|L_UN{$hsW@cSZ64MB5{9Xxzn
zR;)(e%6*cZl=$^E$8Q$+^W45BfA3H1&4A?(F5WwPqb{&J&U*PmvA2Bu9S)1Ux{Xp#
ze?EWz*m4Us`TDl&b>AvdANOXh`=;?KmSvUjc7cf=T8EPU?^)hjxVy|C?{1XEW#dWw
zJ8L*?w4;)qZx+8WbJ}r-PTrt5Yd#n}(23ho*M92WP3^fk5mt*h(i<9<m!y?*w%BZI
zjSNk{@n`PwDIL4YIf|#pi=Ja#zfHL_L66JZ&U1@LKj)$1T+S;Bx+$~LUJ08E%yZ$|
zpx{u_*|=l!tFBwFxeud`2`{TQ{-71vIpsoign6$1g+vjxFY69W-|TXZ#Z~HWkFxZy
z!+lS#A83eJG1)))>LK18(%xFX*^~{|<}me?Y~PsnjrEAj#7~d*^In$<IcT10_h_2u
z&I=N=4&A!hz2`N*C=ajD{5c2i>`ZSdzNC=h^Qm4l|HcRVla7+&9qwHGSBkbfPYjZq
zATv$bN{35-iIjy{ar@-Gl3q7F1pZht9-Z60pk{JeLAgrr!cDG;72g?|;@X_Egu1k?
zpFavY<J}^8G{JxFu@yJ&HE;j!m|-~~sMFz=y;P9hiTd<YE{!wTZ|tekWlA=Z_D#!s
zYH(#SpUtK%p;Z>|+@%-CbUJM)->kxGrpq_Uh%4nOt7uYu+`(Nlk0;#CXL2j~pps~G
z<QU808?_2H8BwNdc+WnqttfbI*p(ggFm#Q;n;4ydBR=i6fhV8boWXFCo9m3%iiZy$
z{>;(*rgA6Jh@*M?t>ioBw!V1Gx@4YI^Q5_Y$roNuo^kDhYV>Pe>qHBq3Z^niQRm3+
zfFJwvI_=AA+k@oy{gn5#{wmCNPph4CG25a^krMCb_Bmg?cCKPawdu4wCJxWD-g)rs
z;y5hz_u`#DYHanzEUD_>ote{%Gko6!E-j2*@_v5v(d8*Ct}Zo;lfTb%JpWm;&-yI+
zoTXWM{?7l6(_Vakte^2pk40_Ifs?V_f&uBGZlR)w{#;-DFn@XAt|aCw1?H_S9V<?q
z-L-htZTs+fkr}D{2J5f$-w=vrb$0uGpv%JcwNdZG<O=3y^E*zLv!*7_k?HZ6t7%pK
zM{HmCw#RNuM6*OTx@@^0X|Zi?<9q4qkDna`Dg{4J&u>`s)9TN~7rwzp1;-O|w*KLL
ze5>lvtok($Idis&edo1KxcUFpqZ1qM?TG)&-Xn8?MShjmJ!kdfy+`+ce7nTtOWa4<
zJzJwBET*|kel~T%zL)%=h58cvXY}yNzF%~3&%YI!xh!*c8fRVAYMcFf`h$!f<6GB1
zH2nX2c*BbS!n<~{B>q{q{6)-W8>2<@6)x`4xK;CCILnIT+b6?Y8_r5xDU-Y8E_-mE
z<5ADRojntM_aA;~RR8GHx4Ht+ch%COfB4rQSR~pX_(Qt<$6HU=$0w67tY=(l(Q5rq
zQdLQBz4QOI`WN?>vD%##I@7)I?f2%y&o3lR<WwK5wCKL)a^TA95LUBK1uiR8GA?d3
zJ;x{6b67~8M=F3fO=bPf@SM&zF@D4JH&sWrz3VU%O#i5Hmius;kF%`Rk#Bk@{Wn&A
zl&=WL)fL;mS(K@9Mf2i~USD<D%GY!r3h~g4OZ<I@bH=YNCdbUr>p19%&R&pM>L2lR
z#kVIDYRZ+X)>k%c+p2ZAf#Z`zr|qsSZyUJV!w-dr@qG1)Q0_7*=-N8J=hdB9A8V<m
zWva0g#R}y$zlmO0_}(BykZb$>UGrv4Fyy-3cD=QA!iiVxuQxsl(>hfm)hzZWL!$l2
zZ|w{9yZE^I`dU8j+#0d(rDoKc*d8@Y*`Eq8&66%V&bSfcASo_;i22=uH``BNIHV@i
z=(tQH>Z|I%oDbUXDomXJ=ZPv@eeob@v89*0?6C`>+b^!lb(UzochtG!!Ev*%1wWqD
zEs>n+$ZF2)vS$z9`?%8=yIo#6>rK%+YFGcSW}DEec?NU5$}@kT+FA8gE5%6i|I5gK
z2U)aQWwwdQt+>6%XpYC~14oWXXiYB4xU<ZtD{|k=sBdOw8lji@zU$3BeA*?u#`<yj
zmERMBPcvFgmGScS57CKa5jz#WV~@4~-`ZCT!UDx5>~8iaZ)ctu_{*B-{cWzWh2erp
zDIHfXgny`(Y*=ukWJlPmj%&GE2XtQA`OV$U@7kLvaeuiYSM8IFrBaq6&s+nxwW!N%
zn$vG1*XW<Gd~vUAR_axqBQv$)e=A;i&&tHq{6Wh`>|AKn;+TapToaB+v`o6T#%Yz?
z32ys;=0R^fc5TaPXX^^SQS`<zPE+PW%>nt0m{WXHJ5O-#t`m6vp6$S%lPW!#@oK>}
z0b8;(PRz{y$n~MDBH8}q$-o~{zZc|rS|@6FvTt=_`mLnu@h4~DwDbeFR?F<^vPhY&
z@`L|{3CHK%jV{{4N9;d0*E=XUiC$X~vzsNz@4oY%x!OHb{&^UgITQsj{E25%(s1m3
zWOw)C;#r1^-px7w^mwDkY8#=;?52(F>6TME?zHDV|09qV!*;jshve6P%GHKN%Ys%c
z4qb6+6R(%`<R(Q^m8s3#UE%9{*;2V{m)yQ4(6`h!aanC!@N(wBXTRkyt}l&DyrHWu
zaq!k&n?1>VA2P-KF0FaJpzuSXXY2cg)=&0Y9NxW*KTA_D;rqw-3Qc48$BM=mE?J4_
zCm-&t@jSj-{9jF+w|)q(uC#fJza{Ip_comc>r|rne~adJ*Q%&zm<D8d-ut+s#i-Sz
zhV{}PzlZa-DXp5S$Fs=XQ-n8hicoWbeS8qx$>023O_vthtO_k?ckN^8VD#Y*cWa%J
ze52}<rjtothH-+D)RZEp)b^4e@s`cf{>=%OYq;FD=rKQEv^3D_qmG%(?skpUuU^<@
zuw<nOZzu^`-xzEeqLuai`-io9uN2?4t$q-)%gl?zR$`7H>(+_fTH%^p!M$7t#VzSa
zjZTEk`6u~WXhpJQ&+2r&$Bp$OU8V622VG98ve+Ctyjx3PE?;DjiO4JwmI>to9+zAn
zU*vcjW#Y2(%Htd5=j0c%E&a%=$$WNI#llrTv+vlH3x5B5=;6P!HauSo|9B+xqup=Q
z^0nbfa1itPgr}PxcT~K78?hkjIpd34Cte%NWZS8~)8xzl$6d#}EwRQ|@r`}M|6}(e
z(!a8+m3?dT^^?_nd^(W*@rzZt7UDm?v4s6j>izKc!?_QqCf@p;FR-y%K}?f9DP;Su
zg7caAj&h6lZI=1G{$#+u-z-~xbG^#B#=I#0#)j~HEzOM+HP^g-lkojoA~(12;{H`%
z|Eq+x2JU>SutiUA&VToUmF5z6S6LqJnW|7|XwWos>RIcjhxp9G(&F#7nC+JOdtq%J
z=Z*jEE>jafs%2bW#H;o9bX=s{!KSZ}sj!cX5&Ru>iEqu>!1Gm$f)!Xe-aaujNn!p9
znoBxiIf=hc>)Z)lt|J0x=GXt@jE|2$GtV}fBN4Qa<?;N?`}=JFtMW)UUF2tVYIt*V
zGyCP`{_UM7tG$^(J1v_(IzB0~?31x%^7r4hLsEIWrT|lmQ+f8)O}_1*iMxr;Jv}}5
z;x5jZxLQPl5i)(J{Qp4O4Up;0$Y<R8*@-H2?%0<t^{eJK`{nQV+$IV9lIuKQ`0kBj
zO!eH{>MDr)f6lAXaJW)YS|wh#j^E*9)zJ@0XZhY($}{yAeC3t=aMxVg-v3sY_{p3}
z0$~6CSN*h*!Se|BevS<7Z%4Nz)-UppWIgov@BP=To)u-x$G^p}haVCaYs-<-g{i+E
zZXkJnW7^fUn9cGXx_`Y6<=5)xcx87oHve9@WP`HG^at&KtIHp`Zc^o0y0ReKj`y!t
zTHNB>@Am)RsT<2Wwa#nl#Xa}?A%1=QdBN%<vu4gbc;m<Y_tR$lXYu%Dyk-&8k(cZ_
zuV3^2@3q}vw^Wtwp8>;CofD;gZS2+J3BNj>B!2JZ?33HcxqI7YgJlzi&-66J?X5a^
z|Gxd_?JSorU#<*H%FWenc_BV)$rpiS$#}!uz$4q-ujdOETc%|7cZC}6`zwA~%+;ql
zzIdOAb)Jaf>4Vqj=pXHqKC3Qb_@;BN{!}m3{Z2Zun&0kE`p?24-m2_9?Qx2a@tQd|
zIiA<cHl230PW<uVTEVjGTRnGdsNitR<!W21BAHmYvLNTH^|kX-t*=@eo;-Q-y~^s@
zxw+jZPI&0V><Hkvs4pog8L%>B!`7{$PG8u!PM$T3i=CZa(PjUIElV@sym+C}@`8Vs
zsj!gHkGI#3-a6fWYq3+P)>JOVU(L&ub8TnLp3SZJOI201)!*IQ+gs74KH#GN=dRw~
zUV%mNFS@3J4ieV><+e8Lv+dfXsg}1Yyu7>~z3mK~*cr*D(b?I#VZ#Q2)TLQbY%d-q
zU706wp~mU{%&AkS3M{fevZh>Px&QoUN00yf{JeF-d3AX`mt{@&7e0;H^GQ{UPq*Lw
z^!&wlZe0AaaVvAv`eO&SwVBWH?OpJA%Y|R>4!pm;e(?u$Z^K>F3@a}l^54UJmsw3m
zhv)P(U16s$+@%2_vRw~fynMZQW{i%z|3cB_5i?_aqD5XUIO27B%NCP+FT0+;SgEn#
zTsV)rzpSDzdy-|9R@n*;!NV7WkDO5#F+AOPqj2%R?q6PpQSY|!T=?`&^)TCf=ChMS
z8fMIz#ijVm`Ak)N(X%s>IuRQfmix^Wa<Y^E_)DO;$Ixs0`_8_(ODy($(m1ob)bYHT
zYT}yiLvL-(1tu+9^fyvvvy@}h3YDxYE4n|OlNXm4xz)5FHb2SHn925t1IU3dj&5>4
zD!Ntmnb5DKWy@!5)6mJ=*?gmL@z43UgjcWCDEo6{%kf9ks`pr5`jCI3ov9_^MOT>f
z^aod721i)z(B%4<`1E4=O@%8(r>-q3THX8Z?tb^pj}BRa^H9%!mY>0p(&ylhRfrjO
z184!@T!NU__kpStAojHDL?)H?f{!03=tuE<JsS<3I`66XZWK@`*?v*~uKU4;cdE`V
z9nX#wX6VI>Iob2vt?}rI)z(bP<Mb1}92X{4x3*Bkcz(c<E#FO#>#qN_c*aZ3GD~so
zyrf%;YR(p(?zNf3Uw-&+(Ti_il8^U2EmvA%Q~iyHSK92zp32WZWIg_iy17k=h;;n=
zMN=jF`k@`A(izcPS=@6T&h@Q)@htF*K=N_dT_@%4HhA>N`e~Z%zA)GC=qC5_@+B`d
z!VWI__9Aa)l10L-zLM&ist(4p>L#);`*!?l%L{S++!bN{cazcd>W)Y@jig(`n|T6`
zY*9~>G%z+kywJIQL*?hRIgms2_IWWb3eeb)e4KCJg`gK@2j9JW7qKNnu>P&L!G;YD
zPmXeHY|CrDb6<X1@bUv2QalTu92NFIc;ESL5W7!x+!x-n1txw;xz&Di^WEIqGNSE*
z4|+USo5ry4cIoA{n~w^xn#it97Anpzc=hDyt-krsd|$0N(qL6pRnwc=w<}|o{!y*s
zq-l&?Tirh|k(g?t%WM*tG}UsJ|BClQtIu?XzQ6Fry66eVwMoZ*OwT#~Ka^`idE|})
zMJ6Vu4M|726rY^F*xK&={R!ul>H3Ga)YnT)(Nc{$dFDyT)!Vmjfr<jFyHlo!SXfzc
zDgJ8Zn$Xh1Vqs~?srXA(Pp_|kb_A1(o!z|p{3MIRPoAXQGwclYyj<h-Sk>*Q=TXtK
zv(3!RoI2_j_RX7SZEbB0DnZo!@6U}uarRgBu&}U29ZXSd8Ts83Q%zdG9Sgp%+EyX5
z`QE|{^ZJi=i`P$N5X@ho&%aP#ZTmzKO{T@y)+X9i7#M}EZTptmP@sA_v194$BiH&v
z8aiCV?i|_TDfszr=g)sfwtU}u+}CH*r~NlxYN{pev)*|5V|L%|=|KuC9d?FazO=l2
zadE=>D9*Q+mtUB8t+{dK%7Uo}6F{5j+7p;m#0_-9M4s9I@A+cC+}W^}&1B)iFPEhs
zLaw;(DNkflnLc61&VyCI&1Tfx7k~BhbE3qrs2$KsCUyqHN#CBHgoveFI={ZP=G`>P
z_#4k94yu3;CZx1;3fL}K9Vxu(+uH@VHZ*n!)GJN_TkIz0)9`{(&sO%>+1busE*(jK
zt1_6GTeU&$f&>E%pN1FA%*+LyouHx5!sC4bYogn?1TL;jgxCr?Ia*O?j_TTQezp5G
z%$Z-aPR#f!ZZWfmAG`*3vBGEY*2txy5&`GgzrMcy|HH$}BKP}lHQ)LFthqUCvFiWd
zf)={_l@^BWDGmQ;>SmgCU`c+wgn4#bkEHRzrRf~uVE1dxsBvo05EP%mqCC0nN992$
zow!Xb-uJA;l4}098Ptk&i9FOVV%EDWe_QRVL+>rq3)!#oSkh90CFk&+WK=g;7+ZQ}
zU99xg+kA)HtUt<&YyITNT-;`mcbQGH{tu%c|LV<<W=#A;VWuM@Q>%Ip9XcF*abcEg
zMP<c;4Xd?dPCg7f!hF=WONh}xguAcDMe?EkJ{e0n**op4`A;X@+h+M;SFPahKD&eW
zqfeYnF8F%J@W<8P%+}@a4y{Sc+_AG-G*6A|`e(~aZM+G0c9kyU@bnXN0<VYCh^TRD
z@JPr>WaQSC&C{3dS$1{xg2LH+FD@*!jrtkVn7)?n#l83bbJV8Rugi^I((PWbh-s45
z+6zlcjJK>>+iauA!WntHafapMqX#N)7%pVqvv==>C2qVk9J`m)zi3)$ZQaFrx8}us
zGylnEc`TE~bQR{?vd8%J2>g04kUe>u&XFzCQ(tHIDsNRTtExL&D9mk`8@TC>Xp6-w
z=`8m*C4Xi;{<ic<fq9Io-1=XlyOX*XKYt;pk$zC|;WsXxTX`+=(yI%;>`-2o^NKnA
z;X8e$ubk7?-|Km;=e+UpZXu2vmqb?!M<rh1Zw~l1mzVWwVgH80KXxawx4G_@f8FqI
zcjeDdsddK>zj<?a_w@TyC-X_C=3ZRy|Dvy@MEyely9SSV8OxCL^G&<!n4f)p-Ml)I
z*@~Tg*V^R;!RHoyPIz%{@wIE$Kp8!H;$_`WM{hixlIA<p=h*uxp4%siGiUX`6VpBx
z_QXW?<+(XYIahrb-kx{4qEqq2%XeE$)^}`8wbi};MIiZlpp^csX-QKpcS*|L4V`*R
zcyW{9W}bkII~ntqq&nUQmBClcFPEzw>$^UGO?i>vuHa7_laFu6x~gTk?Xmx{g@OAY
zEvsesnR|<`Cdlor>wh`^3t#H*?bxoud$_OP$@AYmeV2#*yxQiEXNAh=NQAJR5Bq+w
zEYzFl$3yFi)YHZ<*RM}JyXCEi&NZ%P^|F@T0(Lb&3iece^|CmvqM^aDHhTLpP<3-?
zY5t1lMJIpt-;NA+carH+6jXGRHgk&GsAN#Uz~lMsp@-Tj%`1GOib*1ITwC3ZcS=O3
z2WKpGdaO2W)AGW_?|pfyzw8aPPO_{reEW0-&l9CBla`qs)nJdWo(Za7R@lx`Kbn!U
z!DzbmjM=jvUs&jTV^b>ke%=53Roj_ZDr!>|!`AI@zH%rv;KY<>uW4-+*B^c8vg>Cz
zOWv5ch`-1^Sna`?M?Wn-EaD3ce_L4aAmPsXYr^)t*-X{{cJXa`@cYKb2LeH>w;iAH
zZ|g@*^9>0HnONA^l8$zXf@1IX|6tRs>}>6p8mX)6?p|PHIgoQEV}ja#fnS*!50~27
zfe*^BTR79k&`{9N&(Eo&uCu$lxw*MH!&c$r$B%!ig%=B`tE+$BE1$HbPs3#Xg^JFL
z+K$n6Ciz_#gWVR|>Rnm3w|3d|3+h{f7QXjeW8{7`)XAwSBh~MWk;B5m#e3%@ap**`
ztteO`x<cZ@Jy|V>BQK`@F#mdPx<l*nM@PH&uV7a>9(Q-~!3dte+f;Lck_Dw_vn-bS
zyCEy4{EEi&=J!=0r&T{XZgg#pdYT})Ny^s!%Yk1W)gdcl`OJ1H%!w%w@?Y#!m~`*^
zkJPi4KiFjt{RmwA;da;Iil6+SEmsx`39outwBq%@V>{CMJ-nv79XsSY|7+`+=eK?a
z5tTIq8dM%#``F#_{YA5+_w>Y@n=CUv)F`+8uMm3o_t>J|^1N*icpgUWHfH;~UR_IM
zRmZ)_Yzvb^(}lc3R<E_}>D39?bywhz<#z2Z>Dh;;ZE=#x(NPdx-nb^*XIE)!;?GYf
zW*E1dZEgtw_qz7k6-DIEKD>2>(DP?sTz7wyy}0vq{*L5eq0$<g#8sksCqvH!?)q2$
z<NlNX3(I5IpSdU6$u7m0(J{%dHDKr0j2_9a+&k?gC!hRydi&Xcm^nWas*W%5PL~K>
z)$-+~F?6ZrKD#0f2cN(#HO?jSh8(e8OCQ}i=)U3A1@`;3;rw}z&OFr&m{Ib|#l^!l
z#b>5g3%LLIvGgOTj(PBMXGZ)X>8D!e2OI7`PddN0;>J$4q>tuy8Mo@}-mN?$U99Ed
zu{!ke_D|0zO*)`C)ky=~OpRxsFQ6c^<&;Xx@ui2CMuqpt8FM8s*E_cDZhOI-8-j0c
zd|=k{I{Gt2d;P@Kr5*lfe?H$B-*x0HZ`%GpOp)K^CS2}Zxia&RC^&>5rvo0`{Wc_~
zzpBSROD*yAnVB;TbGg+1<r}ZF;dRXk;o|bTeaGI2S@?UKf==KP32DiLE22Up-rwXs
z{OD*WN92iVd7z5(SomS}=M5e_y@`1bS>`KV-uVBNXw1X@LIdj^V#Uwrx#k>v!QiOM
z@BL-P+m@N_@sC4$Dx^<J-ne;iiF>(3)zpTXn?-dVZJ_$S=f9QZoR(EiUp8A?>?&3_
z%a7>)`ue=%<sH2HUM6%^x92Iw?RcHtrpI+-#~NL$@bV*ngdcK<1hxeDRDEw-k`Z_!
zd=1O@b3vcM&4EAHPb_4(sQBhgj?dg*_Bl3He9zC#J$i8I{)MlvsNUF_$!s=<tFdCU
z@~3HHqHiv&Tg5Ckx5r_^38f=j&X*hLgz<b@dU`>`&Pn{n0-0N#z(H0tS%yo1*W}iu
z7iJ}Ld~$a>=USIPx-f62#1mr%<@Rvr51Sry2*1<e*s?CA-)!pJjSU?Wu77;AZd2B$
z+<b|uN=I=y#;06LPAWnY9b48jf@5^2D<5kI<D^GQ0+PD!*WxxsMJgpRISVYjaPYz%
z3D&h-OPH1<hq9lslj>WM^7s9Q*|L-8*(TT}Tk-h#OfY<{U!as5bQIJgbIY6P%$USD
z|KZ*TlKZ9i&fey<I&AHQkL#~zm@E@g;(PDxHhGtZ(w&*|7q7de>1y3t=q{`NXPdSJ
z^YuL~e(Es-oR1rs6W+YwcsXe)w1e`Ww<yLqx_XP-f6n@(M>_%~OtUQ7c%>T-u8mss
z`@_p0@#io7T*uz>E@I~23*x+9w-Yjg!%Z~Py9;kOFHlrEa>HYffAbRNU(Qb-Fhu_5
z3&^>p(*ka{Ox%C+VcDNTi|v1zf^@YO)E?htVD#bmExG*(^+C*MEI%7-ag{$6e-U<b
zu64OvRh3n}oTOyuy4c-G=jK@cDLb>Xcj-#S^-s#~`yP5Lz^k@pOXJj;ELK9RF1{*X
z8gcG|z^on~2^RLlKW>$JoH@Jj)iqI}l_G3HoEEkvrvn_-uZ7)By0s{vx=qFRrP!@s
zZmX|;D*JNP`MX}yt;NwNg0DMW4&qs%n-$DceMQXId*kP&GgAH57&#=S>Xi#@J`))c
z@!-M1<{R5`rJ)s0i-^@!`E7sfn6vfnxx3_q{@GV8WHq&*(N|G=M#uFB=LNqkZEtJ)
zq~Efs=&4to_rKKB(>`AR(zsB?Sg_B==UC_Ni4u1YNxH`5B<AM1aLxF4EbU5`>7@>a
zjpYRlfiVGjH<^C+%{BP{Roo+bYZIfOl1y*$xwy~j3tzgs&e^+nufQVvjB7q#UQKJ)
zuFc?UzO{MNCZVG@Pp243NJ}5SGUa|=;QJ-ZmVG*Ra!yA`t@8BKKf79&EtSxi>b0-u
zHs~szU(Lt5mo1$;cdo#q_!aVtd$qFsd%U6`l}+WOX{@!*_oaKM&y37__uyaQrAwE7
zl)Gu?)H;9O@3pjP>(+neX-oh8`0?>^#J(C!zqwYbEp>LF^65!uBFBgRmO~xQN}+8V
zia#5cgz5aso!{;_)$8!)9KncZ#*Clzwmer>QDM;zTO;7~<+S8|7oS^Sxnf`KdT?BA
z-3G(!^Ocq|wQw=HyB|Np@JPlo=!D4WX@@tIygakm>F1g3oeZK1ot>QpMMXkRU%X>t
zWMn#a2zfUgIez?elRM9IZ&_PW`6Nr{S1&U6=;-RU3jB4fme0JmBvX^^%Fna_MZG42
zWlSy0p59OOJ0HL}X~G1BC~(sv<Iai)g3b*WzN@MB8X2-Mwwf8OU=Vcf2)^ilx-sI=
zjBhnMaeIDrvz$=hW7U47!8^h_SE=r2rj6QvOX=77D+8A{n#!&H!@S?uu0i49xj#Im
z5=oafERodn|I*gHRHV4SRZ%mx{@eY_{YNq{Tn#>}_K*M7a{q~T*<x3w>v4<kpCeN?
z<0)6<wj*0SPj*`v?dw_pb8hNQZH~f}Kh^)b-@g%Na$zri-X^jA1&3bz-X?Ex{Rf9y
zyLZ(5<XRWAw@di9`@%_Pg8#yq4qSUy)9iQLapk4N0Oj-@)-w`5uH?wsC8Qf8%6aSU
z_v0ZExpx?@{`?$}bC2ok+2}*A;Ii%0G=B~O(LeqAM-TjxHGFp7{^RrN;~_n7Zc8(>
z<sQ|3s4w9nIjK2AV4k9HY^7k)$4D-Hmm_WKM3W3Nl}z^aFSM!<c-1Wq?TI~+oiCt}
z_95>YS1em7TT=4L|NE;|4qaHPwaYh)oByG{#Czin6S>X!b&vXo$Zl5U@IK$6<I>Zc
zXjyM}#;vd6*QwAYfBzVp^viRLgF7Aq^FgP+SWL-kduaST>EflO5x?$jWa$<=b7Y3y
z)&~lISRX&`$#~c{X<eGf)a;ApOYOJCb&Ia+Xg+dRc3E?M!;zDms~)RQ_;xrU<1p7H
zrC*@x;e>vTQ-eX#?8LKo4Hh=DOHJG8SklF{Hr?*v$>W`eLjNikmbU)<@zLPrFW#P-
zngtOXg;p}Ne~do|uEiC_d>WoGehIF#(lK7rsol1%;PBlAAwPU7JF3?QEj&5PW>Gqi
z_q3Lm-)j>;-Q8~R@*;C)a=p{78HQhW$NgHnwm=+Q_Wx?+oM3b0))@iWRn`d^#^z`K
zu4CC2)9ZSA|GWpOQ)D_{O06*YC9drD^whx}uEjI@e{-tIS}SdhuU}H~;>3F8L#nDD
z-JflVViXi}N&<Dtuk#Bl{A5ti)_heFom?c&zeegsuRVY3B341A`#M!^7Bi!Ec<+~(
zrpcW7_}GRY*<w1=^_v@4a|i8z-F#)={m-9Ww;Vipp|y3gG%urI*rgP(k-m1K3RX*8
zen0+p_I8Ej>{)yN{xv`KB;n4^QfYtZWJN#Gwe>P<mwYHQJKXi}-i=Smnl9?AJ0&W6
ztsPhHke_qxzjpZky=$uTzPn%OT-A28>)?{&^oZR1Y^!sl7uNn`$~^3@ko?FcV|`rf
z!Ncwsj&@i#P6M?A;>CXkG!%I7@9mlTxGnL8zJ1b<^VtQuI*)Y)7x`4R)e5^OKG-2B
zVU?xE_j{SZ$xmMsQnNZXwVo|3uM++8QL{z!x3gh0$HdNR=M5i&O!{m+j+}Jw-0^5S
z)5?vCZ@z52vfG7;IXYV6#*G7So)>PgtYQ(<4tLmFZ*Nd(6!iN`<F7-kMKLX}zDO3F
zJb6eSTx)&I1P#g`ZGQaxgV%T2bFtR#?<D_ORR0pZ)UvvyaLa|==>-ofV`X;M2|o5_
zm|i}|eNMsG?8R-%Mg9Io$*~`sc68=_Er+Cp2Hxq5H$Khc`7imtt@~m`xhd!E6ZMyq
zWd$`RdTKpfU(9LszWH5PW**;W*X{+e6L+5PDSB_G@qKdgaXyW0IgLfP%Y?R>f4;GC
zvToI}1Othl{z;GT7Pvagw#aImJ>2v}dW~G9<acqtBZ-g0Bn);)cX^&HjaABf7ui;M
z{&n*IEyp-+nMy|g(Y;vsXZ?y_6MbD@wpr@O?|V}IPMCR@vf|yj!9BbkbvGrOmV~hC
z=o*=uc!$4w@G^yK<wV9aJ^v%)wXVvrnH03VP5-taV~VDMQDyq|i=WjSil5&*!>{;}
z{qEF@M_b?f{(SKyRCMS1jKT$;+KLZyA6?0^@L0M?^Jzsd+cq~hfn@1*DnVa-Ja=_$
z7L|4Qy&_}Jm;Iu$C)=Maa9;c<$CX{<#KeV{55~3la=$$1cT#1(Mc0-{>9==%6`mgG
zoWg7<u$d=7XiHSYM7F+v+ZUbIVKxyxdb5jf!o=n(JHu}+(<VDR)^yGFkms6XS<J>Q
zrgPzW-j2$KGvcSO<s38J{_w`t+ro{}`wyPlF-_vj;e;s*^8-bDH%F%>&)UPku5V4(
zjo|%B4|8>+cxU&w`5jmjxmiH)<2SFx-{0SN-&yqZ!*Tig57ud~q<8(4y=!{y$PpKg
zleRzBs6Nr(b$XGi=GKr8DY+Z{KHvNHdZWc}6;3g=|2jG^^k%nmi#IM@$?BtGd7912
z?|Ap>^6~;x1LbeNo;Cl^`LSJaZE@aLaM7MiU};<P_HM~G^OA;R2L$d!Z;rA!A<Fe>
z^Rk+lqYdxWJj<VoB!7<ukHl^)lMNNxsBSpn!|ujc(!FlHx+mk+j_r(RvuknlJ|&}B
zuBNj7g>+P2#>~amlHH7@7rB-)rR}l(JDu6^G(+pH#gOX#bc15&^obKKlKP$rzuL7V
z=<n&(cUF}1oXB4>M@I1WBG+a5|2u3Jn7zo`(atCP=>OmCPtMCtm^!=Q=7YI%6BO?T
z^!&<P$e!|V^RFA<)00`=&FRtA*S+|2dwgK)lHa$sW(x`nPyQLrG+jU5ZDZ0=gW6vu
zcAH;I@8Y#Q%aLTEk<}iS63Nt(l$mwnd)=SQla#LXdUn=Z{$k?rW9s28p2k}eB`e7K
zX-;l>ZUzhUE$&bJD|nU`Om|&$`n0f1LqPlYV+a53-@Ch^|Iv-d4F7iT-cijY=%L`j
zbg+B7$abfTOh@nT-QpV8Dpsx^G-uJ#E^C%@jzS?Pp^n}0@7}%5nHFBJ;xMi8&;GwT
z#n#(X)OQ<O|DQYe?p4nJ8yhCFTCaIH#d+BVJ7vWQL7LtF6HaVfJa0qq6AliEuy2uz
zm5yhh|9qt~DRScKiDBG~{ZVuIC+}xDcGPk4RgT+6;>(Qg@*Zod`?jhy?6{~Ai$c*g
zMm23~Z=K0&^hC@z@~vpGQgC)Sup!y_c4`sJqcwLE8+UBHxcWL{>xcKB*Q}j*Wy8b&
zybd@1B{d$OXIp)5GXqQJjxAYw+v0TEZ(3U?#9v?8k!8ye&$CXyH2JCGk0)AZ=1y+S
zOh5kM;t@%U%nypo&cEbw|M+`<^?dz<8}3e@G>IvD;e`{fb7!*D21{qIt2oMi`_i<z
zy`G<s>N>7C66WNf;6C4FQ-NBp3Jc4o*e1bKU2?BYCqL_+T*2uUF@I`|ZTO)nsw|Jq
zjOMs@PfutmN>UGgpb^(3_^NR)PouJOx@>|_>*l;-TiZ&#gB+<r@fwrgzg3lZI3r0n
z`25w`J6M#j7w+Xa6S%pSd&=e8jn8_c68bY$w`7I$rp@|&!=S=+or*@lvN&mz@B7;N
zc<qkuInHJB@+!}_OZ)$+&zw0k$yrzYn&>e#%RMi0CvyMZ9kl65<oq4ygMt@M{`g+_
zx_VA<<c89d1)d-3TfQnj{{HaJQLh!nkA9^rIxWVx-)ODBj(pL-+%<nTZ&JE$*t6Dq
zoz;O2UpLNUvfS|Z*r{bPms$i|mR*nOI4&f4`swV9#}+&eEibOTRqlz{!Idq(?&zwY
z&KDL;;S}-W-y(INFHWq=V9SaQJ$s$Q$BwSvn07Rz<jck<ANdtq1e{Lnf3W3l*nvYE
znO<F4%k0noxoP!0uHqdbh0RkP9jC8rOpUxEw(on{*6C|kPY`h8P|Rm5l>yN%Wg-of
z(W*)eiTUp)zwTYkQ=Of<@SfOjwhjAz*OeN+x%#naZU5e;`D?xVu9xgTa7{ftGV%4V
z$I(6A($Vu{e*2v(HGI>1vS@ApRDR3<W?}zs{)(ubz#Kh&&T;Q;`>t2E)&y=SJ-PG!
zlbHE)-tv7`yH|4d;q8KW`D(}8bFIt&eV?>VH+q|bo*v(1b$_wv-O|zP!&XmSDzy3Q
zhUrWvKX#S6o%_0R(aCSBxBH4@Yi`c&c^W1E`}U33AD?n<coHMOnmOnH#)eS7qU)C1
z>~>0J?tIM{Ev~J+X3Yu5b44fnVsoTVg+2#aUD^OzBy?_$W%FY9elJbe?{RDjD_5?3
zac}SLA7U|TT3TK;wskv;o*w!6NK9B*d7sk$pru|xULQUE{oNxXBvys4R$D5v{>_^l
z7FO1URbO8Pd3{WD{d{k4^@^CCpQJmtaX<d|_ji(|p|SSA>DSm<SPmRJ#@5%@7v%Mk
zi<48ZnkyzIX33OCpWoaxPDx2w;MB?$<n^(uzh7KkUteEy>5r7uR7DGmh-p>_HZ1sY
zaj|=n>~v*~gwg|-F9&bCx09V;Zh_BCqYYcOObP1Zzn#A(Z@OM=l$U1Qn;U1E_`iJ@
z-G1Xngo>(a=W%aK6?OH+H9tRDRD4)4<r7x~!>4_-t;^TteR*;5Qq0HOI|>)CbMKeC
z6!URc>Fa6h0vEeoiuuUR&wu^u%3$|d+I3sAuU~U@bMq=bx<2u6o0Z~=iO;&G3#hy{
z%fF{{R&;;j;kK7zIuQzIMc0dJhrRgq{k{HK(fzj7-(Faiz0o);s;|g!{p#B2@LAe*
zoSdAyqPAweyppwbO3<EH*VnJ-=HZ$0tSf%9ns3RzefuuOd`wE6G}U*f&pew*^W<YZ
znd>TY@9qk{zBbxCbKQ@*R;6CoSA}Y4zPmc5!%#tg*Rm&{7X6OoTk|`}Pyd?w@oy=2
zr=Pj~OS)Sc9NVpLjd#9cjP8#qZK$08TIMz5&&U3jC;po6Tk-m6?^Hp{+f3W+cAi=~
zr?jC`ICY5&i^7{Ap4}me;ybw+cRx`PFI$i>efpCh(l@Pc?0RBlVVDzrs`A6s&1*Jz
zE4}&DD08Fg$(mwIOG^)L@5#@)u6J80OczgeS+_~4TsGnLWbGYEsX?G3!RmXGhC|`x
z&k=_<B=WA0ejak4YsvZdy4l&;KYsi;aQ3XPmuB4d{QF|-|CYYK=If<tmy^S?`<&kK
z3gI?hyVUD{Z<HQ;BqwmZZvX1lt9QJABBlEN%^RJ#?CHrSKi}QmeKa?6bDFQ_(u$k6
zZ+F+vo;-Q-l%Se5Yt{s8%?h2O8y)7Q8TahjvqwMpx7l{zmVezK6R~(_@^L;M2?K{|
z2k+~@VvyEXVK<X&Ufcin@S|hLqBm}|=HufF^7^=G>sHbKX4`zbZ{OWre$-Ge=g(r9
z8xo4w-fj5kwEopznU-JM)<$k-16_6d@9*!WB2NF-B_Hq0xV}!djZao<slcc5ix)3u
zTwNu)E`Gn>>)dHi?ry64TP0&v;xXr*s7Qkdv*r6H#rNwD9B|lJ?ze7t!in9TvGYEB
z|1MrV<;kwvDSN7K#2UOgH>G^#-GvM-pi*p;wqSDrr(%o1A@Ns?m7+U4Ik<TaedbY}
zvnOl8oUJAfM%rBF@7$eI-?p5ZdMEIM#C)9=b~XjINapKV@&{b^spkvxWjvC57?z>6
zrA=%_#AdFX8$0g4VQKl*u3+ZQUc20DMdUfQH<b%lp8q58$Aq_1N>oS2Cg9>_xlcCt
zr|pT2T4J-W(cLg=##F6tFS(@$`!p&w{RRG5uw`0Gy^yqA9JF@R27yb)kD4BcPh#=@
zeriR;t*&!Q-jm))u&}o%+C_7wFSOOnUgi=tMPANrgSFz+3+84m3tMGR?bvxxNnfb(
z;Q0xY=JHQ<)Li&y$KfE&^TJEHyO|~|I@NppY5eqrZ?lX&E@wW7N$1-4cN_DmnJS0B
z|L&Bi(-E1rEcHVAudJS&wB{wos|_Eu>vo**as6qQy&)kgd5YPB*E>`j^)y+y_sh32
zZ~wHw*ueRBqO{?<#a!Zb|JaJJ-Dx~`ieaN#+>HGRdQsIclkaoL*Ho_-k@3}icsWaE
z-`s0LWtZM7z1NJDdn7M+d`tc^WrK?{Y<yo0vR;MM1YH*67b`#VLRYY1r)rLOZJT^~
zufxw7uOt3Ht>0j%BWQMR?#Hih3NxPNvF)2B8l+Q{R8aI<N9R_JaO5eQDZeZ9>V7<O
zR(U(W<>Kpi%vDk<EOw4wKjm(eCMd@6e{;H@T6e;Dd(+m~^fPx1#kThR;0o8Q&|5X<
zImeaCho4Qa7kqr=Y4T|=$9-%6i4x_KyZfdddRF{=<ECiQJF)c)oQLY$&F(o)&C@RY
zcPDL%)i>^Qww|o6HLA^e-|QA;|7i%`w{ORuJe5b!|MVPKli{*LE9t>BZl|9+TVmJF
zPq=^aGY4;F%ZeFg5v7O2J?xuAMQWz-+>$wRO#M*a1<%C&@yGh@uI<?N%Eo9S)Bfzf
z7rQ^Ptc%&xaCo=dA@;}*)`d*`LDmniEWP|<dDoGdhs_nwU-mx{J^iQ1zqVe3vg4r(
z*T^_Mt^Hk~rotHdTjzLdw|L>hBUV0dugch3e|M3ct@2}@q5Jj9_JYtK?_R8byp!8b
zg3F=n)Ft-js@lGJW!pEFz6{^-Fiv*sshiHfRhayxO`Jr7g{OQiY;DixnAhg6bmS)U
zI=j@wq$t*2DVIl)A!1Le*N9clo-%cJQsI6!k9~iP_eIqS9D5se;OsKCHh$^;x~n&L
z=UzE+ehm}5ws3~BUt)CvOWp5h(ly%?nEP6viTx4!R2Lk%z-u$(jH`a~)9YupU1gM9
zapxm*#FDv3*FW?xOnNF)^Zl>Rnmsc5I&+$4$nak2&Eh<`(sY%12#5OKi5=6wFI@U0
zcjI4%$G^+mqo?X$)1TFMAd5Hf?pd#2LA@J_#XknT?74S1>#)I38$PbwOB+kOKmPr0
zyzxuTlr1vx8Vr@Lx8CS1Svuq3&MK8jK|vFK*|46M(K+z$lDXi&<pz~~Q!a?un1?Yq
z1t|UD7yEY6!{cOg4gY<${P}D<BPB1a@_G0`v}HwvW~9gW+dF0U-zjz99#$H-E=&1~
zTpYWaq^1Yg&bDIpx}%3vG6O&TJAKYItV(W8%;tq#IF4QB;V+TCFC;1};?dE4WbftZ
z0(ArCm6bC+HtJVo&Th?>+VpAi1jYN!ww&yrTDGa19%a)rJuEnVMr?u8>{tDh_bs0o
zSf{aS^Yi1G+KXPFxb~qiP|@(8rQDpDe&dH(@2c)=GE};HZ9gXQ^{i7*X=Te=^?c=%
z2jo(PFCUQGHCy$M|MXC)uz6t`bJwyO-4s+3URii<!*(-<UItCikb-<evCq$Z8hY=a
zzwxhO?z&|M%kTC_?9%4+-T#|s>*<I?JFd9Tut~J4i`gXN{hZ&e^@_2Dn9K5Qs%@T`
zTO_RHy{o1lzkC1N<5|0`?B1IS7K`a0`XsvA@Yv6J0&CO`o;o39_K{UQHb__}VNp7>
zvDA&YMG{l;J3a5~yTorkeWSuipwcN~;)DMj{rS<0uP(ndxjlF9#l6=n&O~nE@SeW@
z(3B#^8-=Qy9$5DUFa(9H<lj*DJ1l4Sbj5RO>CX;bxg;|!HReIlRq^jPUw?dW?;0^h
z{m!Xfhm5Uc{NJ}L+WxhxS-*4Pl<v-o<II)+Gnv07+&R|mk@9}uDUbH3M3(f^Au-Y0
z<*fB37e3#knejYVKkU$x=xD=#)2kotcdimEsXAux_`@vS%EKm^AFTH>#>;UCr*FQr
zDIp<?arg4@kAJTvfACLQDS0A9JMq<{o=eBHUi`l2q9auJeG}i$s=N)?#s6zo-dDYM
z;L+Lr4+;VfK8-9Z?`{>SeWfgaK53rv(Pg4i`zsFBe98QiemU_@U!rm4i4)hGm#(zw
zzoyS+bx3sTM&ng4SQDSm=)bTb(b?x)e#5@p*Nbb89(!@mitX=glY=Yv_6KBVsNdlH
zUn&zL-T$r6X|md1!Q1P^XHDC>MDVq0%b}HOcjW)E&%cu2(Kg@DvEZuwh4bI!%GS>A
zoSR;r@a#lihR&3Q|FrcKkFR5UbDr1HHgVs>3-c$uGiI9~x@_O3@AEEk`1$pD+`bcM
zGtVSmq@_!@ZLwo$d4=1$;~m$&wtn&75PO~buw6lOc=xjvS+xwh(k6$+b}V#lw|ca8
z=MokJUGDjRvLg%^OpFMt>v`ER@vXLV{OqnBQz~4-i(L;MwQLMk4e|ZKI@$V~@U+~<
zt(LY1>t+g<=knie`>pk9l7QeJ3B#FDGj{$uuzQP0WSafq-2E9V*2n~2yv)nG@@9pU
zP|FPw-Z`tU2%Sqf;u7SPA;eT@uOpge8@!`3)KN2(Ymw4CB~4>_OH0=4DZbvJ4yxwa
z8T0KA>|K8If@I|3#X+n$PJjMq`{`Qd#9vSNn37EoZ9FVF)iyTalpk;K;fLZ<{by=K
z-)LQNvCO_!^J0SFe~HG#lN&UG8K2J8d8xBW<z(OC#}m{&PFy>9X|I}=<%W0qrk5s9
zp0H$to8)SH8%vG9ntz;=CaeoPw5`T>%J!%0mjp04aVWM3+zkBS1EFDjBI%384jhXA
z9k_d=n0pH<0yMrZXkz;r^(~Us*7oY|k0$YJ*|KyO1g%`~$Ggq+Rn3ctSx%f&gE)^`
ze`FW@RJTx0!0E*O)Vl{KDbBsHz_GR_;5574)>n(_n%Q31rSZx=^E@r$sZ}@op5SIa
zmd9uJ?FsE&aUeLt^!1(j_3tM)OMJ*wuDMVwc<y)J@$1HX3bXc3c8_><ZC7W;-Atur
z|I)dBU0>Vfn4PaQ)9*0HL|ImamI?cfKe_#v4^RBAA8oLAvh<zZ_5JZ>?~iTz|HY-X
zzVhcxJ#98cM@J6Mey5~)H*Rqk3CN2!Eja$LqvB2f^ObMz&W%d3;dY&{;mzY06)E1{
zPSYFH{aaF-odl-`Pgrv9v`bPAkCOAD4>oqJD{mh9vst}DMyBV(l$wY4mpndsHQ1u?
zI{(AY$o>2CY#vKC$wVieT5>+%t_kx)|Dc7-&m5TR8@w?mU+UMHIbEKQmoM;-=9YNk
zqWE`ela|wo*9#b01U{8}CEu{xeem#Rp;J384;)-;qg7FHVCxj#o_`OET<hFa>gJkD
zHXrXf(y&k2u=cRCqQnJ-hc~Kv-rg15d;I+IlLe+eXLu%xl`-D$dDU&WxP77f{*Mv$
zCXNwC{QmVb+a34re(-sptl^_}V-Mk`{sqCS4Hp#G_sCcYzW(;+(4wElhP(Xbc_jZx
zTKU9vHf%7sW3_{Oy8hoLQ+DQ-3vP=74xTtBDVNu`!N9Po(NTm?cV5p;`{fHxzq<M&
z`Y>l7pI<@Yw$_~!zvOc$ZdwHL&3lubCz6vLuT-9xKIxxlUXjM3ivo+=`5m6`@;hNs
z$bIo8|HjPO_F8;5xbMdwKYaTN!>cPIE_bbZ7iY9ioSgpP^m(g8nnp~s=Dd#Bp(?rd
zf3bl0x;#hU`%iCt*WipS{CHuO$&qsP@5#qL%nG=})98G>@<#nXo-~QKho)I;nMhc0
z%I@+#QqG+9(EmOEwP)Ow*PT|LaelP7He%x+u18weTzfa|FMqh=^VSQU&5j(3MT<dB
zzV#)PPb2-S%<t`Qk8ISw{vl?1+lOlYi4j)?P3^ulEv%C*`Ex|@*|s)~;N7CXX5KkC
zNB>yzwX4ewR;IT8Iew92T`b=_xzvPJYuci8=PQ}naaS($D_9vReeV~ShRM$hQ&%@f
z*`+3~+~U~VX4m2E*Wk8VxQWMh#XrryfEN?yFKt{I%Kc|Yxnk6^wa2fxiceIk_2sCn
z)?iR<*`p>qsrGu(7s>LRUti60q^|R=$}v3?>wQ?kg!TNqCtRm9KHjlspZW1-hu@i&
z?`vvzl%;6iN`HTBi+tUIry<chT8=9#xA#8saDSqkEFr1cdccW&u3PYh--`kq1wTs!
za<Vd;O_FbSioYN6=3s#2%mY3?f4S%KMcFz_Ok3MkWjcG||BiDWH@_*1$#e_v54-5w
z(6YxAG)nW2U-nb+rPc!v{>L^j`m73Zd%DE=N79{wo|`2i=ab|VkFJ!ns*-+mWR0GL
zRS`>=48Ma`&qR6ow%%a7gEx*IpP2ff@m1*Rg;REm|C;7`s84c!;)N6Uc4XNKt<{Ql
zo;|y93y)dB)WCxW6ojvv*Y^fK{+;m1RJ<fNMA9$pCdZA<T-^O^f9=>@4&|-Cnz?D>
zv^h;jYE<XU?m7OY?w!SlyBcpQCUDvYGh1;8eVVpnpQy)tPQ@qZMZ6>;r?t87?9#|i
z|D%8Yf53qY_jpA=UlvGz)uDCPD)GZ{(|}bqsTJ3CxxGXAib~&Qe5zzO`Mrbl)wNaq
zR$?0~CavNZe!lC+7We!sg_|8`M(G7SOL1Nq&nLTIqAiNg&A@1LTYI|Yj@=PXGyjV`
zU#EI-*A(Vc7So)jt`oknd784$8lA+{B$m&cL?6CQ3!QL$NA!&+%lohO+Brl<Yg<e$
zbZ<2(GYFA7u(V6vMy5CM?MKEni_0GS&EtP{Wd)D6?Z<w_mJ=;<E^Zu}OMF;l;(GJL
z=lnV?!BzfcraAxK)sY^bkE*;kTGnUB*FW!Z3&U|guRr3A(ibug1f@)s>|6WV{m^gu
zb?05=W_Mpqu6Ox&VDFDgFK>%~nJn6hOLhb@IB{q$sZp{2cvyG8#)d%I{l@OCRizIz
z(?j<7dt6<rY-GdAcI{iimb#OBH(P$J_;P?h(6Vnu@Oq&fo_}=<RaO7!y=z}~a8;0R
z#qL?nRt_8!#aR_V{oskRz5A6~1e`kFfRZyQw21$FyQR+|BZ6UFU%r%ZIe;oMCG9F9
zEzmGyihD9dz#1w+D|+|$Pq{lREiFOI>pp$@bfi*PSXg7KS4v7s$7h>B4UtFwaplbC
ze<uH)^0fO?n2F8v-o&4mv$kH6iPy+q-}Zcu;htyxvh_EQB;VuV;d$`(ZEqW|G-&W{
z5`#<oln>e#d)_l0x>U4aV$gq&rTKi@SLt4Sc{yvtq)Yd<efd)2Gsi;k=FOXr{;ZAO
ze&oSo&&g_!Z2aR`Jaf`NX_%XbubK1f*RLQh`-lZAmoHcM+ml$CeA{Pfkf-LK2bTFf
ztGBncwI%I*%zJwF#EBRGGZn{eIBaoyz0LEpH*Q3DJ><^5bF;AT_@7J@sTEhV3ip3{
zc5<@%qrxY5b`}SDUEHg}aPrvJslkRnSFhGE-(i;%VWL(W?9kluU^fTHAC7G2^hIq`
zPR&;Jp7!A7<>e7uGA2%O;&>>UEl|N@Cvocb>W7y3JlSlO+;=LTzkc04(>VRnkxpTV
zxq-@h3KHjo-vq4Pw|L68@Rb!MIzmftg*5g~IW#+RbDE--7T4;qwUdH=Oq@1N?cbIS
z8wBb<saaY^zL{%iYC1LO$HXa9ROU%;@Xi7G_vfRJXH*Rh1=G^flJuGTA3c7Yn45bx
z_Pm&Nh?<JZfn&$ocHdLJc3|`0tnBR5vCjXM^2^G~V$43RX;(Bg4Lu{DA90@N_1^T~
zQ_bD`<&JJjJzenUN1^7@7jZ#BUmphCjOMU=^WnktoiDC$(~a7m)j3T!dQs@>Z5j9X
z=~ngK;bJ|0kR6m7e*~Whh~##C<(x8e_Tr-pK1$fv>HNB8-adbydX}YI;@daH8W#QP
zpd3-T(}_*tWe1OTYt~lw<dW~(GH!3PwUfUsKiAanL&givyEAuJsOfrw()uT(RvrhP
zhXH!Rh7ZLHANesbF)<aq{o&hk<Mjjqsje%h-ffsZO$BV|OeZ!4tt)chn5}jmO@6sy
z-;3Mj3j6lP3Vu%C-lp`z(8fNK;a}Sc(7;qncq@;?CPCR*ovRLCdvNCL>>ZV#Wu|S}
z;BdoN)h>32^yR33w`Gk$hAP&FpI}hoPUJtIc>2xGh|P)IW$$kF#n;{I$-TY)f#iJt
zV6ffCxg;BIEGk@Xml1iMrM!M_bDb^UqEEl(-q@I|vg+ec16NQ(wBU^@V~5zse!s-4
zTUP!^dgPL`?;FoDw_gDdjGlde+ua#luB<VC7dS%)ndoymm{gQiv+tW>DlNT!*};`-
zw6(U(?C7-?PyEnsr|~$8JGrVx7ZmJWFH{*j<ZPmR4jpX%ZSY<=z2)bxM~`j_ThtgZ
ze?9JVY=_|42X507K!F+LqR;6dVxS+&de*wcZT-Hx7xtFte-Tp`{&Q&^uieiS!MxQk
zg?PY*E}PICz^FWZ)sG#z)m&P$e<dC|6glJLSM?7I<iH^)61b3gf_?CzbGH2Ziusfk
zf_0Y)f;=g5PMb}^A<s={Ui)!HZ*Qo*ChKJyX55N6bjCy8tIHnllr0{0HKM!2)*R^C
z@5B8(_ekrClog@tWe$UESke;og5}cl`US3g?g#$a^Gty0GN^!%Yz>m%mU=7cOL^=A
z#ibv!uC0me=;}JODs*+hhccyi_Geo*?z3qOKF{{8V58xbXaDqcb$$P2CMGKWd*WME
zWW>Y6laQ6Awe*9srY5JGo11~5;l!XH2R|MAboA5l*+-7J%$Paz;DrzOPd~jaA}`OM
zot^#S<x5Y^nuPXKEiEiJZrpHK`Y8L$-mul8-&e0)t2@POpC4EJle6c}@p19ZmtGpS
zdg82ETF?5;ckbMI;=~Do@7no&a<*Nmr>8yq@$oSv=bt>fxw^6AWP$5hH?yEy@hYs3
zzwEOJk-Ws=7j)^h_tCY^(i=W%R9}84z>^g&`|Of={Uouj)BJMI_xG~e75w||_5C<Q
z%J;1mcPb|-dNUNg@Dt+s(x^6d&5|ihl~S@&VH+HtTRAnJKc7_181V7>0b`MdJyKi_
zak8umuI`K{Rxf6Fa`l8j!;=Tk{Nod^%y_)vU4&@8z58_~RU?+dlXEwyzOW9N92D<w
zr*tmw$RW$+3vwQ{y!foOWu~EEt@Q3k=i3*{u;fT}*S(%>P;pg`=j+e!O@EIwxcEK%
zXlYSo?zy5QsOd>z4&S!ezN5>x<}M7(UT`hLaA~vksvV!MPY7c8l%>H?St`;XBFn0<
zzK>}__-8ey3Dc*9I9JqKiEOU_DK>w5c6(X<Y&*yMhQ=EbitDFL|9AAYchmpF1y3q@
z4^3Km`oeu<;fMUp6P0RzI~9E>mAO?YC3!A2VcD<$%8B>GT1&Q@A9^uuso|=l^Ow8s
zwcU_e;cBuzsn^U@S8(c#)_K~^7iudRey!(p^9tMdMVdpgWy1H%-c=6wn$|F^iQg<a
zeGPlU=Y}qhi2s(`QnnsBp!oMerjG7pp|0lL+aHu|vHNo7YC-N#Tecq}HB+ZgSD&}?
z&&4}Civ@*+mA^H7`0)JSOC5*VtsBxKD<&;dpQHKW!&Ci-7lJh(yiIDF`q%d8`Co^=
zG~M~>@98O6?NIS1HDRyun)ZV?ez+cdz<yf#w0OU*!kY57uNfb2F(0auT(f4)jyH^n
z>7Uk=w;h)g*cKo8o~PedK_~x>&b;e#0%l_U$K%+pF;AK~Q}bQ;ybXUVo}3WWiQl)!
zLjT|%R>``Ezn9Z~Sn(YGX7^NZ&r0iSOSc?apx7MH8OwTM>EnY3MQ0SB;Y<EK^T7$n
z_=v5un+<t&6BT5H?f(BMW?^R+|D$*E^Yil;w`PZ*nQiX>ChKvh+v3KB`-Ifmstz%(
zd$7qjz=!W&u>q&wwKk8_7Z)||R#e-%p{a2nm)24yDarYJ4}Ch$C7sW1+V*|V#+r{6
z2hN^9FD@M*_xad|Irh`c?=dYF2ek}L8`tdnG{Zjb^D)1KZ}0E-=ic7-@W#gEpsb6c
znhYm>tNPMUS{iIDZ%8aN>ydf;;n?~2B^NDr<nZ>XZ#(kpz4YTdR}wAWUt&D$zQtLy
z%;u8H!z)dU68jXHwz<9R=sDjIJA37i%5N4|3UxTlBJ@wluZ`Im)T4Cs?O`3M=bXFu
z9p8}ssmE*AT1!pm<~26F>)Mw+p1s$9ftXgoeYd_DSMG_ru{mv6bk(8HqJ=f**RNkO
z-x@aDlPnWEpUlqzj;_5tYs%YX9U{()^+)J8FI}oy&K_H~A_Z%V9bYi%Yr~S|%Zsm{
zKCoe1&(_$S{hwOix?f{HbSo^f%Asgd-s9={X~`!SYJZrwh2`v`cS_5zD)9W;VbgOj
zqw@UG#kSrXYYrEi{M#g!cV=Ic(c)tXA?=qc>dXb7-OJk$^h7ya!{jG_`NP?<*B{)e
z)I4Tx(t2<Iljg5AHkF@TzB#UF4V-biVDqOfKc0Hogvs?Edtr8NMc^?W(^IF6HKxc~
zWC&zk{8%%y+4RG+XV31iDdY%f^)uT_PBWKduiA9jVt2{W#}4PkD>rZ7K0WBip{n#7
zoXq{r0g()cnv~`A`8Uq%U+O(w?76}f@uGs<t6Vl)UbSdGmO6a-ki^&Drfv^DIdfDz
zW>({U_&1Y(OYY3h()(-O^M3nZSnQlCk)>RacUF^S`7@_f1rw`f&o&gSZi(7z*RcKb
zes*~t?S%J6!py2{riDl5TAEIrv+|g`@%zM&8#V6K%+b?ztOz-A<KJ3PJFov|^+fek
z(HB3=F>kwGWB9)M9+zyxl4CCq-Z&$APVbn(<_&GVD}^)zIX$%dyrq8Sy)Y=$JvZOJ
z-!%F50u$~Rp>`4*$|PP{|9R-Mr$qV7J6n<5ih7}2(k3g{a@W0x6MOzQ_+nk7e4o9?
zw0)rZ@t$lekHeaP*PB-bwEgK}<<?7h@6T;md#FyMZJUE?a&4xh()5jM=M)x9GH0ug
z;fkI9Bl-H)ikH$(9Ewlw2E5>&smFUf>CFSZA4{IQe95^fFm?8~W3v{@9}b+q-_cd|
zX#d^QU3(SlCeD=Dt0^+Q>Bp|a?E+35Kh0bD9E_Ul4}UxCUZ}6aaIpWdz^na&!ftsj
z^Jm@94pBY$<J!3&tD3bRUAppOqYA@55l|DRl3m1z!SmQt-RB<+POw~+GI3x|%(}5b
zbC&6PCTrEN4SRBzwQ1!@1`6h8-&pWGsQw3AFsS}*$#3Ox@Ok*+S;wnfsYjRZ?Y$U1
zYghR?X7zvXrf5&>`7$-))_$9)(CwntPV3r4?%ea{P;B|IVgh4_olR{{LHYNPEo)-g
zOJ9lj_}<n(u-0Z5%VF-a-S3PHIX1dYSN*p`!owC6jz2<PcpHTG9bHuOSboF%BZVIi
zD(BqVUdpoSqC&{J4GJk=9sIYfOl#IJYw7k6Qf(1%st7*8a73o8FSEmYU+?aN3psdo
zXUN%mI+&F<6dZT(@BHel_29?!&<#I>c+UO)|26gyXf?*|&=U+Uyi=Qni{`Z@TyLs;
zwD|1JEjec;ZLS8e98&&fl9nB8d*;^}+1=~aAIPwR++`7Tg29E~?CGk7p0CX^E-y>S
zy1kLxYWq5_+xC03=6yJR%7x!}_q3yNiX4`oJDNb@Rilx@u*mU~aDB|~3c=}mu|mtZ
zEq1=MpRwho+9cCUN-fdbo>k4bc#?PjJ)Z*`e|rXLDYgiF`X*w;VCXj0Z}G;I&uKYg
z%h%r6n$5Rsm-PXMzj^y#tX)#D$>_lJ`8yt+xU2G~tQ~Amez+p@g!)DOOPa+6X1K>H
zyyr5HcJ|46-L(0iro~%#{f){{b59=qE4%rkyVU=K%bvylYkqM~H}H5*oZEN3j|B!z
zyZ0*o(&0bATQ%2Sv1P*cCrcSS{ATy>i7|asGwadkhldSgW*zgJ-)|Xj(!Tg!cFCd%
z+ZVYrvu|0G*S)U$Z=tr1vll2bo_wD4!m(LhyzbBeH~Gb<H)uv|sN%i0E>_#mer;5X
zr1JF(lLPKMetY&S!gPa;-KR}X%a8UKsM|1G-Rf--a7y_yiNS?+`mXuO|L*O*u{)hT
z?Cd`_VYmKc8HrNX58ZWQZ8_}NN~GWI?$~=E@2`M=&70ItKkq*iXDo!|!LIw>>*v3i
z9kDQErcuF0uVZU-y$!RU>71Em%5Cp=yW_H^Wx$1*pRG>^#CQ50)?SzzsvX0>bozBc
zCyt5!itGhX9{gF<x?|N30qye}o;SoCX>@(Mq4<!R&51>~3+|_Sv2LhpQ1`R*Ie4+U
zq*_n0MW9l|iovrt_~3~vlBqp6_b{0~otyaEhE-B(?GBd8@|P<`9x31UxA8cZUoN~f
z#EC<3$qx}DhK){Z&(|#YpJJ_6V<>xhx&QGc7u^?_?_t%F{9G@+ZskhNk~w{wLNr7k
zec3isO6y~-d3g+vk1+E@@rsl8?HBIZD>Y4j>81&x|8*Z4*6V*$@2{+$s6OxWvFzFh
zg|qh_`1H*#-@NsLf%vXeza5*zU-QMdHn}k}f95y*b(^nX+P=r0Zf<PLd}p`4d6QH4
z@7~_(72)gU#B`%n>W&L<-IefR`M!U*`JY4x6qzY77xy1|^d@|s$JtZvd3p09E`0g&
zWy#VX6KBunp6Ycp_g=)lh<_D_KOH+Iy`KHvoH;TQQc^{g51!iQyScetl8LW4H#=;#
zYh0Y%^q<L<$+;}r#WsnzUxD^VY{?YvleJb`Di*8AJVEEq%{>gild}^)O)1+jC8+W!
zQ~&(BU!FQ4XKrpzfB5ocr>gg~Kl&OESy#{C;ctzPUwUA32=BId&z7|t#hhnNb1I5j
zcB4Z|Lc+uQqq4TPcaBFT$Gv}DPkVEX<(ie}eLj|wmUigIjTyTcI%TzPZhLH*ucoGU
zht=KYdGEyxlShR!zE1h9W^W&#bNt4($DG!6GFBxVudlB^{_*kgrB@bdr!Y)vUorc6
z!Q)4jGP_FoH)=L`cAvaqvrh8N59@=!rNt^(SXmRlzPcL3Wq;{1_dK_(yga>sPaKon
z?8M}H+opF*R$VuADccuh@#0e`<BTUyQVa`{d71Jf?%i-~-fk?erm4x9mX;R7Hr1!5
z#wI5>cjudhiItl-Z+^T<F%?|3KKpT~_+A9Vp;y|s*Y8O@$o_ik_Kh1s{SzksYuonu
zF$A5E%43*rwe~{grHURI8=k{$yw2%IGrzpt%5#0wk9u*Q?tPUu2?jd<v_p6_l%tJp
zeR6`O>LyA?)V{Lp;rZEPRC%XNKj2;*|Ldw}XS;KcCEtsC()oPP$Ear&chdAf#Dw2J
zQl_24u*f;D%4lA^Rg>=P=}9jyExjQWEjM}pJ05-Kf9HZuyxwel{rHq`=QzABB;MDp
zas#!Y%~wyj=&Y8PJEQAl_Pj-BulPPXFqt?0tK;EUdK&^h-rVdEH@|nK+`jiOT6CW)
zZG0WoG{uWUv1QLbCpLv;E3A_gudSQkR~CADLC=qr5WDsAlg&@xiD*1^?wG_rLlO5E
zj;SpIPWL7_u_<u9keqek%8c`YpO^etlJYb;&%eAUFOX~gdY&T_cY9v=WLwi9;B>;e
zfvsS|e}4|MqEB09+}z63X0F{jQQG<F@$JG+9E$4~doX(ZSSdT>|6!Ro`ve<Sv-c@m
z%)Q4PER?ZCuiw)4j^VD<%r*A%%ICnUS6yH{vHA7tjhW8_=iJyW#9s6MLFR|hHMc7`
zKW4q^*Y{N0R(R}ki_9AP?=fDWnxkvo1V#_8ytg}gYtAdq_!eqhVSQs!-u$o&?`+x+
zylHapoIJ^KY0!h$e0d!{XO7M?hSbrftvn7r35m;H<NS0UJ^sAlYUV^y84i2zWQmm-
z5}uyPISY;~DO*=DZ&G{ca!n4!7J;CWRz3$i2{Va#A9ow1|BK9-VafUTSe)~1`Rc`5
zcO`?BA|+NEEbKL&r~dqr`YTS54wqIQhew5(Z(~z#lpde;_<2Ff{k)tTA7$OHm9z?$
zHcW{KQ>&VB=N_xSaPh`}F+5vJ>h%;`COB!O{8-@N=cH0}W^Tag)kb?(hqd;XYkv67
z7o=qFoows#`bF3AjW=&Rl5X#4iGj3m?u&v-KFjs#6&3li*JP~vKR@SIyT4k|<KcH(
zI~O&zHm#cbYjvDj6qbD3Vr}u&Ao5omsCkp#%HvQpF+E0*?WLr}?o`&WH4%+ZPm3p=
zyd=zVJz%>v<CjpbKN>8G%(E;O{ocgzX8%l$T4xT$mOrtI%mTqz-Wc<0r`0!}zqQSA
zwps3lg|~fj?psQketEfZ#*^~TRaFTo-Is3EYcsaLzqC6Uq;0bkzhdwA+igofizR%|
zjQ{Z~?$F6nZo|y?xhmO9SUD#Cxv^I#j9;f;`{2qM8_k*2UryptY?-iMBZXm7+iUyz
zuA8#+b8c)Dls3;h^v!pzfbDyRKbu}SraXD?!y7u|<4Wl(KcjxIEld2;Ch)^G&Fj99
z6NlzYF3E-!2?=Xl>+00vOcY;j@p&R4?GW!cJ>i6Xa&z#_-^p#}`mG0^N50sm!{B_4
zz1u%fwM8IklV}x>$KQwZ7uQ^>`;vW4YHjp(r`?U=7ZcL>LrfR4Pn`IF{g$naWxd~z
z@!vhA^dQpAF7^vYZ8&@9`d{iT0zpQiRXiO#v$=VGe2T8I%wuuuk?1Vky!_#6e%r*T
z7xx2LEE8{hPL{v2HeCGgvp2^l@1JLoEmT-~SK{ICsvjkfg6{ZEy~Mda=j@jYPnoUX
z$VN+Y+kbcX-!EfWk!!%Vj@PL#O4~0=_HLjnhoY+M!o%!qt%StuBfC|*!No_!zVABk
z)So>#YtN>_&j0QGp_ix6&Di!R+hU$|qwRj%L+=ec*e06uCq54|J*M+h>}!%-;_+ME
z9+UT}))a3tauC+nHW5`bi}?Dvt?$LABl5oW6%DQKiv%anYTse<_5ZT}$35Z|eU1t;
z?zfxw*^NWdCIB>U^j}&2`t<%I+a4Ibuvn(ACG~njO|r1syX{9Gl^zbf8lkHDo$bY<
z4fQ|$EoR=4TD?EBgWI_6Va`f_gB+LYDQSm&OEP!tt!EXR_wCrXP}zt7FZ1N|mpILT
z@4oQUewp{;dNCavHW;jl*%{>Z(A~|g?Z@RaXMFygoPFg=h=i2Xp%W)OyedB@T{gME
zadZN2SZtk9RLw4}+2NWZGk&eqmeJw);P2cU6clu1kEFD;x8|RO%H*F(Keh9udinCU
zu_avymbm%yq=8xb)86yxlIhFT4qdtA_T$L?ADf!?-1I80S-5Af7VoA@L5WERPs!w8
zajHEl@M`r|lk@$LkM}2^oTU2be0b;y1{F#5W#<m2Za(&-D64wLrX@?1B|b(P9Gf$X
zLBDXOxyoVw)pfUePWK(&u(!ODCI4MpspndQj28(ZN!nq@ADp?y`a^NA`nlfKtuq$K
zC*Aawjq0D(&i}R{dVAjA^?~(?x3}d6tPDv~m^A<V^&QP?*64g(-r3ptW3u_nmoG0|
zzplTHp@miKm)6oB#_ImvJuzqJ&zgJk_F)0B`JeUoa^`r(>EAvvefya?HD7+6;FYhq
z<+NU4uHMSb%%p-8g*V}H8y}p#b0=oaW}C!zFR=-;qaz%aK3QGfy|-P{H^W6&M`vNk
zzm05rYxO^+WoBw#Dc<+#*akC2W8>g6^7)^xI5A9`%j>=H%+u_~OV6w<X1zReK3{nC
z?Bjj1hmZA2ADzE`)da>4ss6fG{f^Pf7gqevxKbv-C$xQA(k*5GGw-hoER9*U@ZxdN
z1U=oqQJa`ICZ0`;+4Q2_w^{38eQtiv+052P=idh=Z*BZpxMM>y=d&Xv2R3Sc6(}u`
zs@t{PX?N%S#q%aKDmu3*n3!yNQ0}Ruq;z44r?Ag#v$y#NPu~8fq;To-<6;B-)AH6C
zCoW2CNS@p!Yx6%q$@I{{*Y~+H_61l@b^5R<<kQsvL)OY*&PwfnZKqt~+yDOiwL@Z|
zkp2Fis1wq+=NCPB8@l1o#$N}LlaFTKyOB8OYUsSr$NW+%juijf5~XV*)jMOm&sHW`
zt!Il@y4!7PIiD|Vt(a;npEF63;pCxa+w6^1+x6!?f7WDM8@te`VPnCD)8|4DU0trf
z?B4~(bC)iySC>0JUGG@q1h<IIi*)&TrMslB?n*v%;+e*a1E-H2c0O%TznS^kTj_@1
zoA)2m_nc~wS64qpbpQX|tlVN9(-XqhMyW3S@Hln{OLBt3n`}P);w4L$afmuvOrHMG
z$USi5o|!Xdaq%+Mvu|CqC1u72Zv!qn>6V@;EHffEzAO00w4`azMrFbJgMp6s-Yl`)
z_hF8C8K+wCiuEyZN|#nnoH~zDxcmEOAs@x;9h^10dXK-dtuB0UAyLMzMxveX&Ea*n
z`yX9cxHsbGu_pdwQlVL44TUGHc>ZN6)YT<*dTrg4u(Y=6vUb0+fiJ(_J<|Zobo*cR
zhD@LJk1Q;?%ci0F_jUcG>C@F~AMtk=+&rQ^@ALHa7rBJz_dgQ-Jnek?y&JObm4}Y3
zmf7lO@%pi0y_I3U%{BJ9eRn;V3D<vm=6dhOx5t5X|GNKtY`+>D7GL>A?G<Bt?FOfY
zi#xR0e6o10dzo+5S~ARiJ*~}4V^7q>hIOLnY}TAMb^rgqYJrYUKz%^`m-kVOf95g^
zA5!0_`QUSf_9N4J9seoY7d^JjKhyo^W5@G7dpT?3SlT3OqWBKa`B`kRWTp6#hcms(
zx5!-QixbOP(;~Dq>-(WMKZ^}FMhoBA{2o;Me>zv;$*|~P@O@s1i+e1iwrN!`WpO_&
zE>6t4xJY!@*VyLYbIM}DBlz+9oDNeqeElQvcUeti+|?}xTei9Go)~P9dMbtI-vuu7
zPa+#GeK42k26uX^JsB1?tX!=AYHLoH5!==ej=ldRF78x~+LqIM-tDX7>*t&m=RPv{
zgJuRktelYSFlB?r<hJJz#S6bIlmGKa?$Gz`(j6-vaCp~NNy>s-Ps=7Sc5rQFtM5KH
z@8%7&T%luqGL7%^rW}5>lsWL`jtTq0ePEZMA1@pe`)B3uPQLJB<BZ*v{9*iSc-@`3
z?4V7fK7}AB{-nc)e*P#sq@ZI{z!=V-bNJNV?Gum5b%R=-0zoXTJPt+$rFZL&Op|PR
zpSHzC)SBBw;*ON(>%N2b-Rr0C28Ts`E004-Lm1<?Ny@E3jLgZw5=)LM+vxMx*yYRu
z`QJu6g(0br?XdMB#U$o^zyGmZ`~QKJjnA^}l<}^`t2pQDZvjpGa_r}_WjnIz&T<Kp
zI;Lgk<GXhn?>n$z{jsE~)mj@Ky!U+p8m4)8$D2ujS4nT(;R$NK7nYnn{=%$M>{{N<
z4&B>j3Ac}}zxaIf(;eRZN$M>EP9B1LRTu&fZF}S{@!{$8AD>QZ&ag-mY2%meT6oAL
z=Y~X&%te_zttt^~aF9MzW$fV7Oq{+k_ac){#0H7e)AWyjviEsy7UyDew+%FIGeM~;
zlOgHZA3?YCv5i-?>yETMJZ$)fKluMW-hf$EkQph^)X|j=em>U|i#cp~cXs5So|br1
ze%V%OeWflWC0`Q4?=e5su3T8y?s=o=mx<s1#9RB5MOM8I<_E=%Q`a+9Mh~+;{O^z5
znt5DM`%LD%xTB^24OCWg?*ok}a8!zdrl>9$n>1})$#}#2`{zI39v)b_yW^DJk7;}C
zKEB*^2$Ut=E2~Xyp7%a9t=IqLTB$8H@AI*MdvRxHpSbSLB;c@IR4hpHkjsypoIFl%
zZtfYg#cIB<GcYh{*k?E2KgZP6R8&1~=FFJ~kF>n4{kH*J2N%~QRvMd_OnLU>(5GXs
zSk_1U3(>NhUvT2nvXFgWHfUO3li0B5<Bf>DC#2VZ`SNAQS^3q=_dGj$;)KVqFRw(b
z8o&IMfAa8P-+RNnGjdNti`(jwI1Ux-Jbdwj!Pxe|orT8xZlAhuG2zOUkT37<O3$1*
z^HGh93rkUPao|EH*1~z9l(b&Y&`>b-^t7V~o7tC6Syb)G!1QE^i_(jW$w$(kIWEuV
zadx%4l4W}1to|>zycO402<2E<D<=HhUGh@s(`W8`S9TXa_d9a@c=DMUhL3Fg!`8>?
zKAU`ekKz5A&%CR`*Z29&wer;b^W)X(^&cL#%P-2ky)B5#Ud?Y#2cN9f0?)~6p!xI2
zWX7tyyGoae)NMF?ae-s=hqv4B9|G-mc*<<uDQT7?@$B4O?Kv%$UMp)(oH%h{Md0EM
zB`<>_A|pLl)_8b%9ctke2AwaYS6$7_#I&K}W73+~-C<r2kI%I(-%$6rs_^#5XUBS_
zcN9J4>XWn8TDpfxtYOc4F`bA7(&l+{Opc2$Y`pF}*D7?@WB>hie@mpz^QJueacOUL
z`Q3MScQ3Wv$8oUTZ^evDGVxJcvz7`om1OqWe|>%ZI(U~$&CdtT{3TA!T4z5xTXbFo
zZGxFTcdqWz56&EYNA_fHjnZt@@0YW^#Hns{NhW?>{Qh;>*VfE5IX=Dk`MJ*Hldd1U
zfAmb!fpamRK7CqZxo^qx<=w*TBl3g%{Q69ei*LJo>C&Yomisou=`J*!@a)H-ZIbJ6
z`(`Xza53Xw`OhipIrX2S;v?tXC`-0g+*7&nY=v&|nl&49k1NNWmYzIys%mXjsj3pg
z!<oBxTie*!EU^p{xp(j0ozm9*+^a%Yvq?)!XZDGRN!LVePV>!U7ysPFyCmgyFYh-M
z*TZ_tH~#vyPfL)I!@Bt4$DS@p+bWY|{qp)}Keo>e{CJDmsQzEgmi+s1vmSF>-+sLH
zdT+1ws_^ymOpeQ&b<8<#93)neb9-Cw=>_4-FL&PV{riNMyKH;@{c~^c)~(q-Dc4%=
z>Z;K0(;GE;toQBBTR-hpwAroKw#TIc)z#Gt4OBH}J$aH+QCS(N?<=^mvD`H4O2g*O
zo2NK&X)7u+_DY+#?cBL@ic?%0tK6D(n;g$yaSk?l<SXiQ;P*v$c~8wH1~)o2tM|Ab
zZsP?d=a;btph8YDU#gc8R45_V!rXh$;4-~OI(qqn$jfOj{vQrw`D{7ulkTa*U*{iN
z=)HMa#;rB7zw&nkPgv7^aAoM?qi@ZUZVI}1K4$zZpW`_F+Sv<hUMsxe*Y?o<SoEmi
z>vh&2FSCjc)-00`^L?wDw_CDWe&K^<9;S=@&pLljJ9{DXi%*QNkg&Ig>7Q~xr_alL
zFRpnUpkpB)JYi0a?B-)7j>d`7XD#J4r}(G|H~!u)xIOj!`tV1L_2n~8X@{?v?)`i5
z$_;O4eg7@T-n``Yp2K_z1=pWtTw7&qc6a(ckyV|?E~Y9U%{9+DT4?k5v)<(-@!t<j
z%xd<^3tqCBl%MczM^lm6?}{V;Peoq%mwz<(>f_U?JN_@4<2wJykA1l<snN-2OY7vP
z2G|rmtWVH4)3@t)$^7?g*2Wh)+eF`9tbZJ9D0(a1Vqemf9dF(Ath+K+&RO|B-|2bS
z*$aDKC&>J;&plc#(~u!h`IVvW=7bKv$!rHcUSrL<T@$R4^`v!;^y`m@OHHNt{|LqR
z=kh*&Y`j5NL$=@l&C!E@t-j3qWcj7<Pg`tzbL%7Vp5FNXY}2Rhy?FIDL-n%UqscG7
zPf01fZkBNCi|>x_J-ka#wY-0Ic86@3T=TK*u17wtwGfo)-;xsl=g;F<6Db>s(&G6E
zpYJ^O(D?COwMR^|v3<j@7S^`9&%ACX=58m>9o;c)^|7U@vp-s_He=)e%ke!u|H#so
z5S5m>ho-3}W*C<#Xtmrw_$+k#f#-X<icYv3Xl1@py54A?*tXd6-PRVHGL4%|Jb!$>
zefPrWS50<n?-rE2a$C5JYwOn&d4Imm_F8dx?*fYwj@@<KQ>1PSIW2e1I<kJoy;7C1
zIoys1g|&qWiw>r>EV+K@L8AQQ#(;BrN0urm{xR96!{@r%usOi;lbxCV{vH{XhY!qe
zPkecS?eFgJqdO&E7btH|*~1pMJXHBmxv5&u4<T#j#|PuKOe(LHt=loNU#+=iTau5q
zg#7Hjw~CS+mfOVJ`L&M}E&KJ>{EeN`R?*=8Lu*UrOFmvY{O;xLkNJits%08d6n?!l
zRtb64aPe)`<IViJ6TkmaOv*U%_P<2vyPl=R&y)T<UwdIuvV2X@O%8shCIPXTETw1l
zB(78`?79}HpsOYF@nV1B)fH;Lcx4+J|5`0{`sd0r?S*lr;wk@K?R&G&9oXPyIb)Ut
zhp9PNd2(n$_C4XfRz0rP{TeQ<_Ren}8?acI9-cAJ_Tuhj-U!uL=ZelOUX?co%AN{L
zTD{fb^DNVgZ#JKtVO46gYSo{XwgWPD^K1I%&F^*ne2I~RyZh+o4a+Nnw(%aT(^|4!
zhk5S~>yAra`&S>isN_GFpLw>|3f-LDQcqVe>{)BsbBU?I?!55)Z?X;loPRH#cG0xO
z?dape5U!Ha2wAxny{#r5T{S&Rgi79=_N{H=zWw*1=`QwHkskWKr~41|su=&+B7Q3P
zyJ5ydnU;cub8N*=MOtX5&#hXRuFd~K-R{8WEgUgtOC3MU)m}`$QE<h0H|PHqlL9j*
zH_1JCwpGML;s$SM#7^N$U-s<c$~|h+^Hz0>==^VPzq_2GAIf(aES!^>?fG;~AD?Dm
zzo7mW@#{TVolgrL?)yJnxv#-tW%G~q_wF;O=reo1)a>}Gr+m(8%IQ|8_nIvY(><m<
z^ZT$NeY;hbVC7ehb+&&b=3h5<^2t-1q%C^K?p2JYY~`%y9yKDp$EV&+(4HdUEUZ06
zOS(mU;v*&1;5w~5*;~!&^8E)FxcOZ$HWKs;O8#)eMShpjwnI$6G@@0dItw{HxcZ%4
zLd!RVaJw_lxXq><wChvAq8B9{wZ9mm9-b+=;4Z%~bNR)HN_+7(&5az}%-ZWTy%QC+
zD?&tHy`1c#a!lpX%nf&MR9ENTWni9sydutMcOQ$IM*Moys2y`1*%NP{{kGYuc%flI
zomd0=I=>A@qEeAdb?<1kEBy*oO8WG9g4)%@>0X&9Lhao@y|&-+X>MY|!>(tGk1ePz
z^^eFfIV9*OAl(|EZTzD1=@}upP$fa}i7L}JXDpnv(cq|?M!MTHe}Qs;i+fWyw(k_J
zF6)#%#dX`%Xw`$eN$;&!7lmHPJK|xY`<6qw^x!t_4DB1ym0K&STr;%gOhs>ZrB}}M
zSouQfpLP1eIZvM+@5pssaV1P*=D+{j9{uHY5aH68s`bK~-{ex(lmM+S3Mv!rPr7_~
z>KpOzZ)runxy02Lr)2_ObF}s+?9TiYdZ<iTt#+I4)(ct@){C0`R`*Z(lW=&7wX{KU
zvd|pg$$}yxjThL>Kj^r!Coc^+*YfsAhRLshl`WOFiMO9-AM|tBdWbFL1&`OWZNVJr
z9w#L`PJKOes9U@+t57`R&Yb4Sb#5Cjif`-Qa(7G4?w6dmeZM~cwOXLb%J2TA_&=W>
z73Mw<TI2t=Vez4Dvu|2R%?{5w-2434hHJqhHVr;2c0Ag4IoxTfz_R_<9)91k|Mz+k
zui6<Avz(_cZ!^(p+*=;6;pk*}dEc5jFC9})Txxkdr%yL}Lu_kSjM54op2Rb9QqyO%
z_g?7xr^oC#-7M+nndlY2{wDmmG1Ea)=6u|(unoE2^^foVzTM;1?8E0`X5_VYu>VW{
z=k?^-6i3bOruCeY`z}1L-cXmzVi&hpWd2W%=L}lh7B8g_youYf!{tbA^1}m9d8*~Z
zr|gz)iP##TcloiPSOlkB&E7R3VK+0gZbY;^y8bnL<L4u`cSN>5zAI8)k)En#uhOU6
zxL~&5hO&}|*h=;t_dd9<nJ`OgX6KI?Tm{;l{u8dhdhj4bN=|-TOZ!a8H>Y+U(6Hye
z_-xyXITKpeEMHS?B-g)g_o0J_<-RS=eNdttu%}L5ewCYBR;9(}yd{%7=JrmR5;0@?
z$F`jt-tLhObuUUY`4g)4p;D&v#}%2xnGq~^b@{{PtEY%bg<k&6>a2hG{cJ8?hs+xi
z-J4ZAu6+L3v{&2avCstBgX`E;4*hTAeslNjk)kj!jr5#1n%e1^obL)&J?r|UIMJgo
zeKA|IK*e^MJEvZ3z8~b2air{Xxl?qZPlmRc%c7gJj=qRH8jzu_^Ki+f=97QLb6Zyy
zGzCQEXrJ=Vb@f|yA&lj3b@WF$d(O~~yw8sXHq`U;9kXqC-^wy2_a^JvRX4al>Lv!g
z({t;;radw2JbT$m{(`UD<c-#>UfA@q_|D(2;dA_Ubasbt`S9`%Bk$g~6Y6W&ul>4r
zaP8-G!R-H%Rb`)CJbRy?v6WgFy?)<|+pAS&ikTN=ZI%$W+tP0K$f{4?vURt=|3UK$
zvTNB)+QTzdlfLI2e)fRjj>T_=s;kutf|J8Hp5E>v=yz~!>*h;~kMk*?`LC!qZ@<zM
zbNwwZE-;?!_fI;1vA9B_Lgf15tVNd}@V6?cvOlaYO9-DLziv(~({BFVi+y#~KTh)L
zRGt(1N@)JW>$0;2#id&>@1N@$w{q5tPnp^l_wKcqrmuVSt~Hq>tkhxsJ=28gf_<;|
zzdOFO<@Jt=&_=0PJIC7c)!!>G+_%4=WcPthPxiFK*~H$5OAOlLUZ~1g)XDKT^*xMA
zDXr0(vbjjivP0n1&2t|0G1k&-ui5TiSQi)h;=Wza+Vph~4o*G%;dEx}yuVoo9M><&
zIVjUIZ!gFG<<BzithFlHF21mOcIb%}@0o8exqrK>>sa6p-6@-mIn7(PF|E+sBFeib
zccI<B*bMD=T)9Urk63?kIPZV@aLli>^<U)J6}V<tRvuVeVx%{Rw=sM7JBd5H?ba;G
z?<_Er6Vwt>S}5t`?~-!G_=rmCfnA@DX9TV1l3BB;@S~H;o~p0T`^)Ybw5sm0+i>J;
zxB0}ZNJi&>#uE3`F6nEXyz=uzyW*P|?M0KCHRr6FF1{_DA<zDV!{m>TFYH{U+`}^`
zaAOzSbHBUoo?F!<?BX&Cyi-Khv`k!V{%YmB<mW5dJxta$^f9Y1nzxn7&-Bj3pMMzT
z?5-_%dwueSWouM>bnZL|)DwR0$9`a+Cp(YqAHz4^Vcfs0TNPz&Y#z?4V@-c&<Gkwd
zaS4kGjjWq97v;#hv)td=mu|`T;`3dWE1N<NUfL^@b9T{#>X(vxs`*{+o5g9&yc)`w
z{QA<0fZaT2TB=?JMQfxRI$3g`b)UUnZQ)#jDUvgHFO2z_vvAJO!`}{<Nm#AX%$eGz
z5q+LD@ZWZUX$f8L?$>o5<5OL8=~c)Etza?Hz21u98QPcD_AIEr7^aeb=$Lng_N(f{
z=bSXs#TP&P`jg>H_Uq6KVOKUD`O0lRF)x<WIgO{~`hF2R=(t8oc+h!u(3rv}G0@U|
z@J25pH+I3)Uu-_Xp_uRIrt|KOMb{TD<`01fy^a36i<h#lE{}8A<!oEBCcW=O`n4Y`
zJa^jLN7>p+sOv3V?3FBUG5fW$wV8|}f1dK88?t=Q&aH?(>lyXoeUN<ok$G#yCkAik
zt=h7Zb@!w%ulStqIbLCQ;;3}~Bq;v0yV5@I_|3i355(zyci+j_{^9Jr*(Xk%b$N34
zam4<&(|#=4X@5!e?tx$P`;=8W_x`fsf4KepgXwGcKYX(C{)g8mkF#?B<#t}m=UHB!
zc)sy2M^e6+a!WxklYr9+>4m2|4zA^{PQ0BVp!Iytk*h8*xjpyov%GV=|G*i=vk!A}
zc#NZ~XDqpU_*LoYkEi!uX=<I)W?*jKwy$xYK>ZOVlRNT1J{X&9xz@aJtF1t##N}&m
zjx<Ne3hZOA-Tn1g!@tiTR=@YVv-K~B@V-}VX>w6dHvec9IAjXic#!W>wZ}g1U9r>t
zle`IOYY$CjX1rw1DspJaSwDBLGBcB^HUsav2I1*?N+FS=_xjpcxjm<7shVWoJmGW7
zZLgT<!Yfh-R6beM?Gt3Z928ezP~D;%|EBHIbLA_V@{P8^*AMHno;Y{HZJiq@YqX?d
zOEzftP27AnX2<k0<t26LAx4|pmQPmP^f&Bb%$zTO<u!Q|R`nixxwm`cqYg>7@3~C#
zgWMj4vlccB{i=%e=;A%J__f>z&1AmGXQCta7OCo~UOmv#XIJ3$`Eci(R}$u_9BzEC
zdtSY(yl|P5k*_yH`N>>IMh?X%TQfJWOMJX1*<ydW&aA7sU2&J|kG-qiUid0$!<HlR
zFRq-ps?GX-R&T&fMS<{lDb9<}IpysWGcXZq7I2L+Qfk(FTs61<L7PsBMEJquyjq71
zp6b1G<2t=@sgLgheKr|4gRNnl`={5cwd~ObZ4=oe7pr%uf3EX^^zOosHw53<moT*Z
z{YttWes*H*XN|m+tR<}68YNLr(w-k)<(IuhKfh<T_V&c<efb8(|8m~!mQiI9OFMDe
zqv`(B&lz`i@r9glcT;<CaijUHB{oO;w(eIvvWY26{r-V{_w^osxf#5pE|z_%K=XyA
z;!gKu!NJ?@H@WA4LU@h&K3SVPUWbn!Wj(i4=3`?2wGG9_ZUrCSZ(pLp+mo1;!^IuV
zzGKR|j%Rmw9lC8T`*G*fh28s_DvQkzFO3ZjDKKiDnCWd&kS^FNI44FnF+ZByR;{GL
z$Xv$p;=CCf7V*mE#I>nrA4&*umOr$<ZDpq*Pl(lp!>k++<!#wp1eChpTn-MbOO*O&
zT*mWj%SsMm&A(Sw9v$3xn#1R`ThSF|mm{|pU0!mnW1czJ>`kkaFP&k{$kEpI;&>?Z
zwL!osCGka&^jxpyk3PK(Nb$;CuP67N@BQ&}vAYXC1+r!F$TqJ!d2okpCcF9iG>vRE
uT{n)0VjyiCiY{fK97{xrGL!K?>%R!6|C<*-C}m(^VDNPHb6Mw<&;$TEf*rj8

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_chebyshev_series_3_3.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_chebyshev_series_3_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2406aa13c117b5c11c4a4be45d7f8530ba9a171
GIT binary patch
literal 52008
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_empirical_1.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_empirical_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..162a254629899be96241639af2c8a95fa559f436
GIT binary patch
literal 48465
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
a_J(g|D&GD%c!q(2fx*+&&t;ucLK6V1&!js5

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_empirical_2.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_empirical_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..deff7950b60d862952e6239c0e8a53f4be33a141
GIT binary patch
literal 50362
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_chebyshev_3_3.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_chebyshev_3_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e2bd9ba2828829949ce93b782235b153898fd0d
GIT binary patch
literal 21520
zcmeAS@N?(olHy`uVBq!ia0y~yVDe{RV6x+2V_;xdy7L`Kg0VQr-HBn{IhmIX3=Ayk
zj=qiz3>*8o|0J?9FfecyctjR6Fz_7)VaDV6D^eI3f|q)_IEGZjy}fJS^XT5Z??3e?
z`&vksz4xE(z{+83d~>Qp)u%;5N<mFi6)N2(loTxG^4{gBzMzvUv)QZDgKLqm9OoAE
z*^-JSp=!Hd`KiyD@b!BA0SWmHjMB{Sr$5OvVEZkz`@vyL_T3w{aWXJ4B>iN6U(dk6
zaKxd4iGji6LE^5rT&+#z+zffbi**`mDpq_rBF*0reY9F)f_%wsMg|5Ih{A>sEDQ`2
z7#?ymFeoq{5@uj<U}{-zZSq!RPW-bS!S2iM{gJ(VE^TJt_5)b~+&1UuW;IW>Q)-S%
z*!Q0$x*)dk=Dd|9KCk;dx1YS*7Hd_XU%R^TN)~f<_W7xM_8hb7U-5jwiJ~QW_4{4&
z|F8UQ>$mgHb-V3vmOW0^jtMKC`DN>(XR}XbMcJ(@p3ncFio?G=T{XUY)t9wfKW~2a
z^;hh?z3$uI@K5=5DE8Q^(~I8K?GV{*{ND22pH*9)ZjIh@|4H<v)joTU>%7!|^{%}`
zmgm)@^Yc3@)<3?)zjhbT-fH!YhXYode}9*vURmi|Di?eHy6D#UMce-;*y{XBs{DL9
z-_&wO{H3BVKW^x+-stlyYVosWKJKSsu35$5Z&@@kf6;1x$+Oy@LcY9nkE}hp=++eR
z*kwPI&c1Tm=OkZudA{vRpF8}4>LGi73$D@7Kf6lj3+MUwjXxcKy{*&XwNBWw*HXH1
z+Kj`gTjCd+PV(CQ>TZ9wrv2Y(t-`Mj3PFxqJg@f+|Mgk%{^{H9<w}0*PW<irb;GYH
zkF7tG&VPK~-DCGyG^e=ddflz+S2D-@`d@64`u=v_swv*zR!f}P^-HFc<ym=p_RT#x
zJ;{F_d}e$i_fS*6Y+vWC{2zxu{$o%3;CplSw|leKE<N*>|D}2T%oXPOvCBSfseD|w
z>P%{;WqHiEZF_Fs-&XIkZ>Im#^!1Onc>KJ>e`HsO__jOz%^hO;ye#>t>wB_icKp1(
zZJR*PEcs81-<<8pwiBte{g7+tC;P4=FfMqm{Oa_@D@(kTGplqR!|D~kesELMYd3l`
z-Qu{<0=X`K(V6{rZz~pseX{JjX|>|`j=xgEcmK<$M!MMQrtR#Lmv7tjj^oYkr0_I(
zCEfJ7x)b|nT5RS`-8!v!<%#EJ4}M8YewHw|lRw~F@#4dm<NN=8)e2rR*F67iR!7Ft
z3)A@D``(=YZQt5gM)LBX9@^$jy`NOG;@zdN<!`q?Qh3W&IeF98-wU6Ve>XkmZg=3T
zbJe}clfE|wZZGzGvb|2<qmG5iyCyf&LOMMov?I7(+VFIBqt$)EoQ<2_ZktviH1%=E
z;@k48*sFhf9=+eM8yWU!E1%U`-M{khvTq#!{W@;*5?#NY=dA2%78+${Tt4$;&E=oY
zciuz?N4A$0{;|5<vSi2c9lD=>GUPS?ZT~G$6o19@_Pt}@Zv6{eSAH#b<+|VBu3wiu
zXSB(9>s@t;$iJ_4N!2N?-oGyFcXs)@t?$B{UtcQyeOqwB`OaI*8vd5H#(8hIPij_w
z>oD`p@vo&#saG^(*kaS(FP)QnXPy40H-)c1Ecvv{>@)wh&8H*!&VJ@enxY)DKDw>;
z%}velo~jF9TdvE7t}Cc@wbl3A`K9#GX_vR`;VzNNr$p|VrCWb9%iDeSVeWk!`)7uE
zHUAiY#W4JI*d9A?i}bzi4+_6HytcT1>Z^3g3+<fLe1p@IL!K!YwykVAzT0B0T&iYe
zx$G^`z^GHNZ@oQrgJbRKmt7VnH&%sAd-dV0bj+IMpgZ~B&%bXpy2<(}x~ycAeaMl2
z0TUzNgtaZ~nd@7$JL20m^|aG&i$2YI^(VkqUZ`f?rR)6vyA0ec4}Hx_x%JQDYl8k~
zvoF!V`Ltg(EWGDmINx$=;T1=@#WCr!@@+<M%g*17PS1}CWw(_)_3KW?=?k_OWM(HT
zg8X6Ea693@p?%9A@zDK>zwi6pKKHgmf5S$W{ZI4upLN^9RC)T%8udrBKcCy4mj5Z<
zyef8INB-Y~(^@51O=^{||E%^ekIH$oYxS}EzZ%P@T#w*iR`tzgnzQ9v<$u|;qC5RI
z?~h-!%|6doMRWSO^7-lS!>jG*?&vlv>+kP)tZSm5H?!$@-^w+&H_iC|b7As@A2rOe
zd=7RZU*v!He|q=wM>D(TE9VQ2x9#Vr{a)*4{w(g4VA=YoyVUL-Zuqm{HXo=sj+)2t
zfbD}E+Y@$Oe^4zWFpq(OK}f-d5pU_O&cM*X!r@=;qdzgQczwVwfBlLm4U5a)b}ip}
z)~3E_{`<HGCC2szf;ThMt?dnN8&CCH_&Ap1o5?bx7k~DCed!v1Sp0(R#Fa6H&%~Qj
z`!GuIZQ^Hb+h6{;!8QGAj9Ts56+f44nl-Ke^_}O;JLC>s-n*&U1yty^+?3b&+WKYf
z)-`MQ>AZT^?)@R_tJQw3+{(9NZ>MK@t~dH9w|U9_6}#n?$_!R?+t({S+S})CzvY!s
z>BB!a_@*hkE-R8ey?fGn*Q;y&pKmNL)PE@!3oF1M)Wv@}`svy9`&mT>`<Fa@@o{5(
zSn|v-Tiwq3&g`3ZbxTdmb36G1p@Q>@o)q18d7FQI?Zl8<q3`QXyz&;ix@?cg+uKLQ
zGsDC`iT?U9``;VS)JJt4RtvL=TdyzLW3qbF1$CSK?9bR=ZvVZ}<W0lHZ_jdW$h&<!
zRk4J}&HLxe?K*R!+Lsm0e74>$)nxsN$=A{YdaBGe*~etp+0MOLwLSHQe%o8~x8JW`
zcUpB;yt>amKIMz#`h?lZd%j)17yR6!tj1;f)e4>WE4_B6?C)B*X7%}r9tm~j+wR4&
zSROO1`|y*YsQ<$haqIgoZ_WQatoYAt{A1Z0-@x~0f4!}`@@Im4YQEcyty3zWW_~{Q
zH)Q7NOGWQ?yveQHyg&DUM~(6PQ|IH3W={OHQ@*2AP(Np<Jlnsw3`m9ew~IzI&a^A7
zXWw`B_!{S}@p{+q)vWcmme~7q{mcCiHddL<@>*^(Y1wt5l&|7J{P`(OMLCk+x-);5
z=X|gJxKio!#pSa8SG?@p4Wrq=N^Fl$UiAC_Vx8_4%VS?jm`^Qre-NQpmikTcQqi@W
zLO*A88s82G%eI`}Rg=fOZvRBX{=&zf8Sk{T^ZEb(dj5aWRLx80W^XSub=eY>ak~Bc
zvN!(K_rvxId=um__sm><`CD}1gtF#6o;Pp(4fwSCx71^0`3JugZQpyI{C!}>ZA<k}
z(f=b;GrSMqv~XVSG{@@8j8j|9<KsU+cDCDdee<dO_SX+*By>;B-M;n6<OMSBvUmSo
zsM|h$e#oD{HzuX3#=Tx}`PQZX5BIgz?%Ds&)ce+>DX*E1|A?DuvL!RE=-SIaih1AG
zu3Y21+oEo6u2ayR<U3+NYZ%NQE<AkM{_pYq@u^))^6xEOy2mPinc&@6tz+AZ{x*EN
zzsGy;&NJ0Z|1xe}x+z3Fes=z4t9!1yHDZD#`R{J@v;HEz^>gCmI_3T#t=YRAm~Q>6
z5H6o}Q-7Or#7(_`HAZt@wTMXv?<{*J-ff+Dd1n2FdFMqI%RH>I)yVoiHF3ZF{@=d~
z)Ocrlr>;N$$z{6LG5$`C;2qWLvekD#yb-%`<(jwG-z_^=*4HX=e8=V)FG0yDZ?{dR
z`JViPk6$!iGu$`z_gW>Z$iJ&Xeoy=SZ13V9DpP-Y%t_RG_)*VqwR>cl-Q%x^k8zeQ
ze6U2mq|x7Ox%Q(A?JL?kAI>)45pjIU4*8zj{OZ-4xJ6d;xH%Wvf4-wPZSUL8%bOCl
z!q5CXHM4%jJbq3)|Cg`Z>s=*4t~NEwt)KHZPycgTd+zqF?>8*slX&%a%j2DwCcL|I
zqjY8Rog)Fu?!L3Ee*LC*b=D=*DPMPP<PFa%);VHxtoJ;7f%F^uXYCXIFY>#VTP<B`
zz4UHb-gfnS&gz@&Bd&d8?=JU`-=F*c^~^1IOIxom{_LzhZ_D1dTt5F^v&r9HcUnAZ
zIoBHVJ@Yhnr{1{qv)X_Auh&^u*X_>wbKTr<s`kr236+b@)Hlg^oql9{-tX$}(u!?=
z{|asWd$6)y&O1nN?t8oQ_tt-_vq~1XB&sCOEdJRn@>TK0g17ViH~$S=EM2Vslw<ex
zqFCYgi4Juaa@j%6Yh8ba0_F;S=1<Mjpv5zKdHx}Q`55DaX@&_hC)(RNLB;)ahwZZ9
z<~W9q6Y&+Z%I3r$dwFGM)n}(Kix&SgV!iCdz`&q+BC=wZ*YbT6_HCWE_3Cujy~*b}
zBYBsYW_4}dHa#->Qv8)(MQ#R$2bVsH&I^m*w8HG^(v16h`#d)9ny`NA?+KBir&Qmo
zF)%os`XoAU&C)a4{)=v&^z;7&DQI#;cN_f{$h5p$25O|0+*M~_U|6CTuYU5%N598y
zYwpkAyPH+g{Mw_tr7w;0Q#Yo?TF0$T3D7?IsdP6_x)3`9L*ZPZ=1*5Yg=l$~eoS>&
z+B#|d(Yon(US%s@eRg_T>8jtirai2%e&MODm}T`PLhSPT`29-H(=B7GrB^V&a!`NO
z@b$HeYyi7eY_+uC)b$@iY9^hkQJFt$Uf6u2S>aDKuc(ICtU6Ki<t3}m#FrHsp=`E{
z3=KU`-dry`|H*Ep$NG>7PAk=?p4@Hg?z=SjLtW+fKYEkB{Jrk2<a%W^QL=d+1A~KG
zk=VSPGK){MFK<hp`zB!Px8^B&LK$VZB?VX+7$&Uy(+Y|S8D;$S@4^pDo(C75pI=h(
z>D*2h28Is_N>TG}8GSszP{h*rjVc2JgIutN&D(iBMp1K885kJeO-?*>dEvX=vv~e+
zpJrrWu#s@CsG8;$y~LKY<ht)1$xYj48D;UBi9cgyV5m?zHf{OG4Z6Jv_wN)t-#Wa}
zr`tbhrvA}SY0L}^EPp?)ukSUzyXsKX?5W?@fP>z&pzvO%J6C?{Mmv`%-HH8?;a&Hf
zw>#{XQSP2K@&5k$)7$g!@2S3C_%?R|-wI||*$s8BvMHN+uXAbC|KDz3xt(wKw>k?`
zX^BIVFBSTiN>+Vea!Wk>o6`KU6;h_UGfVR|tpw+Z<cD2pT*SA6`J1END~0ZaVvQpO
zGE0Q!z2kn^X|C-m8^HeR;_HUm2|0f=Tj%Wm_mjV`Sv&u5>*32GR$KLdZhSfGbM(S5
zG6CBwXE7bRoVz!2X{*%&zAKBbA5?zR?9DcBM{Iy+p-fD@wBG$sTckYJUYWeJ`1v=d
z$zdKh*2nMP6V1@D=hx-<fA8*E&E59u!H)Wxb=BL~J>I`u`2Drgn*aZ7=jQFcx<GAd
z+|#t^IW=2sKI*y$vR`Se`eJn=>F@I`f0kUmBwUgw`{%m-|L*eF+x}jz|FgUNwbi=6
z+Y1&>TYf>|qixCUxvy@qcT}~QzextAMB6G^mB{}q6<<U!bZzFX<kOhWA=_Ukvnm_x
zskdz^!iR+GS9F0raqXa{;|u%$<;QnV-D?u<YQeXXxpd)&C*0c|?$*svviaD)3S{D4
zZ`qWKMw7!D9$GBnyRvor!$S`>d*W};?QWi86>#NX@-@dO#pm^Z&X+&`za+T@WQeQm
z61jPK@((-hLqGwnb<!+G=|@X+{-culOD!{IJ)Qv4cl7Y(g^iCxUq&16+$h{5JTK?Z
z!XWlng0COUVVJVzww9m4qbD7IbhTbR_;tJB<Fw_O%M~8Gy|`8OxNS{+jc0H6ZPjCr
zUa}gm9{l+_U#R5}<BK`D7Giymwn!Ap1hIEn?f7T5<iaPDX~)j}P^*t~K33iT6zZNQ
zoB1ZOEb`__unS?I&f$K%0H!|1!Uj?zm|pqxB~0wK^Agw7!AUYpt~6FHu{vQTpjxP*
zu+;L}iQ|PHAbWq^E_nE1iPPhGt7<o<>3_;>Uln+H(#>ApDoDUJpU!cflaRvY5_$FD
z!iFy|lKb90wXk6?b&y>la_DlcA~<xLf7~w6P?&o;sN|)ULF*D{U61}cnLC#XXNbLO
zunG|8^ACP`W#5zI%d*eqw?4A*U;ap8DPPFER}Ugy2S&waF28nAQ}N`Ji~Y?uvhCNM
zKuP(NuK()BD_*uUt;;PA|JZ5av66Y}*I$>jY^{!OwAzv4VO05Le{1&ocu*qS_025C
z&ZaV~dDfIF(L<MKf)!u;<*TTvrSNnm-=ZcV=53eD-+t8wx#jx3Httqfg6jgs{PT78
zo*qU!-DFcP&YE&$@qgWz>c8M*wROAV)@jSD9V;I3hu-y)jZspWxg?hTc+_MIzKH#x
zoLKrc*TPi#PxJTv?$PtCzU^;668Vg$%1(2)fmLbW8kgN7+09eS`FF%hO>3Imwq%87
zzKKSwI<MD5PKI}$8a68zUfKIW$X52%HS6iJXI^o?jLwdXu8q9H-?HVZLzHc~g>`}V
zAxBLuou`71oD4AwKYY=7pKZNEW^Rzw_btCBxo*|euc~W#)NQhw`)5~9MAXRzkg*T;
zPnt55{(aoJPkc(As*d0kh6AD(Kb5#%3wkzH{r#OF*GkB!MA;fPT}e~>C+;_AGd^*#
z&}ntPRPV2TZ_-a8KCi$;PKF1kt~V6QzBkD`aclR2ds~7h6e<_g+Ae)Q|I@m)>dmvZ
zJV|~YWO!?9#;4cU_1}vXNZy(xGUa-K$hYPD|J>dE^wR063<nnf{P%bF<;BxN_8kgV
zkPw~QEo@z`QXy&keNXW2<hiT<KE8hIazN?XMW0r;{a(SG>&xYJ>uFi9)rGJn8?v{l
zeB6HEmnbNiW#=DWdGmq8_PPI7os(6$H#2L(O3zpJIofufsdkh6W6!?|cKh6A(`ppB
z(faeT*tJJrg(tJBKL|O#>*1#t5#OcP`Y;s8IagfT5F$QvP3om<zg=I}nWSEky3xPn
zW#m0|(U()-TnKyRnfi#|$N%RSj)v!QhlLm(Y~p!%a?;a1y1fq~l$VEQWZF;K^!&T;
z=}Tp6Cja9q_%B{}i_3Mj@VQd&L`|6~9Nr8QY@I8#Ja<}6DcrC!-D+Cm)*O4LJ9fbd
zr)DQRc5Yx{xM|$7d{Ifd@Wd*|SI!d`{;hYc{y3-c&Vk%Z3zqEfJ6)V$B{q$L;d*((
zfr=k3Gq+bdCfKY?cs)se#+MMLN<N<!RfZGx&Y)I@n2gN3|DXCCZ=cv+5W(eFx!`#?
zSKHEp1SW<j^A&AuPycTBIBgy3xX@r4+gkq<n!yRDnhOFhU1ni9EY!%!kk`NS_PQHW
zXUfj_6657??}@2F>tP{BPKI~>8aBE9Jum&=-Q3e2RQ~RAZu@JFwxu?#YKMdvY~}@2
zaPbTA`<L8Sv|hHM<m>^L2qp%J-EY506&)1QC|~rH^Q95%vTQ{iMutN?4>PswtCea`
z@3rx+-ZX7%@nXl*!g_l8jgW9^(0Io9_)*-H?IG(<J<3-7bZ5f10-w{udP@9_FCzk!
zbQl>HNgSFSH!oFj*32${(V6<e`xnW|HPn~A&t_HQ^*H!hN3%(YK|#~GLd)y>R;9hy
z9Kz1qFWJAsdttzI*Z=Hy%RE$W9C|YUuJ!5zPuf-LFExnRofl$Y@D#oF%Xk<20_J<`
zBd;K8<cU|!G6FuaHV4gm{XKe8)1pHcw|+mYEX%HTh4FRx6~@v9>-O?4Ph)=E@bTO|
z{nv}0F|JGCo_v4Tlr-+(kkvsIObiOV3qNd`<ml_~88H3fvm-P9rJP?qZRr!;&f{V{
z-kI#n3Ie*gycrl$j$X)JzSgJ8cK2^fO|`pa&-0txRPJjkYM%RLD$yEiBokY0f9G&v
zf!?bIcrg{c`Cy}=ztn;)tfzwCcALKTy109Gd6Z(}{<^=P@)Y_0mc~rr`>{{u@6+fR
zd@tA-6u9s2uiu|iap~ReNjmY@KfN=z^|cPF(7qqiz_sY<%O7Se(bKLh-TmOuTCeLb
z@*dBYD_tPBm+uBUs8Qi}o~@1X@id+1xtT1#-+WP-`FZJIj(44zcP?2T)U+_uv?!d#
zz;M9UpzOA<HEX4Iw9)ITw?4N%ndF_Qx-3!}ol#k|UGa`+dEV<uZHo+o4IV}Fl`dGp
zd~H3b)&;dA&$6+z^{^kaew%sv$uYLc_E{CXLc(K0Jc2x<Cj4+-$|q8a$m*?!E;n8%
zNoGEFSWeYOmdm?v+e0D6lP&fkuN(r|*T4(>9Zxgomp#6k>a_iC=OrtLNn3PSw=15V
zka9>~3&rjre*aBU9&5Kuxh`${{qo+H<xB1sT<7pq169&pRtd0@{^6CJgdbaDTOLgg
z*)#h@8{5(kOA<9LewwJb`btguqxmD-oPnW0Dr%llkxp#30T=gntxO4{PT`Ip)0|~B
zUNu-H$Oo`@Sy|Xh8$8ogKFIteAi&C8K^E$mR}Hlepqe)6VQ2j9*q{)Pp#P8S_f>EI
zw)E!GV-WWul)S84Dm!mc(<Dum*z7Zc^(#Q}vx4~>W9fnw&6hVj{$YH4V_~AEg(k1}
zza@7Iq$d68Ja~(N;ST$u%YqLlJn=sW!W&o^7~Tm#)I1<EsfkfjW(ottf#k{;A4K@P
zmQ7$`V0dsE+_Pbfu_|45Z_fsc(-JbEM9OgdiH?o$(%^WH`%$NFy*j<<-p1!GM<dhj
z|NpuF-~PP^SQr>4gzP(X88W`};^dMp{Yz`~o@76@+aj1gljHx-{njjM3=9R^YFgE^
zH9w!4T&{F(kxl5cO<U$zM;A`({80brd40up1_lPd>FXz_yoy*>m|V;$u~+5Hj*Zji
zY9Eq`bUW_I$iQ%<(2M6(c*Uh|{_QSyb50*vlk(u+#Jmr)3<{@pE?D?#mh0Yc;EDk$
z+-v{-e6<Z)A;=!y@@vY)Jxcx$14Pm#85kO-Jb8bs?3QkLxxVk6c|YzJRvmn_(d63u
zNB4T8o*4+)fs)HB2iq#y4g8?C`J8=qdOULk`GP>{?Mh=3IAV9)wNkKQlze32B3B@z
zq@VXS;>>-?V~h+8MQ;+L<}olZ=rv;YICuR2u;h7*mdKoy#$TT?iZ6ez^!mnswi$hU
zmwawq{3VO~-Nwg02bnt_3rJq_UZ!fbF7J!Qp3fgr>K9xUzqI|@rft7At!THq)6jk4
zL5TSGEo<#AZ=7CYS8ylm!lby=M}MAF@7=a!|B7mP3z_y46J#r1J(6!1o;bOG`ycuC
z@3PQ-r>p+`pqhzkrHb)Yk>U@MzDVz%_qR?dH^1+2$s5(V{6_-boHG;m-v0ii_hv0_
z+Xf51iA$e<KTs%9(0=@3Z960u|AsB<g7!@r#Dk{1JF`0{V8Y8A-d6G+Ia>DBqLo)y
zFD;gN#1+;&ON6U*V(0gJ7463rLEY>;pQXVSlQ)S9zG&>R&|Ua?tI4tN)_L#t9S&Zp
zbM@%-9cyc~e@2BYjVXG^@X|=O+VeSc;aaw!;-<?!TP~hFSlFShHFfX1$JRD{@2zb_
z=PxmmKe_x}<JILo&qOOf-4AInnF$U`3loc}(?0FuV^Kd^*rD@M{|S??@3kU5QQL-h
zA1$t&-h5}PXSBZkW1qL3=KMQ$oZO|G`};lvBrK0Cc`IjraOJJ-f7s1GTkuWX_F&@<
zOSY?XW!qyQL&I!6%)|@=qmMGc=lmYHfm-4o53H7G&hT1p_F>&Sxdq}5x*|&!^uKhi
z{Q50z)yahSoOb22OLvxRmv)%N;m?q;>DQ#z@?!sLrPq<+bGrA2|4v$ay=q};q`%gs
zY*!XN_rP77xBA?=7t3JY`GG~D_Lf!fYmejErJ6@F$|8BQZeN>o;M44%Tjy{3@{BdQ
zq+}KAth%Q4n`iFdY%4p{EpPtcS!?H=d2Xxey47yxlv6=p^Jbl5c(6@y9z#m<z6qb&
zx1Ec)6n}-kJo;whGSjT8wU)w}{Kp^ZtovLoI`hS!{!Kd1&RtTvJpa;apF7j!tABdE
zfBx^&xj)yodFO7negA1s@%{Vz7M0ll3c4Dmy1!MEFI)3m+RRf751xT6SbS@WxO$_=
z)1{G9k6v%wHU}~pwfyQbJ?F>{y?wuAI=|HKNIV|*?CSe}m#)oAyqo<{u<|?eM7Eh_
zhxg|GznyU&G@HhB`?2Sy+QeH{Pq!Of6~FX<!{KQQc^LBKA96bUd(rUbQc&FAFzNhl
z6WK&#uf5853R$){<)ESe>zO5{EvmZA4YM69m?rf8^st*dZTi%jzGp#|R+j{yZI|#p
zZd8(XL-OTP%}3=YZ~pJw%RXnL>#S*e1eP*ynmbK-x$CL-dY7NB4$`wM|E79(pM}yX
zh6mrkzKWWd>b-k|*SQ}{%D3z5-YRy!RcC(Z#yN#YrQ2^le6e`{gk6_Kzo~KOr<859
zp4?e+`gU;b#p(RH|87R^(=+-Q)w;+fH~yoimM449Z=Y0#g3nypx#?^TCNJ0Dj8c;K
zWQ$AJeEBVN`kft$ubVk9<lNFcv16m1i~{2mF<pO#b<WJ)*MqiL%UYdG>C0Fh^hiwe
z`xLIyUmqG~yPXElGH<~@jM4%cYhmF44TNzb&wB*?xPAZMF>n!=^yrfgD1k%A*ifdh
zap;Dm{|AYFlOi=l_Czxj%(hr=IDwyEbY8_{#)8%05xP8U$OH<=Xk?oqdK*5Jv@e_6
z^!c<*`KuFGX75kFbyMf^N3jUrtj6a%gL5}ra!(21KJ$Hk0{1#?(Bw*A=3m2?W;<_h
z@P7V&ZNBM*sN977w>u|IzaH^i@T-hSWZ#vy@29_bYhSwmxaRcVx1LYCTT+wLdOAyQ
z^1iSuHNla-r;nGu`^*@_|M2CzHBYhwr|#QYR(EYr-2T&>zn_@)w=pPw$LWaL$SZgG
zrze#^vpqgHe(JV8W!>Lq*LYV=?fgDN^{?yQzXBVZ9b^Ce6c&768uM#m==6o<?^Vhq
zvc5jMH}{Q-{`!^Y7Qg<vYtc9FFW=<Xw7bUZ<k$UNtH%D>JE~7k{&%YBG|%|#D|e>6
z%z(Q_^r5D^-Y4IZubPW1UFUV(`>U~9KQd(Yr$whl;+I6mo(O+&IRDpX^{Jh|6<@Wi
zDz|SE1!b;QyN5q*4eUMk-|b(T$lkNfJYD&MQ1OnQZ`oVif-=MR{w~ygy8Qm8f+Sfr
zz4a^4C12S*@$bW^&#zyexwc#PaGhb!{*`iJ@!TuT;@?>QtC@H)eNR(v-^W}2)&6rI
z-}opP8}@kL-QcN3C+kF=Bg5w_PdxDFU5@VT>Ai(L@-=o1ca&|O9zACs_?x%h;@<xQ
zJo_}OFW;-)ymiXXzlwjK=?i~-w)S+$JhS{e{!@4A=sxc|eQ%oi@7v${PndsR`R7gO
z95K!LzZ)aOKOUO)J5k``qos`x*1nlqs4Hw(fBTwPQ{ZRkx+!}l3(rF5S5_XDH9VEQ
z>T~kf9FwVjnJT{PRZqOqUm|z!#F3`~ZGVNH&)~e`jBirqsLu6|j}Hf2lWnYxesk)L
z^OC1)HmiOz6i(l^a1E#y`FV#erd~N&?(wnb%sV*wW#|3-aeaSWYS)&}&(_BB3a%Bo
z_37bW&EJ>rZ4Zro2AUT+zV=ge5C7HJTd%hK4U<`NS0O)WTbccoKkxP(`*DJON1ey{
z>Yz_{2CvG_b^f{bp7mtELqg|zUEcJ^JZrfMUlk~)Rq6*kw{Fr6+jjSwkpH40nZlCa
z&R-Ms?N|Qzy;1eF*Pd&R%eOB5f4G+ScSZf(>}gw$YF>{#-mV{_#+y59=A2Ti`i|MP
z*;=nJ==H^?&z>OiU1Gbdo&15^4gU+|o!)g@W!}DhBkuP7Q(w>R(!E-G|KG1&ha=s}
zmTmjZqP#jjHvF)D%Gc{xv+CcT+j{M9Rzd8pyn1V<FP4F~MK<hTcOm=bH}{+mOJp@B
z|J||AZ$pn&>*)oj-|U^Tx%c*0*J-wSvhzaXuBZJwSXCx@dSm50$DX2=*QKX7^xIlL
z?F!`IHSfc&#ivBqtzYr{sOI#2eibuU{C&`+k?k_`(CueA$L}4>-EO((?d<2rLDLiV
z4)eJc<X>z%J-O`gZ!w!bxeVFo(L3v!`D$C&zTr))1Px1{Gno3JLVWqv#X73**E#Q2
z^75{X-5o0_y|C0WR<NBddg`el*?pDG-K9QVzu*4*X&a!n+oA4spWnCkt{d`NM%{N$
z8BE!@*)vc4^u2FKa&CHrfYw>8dhXnGKKR$Khw*~PG~9Q@_4?eFUoQ71^<G<D_WeXx
zS%WLTHQyO8H|n!Gkv!$~n#YF`b1bhGs5?i_m(G>k#Xc(;W18iadCLFUnYVY!eq=S9
z_F(&+x7%-agem0Docq<Krug2^Yj1r2y>?rFTKwZ$`x~1C7B?)*e_~bt{-s}cZ*2M1
zAM53xPWdGD`e4ZUc_)fAmX{u>_bt}GnECCy_mywQ*S4!Xz4Y_l=Qn?|-Y*v}zj*B3
zN5R59t<R3?27kC=IJGod?6aMH36IqL`~{~OPqa7vOa32t&sMhngMw=<hgHV!=a+N#
zUwv`xj<@BZcUxnwA3<8abXu6<4g+|${3-I{CA=j+Y_-!%K3{9r=Pgz5u6)!xBDF}|
z=IgYZao@LyRm`)#I!AlXE^&*yXZT}W%yz6hkaIr7YT4K0OKv~OJFGW%|8~2*FS36y
z?NT?Is(tRyT-XvPwR?4U@*qo`;1lHX&CiTpX1ks>p9-6k{wgr<-8rv)Vxcdi|ApSU
zpZfn((l>Um+J}0{UsD6i?PHq4S6}}bnt3{Vd&d5g+n0pTtmu!t6o2I|zo50mm80|R
z1wY0eUn(C}+PSNsE(cnG^UOSzssky)qk4W{-0+wE`|m~i)6Dn(37g#fQ&rc!zyELY
zg$T9UwSmRK%ND1a>dIf=d7ix>v}L)>&J*SrA<b5;s_%=}>`MvEJ=Luj3~87z<lq1D
z{JapgckL^LSDA%Z=$-<##cL0Ju1=_%P`6v&`!JtGZvMHpzlkF2F^cdk*;%JjXXUT@
zEb%obrGCe?KUG$nzn)9K)8F>iTz5a76;8<)BG{`}1?k;fpQQ2nRk4cDjQexfZWnj#
z8<0ZW`F!2ZnCj2IrFCoO^)9=l*}LTBR+h-Wtyd09&s-pLk?FVLIYZ%yeLq4b{(Nz{
zPd!U@{^A*Ho2z<muQ$B-_kZ9t*DIHkroI00G0}ppoaNPm8&hw#dz_9;_kNPBb}q*`
za_!R?txr37cl>iZ1}a(D3xwsYZ2n%i|9?7knTK`$y<1lWE_yB0mA^N8ll|M;=&PxA
zc25ph-_hEy`X^wkeNf#uru$vZTcn@(p1Ss~ebW8A*CphCGF<0>S?TX}kKOI=Im?On
zf9+NHDaeuWaqH5DIdc|<D*DM*`8>TfyB>L=)0E`+412k||NcHz7p=G7mJ-={-Ri}b
zZC~nltWT7GzrOnHq-_>YtzQ55(0XdgLSN&_oBf{i7jDk?O_jZM^yBLs;Yp9=9&bDG
z99j*%wEy>4D_EuWv!3qLtChyRFWv<eMoV`co%>+(_h+%7$-k{X&DK7S-O_!?bn3?o
zvah!|?+>(=H+yIPNn`1zmE0-|-u9apE}!`~$+~&!Tc(%oYyLBaygHkDPg_<}WX=Ij
zU9)9HZ_o6v`rQ1rW|_oOj_a!rZ;|&s-jn$Ad3nA3xh0ClD`noO`zg5XJZER8bV}si
zyw|r*=2?`5=V)dB-nx6`=DEp=#|+=;q*d89+*y2E&;J(h`{)lARSQbz<UjrOQ25uD
zo4*slU3Q`L8D158x-Y*9oHqA-#orBuO|dVS&9~?w&yL^tdv&s1?eB*v{$-7SrpeA-
zQy03b_ViDNu5^ue>GN(M-L&0S{mR2-F^12z)Bi23vQznCvvj@uKhZ=`4P^SRF67*|
z<B|8`o}J~pod+w$GmjT9RlK`%qqZApc^OaYt+(?wZ$Ec$$11g0P$_=9V5!-0r!&cS
ze$+5*Klm@Xj^n5PtCYLjwg+wxzLopDtoo7dlnYDV?(MU^DX;S{=C|qXZ~NzYR&PFY
zuBxOi<LJTbpVj}DF24Shdu=f5HR(8ik>7_6AC=xEW~zMAlHZ2!K6##6`uXnjo4>E#
z^G|=HbeyOnJy)-O!Xi5s*)4xRXKuTnRg(N}sZ8ScsCC(oY<W)b?|KVb*|gv(Cqo_s
zc-s6EXiNunRVuh(m&-a}!Encjt%v#N2Ln)x|AEkpZOjY|9<Y*~h^nAqyZXr|J&za|
z9?S?%y5Jl;?`f3l-@m`N*Zlr=cK7tT*=xfCpS=lqmIEPelV<v#Wh1m?7VJ0<fAt^h
z>;H+r7h_<kFlkvX{O5B0pWVU>{%|rd*z^T}2FU{o{G>`NUfuAvGvf{T=hDH%@SxCT
zi_O;5O>x%gcY5ZjeG}r~YS(BIVPN>KEi!N3)7rmz|EoRbq{<1e4P;=rV}E$Ya_76{
zrjl#+9KB@lHs{(^%S+}vq^>NP_UhOiJ&8sCKJN6Jz{K#tPvX$!%_g^$-g++Bo%iU>
zgsoSn1ZFF|bP==O0vg15^EDDQq0_TAig(G?+12HryqT}m`>StpV`L~$@6q*toER;2
zaNo}7ZCl!tXNt{VVie!?^z6PBSEuW&@~zaowY?iWz@}}qbZyE7DbJ;`U*FwtOUM>c
z<YH*Jox<U-su|vH#Ao)~=eW_DX-l85$o#I)|K=L$Ju`fs%jU^*=RH|zG(FYDE1EaT
zD68&7|0eUt$6B0496`DRBeLhmsK|Z~nZB^xe-(J*FH-yF!K0HRulHJrFMT}s7;ohM
z-M(>`{Tz?=ZmlSfUEO#kN=bh6x)Tf3bbsEsDJH9(3ZD51`}bmp#?sgt1_p)N`}^z5
z+tgG`6>MT16(mHrW}n-ud~nXP<|Ez<H~L-u_t9Ya!dFOXpnS%CuBE!c&%HL?^WJ@J
zmuB%cjp8y5Fu5-BS@7n@pV!N_K3Guj|9ZLRe3{FV{-%@sV?QFz_T1)4+WzZm#KD)-
zE-YndaM&kVpZoov;-w;{$$rV17LBTJKU?2?JvU@Y_@?WTpb4J!{)cZT&%JtwKk%Re
zD+9y2^8)j7j;=ei=h|E!+x_`b)3zngUF3ge<=TMnS6-z!bucj~*gHKu`F`GQzjr?t
zExa=Kcg*E?vp5177-Hrxe0s8^)>`lMB=!~!28MO&BJ;LX`#1+VAG6jC*kbWC(85J<
z2?K-2{K^AA{JJO0FXITTeA2EFwHPYKXYX?{cY66jfupRQj0`($oGWh0TkM;gW#sXE
z)qx!fya6#2Bp4b_8<*WS1t+f8u*9WZ!Q}fSc7th`0xQFTN>~!I+XYENR_ToKUPr!G
zO)ReKQ1W18D6oP}N)?p+DA75b73sBFKk~)@dvDx9i+r!{F5SHdlm{%%3C!!dG}qVV
zRpUlK(4rFkPd8t6n#8|RmAiib|66~*hF$FfOEY?z7!>TBD}okY7Cp18Ea6hX*18Vw
zMKX&SPw@wSS6T&el-}bR%l&jMH17QWD*L>WYxnjrjrfoWObiT4ty|5sT_bsyguUvF
zyLoPJ%<0^@k3Dxw9j^QP>*-yu<MaQ0D*yR<{{Ii}?#kQdPx1F}W?(p=`x`WcxO>_Z
zOXvje)Y;triBik_RxVibM@%Dk;-|m={zmVs{r&9jX}?*odAGS_z7DxzJME{$sX4Nz
z=IDaSwZWSmSKQ9~|76C}dE0Dxm%h8R{Pw#U4<c4nzdps?_3GN<Y<`9h98M24YkYTq
zIPx^|5m%eW+jG0q10A()9A#%XVB48dX?1OvNV?<?6Ni@;E2{H5KmAnnI_`2&ij`r9
zyWsw9pLf6T3BDW0<jESnNX~T!I3#wkbMAior}N$J;Gc}I1i|^PfL|$U-h^!l+E<iY
zHBz~PS~M9BtW~gyy{O!-A<7f<(14Y}Ax>~!k%G)3IYST4;0a1Tj0~TiI8@x4_j#pp
z?8yaTlMjBY()DPRUnIBF^prRc$OMOZ5{D+YE!}k@MR)SHd-`7A7i%sK`%qQxA*`5n
zeIdxmY4EvB|5sh0l`L=FC#X7wm;_IF^kfc0!xqUy!JenCF6?PeKQyN=HA44x|B{?r
zH|GSe60TJ9%N6CGQ?6CDaJO@Z5jWe)2PZB6axye{8(~gorp5lAXo5U{u&-Y2^VJ2a
zdruv)zCQ&tLL#u~ov`Ao9SJioY050)2w`X_mXR=!vr9~4Q$H31S@-Xo0bMmJl@j{q
zT*}{f`JRDsvqB?V#H$z{3b;-%;%;BL!hw~+A*Stv$y7gG3yVAdpT?fLzGd??qxCkG
zYoo#Q+m!_qu7=co)B1GFce}05`9A`#6TH+UmWU*BF$jbwu087&7{<JEYL!v>yDh1c
zTu)E#E0;1i)Afdwb~#eB$}$#IPu^rYIic)QVSpNV#_jHY`@c`$-_tGB^XW-h#5V7B
zg%-nszdz8EXU?I?Y}=-tXgA*G#olIJUUq2WVa_t;%(kY>ic+imRxa@V0j~mO>-Qd<
zrjfhw)S<1X=d`U5)7<~m>u&PQ{)K05E<AH{(V3e&(`NdgWm}lH`)#M;-<4M`Z(9y3
zgfz=<TP}B&IJx|r_&V_F*x;0cs8g@4>I$k#O5Vo0ZCHJNep77it*EE>*%<DuU##mt
z^YS|Dzn$~f+J4;q#^g%x(v5ZEzuP`@A6Sref6~o~Dqm0N`l~%;C_Ndr()|yca7=kf
z!=(*V+xASc^qyiFJ;l;`ie>cjH0I=rqTR3W2>M4$_SSkaK76^uyX?K~Bl(9LOJ_$d
zIma7XsaG5YDZMp{xA~oAI~ITY@0-rzeX4tHy0<Z`oh#ito5!!?_?5llc?%C^Hr=f~
zc=G+L?pX{BKZ_sO_`j=I9CXvV{}O1uRpGAWc@v}$D!9(@3J+QEY559=rNRsks(2oH
z>Ysl!Z^0%|Kj7hH-G__<%hoAt1-umD2|C#L%8HTUQmUN6I_B;7PbHm=d$Ku9NcNvd
zdO}&8;WN$HKt?a;uxk?f33Aa-FMlZ2>@Ub^4+OVAY?Ef{+a>(DCopf*(${?RRs^RC
zE?XD-Ec(Xz={(`vgPwUW0>?+y5u<nun_Pe14YCSyrtixH=4}$)`c5Zm`KPdFIx$sy
z3wQrBNxADibMgYXat)i8k$dmz?ee&~FXG(I{rUV4HKPl!=Su09X06!OY7~EK>$Tab
z-xDN$!$Mhdi_KlLL&4k5#eQG8@YS@_HLLbavpo6W>k`NAzp%25yIp-L<0`$`lPm8R
zte&i7ld8S8RQ^}$e74oqI-d={2Ru`8^nU3&>*je-B3gLn=B|Q@qTTPOt^fBlFlToB
z{foKNMe18_T8OL(xy5|#=J}hRQroU9-6aT75Amd7!k<Y$l+T=7_*E`@tCjd~OY7xp
zz6UjS{{<DPYu$A|w;rBsW+M7zt&GL`$=hstr8nI(alI>cD0o}m+B3(a*4DH;iT$>;
zj$HeF$^p@mla8O?JO{P%Vm6=A++xFe%=+!g|Ex`0oeqHuekMO*yYi_g<NyC@FX!&}
zIsdPY)9M)afv2_q|NRwu_|hRG>A;VZKiDSE-8029&wJYYIeE_Cinp!X_^vqmK$Bl4
zZ?b)QyHWb<M|aB-Z}o;x=e%2{{-EE$dVAEf;zMG;Eu*)`J@aPUxWKzC@Yjv=H>-{q
zEti{@VmcuzQ*%9!gny6yp*J>OGbgvLUEuxi)r7xu=I)tpxi&y-ikpLRqJ8@FS*d>Z
zHXpNhPyXmWL-th79m|8-9?lZKL3v_!gV<9+r`c6Ul4nm_uFT;N&av03^hFQVct#xo
z+4aRJUVBUHQrSmxh4#zk=1F`m+2vmU_@q$kxofJ|YhN0OJr#<b_U8GUfM>CloQ20#
zcq^~pIWNxT|L2w-@1Bn-Aa7keHOJL~d-oLy<8Q^=G(NvvC;Mqq%l0eL^YUaLYC`j-
z=k?m&17$v!9FEtW<4Zj!_V6Xgp<rlR>fORKl{_Vdv8z<yOZ2^c6SMhD3(T#MGNv=?
zy)OIy;uJwC`Hwf$Y-AlPPKl+0jRBEmwpj@_p_3MPR#-KCm;$LyAtWdnti1U^e$W5U
z$+rr*76+%lI?LU?nTLVFfvZSt-m*(8^_S$YP0jt98u<Q3@u5dL%nS?@`f6I2LmIai
zCwq#5hp?}os?AV7X9QYRdosLY6Sxppf24CNI91R4^v=zq&>7t913UUsrOeHyH(c~S
z)FYjJbEndoiK!(rA`A=;GRu!FsA*N-`=h}7$>E(mXS~?n$-ZP;&ncWflS69Ny3i}x
zYiAp!cN>Ay350xorS$pg+v~uqv+YWGE<@Xt&Vk^iqCu1Pf40fo9&>lENn!P)^5ZXA
zyN_Rr*xy}ko;CBZ$7fJHL&6SBek`1HhNr+GtsTjV=VGV-7(9GAYh7i+gMWoJin%h$
z9+!3H;(uBnwqRgz=(`B%cVXLZVl_EV&aGZ^0Vq5}s`OT=d}eHZk?eDR-Tt}p95Ox!
zpK`bM70h@jaJhQMM~g?cJe;nw$*Uc6jnB`|V*al6fBOeHw+gHFziL6#J3kAb{#vCJ
z^u7F3h}GBDFS^zHu1-IC@n=KhLy2hKs7tGVeAa!b|LWfCOQ4~$?-IpwpZ#>WT@3fN
z&+JpacX+~thZ5Rl>Gy2DN38OSj+^^>&D~?w5)WU>oPR%?TjYHNq`J1{>jL*tPVb!4
zlW3QaWN~bc`Mk4#AX_||JH5peIUiTgcnET-=ghv14d9`!IFDTuzZ)F7%(~-jf2m;o
z^Jq|y<xRgy=#=HBVy0bd{CPmI`uL4L&~(6^{M@RZoAMd?b(78iYIP`nvekJ7GECiQ
zU;A3NPupIc=C6O&yQf`np5B4{x||+K=7y3P{f2wrJ)S*9_dT!Y{-?DyC)%&e<W0SA
zp;mb1-p8YbE!@U?+cQ^BHi_Tkkhgnca{q@C$EBODmj;2xOjPr-x81If*0bbxInSPS
zOD6f$zhhyb8R<C-nf4_W{&q{bt-~*~vAD)n)_qU=Lm%toGyXo!xA}71iuKL`aPa(E
zJ=sBJ+qB}98Sc3sJ+(ehta<g1@7w)Z&zRMgCHpi7XKJp09Z<lfyME5oMvY~UPnXDi
zlxth!b9_e8u?tgE)$8w{s=gtWK68t!e*R;htNWgw-RgU5_RqJS=KeFEF|!38k0`je
z@OW9Dr$W=q3eP|H*d%0ZrYZ3)imu>)e5(vJnMU$F9a^8h;mr%yUT#*+H@>Elb4nk6
znaY#J${Fkb<<PQAD|z3Tw!Ucf*~;^4#<cu&$={a0BA)**+~z;syIh(vrSSucg7wjL
zXRc-MRoEE;-ULxxy?36c`TOwa*R>B+n}6S;zG+@*>UIvPIj@w2ch|iCzr7?qd*+tC
z?F@HJ4hc8hiRR6^9k$Bh^4YYyx65_*R@P}x*<Yi3VTowX+_N>yx2{l@eQqf`^WB~8
z>gl!LvbR+k&Huhc<m#_2>C$uV&EFfz@Q&>vr^7z*+;!K}EdjnuY-Mg=JTm+K>Ki|g
z%=;fW?dYAzTjzA`mxj-*(2Wva`K9ii{`)iexx2ZZb8FVW_)}iE>D;q@s()Q$tuBM7
zvDbb(dMi7TOWN}^pPzH}O?eje2YQ0@7@o{7`&!!}>#;@k1fS}r3HsJw*4Vi#{guzV
zv2l9k*WE|FQdjc5j$1wP#BTYHHA~Oj=Ka3yZ~kK2=}Vv95nO5ZRCPv&+4t^Gm)4we
z3YVBJ`)JlQ*<DN2*M4RzVmzUFNVuWqGULsqOZWWJ^}m;+Tpu&_>iw1#KJ1y+2T$j&
zoD|o|_~?MFk`3bt`~62VtfnnAK77tY-`9FhMQqWx{mJhc(_<#9iRrt%RLEWa^hD;w
zPrLrifzDf>b^r9zL~8AmVw35oE^{uvS^D?esrIjZ+x-~6H+^7HxIa(&(zo3YkCpWa
zt>1l?PhI|R>y^3h_LxV8+&$WTcc#yg=zH^Cb?>Wr;s3L2+Vz8X*y|pKuRXD8>FKF+
zJ_es#@cz-{kR*PI?>75yKg`wms&bxjLUrrbzEvy?JHA{8ZDv@^eAxEZT8q3BR>#i2
zS~j<-NBR#F|BlivHjF#$cy;2uFTN{zchcB+k!~`3^z=KI)vx@ub7wH`g)FSesAM8-
z_z5zPyx_z3{eOFnLCZLf9C;cE9{z$X?SO8=hK?wKG7h#`XdL5XkO}iA`Zm7SK^l++
zKCNrmww@iZ4I=9{Y^&V9-v79Duk@z6`fu;VQtm`_mtS9cde79Ovr6AqY@Ot|R^{~d
zw?<ZcTnr2feZffq`=aJ~rLNT5_r_yM*r%;G-cO3I)m?I{=H?c^()im(GWqPbnW`?n
z?Q*AYe|dd<{fVEIbMrE*Z(b`=>$~|yZJX)b&SbN_FQ;w$8uF9N|ET)PGwz>OzRZNo
zR6E5M9bMja#(jR=0il_F?Lny*gc%r4c$}-t{jT$Va@Q9xR?R6@K{NN<F1`|C#rl4F
z`T6%oE59sxGI!MiJ>i*#FE|+(QdH6(o=j_3-fx*}eeEP)Xtuq_OQpuN?Q<Ce85kH|
zo{9(UzdvD!9E(m5J=xQ$ulHD6xW<^VGB7+~1P}Q=;y>0mN9~&s0|P_9rpUaq`m18P
z;0DL{lLpUT27Hh8WpmfR#?8P`FrVk)%Sfr*iQiN%#F`hTow${CYK7^IIS-{77#>WN
zh@N-s@HUgC+T!!Pnf%9%O7#|Q5;;Aamx1Af2hYQmDo<YpFkQcWwfn@$4N=oBz48|O
zwci|~@lbH!uFahuwg%T;uGP8r#?>y`cH*<{y(|n22Ob-?s4v~Wio2(BR_WUVOBQCG
zZLMHrIB?jgukzKErshL`<L?(1`7khixB+t7J$sj^*_VZTmOk9#P*|r95<YXc?C82P
zZw{n<U44&-fq|jr(B*$84ZZj7w5``DeQtNRjDg|7M#-poKG(M|2BmwOZ2=XZ>JzU|
z_~^$iqU*=Nz;MbYp=SBfll;M;fvgWV&M+S<|B?90Zr5ATM0cJV14DyKQk(kH=9BLi
zKYjWB|2OsYAQnvqh6yfBA4=-~2#E3pF)%Qw@ypI@0*#C*^!;gFo|*nxdw<`;{sPk#
zxzjXfh*<@0Fzo_u?m6W2F!R64%-bvVoby+Hx$$~Eyp7l|k-SyPBm0WTX~_e5p7nv|
zZEK2K!DA*2Er)`Ch_F7?d>VgyEqLn8`{KS>$lTfO)xy?c^OYw)>wcm1&FRwIwNGuI
z&S&_g=q0#-fuSNtP}l!>UEuUb>)(NQS<O!P0^MR2ae8OSli;kn?ue+feu9T|0~r_|
zd=$BMYsr>{2Q~b@&xzZo+8U+-S^S>uHLHxvDDTZSotJxlEz-ZX=5@=O4@Ocee89aI
ztNZi+eJX!H?F6L%!oYB+>;3)x*0$N6t%oj8UCS1f-C1LCFhiC3dtb@jWg6}lIxio5
zoK|x}XGZ`FZ)m27=?$i*<!|S{{{H^{r?<Dw-^cyCd+FPzwJ#sc@a4Zfi?8qImphlX
z&6~yh>1+1xN1zSiKd%(}K@Lk0IpuP`cN@>~+v}{BOY83mXp`V)WjK(0^5#mec~5JD
zCdRE)Xbtk$65gL}U~ul$&)7AeW?SDoIq%-7uvg5-9&@m1IDtpMA=xa~>2juY*O%~y
z+lFCB-{ovRv+><7or_$o3<v&N3(VWH^?2^xmp-L`0)5#QUS?B}S{uN?a7Q2OqIw0s
zsD%s+JN(-|q?|0eH_fd;XQJ_p>P-746%LRlap;KTf&N=A%aSF-PJdJO=wblbW6+|$
z_svO{C2<pe1*ByBkG~LS^Zv*bk8|&jC4-vz+ut5&`1qmpUC_RDcbgZ8f(EhEc>Jr>
z^8d$p-PT;1ealvYNrZu6`)PrB%Z%h+eSO`e>%YY=R)`U#GKItc{G|;2C*7ZgmVj-0
zYgl%B>ZwO@YOQ&@LoypKb%LCbYfyIk@0-vU+fGlAUjRzYPo(dbSw1R%%*fF2$I2j~
z#&7#w(ToPrJ}5tK5e5d!)SSv&w#S9<mPP)0J^z2fKXnI2h6(n^rY%3`*Db8;AGw&D
zpP`|q>;5N`Oz*A#o2M=3`KWEf!0_p~z&s@z^Cg#ld!7zH1`3uZ-hV!90j>KJzNrK<
zL;mA&o2gYwCAVXFLGG{Vuzz-PUfSJ7-!0a)f?QhKdT8>?@UnkL*1uin89hIvk%{5K
zE~kelOX}3?AKCa<Iy5jbJgDO1k>KC%bn(>`a~2H-hE3@l{@RjPUMWp>Sbf=LNu2Zz
z@Gu|CwsRA=Y?HdO#H`{B_lL~alfe$qb*|WyVwvx)e8c_woeAG+GVLcVTUi3yq*4~K
z`PZfu@)>WTa~g8OAQ!%Yk0G8+h3tNqq+~liWUHqBuf_WwVeC<<j{&<VmBZil<+&~M
z^$ebQR(}MIABuoyFZPs*JO$5P1Ygg(FbTTmhrf@3mBFEmD_i!$6mhG2nRh09-F-XW
z;;jgzs@p2%u~zj{BD<yJl_je3*3ai(T9Ez;v^V8iEhxg?{rP|0{{O>2{0t0d_SOG?
z*Yn!%l)$_%)5}UDzpTyi?~&wib4|antJuA1_5$dHg~aWZ3$^?$KTd$}7dV;mdh&gt
zsZ)!$nP=x@Tjga&i<Zvj+h%HeCD+RDEL&Ti_4gWo`AfITZp;3Dd0SNkvSzifII8wk
zM%={Z0cu)h>9gY*qW)&BdGN)<#NuKtJA*?N&%=|VJX)`h-QWw%od5bHUoNPIEQ`?o
zy2R+C|EZO_iF4Am^gwC*rKQBYE!{bnKP^d~xXI%1kI%o=Hsl_+%JjbRZ<pzvi?2j_
zK_O(t^YEnY?j3x`?rpJo+jHyKS_KD2hJr};<2Dyp72mdKWn^HOUcTWr-}Zh`N=g-+
zC&vJa!PAO1wj3Z^rWY#M>})>vb$Z#{mGd@iQfof(`pm;Hfdvc<7V{NtG9xZ^-&~8b
zjpo5LP;qO~uV@pwY0mbgf;QHT#oyj9{mYRj3o`gJJZUWdG7mDm{6G$DT(6>y=u+$1
z9ap%6<hyv@{^!2c{XAxa`1dA|H;URmENMP^{L+W>dhdKBV`j0=R0idY9z~mn6G6H=
z&I`<&xAY=kZ{?v_kc>e8#@l&s`b$5Z`})LB_P5|2ZQcMYki!g&x7oaGZQTBNuEh5*
z8KB(eVr}p&v%0M?YOWl&ZU6(r49P>6zwtbt9j0zu?AUAEV=rXyAh?Ku;f7Jm@($x3
zd-Ek{C6CGXv1zzAFfklR<?x@AC=(4zz}t8pW>&X-JUc`EoWZ{fO^-o^MuU49Xb+Eg
z`JYRCTbvjf3KVQw>vE4L6jpEqFf_QQarg`F-&P&#)ycr>zd`!FfBnzh=Hd(uztcJV
z!~bl(yJd6c+gC30BD|Vo7r5$FDW<f9X)qjEY}lgy{Z?6ivxD{If4A1%^{Bja8QiId
zp8W7z{aFmCOYgHs%+UK+_b$a0MeX{(pXFzVflB!Y_aqNZuFl<ExqeIT!<E+JyFb5M
zUb5{YbR=f}7syCV_=@=(Zp=OT>u!I6Yh`9ws$d*PxTCfR!vjHy=y{9Q=RWt>{QK!#
z)Tuq6p3LQ2r~z8O$Nx>(?`isarS-9X3nqvk+!)ZJ!EnG<>qcV6+q?VhK=o%%)HHBQ
zKl`SM$=eI@%=<iV&hj*{&OANiBzRlti7xvYF}uGpFr1hSsyBO`JfCXYK&wsl$5$F3
zo|`+j;K_xjUa%qbPa#*F>;C`Ky}z&a^Sh_<bKZW9UifF--t3)Accn&OcD}o;IoFrJ
zbar3x=EjA$-+6WU2hHq%65MXE7Imon&{x*u&KKvhGweuR_(8<V@Y%g7mmEI!rdQ4f
zPZx%QrVIPmUV2+}-S+Rz$vb(L%H3EO^&!0Rgl@f!Nb({EhV42c^R_V`RnMJR_CaOl
zxt=Zlp$XM>_tz9#U-R64nm6eD`^MZ)%OrgR%-g4FFdSHGRj{h5V{!`Lan0>E4=1{8
z1<wywro$$2)l_Xg(?EO1V&ojT7z(s`9<J25d(&mfKH2b)3hnNvf4KNOrpqq^P5n+V
zZ~L&sN&S?Hg<>*jCi&9~hl*SOKCLspTC8`qMSknUD2^b8hCK!?>b%~i6FYyewq7p%
zezE4_YX|CBcIZLolr|-B_)pV$zA*l_rTT`LTm1|_1tD`uVmzQdDi6(Mxq=xOVh%NC
z-+nn`Ip~-trQDen>Z|s+T9uuSxH9MAEbo^FtQx$Ll}EO&xr7|*j{Ed@<|rKsuFCt{
zZzZ$plhCq?%|86drR2iA-P!TC`A)=bnC-tjAw0f-iNWFGrzy@g%3kL!Z&ztJEWH?Y
z)cow1fbB06z%lyxN{#@R|HDGR#O>DaIzLR2`?rFhUAxq4$D%l-2<L8H{@b;}i@*NL
z@wu0>T=y<(-{s4GdzRcQGg<MRN-6K;yAujixJ7jRBOmlz*;d}Uw&U^2OE0AMi1gk3
zvH{%SI<K3nt?TbDFz?b~`BJMxw`Y}HsG648oor^ClWk>@cDdO5cGbga%WvDxpUnAC
z)Amo`^2c{_&l=?vo>|tO>&t#Trz$TqI+)XcwWDvH-PtF9`6h`#lqtW?^_AMjcd}S~
z@goZlsH4E+urD9>Tgh(UvvxX9(mroCqrT>n4QpR6%)9Ie9&eTVx8m}_ZSTC4C$K)<
zy0z!Ag6#G!YrA&&9%nr){Je6P*}oN+4{uxcSg!Bpmcuu9e!3^R$|4OEB9EOOzN{03
zc;m*kFL#peKC`_O8zkm9G1<&^`<Ar`t8=oeR@^R$$%>ZO)Ua!^**@!@f5oh_B?0Bu
ze77f;eyLb(ak>Q*9_)cuH?E<?$Ory=|1Axt`qe7dX6t6J*6*%5K2KN-JX%}wMB4_v
zrLO&bVXwt$&`|~|@efae3K5lA-EUG<K&6Q8^K)U)f!Fnh{#Mg6?@ZWg-jR7r^TZB8
zsmmoPl5h93FfepHo+2@2{RhzAbk$FWue}1pj0)a+T+dA_IvS~VNS9Y)|I*yhE4gUy
z%sm^vJr+6)C$S8&2#>3M5yUA^-26f}RNtKOB9%{h>vBYTfrQGOU2Es47`Oje><4X$
zLsN-zPWHKTpIJ)1>o06?+vUst6`aPdWLL>8%mbe&!D-_II#S|*>IKL!FKGP??9jLG
z^7FpT321FHE?sud=E#!tg7VkrW;TgttO|c+z47V-wXKd1UR}HLHgb#I->OG5_UgR)
zcIk^uo9yrV4NFQrWu;qQe>*fk-74WvoiF%ot7)~DU#(w#Y1?xJz18utuOmJ7R==(b
zz4k6PcyG}CPRp+<uU7?UcI~q5zUI3%Uw-X5*}j|Ji}Lh+Ub|o06s+(0dXiP&w)pMS
z|Jm$*KMgiAe|kG~arpyoJ3j5Q^x517x4%DG8acH!Y{AO7mG4{L<U4_m`YEgV6u3P-
zvbN7<mj1VktGX`DtqfOK5EmRUwdmx({#~|>+nQd48mlGMpU78T>;1~YspM|lug`Dx
z9iF^(3g~1Vw_lLnn8HTTK<|^#^#^i5p)m340@cOO+W%-&8;g`yi-C`}@j9EGb>HM{
z@cQT4kfU#2nH4yez52!?^=9wsURJR2O$+nN=lric)=+q4LGAJUplyA!6FPEDCtO>h
zDSvJ`zh0)rCj0Bxv!Cl67hY-1_avy~PkWl$^1Qhsu6G}?#XbW$EEuvaNjF#fXH>=6
zGacvuO;~TqKI^+~@XS|JfA#t9p8o9fyeV(;KQ6r&^K9=V>x?<OY@>f~eO()UCF}F7
zXDhF7Ub{~$h_|eB-?mhXZI^{ht1Ur6?Dwo`e)@OWdC<DZdp~4*TFu3NfBr3(g5s_>
zGW&upIQz2xdz3qPX`6Ri)X6JvBj-uqW8ZcB<+00Mi{j3QK@Q%iopIy-{o~FnUoGc^
zTG03Y()@I*tUv2~Z&m%2Ouxmm#a(Cew&?tWnV(l1fK$TD^$y$iZ`&NWJ-x6l^zl{U
zuT_!O?>P^iT9oI%Wd94UzfO9Yu|db#c9&MaJa4=Xa+nG;Xnz~A$6#R@KPxa^Hn-^t
zTh-EY9GCk<xL7r>ux+~3-SF!FJ!k80a?#+$4F9ViSX!4<R@;8tWpz7SfVo1UMV(>$
zK|b63OVgjdST14g4c-PN6dMt@eukcJ<<I?le!Gh<wT?c$<n3M74+R|l40(sXr2A|2
zuG?cGZsd32(PpVDO9~crW_-02%G~#cW!>E8KXjv7`*_~`++xP4V8ghBF<6rS_N59j
z&3z`RAH|kepG{+*Kdt7(ue)`N8n<3~Bhuk#eSRkNaF?&U6i?r~6U%nMS=om1#NMk9
ze8v9CKXO@+6dtE-`?GQlYsS6FL9tJ^R<98DcaC(O_s8|ndGPs#BIePy-p%W*7|ad{
zH_VxR>ioSs=S)@C|6Zf;b>WE*5wC-{>QDaXbkB$R%+(T|!)1qgQ?<?&GuYUG27im0
z&beI6erxqv-TRl(r1Q#>%dgZ<^;)kwtM$wDs)rxFE`JQTbxT}Apr#MhzxaNA@!F7I
z_6_dt6-*P7wI%m-`g}X4Bf9i=)Wmxi_w7!voPXo=R<@w5EvXUu9t*EbKDGLvQa<ST
z$0^?T7D?ZJzUI$u)!dI#-4}A%4}@*le{}8M+YAM}zl0Y)K6dcn!{--2TW@u-OIzf;
zXp3t0oe1x&)yxy3K_j;Ehj&#^@_GO6=dw#5k41`dsY;sKzj^Rvo=WiXSjGyUEjHlO
h)4+R>a+LntbC{{szLI>snt_3V!PC{xWt~$(69AdEuE+oY

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_cumulativ.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_cumulativ.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e2bd9ba2828829949ce93b782235b153898fd0d
GIT binary patch
literal 21520
zcmeAS@N?(olHy`uVBq!ia0y~yVDe{RV6x+2V_;xdy7L`Kg0VQr-HBn{IhmIX3=Ayk
zj=qiz3>*8o|0J?9FfecyctjR6Fz_7)VaDV6D^eI3f|q)_IEGZjy}fJS^XT5Z??3e?
z`&vksz4xE(z{+83d~>Qp)u%;5N<mFi6)N2(loTxG^4{gBzMzvUv)QZDgKLqm9OoAE
z*^-JSp=!Hd`KiyD@b!BA0SWmHjMB{Sr$5OvVEZkz`@vyL_T3w{aWXJ4B>iN6U(dk6
zaKxd4iGji6LE^5rT&+#z+zffbi**`mDpq_rBF*0reY9F)f_%wsMg|5Ih{A>sEDQ`2
z7#?ymFeoq{5@uj<U}{-zZSq!RPW-bS!S2iM{gJ(VE^TJt_5)b~+&1UuW;IW>Q)-S%
z*!Q0$x*)dk=Dd|9KCk;dx1YS*7Hd_XU%R^TN)~f<_W7xM_8hb7U-5jwiJ~QW_4{4&
z|F8UQ>$mgHb-V3vmOW0^jtMKC`DN>(XR}XbMcJ(@p3ncFio?G=T{XUY)t9wfKW~2a
z^;hh?z3$uI@K5=5DE8Q^(~I8K?GV{*{ND22pH*9)ZjIh@|4H<v)joTU>%7!|^{%}`
zmgm)@^Yc3@)<3?)zjhbT-fH!YhXYode}9*vURmi|Di?eHy6D#UMce-;*y{XBs{DL9
z-_&wO{H3BVKW^x+-stlyYVosWKJKSsu35$5Z&@@kf6;1x$+Oy@LcY9nkE}hp=++eR
z*kwPI&c1Tm=OkZudA{vRpF8}4>LGi73$D@7Kf6lj3+MUwjXxcKy{*&XwNBWw*HXH1
z+Kj`gTjCd+PV(CQ>TZ9wrv2Y(t-`Mj3PFxqJg@f+|Mgk%{^{H9<w}0*PW<irb;GYH
zkF7tG&VPK~-DCGyG^e=ddflz+S2D-@`d@64`u=v_swv*zR!f}P^-HFc<ym=p_RT#x
zJ;{F_d}e$i_fS*6Y+vWC{2zxu{$o%3;CplSw|leKE<N*>|D}2T%oXPOvCBSfseD|w
z>P%{;WqHiEZF_Fs-&XIkZ>Im#^!1Onc>KJ>e`HsO__jOz%^hO;ye#>t>wB_icKp1(
zZJR*PEcs81-<<8pwiBte{g7+tC;P4=FfMqm{Oa_@D@(kTGplqR!|D~kesELMYd3l`
z-Qu{<0=X`K(V6{rZz~pseX{JjX|>|`j=xgEcmK<$M!MMQrtR#Lmv7tjj^oYkr0_I(
zCEfJ7x)b|nT5RS`-8!v!<%#EJ4}M8YewHw|lRw~F@#4dm<NN=8)e2rR*F67iR!7Ft
z3)A@D``(=YZQt5gM)LBX9@^$jy`NOG;@zdN<!`q?Qh3W&IeF98-wU6Ve>XkmZg=3T
zbJe}clfE|wZZGzGvb|2<qmG5iyCyf&LOMMov?I7(+VFIBqt$)EoQ<2_ZktviH1%=E
z;@k48*sFhf9=+eM8yWU!E1%U`-M{khvTq#!{W@;*5?#NY=dA2%78+${Tt4$;&E=oY
zciuz?N4A$0{;|5<vSi2c9lD=>GUPS?ZT~G$6o19@_Pt}@Zv6{eSAH#b<+|VBu3wiu
zXSB(9>s@t;$iJ_4N!2N?-oGyFcXs)@t?$B{UtcQyeOqwB`OaI*8vd5H#(8hIPij_w
z>oD`p@vo&#saG^(*kaS(FP)QnXPy40H-)c1Ecvv{>@)wh&8H*!&VJ@enxY)DKDw>;
z%}velo~jF9TdvE7t}Cc@wbl3A`K9#GX_vR`;VzNNr$p|VrCWb9%iDeSVeWk!`)7uE
zHUAiY#W4JI*d9A?i}bzi4+_6HytcT1>Z^3g3+<fLe1p@IL!K!YwykVAzT0B0T&iYe
zx$G^`z^GHNZ@oQrgJbRKmt7VnH&%sAd-dV0bj+IMpgZ~B&%bXpy2<(}x~ycAeaMl2
z0TUzNgtaZ~nd@7$JL20m^|aG&i$2YI^(VkqUZ`f?rR)6vyA0ec4}Hx_x%JQDYl8k~
zvoF!V`Ltg(EWGDmINx$=;T1=@#WCr!@@+<M%g*17PS1}CWw(_)_3KW?=?k_OWM(HT
zg8X6Ea693@p?%9A@zDK>zwi6pKKHgmf5S$W{ZI4upLN^9RC)T%8udrBKcCy4mj5Z<
zyef8INB-Y~(^@51O=^{||E%^ekIH$oYxS}EzZ%P@T#w*iR`tzgnzQ9v<$u|;qC5RI
z?~h-!%|6doMRWSO^7-lS!>jG*?&vlv>+kP)tZSm5H?!$@-^w+&H_iC|b7As@A2rOe
zd=7RZU*v!He|q=wM>D(TE9VQ2x9#Vr{a)*4{w(g4VA=YoyVUL-Zuqm{HXo=sj+)2t
zfbD}E+Y@$Oe^4zWFpq(OK}f-d5pU_O&cM*X!r@=;qdzgQczwVwfBlLm4U5a)b}ip}
z)~3E_{`<HGCC2szf;ThMt?dnN8&CCH_&Ap1o5?bx7k~DCed!v1Sp0(R#Fa6H&%~Qj
z`!GuIZQ^Hb+h6{;!8QGAj9Ts56+f44nl-Ke^_}O;JLC>s-n*&U1yty^+?3b&+WKYf
z)-`MQ>AZT^?)@R_tJQw3+{(9NZ>MK@t~dH9w|U9_6}#n?$_!R?+t({S+S})CzvY!s
z>BB!a_@*hkE-R8ey?fGn*Q;y&pKmNL)PE@!3oF1M)Wv@}`svy9`&mT>`<Fa@@o{5(
zSn|v-Tiwq3&g`3ZbxTdmb36G1p@Q>@o)q18d7FQI?Zl8<q3`QXyz&;ix@?cg+uKLQ
zGsDC`iT?U9``;VS)JJt4RtvL=TdyzLW3qbF1$CSK?9bR=ZvVZ}<W0lHZ_jdW$h&<!
zRk4J}&HLxe?K*R!+Lsm0e74>$)nxsN$=A{YdaBGe*~etp+0MOLwLSHQe%o8~x8JW`
zcUpB;yt>amKIMz#`h?lZd%j)17yR6!tj1;f)e4>WE4_B6?C)B*X7%}r9tm~j+wR4&
zSROO1`|y*YsQ<$haqIgoZ_WQatoYAt{A1Z0-@x~0f4!}`@@Im4YQEcyty3zWW_~{Q
zH)Q7NOGWQ?yveQHyg&DUM~(6PQ|IH3W={OHQ@*2AP(Np<Jlnsw3`m9ew~IzI&a^A7
zXWw`B_!{S}@p{+q)vWcmme~7q{mcCiHddL<@>*^(Y1wt5l&|7J{P`(OMLCk+x-);5
z=X|gJxKio!#pSa8SG?@p4Wrq=N^Fl$UiAC_Vx8_4%VS?jm`^Qre-NQpmikTcQqi@W
zLO*A88s82G%eI`}Rg=fOZvRBX{=&zf8Sk{T^ZEb(dj5aWRLx80W^XSub=eY>ak~Bc
zvN!(K_rvxId=um__sm><`CD}1gtF#6o;Pp(4fwSCx71^0`3JugZQpyI{C!}>ZA<k}
z(f=b;GrSMqv~XVSG{@@8j8j|9<KsU+cDCDdee<dO_SX+*By>;B-M;n6<OMSBvUmSo
zsM|h$e#oD{HzuX3#=Tx}`PQZX5BIgz?%Ds&)ce+>DX*E1|A?DuvL!RE=-SIaih1AG
zu3Y21+oEo6u2ayR<U3+NYZ%NQE<AkM{_pYq@u^))^6xEOy2mPinc&@6tz+AZ{x*EN
zzsGy;&NJ0Z|1xe}x+z3Fes=z4t9!1yHDZD#`R{J@v;HEz^>gCmI_3T#t=YRAm~Q>6
z5H6o}Q-7Or#7(_`HAZt@wTMXv?<{*J-ff+Dd1n2FdFMqI%RH>I)yVoiHF3ZF{@=d~
z)Ocrlr>;N$$z{6LG5$`C;2qWLvekD#yb-%`<(jwG-z_^=*4HX=e8=V)FG0yDZ?{dR
z`JViPk6$!iGu$`z_gW>Z$iJ&Xeoy=SZ13V9DpP-Y%t_RG_)*VqwR>cl-Q%x^k8zeQ
ze6U2mq|x7Ox%Q(A?JL?kAI>)45pjIU4*8zj{OZ-4xJ6d;xH%Wvf4-wPZSUL8%bOCl
z!q5CXHM4%jJbq3)|Cg`Z>s=*4t~NEwt)KHZPycgTd+zqF?>8*slX&%a%j2DwCcL|I
zqjY8Rog)Fu?!L3Ee*LC*b=D=*DPMPP<PFa%);VHxtoJ;7f%F^uXYCXIFY>#VTP<B`
zz4UHb-gfnS&gz@&Bd&d8?=JU`-=F*c^~^1IOIxom{_LzhZ_D1dTt5F^v&r9HcUnAZ
zIoBHVJ@Yhnr{1{qv)X_Auh&^u*X_>wbKTr<s`kr236+b@)Hlg^oql9{-tX$}(u!?=
z{|asWd$6)y&O1nN?t8oQ_tt-_vq~1XB&sCOEdJRn@>TK0g17ViH~$S=EM2Vslw<ex
zqFCYgi4Juaa@j%6Yh8ba0_F;S=1<Mjpv5zKdHx}Q`55DaX@&_hC)(RNLB;)ahwZZ9
z<~W9q6Y&+Z%I3r$dwFGM)n}(Kix&SgV!iCdz`&q+BC=wZ*YbT6_HCWE_3Cujy~*b}
zBYBsYW_4}dHa#->Qv8)(MQ#R$2bVsH&I^m*w8HG^(v16h`#d)9ny`NA?+KBir&Qmo
zF)%os`XoAU&C)a4{)=v&^z;7&DQI#;cN_f{$h5p$25O|0+*M~_U|6CTuYU5%N598y
zYwpkAyPH+g{Mw_tr7w;0Q#Yo?TF0$T3D7?IsdP6_x)3`9L*ZPZ=1*5Yg=l$~eoS>&
z+B#|d(Yon(US%s@eRg_T>8jtirai2%e&MODm}T`PLhSPT`29-H(=B7GrB^V&a!`NO
z@b$HeYyi7eY_+uC)b$@iY9^hkQJFt$Uf6u2S>aDKuc(ICtU6Ki<t3}m#FrHsp=`E{
z3=KU`-dry`|H*Ep$NG>7PAk=?p4@Hg?z=SjLtW+fKYEkB{Jrk2<a%W^QL=d+1A~KG
zk=VSPGK){MFK<hp`zB!Px8^B&LK$VZB?VX+7$&Uy(+Y|S8D;$S@4^pDo(C75pI=h(
z>D*2h28Is_N>TG}8GSszP{h*rjVc2JgIutN&D(iBMp1K885kJeO-?*>dEvX=vv~e+
zpJrrWu#s@CsG8;$y~LKY<ht)1$xYj48D;UBi9cgyV5m?zHf{OG4Z6Jv_wN)t-#Wa}
zr`tbhrvA}SY0L}^EPp?)ukSUzyXsKX?5W?@fP>z&pzvO%J6C?{Mmv`%-HH8?;a&Hf
zw>#{XQSP2K@&5k$)7$g!@2S3C_%?R|-wI||*$s8BvMHN+uXAbC|KDz3xt(wKw>k?`
zX^BIVFBSTiN>+Vea!Wk>o6`KU6;h_UGfVR|tpw+Z<cD2pT*SA6`J1END~0ZaVvQpO
zGE0Q!z2kn^X|C-m8^HeR;_HUm2|0f=Tj%Wm_mjV`Sv&u5>*32GR$KLdZhSfGbM(S5
zG6CBwXE7bRoVz!2X{*%&zAKBbA5?zR?9DcBM{Iy+p-fD@wBG$sTckYJUYWeJ`1v=d
z$zdKh*2nMP6V1@D=hx-<fA8*E&E59u!H)Wxb=BL~J>I`u`2Drgn*aZ7=jQFcx<GAd
z+|#t^IW=2sKI*y$vR`Se`eJn=>F@I`f0kUmBwUgw`{%m-|L*eF+x}jz|FgUNwbi=6
z+Y1&>TYf>|qixCUxvy@qcT}~QzextAMB6G^mB{}q6<<U!bZzFX<kOhWA=_Ukvnm_x
zskdz^!iR+GS9F0raqXa{;|u%$<;QnV-D?u<YQeXXxpd)&C*0c|?$*svviaD)3S{D4
zZ`qWKMw7!D9$GBnyRvor!$S`>d*W};?QWi86>#NX@-@dO#pm^Z&X+&`za+T@WQeQm
z61jPK@((-hLqGwnb<!+G=|@X+{-culOD!{IJ)Qv4cl7Y(g^iCxUq&16+$h{5JTK?Z
z!XWlng0COUVVJVzww9m4qbD7IbhTbR_;tJB<Fw_O%M~8Gy|`8OxNS{+jc0H6ZPjCr
zUa}gm9{l+_U#R5}<BK`D7Giymwn!Ap1hIEn?f7T5<iaPDX~)j}P^*t~K33iT6zZNQ
zoB1ZOEb`__unS?I&f$K%0H!|1!Uj?zm|pqxB~0wK^Agw7!AUYpt~6FHu{vQTpjxP*
zu+;L}iQ|PHAbWq^E_nE1iPPhGt7<o<>3_;>Uln+H(#>ApDoDUJpU!cflaRvY5_$FD
z!iFy|lKb90wXk6?b&y>la_DlcA~<xLf7~w6P?&o;sN|)ULF*D{U61}cnLC#XXNbLO
zunG|8^ACP`W#5zI%d*eqw?4A*U;ap8DPPFER}Ugy2S&waF28nAQ}N`Ji~Y?uvhCNM
zKuP(NuK()BD_*uUt;;PA|JZ5av66Y}*I$>jY^{!OwAzv4VO05Le{1&ocu*qS_025C
z&ZaV~dDfIF(L<MKf)!u;<*TTvrSNnm-=ZcV=53eD-+t8wx#jx3Httqfg6jgs{PT78
zo*qU!-DFcP&YE&$@qgWz>c8M*wROAV)@jSD9V;I3hu-y)jZspWxg?hTc+_MIzKH#x
zoLKrc*TPi#PxJTv?$PtCzU^;668Vg$%1(2)fmLbW8kgN7+09eS`FF%hO>3Imwq%87
zzKKSwI<MD5PKI}$8a68zUfKIW$X52%HS6iJXI^o?jLwdXu8q9H-?HVZLzHc~g>`}V
zAxBLuou`71oD4AwKYY=7pKZNEW^Rzw_btCBxo*|euc~W#)NQhw`)5~9MAXRzkg*T;
zPnt55{(aoJPkc(As*d0kh6AD(Kb5#%3wkzH{r#OF*GkB!MA;fPT}e~>C+;_AGd^*#
z&}ntPRPV2TZ_-a8KCi$;PKF1kt~V6QzBkD`aclR2ds~7h6e<_g+Ae)Q|I@m)>dmvZ
zJV|~YWO!?9#;4cU_1}vXNZy(xGUa-K$hYPD|J>dE^wR063<nnf{P%bF<;BxN_8kgV
zkPw~QEo@z`QXy&keNXW2<hiT<KE8hIazN?XMW0r;{a(SG>&xYJ>uFi9)rGJn8?v{l
zeB6HEmnbNiW#=DWdGmq8_PPI7os(6$H#2L(O3zpJIofufsdkh6W6!?|cKh6A(`ppB
z(faeT*tJJrg(tJBKL|O#>*1#t5#OcP`Y;s8IagfT5F$QvP3om<zg=I}nWSEky3xPn
zW#m0|(U()-TnKyRnfi#|$N%RSj)v!QhlLm(Y~p!%a?;a1y1fq~l$VEQWZF;K^!&T;
z=}Tp6Cja9q_%B{}i_3Mj@VQd&L`|6~9Nr8QY@I8#Ja<}6DcrC!-D+Cm)*O4LJ9fbd
zr)DQRc5Yx{xM|$7d{Ifd@Wd*|SI!d`{;hYc{y3-c&Vk%Z3zqEfJ6)V$B{q$L;d*((
zfr=k3Gq+bdCfKY?cs)se#+MMLN<N<!RfZGx&Y)I@n2gN3|DXCCZ=cv+5W(eFx!`#?
zSKHEp1SW<j^A&AuPycTBIBgy3xX@r4+gkq<n!yRDnhOFhU1ni9EY!%!kk`NS_PQHW
zXUfj_6657??}@2F>tP{BPKI~>8aBE9Jum&=-Q3e2RQ~RAZu@JFwxu?#YKMdvY~}@2
zaPbTA`<L8Sv|hHM<m>^L2qp%J-EY506&)1QC|~rH^Q95%vTQ{iMutN?4>PswtCea`
z@3rx+-ZX7%@nXl*!g_l8jgW9^(0Io9_)*-H?IG(<J<3-7bZ5f10-w{udP@9_FCzk!
zbQl>HNgSFSH!oFj*32${(V6<e`xnW|HPn~A&t_HQ^*H!hN3%(YK|#~GLd)y>R;9hy
z9Kz1qFWJAsdttzI*Z=Hy%RE$W9C|YUuJ!5zPuf-LFExnRofl$Y@D#oF%Xk<20_J<`
zBd;K8<cU|!G6FuaHV4gm{XKe8)1pHcw|+mYEX%HTh4FRx6~@v9>-O?4Ph)=E@bTO|
z{nv}0F|JGCo_v4Tlr-+(kkvsIObiOV3qNd`<ml_~88H3fvm-P9rJP?qZRr!;&f{V{
z-kI#n3Ie*gycrl$j$X)JzSgJ8cK2^fO|`pa&-0txRPJjkYM%RLD$yEiBokY0f9G&v
zf!?bIcrg{c`Cy}=ztn;)tfzwCcALKTy109Gd6Z(}{<^=P@)Y_0mc~rr`>{{u@6+fR
zd@tA-6u9s2uiu|iap~ReNjmY@KfN=z^|cPF(7qqiz_sY<%O7Se(bKLh-TmOuTCeLb
z@*dBYD_tPBm+uBUs8Qi}o~@1X@id+1xtT1#-+WP-`FZJIj(44zcP?2T)U+_uv?!d#
zz;M9UpzOA<HEX4Iw9)ITw?4N%ndF_Qx-3!}ol#k|UGa`+dEV<uZHo+o4IV}Fl`dGp
zd~H3b)&;dA&$6+z^{^kaew%sv$uYLc_E{CXLc(K0Jc2x<Cj4+-$|q8a$m*?!E;n8%
zNoGEFSWeYOmdm?v+e0D6lP&fkuN(r|*T4(>9Zxgomp#6k>a_iC=OrtLNn3PSw=15V
zka9>~3&rjre*aBU9&5Kuxh`${{qo+H<xB1sT<7pq169&pRtd0@{^6CJgdbaDTOLgg
z*)#h@8{5(kOA<9LewwJb`btguqxmD-oPnW0Dr%llkxp#30T=gntxO4{PT`Ip)0|~B
zUNu-H$Oo`@Sy|Xh8$8ogKFIteAi&C8K^E$mR}Hlepqe)6VQ2j9*q{)Pp#P8S_f>EI
zw)E!GV-WWul)S84Dm!mc(<Dum*z7Zc^(#Q}vx4~>W9fnw&6hVj{$YH4V_~AEg(k1}
zza@7Iq$d68Ja~(N;ST$u%YqLlJn=sW!W&o^7~Tm#)I1<EsfkfjW(ottf#k{;A4K@P
zmQ7$`V0dsE+_Pbfu_|45Z_fsc(-JbEM9OgdiH?o$(%^WH`%$NFy*j<<-p1!GM<dhj
z|NpuF-~PP^SQr>4gzP(X88W`};^dMp{Yz`~o@76@+aj1gljHx-{njjM3=9R^YFgE^
zH9w!4T&{F(kxl5cO<U$zM;A`({80brd40up1_lPd>FXz_yoy*>m|V;$u~+5Hj*Zji
zY9Eq`bUW_I$iQ%<(2M6(c*Uh|{_QSyb50*vlk(u+#Jmr)3<{@pE?D?#mh0Yc;EDk$
z+-v{-e6<Z)A;=!y@@vY)Jxcx$14Pm#85kO-Jb8bs?3QkLxxVk6c|YzJRvmn_(d63u
zNB4T8o*4+)fs)HB2iq#y4g8?C`J8=qdOULk`GP>{?Mh=3IAV9)wNkKQlze32B3B@z
zq@VXS;>>-?V~h+8MQ;+L<}olZ=rv;YICuR2u;h7*mdKoy#$TT?iZ6ez^!mnswi$hU
zmwawq{3VO~-Nwg02bnt_3rJq_UZ!fbF7J!Qp3fgr>K9xUzqI|@rft7At!THq)6jk4
zL5TSGEo<#AZ=7CYS8ylm!lby=M}MAF@7=a!|B7mP3z_y46J#r1J(6!1o;bOG`ycuC
z@3PQ-r>p+`pqhzkrHb)Yk>U@MzDVz%_qR?dH^1+2$s5(V{6_-boHG;m-v0ii_hv0_
z+Xf51iA$e<KTs%9(0=@3Z960u|AsB<g7!@r#Dk{1JF`0{V8Y8A-d6G+Ia>DBqLo)y
zFD;gN#1+;&ON6U*V(0gJ7463rLEY>;pQXVSlQ)S9zG&>R&|Ua?tI4tN)_L#t9S&Zp
zbM@%-9cyc~e@2BYjVXG^@X|=O+VeSc;aaw!;-<?!TP~hFSlFShHFfX1$JRD{@2zb_
z=PxmmKe_x}<JILo&qOOf-4AInnF$U`3loc}(?0FuV^Kd^*rD@M{|S??@3kU5QQL-h
zA1$t&-h5}PXSBZkW1qL3=KMQ$oZO|G`};lvBrK0Cc`IjraOJJ-f7s1GTkuWX_F&@<
zOSY?XW!qyQL&I!6%)|@=qmMGc=lmYHfm-4o53H7G&hT1p_F>&Sxdq}5x*|&!^uKhi
z{Q50z)yahSoOb22OLvxRmv)%N;m?q;>DQ#z@?!sLrPq<+bGrA2|4v$ay=q};q`%gs
zY*!XN_rP77xBA?=7t3JY`GG~D_Lf!fYmejErJ6@F$|8BQZeN>o;M44%Tjy{3@{BdQ
zq+}KAth%Q4n`iFdY%4p{EpPtcS!?H=d2Xxey47yxlv6=p^Jbl5c(6@y9z#m<z6qb&
zx1Ec)6n}-kJo;whGSjT8wU)w}{Kp^ZtovLoI`hS!{!Kd1&RtTvJpa;apF7j!tABdE
zfBx^&xj)yodFO7negA1s@%{Vz7M0ll3c4Dmy1!MEFI)3m+RRf751xT6SbS@WxO$_=
z)1{G9k6v%wHU}~pwfyQbJ?F>{y?wuAI=|HKNIV|*?CSe}m#)oAyqo<{u<|?eM7Eh_
zhxg|GznyU&G@HhB`?2Sy+QeH{Pq!Of6~FX<!{KQQc^LBKA96bUd(rUbQc&FAFzNhl
z6WK&#uf5853R$){<)ESe>zO5{EvmZA4YM69m?rf8^st*dZTi%jzGp#|R+j{yZI|#p
zZd8(XL-OTP%}3=YZ~pJw%RXnL>#S*e1eP*ynmbK-x$CL-dY7NB4$`wM|E79(pM}yX
zh6mrkzKWWd>b-k|*SQ}{%D3z5-YRy!RcC(Z#yN#YrQ2^le6e`{gk6_Kzo~KOr<859
zp4?e+`gU;b#p(RH|87R^(=+-Q)w;+fH~yoimM449Z=Y0#g3nypx#?^TCNJ0Dj8c;K
zWQ$AJeEBVN`kft$ubVk9<lNFcv16m1i~{2mF<pO#b<WJ)*MqiL%UYdG>C0Fh^hiwe
z`xLIyUmqG~yPXElGH<~@jM4%cYhmF44TNzb&wB*?xPAZMF>n!=^yrfgD1k%A*ifdh
zap;Dm{|AYFlOi=l_Czxj%(hr=IDwyEbY8_{#)8%05xP8U$OH<=Xk?oqdK*5Jv@e_6
z^!c<*`KuFGX75kFbyMf^N3jUrtj6a%gL5}ra!(21KJ$Hk0{1#?(Bw*A=3m2?W;<_h
z@P7V&ZNBM*sN977w>u|IzaH^i@T-hSWZ#vy@29_bYhSwmxaRcVx1LYCTT+wLdOAyQ
z^1iSuHNla-r;nGu`^*@_|M2CzHBYhwr|#QYR(EYr-2T&>zn_@)w=pPw$LWaL$SZgG
zrze#^vpqgHe(JV8W!>Lq*LYV=?fgDN^{?yQzXBVZ9b^Ce6c&768uM#m==6o<?^Vhq
zvc5jMH}{Q-{`!^Y7Qg<vYtc9FFW=<Xw7bUZ<k$UNtH%D>JE~7k{&%YBG|%|#D|e>6
z%z(Q_^r5D^-Y4IZubPW1UFUV(`>U~9KQd(Yr$whl;+I6mo(O+&IRDpX^{Jh|6<@Wi
zDz|SE1!b;QyN5q*4eUMk-|b(T$lkNfJYD&MQ1OnQZ`oVif-=MR{w~ygy8Qm8f+Sfr
zz4a^4C12S*@$bW^&#zyexwc#PaGhb!{*`iJ@!TuT;@?>QtC@H)eNR(v-^W}2)&6rI
z-}opP8}@kL-QcN3C+kF=Bg5w_PdxDFU5@VT>Ai(L@-=o1ca&|O9zACs_?x%h;@<xQ
zJo_}OFW;-)ymiXXzlwjK=?i~-w)S+$JhS{e{!@4A=sxc|eQ%oi@7v${PndsR`R7gO
z95K!LzZ)aOKOUO)J5k``qos`x*1nlqs4Hw(fBTwPQ{ZRkx+!}l3(rF5S5_XDH9VEQ
z>T~kf9FwVjnJT{PRZqOqUm|z!#F3`~ZGVNH&)~e`jBirqsLu6|j}Hf2lWnYxesk)L
z^OC1)HmiOz6i(l^a1E#y`FV#erd~N&?(wnb%sV*wW#|3-aeaSWYS)&}&(_BB3a%Bo
z_37bW&EJ>rZ4Zro2AUT+zV=ge5C7HJTd%hK4U<`NS0O)WTbccoKkxP(`*DJON1ey{
z>Yz_{2CvG_b^f{bp7mtELqg|zUEcJ^JZrfMUlk~)Rq6*kw{Fr6+jjSwkpH40nZlCa
z&R-Ms?N|Qzy;1eF*Pd&R%eOB5f4G+ScSZf(>}gw$YF>{#-mV{_#+y59=A2Ti`i|MP
z*;=nJ==H^?&z>OiU1Gbdo&15^4gU+|o!)g@W!}DhBkuP7Q(w>R(!E-G|KG1&ha=s}
zmTmjZqP#jjHvF)D%Gc{xv+CcT+j{M9Rzd8pyn1V<FP4F~MK<hTcOm=bH}{+mOJp@B
z|J||AZ$pn&>*)oj-|U^Tx%c*0*J-wSvhzaXuBZJwSXCx@dSm50$DX2=*QKX7^xIlL
z?F!`IHSfc&#ivBqtzYr{sOI#2eibuU{C&`+k?k_`(CueA$L}4>-EO((?d<2rLDLiV
z4)eJc<X>z%J-O`gZ!w!bxeVFo(L3v!`D$C&zTr))1Px1{Gno3JLVWqv#X73**E#Q2
z^75{X-5o0_y|C0WR<NBddg`el*?pDG-K9QVzu*4*X&a!n+oA4spWnCkt{d`NM%{N$
z8BE!@*)vc4^u2FKa&CHrfYw>8dhXnGKKR$Khw*~PG~9Q@_4?eFUoQ71^<G<D_WeXx
zS%WLTHQyO8H|n!Gkv!$~n#YF`b1bhGs5?i_m(G>k#Xc(;W18iadCLFUnYVY!eq=S9
z_F(&+x7%-agem0Docq<Krug2^Yj1r2y>?rFTKwZ$`x~1C7B?)*e_~bt{-s}cZ*2M1
zAM53xPWdGD`e4ZUc_)fAmX{u>_bt}GnECCy_mywQ*S4!Xz4Y_l=Qn?|-Y*v}zj*B3
zN5R59t<R3?27kC=IJGod?6aMH36IqL`~{~OPqa7vOa32t&sMhngMw=<hgHV!=a+N#
zUwv`xj<@BZcUxnwA3<8abXu6<4g+|${3-I{CA=j+Y_-!%K3{9r=Pgz5u6)!xBDF}|
z=IgYZao@LyRm`)#I!AlXE^&*yXZT}W%yz6hkaIr7YT4K0OKv~OJFGW%|8~2*FS36y
z?NT?Is(tRyT-XvPwR?4U@*qo`;1lHX&CiTpX1ks>p9-6k{wgr<-8rv)Vxcdi|ApSU
zpZfn((l>Um+J}0{UsD6i?PHq4S6}}bnt3{Vd&d5g+n0pTtmu!t6o2I|zo50mm80|R
z1wY0eUn(C}+PSNsE(cnG^UOSzssky)qk4W{-0+wE`|m~i)6Dn(37g#fQ&rc!zyELY
zg$T9UwSmRK%ND1a>dIf=d7ix>v}L)>&J*SrA<b5;s_%=}>`MvEJ=Luj3~87z<lq1D
z{JapgckL^LSDA%Z=$-<##cL0Ju1=_%P`6v&`!JtGZvMHpzlkF2F^cdk*;%JjXXUT@
zEb%obrGCe?KUG$nzn)9K)8F>iTz5a76;8<)BG{`}1?k;fpQQ2nRk4cDjQexfZWnj#
z8<0ZW`F!2ZnCj2IrFCoO^)9=l*}LTBR+h-Wtyd09&s-pLk?FVLIYZ%yeLq4b{(Nz{
zPd!U@{^A*Ho2z<muQ$B-_kZ9t*DIHkroI00G0}ppoaNPm8&hw#dz_9;_kNPBb}q*`
za_!R?txr37cl>iZ1}a(D3xwsYZ2n%i|9?7knTK`$y<1lWE_yB0mA^N8ll|M;=&PxA
zc25ph-_hEy`X^wkeNf#uru$vZTcn@(p1Ss~ebW8A*CphCGF<0>S?TX}kKOI=Im?On
zf9+NHDaeuWaqH5DIdc|<D*DM*`8>TfyB>L=)0E`+412k||NcHz7p=G7mJ-={-Ri}b
zZC~nltWT7GzrOnHq-_>YtzQ55(0XdgLSN&_oBf{i7jDk?O_jZM^yBLs;Yp9=9&bDG
z99j*%wEy>4D_EuWv!3qLtChyRFWv<eMoV`co%>+(_h+%7$-k{X&DK7S-O_!?bn3?o
zvah!|?+>(=H+yIPNn`1zmE0-|-u9apE}!`~$+~&!Tc(%oYyLBaygHkDPg_<}WX=Ij
zU9)9HZ_o6v`rQ1rW|_oOj_a!rZ;|&s-jn$Ad3nA3xh0ClD`noO`zg5XJZER8bV}si
zyw|r*=2?`5=V)dB-nx6`=DEp=#|+=;q*d89+*y2E&;J(h`{)lARSQbz<UjrOQ25uD
zo4*slU3Q`L8D158x-Y*9oHqA-#orBuO|dVS&9~?w&yL^tdv&s1?eB*v{$-7SrpeA-
zQy03b_ViDNu5^ue>GN(M-L&0S{mR2-F^12z)Bi23vQznCvvj@uKhZ=`4P^SRF67*|
z<B|8`o}J~pod+w$GmjT9RlK`%qqZApc^OaYt+(?wZ$Ec$$11g0P$_=9V5!-0r!&cS
ze$+5*Klm@Xj^n5PtCYLjwg+wxzLopDtoo7dlnYDV?(MU^DX;S{=C|qXZ~NzYR&PFY
zuBxOi<LJTbpVj}DF24Shdu=f5HR(8ik>7_6AC=xEW~zMAlHZ2!K6##6`uXnjo4>E#
z^G|=HbeyOnJy)-O!Xi5s*)4xRXKuTnRg(N}sZ8ScsCC(oY<W)b?|KVb*|gv(Cqo_s
zc-s6EXiNunRVuh(m&-a}!Encjt%v#N2Ln)x|AEkpZOjY|9<Y*~h^nAqyZXr|J&za|
z9?S?%y5Jl;?`f3l-@m`N*Zlr=cK7tT*=xfCpS=lqmIEPelV<v#Wh1m?7VJ0<fAt^h
z>;H+r7h_<kFlkvX{O5B0pWVU>{%|rd*z^T}2FU{o{G>`NUfuAvGvf{T=hDH%@SxCT
zi_O;5O>x%gcY5ZjeG}r~YS(BIVPN>KEi!N3)7rmz|EoRbq{<1e4P;=rV}E$Ya_76{
zrjl#+9KB@lHs{(^%S+}vq^>NP_UhOiJ&8sCKJN6Jz{K#tPvX$!%_g^$-g++Bo%iU>
zgsoSn1ZFF|bP==O0vg15^EDDQq0_TAig(G?+12HryqT}m`>StpV`L~$@6q*toER;2
zaNo}7ZCl!tXNt{VVie!?^z6PBSEuW&@~zaowY?iWz@}}qbZyE7DbJ;`U*FwtOUM>c
z<YH*Jox<U-su|vH#Ao)~=eW_DX-l85$o#I)|K=L$Ju`fs%jU^*=RH|zG(FYDE1EaT
zD68&7|0eUt$6B0496`DRBeLhmsK|Z~nZB^xe-(J*FH-yF!K0HRulHJrFMT}s7;ohM
z-M(>`{Tz?=ZmlSfUEO#kN=bh6x)Tf3bbsEsDJH9(3ZD51`}bmp#?sgt1_p)N`}^z5
z+tgG`6>MT16(mHrW}n-ud~nXP<|Ez<H~L-u_t9Ya!dFOXpnS%CuBE!c&%HL?^WJ@J
zmuB%cjp8y5Fu5-BS@7n@pV!N_K3Guj|9ZLRe3{FV{-%@sV?QFz_T1)4+WzZm#KD)-
zE-YndaM&kVpZoov;-w;{$$rV17LBTJKU?2?JvU@Y_@?WTpb4J!{)cZT&%JtwKk%Re
zD+9y2^8)j7j;=ei=h|E!+x_`b)3zngUF3ge<=TMnS6-z!bucj~*gHKu`F`GQzjr?t
zExa=Kcg*E?vp5177-Hrxe0s8^)>`lMB=!~!28MO&BJ;LX`#1+VAG6jC*kbWC(85J<
z2?K-2{K^AA{JJO0FXITTeA2EFwHPYKXYX?{cY66jfupRQj0`($oGWh0TkM;gW#sXE
z)qx!fya6#2Bp4b_8<*WS1t+f8u*9WZ!Q}fSc7th`0xQFTN>~!I+XYENR_ToKUPr!G
zO)ReKQ1W18D6oP}N)?p+DA75b73sBFKk~)@dvDx9i+r!{F5SHdlm{%%3C!!dG}qVV
zRpUlK(4rFkPd8t6n#8|RmAiib|66~*hF$FfOEY?z7!>TBD}okY7Cp18Ea6hX*18Vw
zMKX&SPw@wSS6T&el-}bR%l&jMH17QWD*L>WYxnjrjrfoWObiT4ty|5sT_bsyguUvF
zyLoPJ%<0^@k3Dxw9j^QP>*-yu<MaQ0D*yR<{{Ii}?#kQdPx1F}W?(p=`x`WcxO>_Z
zOXvje)Y;triBik_RxVibM@%Dk;-|m={zmVs{r&9jX}?*odAGS_z7DxzJME{$sX4Nz
z=IDaSwZWSmSKQ9~|76C}dE0Dxm%h8R{Pw#U4<c4nzdps?_3GN<Y<`9h98M24YkYTq
zIPx^|5m%eW+jG0q10A()9A#%XVB48dX?1OvNV?<?6Ni@;E2{H5KmAnnI_`2&ij`r9
zyWsw9pLf6T3BDW0<jESnNX~T!I3#wkbMAior}N$J;Gc}I1i|^PfL|$U-h^!l+E<iY
zHBz~PS~M9BtW~gyy{O!-A<7f<(14Y}Ax>~!k%G)3IYST4;0a1Tj0~TiI8@x4_j#pp
z?8yaTlMjBY()DPRUnIBF^prRc$OMOZ5{D+YE!}k@MR)SHd-`7A7i%sK`%qQxA*`5n
zeIdxmY4EvB|5sh0l`L=FC#X7wm;_IF^kfc0!xqUy!JenCF6?PeKQyN=HA44x|B{?r
zH|GSe60TJ9%N6CGQ?6CDaJO@Z5jWe)2PZB6axye{8(~gorp5lAXo5U{u&-Y2^VJ2a
zdruv)zCQ&tLL#u~ov`Ao9SJioY050)2w`X_mXR=!vr9~4Q$H31S@-Xo0bMmJl@j{q
zT*}{f`JRDsvqB?V#H$z{3b;-%;%;BL!hw~+A*Stv$y7gG3yVAdpT?fLzGd??qxCkG
zYoo#Q+m!_qu7=co)B1GFce}05`9A`#6TH+UmWU*BF$jbwu087&7{<JEYL!v>yDh1c
zTu)E#E0;1i)Afdwb~#eB$}$#IPu^rYIic)QVSpNV#_jHY`@c`$-_tGB^XW-h#5V7B
zg%-nszdz8EXU?I?Y}=-tXgA*G#olIJUUq2WVa_t;%(kY>ic+imRxa@V0j~mO>-Qd<
zrjfhw)S<1X=d`U5)7<~m>u&PQ{)K05E<AH{(V3e&(`NdgWm}lH`)#M;-<4M`Z(9y3
zgfz=<TP}B&IJx|r_&V_F*x;0cs8g@4>I$k#O5Vo0ZCHJNep77it*EE>*%<DuU##mt
z^YS|Dzn$~f+J4;q#^g%x(v5ZEzuP`@A6Sref6~o~Dqm0N`l~%;C_Ndr()|yca7=kf
z!=(*V+xASc^qyiFJ;l;`ie>cjH0I=rqTR3W2>M4$_SSkaK76^uyX?K~Bl(9LOJ_$d
zIma7XsaG5YDZMp{xA~oAI~ITY@0-rzeX4tHy0<Z`oh#ito5!!?_?5llc?%C^Hr=f~
zc=G+L?pX{BKZ_sO_`j=I9CXvV{}O1uRpGAWc@v}$D!9(@3J+QEY559=rNRsks(2oH
z>Ysl!Z^0%|Kj7hH-G__<%hoAt1-umD2|C#L%8HTUQmUN6I_B;7PbHm=d$Ku9NcNvd
zdO}&8;WN$HKt?a;uxk?f33Aa-FMlZ2>@Ub^4+OVAY?Ef{+a>(DCopf*(${?RRs^RC
zE?XD-Ec(Xz={(`vgPwUW0>?+y5u<nun_Pe14YCSyrtixH=4}$)`c5Zm`KPdFIx$sy
z3wQrBNxADibMgYXat)i8k$dmz?ee&~FXG(I{rUV4HKPl!=Su09X06!OY7~EK>$Tab
z-xDN$!$Mhdi_KlLL&4k5#eQG8@YS@_HLLbavpo6W>k`NAzp%25yIp-L<0`$`lPm8R
zte&i7ld8S8RQ^}$e74oqI-d={2Ru`8^nU3&>*je-B3gLn=B|Q@qTTPOt^fBlFlToB
z{foKNMe18_T8OL(xy5|#=J}hRQroU9-6aT75Amd7!k<Y$l+T=7_*E`@tCjd~OY7xp
zz6UjS{{<DPYu$A|w;rBsW+M7zt&GL`$=hstr8nI(alI>cD0o}m+B3(a*4DH;iT$>;
zj$HeF$^p@mla8O?JO{P%Vm6=A++xFe%=+!g|Ex`0oeqHuekMO*yYi_g<NyC@FX!&}
zIsdPY)9M)afv2_q|NRwu_|hRG>A;VZKiDSE-8029&wJYYIeE_Cinp!X_^vqmK$Bl4
zZ?b)QyHWb<M|aB-Z}o;x=e%2{{-EE$dVAEf;zMG;Eu*)`J@aPUxWKzC@Yjv=H>-{q
zEti{@VmcuzQ*%9!gny6yp*J>OGbgvLUEuxi)r7xu=I)tpxi&y-ikpLRqJ8@FS*d>Z
zHXpNhPyXmWL-th79m|8-9?lZKL3v_!gV<9+r`c6Ul4nm_uFT;N&av03^hFQVct#xo
z+4aRJUVBUHQrSmxh4#zk=1F`m+2vmU_@q$kxofJ|YhN0OJr#<b_U8GUfM>CloQ20#
zcq^~pIWNxT|L2w-@1Bn-Aa7keHOJL~d-oLy<8Q^=G(NvvC;Mqq%l0eL^YUaLYC`j-
z=k?m&17$v!9FEtW<4Zj!_V6Xgp<rlR>fORKl{_Vdv8z<yOZ2^c6SMhD3(T#MGNv=?
zy)OIy;uJwC`Hwf$Y-AlPPKl+0jRBEmwpj@_p_3MPR#-KCm;$LyAtWdnti1U^e$W5U
z$+rr*76+%lI?LU?nTLVFfvZSt-m*(8^_S$YP0jt98u<Q3@u5dL%nS?@`f6I2LmIai
zCwq#5hp?}os?AV7X9QYRdosLY6Sxppf24CNI91R4^v=zq&>7t913UUsrOeHyH(c~S
z)FYjJbEndoiK!(rA`A=;GRu!FsA*N-`=h}7$>E(mXS~?n$-ZP;&ncWflS69Ny3i}x
zYiAp!cN>Ay350xorS$pg+v~uqv+YWGE<@Xt&Vk^iqCu1Pf40fo9&>lENn!P)^5ZXA
zyN_Rr*xy}ko;CBZ$7fJHL&6SBek`1HhNr+GtsTjV=VGV-7(9GAYh7i+gMWoJin%h$
z9+!3H;(uBnwqRgz=(`B%cVXLZVl_EV&aGZ^0Vq5}s`OT=d}eHZk?eDR-Tt}p95Ox!
zpK`bM70h@jaJhQMM~g?cJe;nw$*Uc6jnB`|V*al6fBOeHw+gHFziL6#J3kAb{#vCJ
z^u7F3h}GBDFS^zHu1-IC@n=KhLy2hKs7tGVeAa!b|LWfCOQ4~$?-IpwpZ#>WT@3fN
z&+JpacX+~thZ5Rl>Gy2DN38OSj+^^>&D~?w5)WU>oPR%?TjYHNq`J1{>jL*tPVb!4
zlW3QaWN~bc`Mk4#AX_||JH5peIUiTgcnET-=ghv14d9`!IFDTuzZ)F7%(~-jf2m;o
z^Jq|y<xRgy=#=HBVy0bd{CPmI`uL4L&~(6^{M@RZoAMd?b(78iYIP`nvekJ7GECiQ
zU;A3NPupIc=C6O&yQf`np5B4{x||+K=7y3P{f2wrJ)S*9_dT!Y{-?DyC)%&e<W0SA
zp;mb1-p8YbE!@U?+cQ^BHi_Tkkhgnca{q@C$EBODmj;2xOjPr-x81If*0bbxInSPS
zOD6f$zhhyb8R<C-nf4_W{&q{bt-~*~vAD)n)_qU=Lm%toGyXo!xA}71iuKL`aPa(E
zJ=sBJ+qB}98Sc3sJ+(ehta<g1@7w)Z&zRMgCHpi7XKJp09Z<lfyME5oMvY~UPnXDi
zlxth!b9_e8u?tgE)$8w{s=gtWK68t!e*R;htNWgw-RgU5_RqJS=KeFEF|!38k0`je
z@OW9Dr$W=q3eP|H*d%0ZrYZ3)imu>)e5(vJnMU$F9a^8h;mr%yUT#*+H@>Elb4nk6
znaY#J${Fkb<<PQAD|z3Tw!Ucf*~;^4#<cu&$={a0BA)**+~z;syIh(vrSSucg7wjL
zXRc-MRoEE;-ULxxy?36c`TOwa*R>B+n}6S;zG+@*>UIvPIj@w2ch|iCzr7?qd*+tC
z?F@HJ4hc8hiRR6^9k$Bh^4YYyx65_*R@P}x*<Yi3VTowX+_N>yx2{l@eQqf`^WB~8
z>gl!LvbR+k&Huhc<m#_2>C$uV&EFfz@Q&>vr^7z*+;!K}EdjnuY-Mg=JTm+K>Ki|g
z%=;fW?dYAzTjzA`mxj-*(2Wva`K9ii{`)iexx2ZZb8FVW_)}iE>D;q@s()Q$tuBM7
zvDbb(dMi7TOWN}^pPzH}O?eje2YQ0@7@o{7`&!!}>#;@k1fS}r3HsJw*4Vi#{guzV
zv2l9k*WE|FQdjc5j$1wP#BTYHHA~Oj=Ka3yZ~kK2=}Vv95nO5ZRCPv&+4t^Gm)4we
z3YVBJ`)JlQ*<DN2*M4RzVmzUFNVuWqGULsqOZWWJ^}m;+Tpu&_>iw1#KJ1y+2T$j&
zoD|o|_~?MFk`3bt`~62VtfnnAK77tY-`9FhMQqWx{mJhc(_<#9iRrt%RLEWa^hD;w
zPrLrifzDf>b^r9zL~8AmVw35oE^{uvS^D?esrIjZ+x-~6H+^7HxIa(&(zo3YkCpWa
zt>1l?PhI|R>y^3h_LxV8+&$WTcc#yg=zH^Cb?>Wr;s3L2+Vz8X*y|pKuRXD8>FKF+
zJ_es#@cz-{kR*PI?>75yKg`wms&bxjLUrrbzEvy?JHA{8ZDv@^eAxEZT8q3BR>#i2
zS~j<-NBR#F|BlivHjF#$cy;2uFTN{zchcB+k!~`3^z=KI)vx@ub7wH`g)FSesAM8-
z_z5zPyx_z3{eOFnLCZLf9C;cE9{z$X?SO8=hK?wKG7h#`XdL5XkO}iA`Zm7SK^l++
zKCNrmww@iZ4I=9{Y^&V9-v79Duk@z6`fu;VQtm`_mtS9cde79Ovr6AqY@Ot|R^{~d
zw?<ZcTnr2feZffq`=aJ~rLNT5_r_yM*r%;G-cO3I)m?I{=H?c^()im(GWqPbnW`?n
z?Q*AYe|dd<{fVEIbMrE*Z(b`=>$~|yZJX)b&SbN_FQ;w$8uF9N|ET)PGwz>OzRZNo
zR6E5M9bMja#(jR=0il_F?Lny*gc%r4c$}-t{jT$Va@Q9xR?R6@K{NN<F1`|C#rl4F
z`T6%oE59sxGI!MiJ>i*#FE|+(QdH6(o=j_3-fx*}eeEP)Xtuq_OQpuN?Q<Ce85kH|
zo{9(UzdvD!9E(m5J=xQ$ulHD6xW<^VGB7+~1P}Q=;y>0mN9~&s0|P_9rpUaq`m18P
z;0DL{lLpUT27Hh8WpmfR#?8P`FrVk)%Sfr*iQiN%#F`hTow${CYK7^IIS-{77#>WN
zh@N-s@HUgC+T!!Pnf%9%O7#|Q5;;Aamx1Af2hYQmDo<YpFkQcWwfn@$4N=oBz48|O
zwci|~@lbH!uFahuwg%T;uGP8r#?>y`cH*<{y(|n22Ob-?s4v~Wio2(BR_WUVOBQCG
zZLMHrIB?jgukzKErshL`<L?(1`7khixB+t7J$sj^*_VZTmOk9#P*|r95<YXc?C82P
zZw{n<U44&-fq|jr(B*$84ZZj7w5``DeQtNRjDg|7M#-poKG(M|2BmwOZ2=XZ>JzU|
z_~^$iqU*=Nz;MbYp=SBfll;M;fvgWV&M+S<|B?90Zr5ATM0cJV14DyKQk(kH=9BLi
zKYjWB|2OsYAQnvqh6yfBA4=-~2#E3pF)%Qw@ypI@0*#C*^!;gFo|*nxdw<`;{sPk#
zxzjXfh*<@0Fzo_u?m6W2F!R64%-bvVoby+Hx$$~Eyp7l|k-SyPBm0WTX~_e5p7nv|
zZEK2K!DA*2Er)`Ch_F7?d>VgyEqLn8`{KS>$lTfO)xy?c^OYw)>wcm1&FRwIwNGuI
z&S&_g=q0#-fuSNtP}l!>UEuUb>)(NQS<O!P0^MR2ae8OSli;kn?ue+feu9T|0~r_|
zd=$BMYsr>{2Q~b@&xzZo+8U+-S^S>uHLHxvDDTZSotJxlEz-ZX=5@=O4@Ocee89aI
ztNZi+eJX!H?F6L%!oYB+>;3)x*0$N6t%oj8UCS1f-C1LCFhiC3dtb@jWg6}lIxio5
zoK|x}XGZ`FZ)m27=?$i*<!|S{{{H^{r?<Dw-^cyCd+FPzwJ#sc@a4Zfi?8qImphlX
z&6~yh>1+1xN1zSiKd%(}K@Lk0IpuP`cN@>~+v}{BOY83mXp`V)WjK(0^5#mec~5JD
zCdRE)Xbtk$65gL}U~ul$&)7AeW?SDoIq%-7uvg5-9&@m1IDtpMA=xa~>2juY*O%~y
z+lFCB-{ovRv+><7or_$o3<v&N3(VWH^?2^xmp-L`0)5#QUS?B}S{uN?a7Q2OqIw0s
zsD%s+JN(-|q?|0eH_fd;XQJ_p>P-746%LRlap;KTf&N=A%aSF-PJdJO=wblbW6+|$
z_svO{C2<pe1*ByBkG~LS^Zv*bk8|&jC4-vz+ut5&`1qmpUC_RDcbgZ8f(EhEc>Jr>
z^8d$p-PT;1ealvYNrZu6`)PrB%Z%h+eSO`e>%YY=R)`U#GKItc{G|;2C*7ZgmVj-0
zYgl%B>ZwO@YOQ&@LoypKb%LCbYfyIk@0-vU+fGlAUjRzYPo(dbSw1R%%*fF2$I2j~
z#&7#w(ToPrJ}5tK5e5d!)SSv&w#S9<mPP)0J^z2fKXnI2h6(n^rY%3`*Db8;AGw&D
zpP`|q>;5N`Oz*A#o2M=3`KWEf!0_p~z&s@z^Cg#ld!7zH1`3uZ-hV!90j>KJzNrK<
zL;mA&o2gYwCAVXFLGG{Vuzz-PUfSJ7-!0a)f?QhKdT8>?@UnkL*1uin89hIvk%{5K
zE~kelOX}3?AKCa<Iy5jbJgDO1k>KC%bn(>`a~2H-hE3@l{@RjPUMWp>Sbf=LNu2Zz
z@Gu|CwsRA=Y?HdO#H`{B_lL~alfe$qb*|WyVwvx)e8c_woeAG+GVLcVTUi3yq*4~K
z`PZfu@)>WTa~g8OAQ!%Yk0G8+h3tNqq+~liWUHqBuf_WwVeC<<j{&<VmBZil<+&~M
z^$ebQR(}MIABuoyFZPs*JO$5P1Ygg(FbTTmhrf@3mBFEmD_i!$6mhG2nRh09-F-XW
z;;jgzs@p2%u~zj{BD<yJl_je3*3ai(T9Ez;v^V8iEhxg?{rP|0{{O>2{0t0d_SOG?
z*Yn!%l)$_%)5}UDzpTyi?~&wib4|antJuA1_5$dHg~aWZ3$^?$KTd$}7dV;mdh&gt
zsZ)!$nP=x@Tjga&i<Zvj+h%HeCD+RDEL&Ti_4gWo`AfITZp;3Dd0SNkvSzifII8wk
zM%={Z0cu)h>9gY*qW)&BdGN)<#NuKtJA*?N&%=|VJX)`h-QWw%od5bHUoNPIEQ`?o
zy2R+C|EZO_iF4Am^gwC*rKQBYE!{bnKP^d~xXI%1kI%o=Hsl_+%JjbRZ<pzvi?2j_
zK_O(t^YEnY?j3x`?rpJo+jHyKS_KD2hJr};<2Dyp72mdKWn^HOUcTWr-}Zh`N=g-+
zC&vJa!PAO1wj3Z^rWY#M>})>vb$Z#{mGd@iQfof(`pm;Hfdvc<7V{NtG9xZ^-&~8b
zjpo5LP;qO~uV@pwY0mbgf;QHT#oyj9{mYRj3o`gJJZUWdG7mDm{6G$DT(6>y=u+$1
z9ap%6<hyv@{^!2c{XAxa`1dA|H;URmENMP^{L+W>dhdKBV`j0=R0idY9z~mn6G6H=
z&I`<&xAY=kZ{?v_kc>e8#@l&s`b$5Z`})LB_P5|2ZQcMYki!g&x7oaGZQTBNuEh5*
z8KB(eVr}p&v%0M?YOWl&ZU6(r49P>6zwtbt9j0zu?AUAEV=rXyAh?Ku;f7Jm@($x3
zd-Ek{C6CGXv1zzAFfklR<?x@AC=(4zz}t8pW>&X-JUc`EoWZ{fO^-o^MuU49Xb+Eg
z`JYRCTbvjf3KVQw>vE4L6jpEqFf_QQarg`F-&P&#)ycr>zd`!FfBnzh=Hd(uztcJV
z!~bl(yJd6c+gC30BD|Vo7r5$FDW<f9X)qjEY}lgy{Z?6ivxD{If4A1%^{Bja8QiId
zp8W7z{aFmCOYgHs%+UK+_b$a0MeX{(pXFzVflB!Y_aqNZuFl<ExqeIT!<E+JyFb5M
zUb5{YbR=f}7syCV_=@=(Zp=OT>u!I6Yh`9ws$d*PxTCfR!vjHy=y{9Q=RWt>{QK!#
z)Tuq6p3LQ2r~z8O$Nx>(?`isarS-9X3nqvk+!)ZJ!EnG<>qcV6+q?VhK=o%%)HHBQ
zKl`SM$=eI@%=<iV&hj*{&OANiBzRlti7xvYF}uGpFr1hSsyBO`JfCXYK&wsl$5$F3
zo|`+j;K_xjUa%qbPa#*F>;C`Ky}z&a^Sh_<bKZW9UifF--t3)Accn&OcD}o;IoFrJ
zbar3x=EjA$-+6WU2hHq%65MXE7Imon&{x*u&KKvhGweuR_(8<V@Y%g7mmEI!rdQ4f
zPZx%QrVIPmUV2+}-S+Rz$vb(L%H3EO^&!0Rgl@f!Nb({EhV42c^R_V`RnMJR_CaOl
zxt=Zlp$XM>_tz9#U-R64nm6eD`^MZ)%OrgR%-g4FFdSHGRj{h5V{!`Lan0>E4=1{8
z1<wywro$$2)l_Xg(?EO1V&ojT7z(s`9<J25d(&mfKH2b)3hnNvf4KNOrpqq^P5n+V
zZ~L&sN&S?Hg<>*jCi&9~hl*SOKCLspTC8`qMSknUD2^b8hCK!?>b%~i6FYyewq7p%
zezE4_YX|CBcIZLolr|-B_)pV$zA*l_rTT`LTm1|_1tD`uVmzQdDi6(Mxq=xOVh%NC
z-+nn`Ip~-trQDen>Z|s+T9uuSxH9MAEbo^FtQx$Ll}EO&xr7|*j{Ed@<|rKsuFCt{
zZzZ$plhCq?%|86drR2iA-P!TC`A)=bnC-tjAw0f-iNWFGrzy@g%3kL!Z&ztJEWH?Y
z)cow1fbB06z%lyxN{#@R|HDGR#O>DaIzLR2`?rFhUAxq4$D%l-2<L8H{@b;}i@*NL
z@wu0>T=y<(-{s4GdzRcQGg<MRN-6K;yAujixJ7jRBOmlz*;d}Uw&U^2OE0AMi1gk3
zvH{%SI<K3nt?TbDFz?b~`BJMxw`Y}HsG648oor^ClWk>@cDdO5cGbga%WvDxpUnAC
z)Amo`^2c{_&l=?vo>|tO>&t#Trz$TqI+)XcwWDvH-PtF9`6h`#lqtW?^_AMjcd}S~
z@goZlsH4E+urD9>Tgh(UvvxX9(mroCqrT>n4QpR6%)9Ie9&eTVx8m}_ZSTC4C$K)<
zy0z!Ag6#G!YrA&&9%nr){Je6P*}oN+4{uxcSg!Bpmcuu9e!3^R$|4OEB9EOOzN{03
zc;m*kFL#peKC`_O8zkm9G1<&^`<Ar`t8=oeR@^R$$%>ZO)Ua!^**@!@f5oh_B?0Bu
ze77f;eyLb(ak>Q*9_)cuH?E<?$Ory=|1Axt`qe7dX6t6J*6*%5K2KN-JX%}wMB4_v
zrLO&bVXwt$&`|~|@efae3K5lA-EUG<K&6Q8^K)U)f!Fnh{#Mg6?@ZWg-jR7r^TZB8
zsmmoPl5h93FfepHo+2@2{RhzAbk$FWue}1pj0)a+T+dA_IvS~VNS9Y)|I*yhE4gUy
z%sm^vJr+6)C$S8&2#>3M5yUA^-26f}RNtKOB9%{h>vBYTfrQGOU2Es47`Oje><4X$
zLsN-zPWHKTpIJ)1>o06?+vUst6`aPdWLL>8%mbe&!D-_II#S|*>IKL!FKGP??9jLG
z^7FpT321FHE?sud=E#!tg7VkrW;TgttO|c+z47V-wXKd1UR}HLHgb#I->OG5_UgR)
zcIk^uo9yrV4NFQrWu;qQe>*fk-74WvoiF%ot7)~DU#(w#Y1?xJz18utuOmJ7R==(b
zz4k6PcyG}CPRp+<uU7?UcI~q5zUI3%Uw-X5*}j|Ji}Lh+Ub|o06s+(0dXiP&w)pMS
z|Jm$*KMgiAe|kG~arpyoJ3j5Q^x517x4%DG8acH!Y{AO7mG4{L<U4_m`YEgV6u3P-
zvbN7<mj1VktGX`DtqfOK5EmRUwdmx({#~|>+nQd48mlGMpU78T>;1~YspM|lug`Dx
z9iF^(3g~1Vw_lLnn8HTTK<|^#^#^i5p)m340@cOO+W%-&8;g`yi-C`}@j9EGb>HM{
z@cQT4kfU#2nH4yez52!?^=9wsURJR2O$+nN=lric)=+q4LGAJUplyA!6FPEDCtO>h
zDSvJ`zh0)rCj0Bxv!Cl67hY-1_avy~PkWl$^1Qhsu6G}?#XbW$EEuvaNjF#fXH>=6
zGacvuO;~TqKI^+~@XS|JfA#t9p8o9fyeV(;KQ6r&^K9=V>x?<OY@>f~eO()UCF}F7
zXDhF7Ub{~$h_|eB-?mhXZI^{ht1Ur6?Dwo`e)@OWdC<DZdp~4*TFu3NfBr3(g5s_>
zGW&upIQz2xdz3qPX`6Ri)X6JvBj-uqW8ZcB<+00Mi{j3QK@Q%iopIy-{o~FnUoGc^
zTG03Y()@I*tUv2~Z&m%2Ouxmm#a(Cew&?tWnV(l1fK$TD^$y$iZ`&NWJ-x6l^zl{U
zuT_!O?>P^iT9oI%Wd94UzfO9Yu|db#c9&MaJa4=Xa+nG;Xnz~A$6#R@KPxa^Hn-^t
zTh-EY9GCk<xL7r>ux+~3-SF!FJ!k80a?#+$4F9ViSX!4<R@;8tWpz7SfVo1UMV(>$
zK|b63OVgjdST14g4c-PN6dMt@eukcJ<<I?le!Gh<wT?c$<n3M74+R|l40(sXr2A|2
zuG?cGZsd32(PpVDO9~crW_-02%G~#cW!>E8KXjv7`*_~`++xP4V8ghBF<6rS_N59j
z&3z`RAH|kepG{+*Kdt7(ue)`N8n<3~Bhuk#eSRkNaF?&U6i?r~6U%nMS=om1#NMk9
ze8v9CKXO@+6dtE-`?GQlYsS6FL9tJ^R<98DcaC(O_s8|ndGPs#BIePy-p%W*7|ad{
zH_VxR>ioSs=S)@C|6Zf;b>WE*5wC-{>QDaXbkB$R%+(T|!)1qgQ?<?&GuYUG27im0
z&beI6erxqv-TRl(r1Q#>%dgZ<^;)kwtM$wDs)rxFE`JQTbxT}Apr#MhzxaNA@!F7I
z_6_dt6-*P7wI%m-`g}X4Bf9i=)Wmxi_w7!voPXo=R<@w5EvXUu9t*EbKDGLvQa<ST
z$0^?T7D?ZJzUI$u)!dI#-4}A%4}@*le{}8M+YAM}zl0Y)K6dcn!{--2TW@u-OIzf;
zXp3t0oe1x&)yxy3K_j;Ehj&#^@_GO6=dw#5k41`dsY;sKzj^Rvo=WiXSjGyUEjHlO
h)4+R>a+LntbC{{szLI>snt_3V!PC{xWt~$(69AdEuE+oY

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_pearsonIV.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_lorentzian_pearsonIV.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e2bd9ba2828829949ce93b782235b153898fd0d
GIT binary patch
literal 21520
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_pearson_iv.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_dubinin_pearson_iv.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f17b3e8161102445ff6ce3b947e90759e5d9899
GIT binary patch
literal 52427
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_freundlich.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_freundlich.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f299db167df9c1cafd3d80f3248ff609435ca79
GIT binary patch
literal 37153
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
P3=9mOu6{1-oD!M<0<Qm-

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_gab.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_gab.png
new file mode 100644
index 0000000000000000000000000000000000000000..92fb15db27d09e5d9c314b03dfc51f58c3644e68
GIT binary patch
literal 79581
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
BU(o;n

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_henry.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_henry.png
new file mode 100644
index 0000000000000000000000000000000000000000..71823a5f63385f42d3b1136aaa489eb5b19bff8f
GIT binary patch
literal 14254
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_langmuir.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_langmuir.png
new file mode 100644
index 0000000000000000000000000000000000000000..4d463892ae0b4a2157b18c11ed64272323a6f123
GIT binary patch
literal 21480
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
X?V`f!y{ejlfq}u()z4*}Q$iB}e>_mL

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_sips.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_sips.png
new file mode 100644
index 0000000000000000000000000000000000000000..72933bf168a5b2bcefb373decd81dcb091ffe682
GIT binary patch
literal 18103
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/media_functions_equilibria_pure_toth.png b/SorpLib/Resources/doc/media_functions_equilibria_pure_toth.png
new file mode 100644
index 0000000000000000000000000000000000000000..443dcbc98fddfa787c1f492e4fa3eab5db96832e
GIT binary patch
literal 17915
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/numerics_regSquare.png b/SorpLib/Resources/doc/numerics_regSquare.png
new file mode 100644
index 0000000000000000000000000000000000000000..f7e5216ae2ead2e1511131ea0315e7233a700985
GIT binary patch
literal 45331
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
So;w2r1B0ilpUXO@geCw-usTTq

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/numerics_regSquareWFactors.png b/SorpLib/Resources/doc/numerics_regSquareWFactors.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b3775a461c6e97d120735dce096be32f9b6054b
GIT binary patch
literal 50146
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/numerics_regStep.png b/SorpLib/Resources/doc/numerics_regStep.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc31392e2a9422431cb6e27643b4bc8320a10518
GIT binary patch
literal 38218
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

literal 0
HcmV?d00001

diff --git a/SorpLib/Resources/doc/numerics_smoothTransition.png b/SorpLib/Resources/doc/numerics_smoothTransition.png
new file mode 100644
index 0000000000000000000000000000000000000000..127eef46e416ba32a5542484e91f8adb640766e5
GIT binary patch
literal 25665
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
C^bCRk

literal 0
HcmV?d00001

diff --git a/SorpLib/Scripts/libraryinfo.mos b/SorpLib/Scripts/libraryinfo.mos
deleted file mode 100644
index 1ba846c..0000000
--- a/SorpLib/Scripts/libraryinfo.mos
+++ /dev/null
@@ -1,13 +0,0 @@
-LibraryInfoMenuSeparator(
-  category="libraries",
-  pos=170);
-
-LibraryInfoMenuCommand(
-  category = "libraries",
-  text = "SorpLib",
-  reference = "SorpLib",
-  version="0.1",
-  isModel = true,
-  description = "Modeling adsorption energy systems",
-  ModelicaVersion = ">= 3.2",
-  pos = 171);
\ No newline at end of file
diff --git a/SorpLib/Units/AdsorptionPotential.mo b/SorpLib/Units/AdsorptionPotential.mo
new file mode 100644
index 0000000..cb80947
--- /dev/null
+++ b/SorpLib/Units/AdsorptionPotential.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type AdsorptionPotential =Real (
+  final quantity="AdsorptionPotential",
+  final unit="J/kg",
+  displayUnit="kJ/kg",
+  min=0) "Adsorption potential";
diff --git a/SorpLib/Units/DerDensityByTemperature.mo b/SorpLib/Units/DerDensityByTemperature.mo
new file mode 100644
index 0000000..5232886
--- /dev/null
+++ b/SorpLib/Units/DerDensityByTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerDensityByTemperature = Real (
+  final quantity="DerDensityByTemperature",
+  final unit="kg/(m3.K)",
+  displayUnit="kg/(m3.K)")
+  "First-order partial derivative of the density w.r.t. the temperature";
diff --git a/SorpLib/Units/DerDensityByTemperatureTemperature.mo b/SorpLib/Units/DerDensityByTemperatureTemperature.mo
new file mode 100644
index 0000000..c197351
--- /dev/null
+++ b/SorpLib/Units/DerDensityByTemperatureTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerDensityByTemperatureTemperature = Real (
+  final quantity="DerDensityByTemperatureTemperature",
+  final unit="kg/(m3.K2)",
+  displayUnit="kg/(m3.K2)")
+  "Second-order partial derivative of the density w.r.t. the temperature";
diff --git a/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotential.mo b/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotential.mo
new file mode 100644
index 0000000..89c07e7
--- /dev/null
+++ b/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotential.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerFilledPoreVolumeByAdsorptionPotential = Real (
+  final quantity="DerFilledPoreVolumeByAdsorptionPotential",
+  final unit="m3.mol/(kg.J)",
+  displayUnit="l.mol/(kg.kJ)")
+  "First-order partial derivative of the filled pore volume w.r.t. the adsorption 
+    potential";
diff --git a/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential.mo b/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential.mo
new file mode 100644
index 0000000..ec93ce5
--- /dev/null
+++ b/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential = Real (
+  final quantity="DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential",
+  final unit="m3.mol2/(kg.J2)",
+  displayUnit="l.mol2/(kg.kJ2)")
+  "Second-order partial derivative of the filled pore volume w.r.t. the adsorption 
+    potential";
diff --git a/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotentialTemperature.mo b/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotentialTemperature.mo
new file mode 100644
index 0000000..f13e30c
--- /dev/null
+++ b/SorpLib/Units/DerFilledPoreVolumeByAdsorptionPotentialTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerFilledPoreVolumeByAdsorptionPotentialTemperature = Real (
+  final quantity="DerFilledPoreVolumeByAdsorptionPotentialTemperature",
+  final unit="m3.mol/(kg.J.K)",
+  displayUnit="l.mol/(kg.kJ.K)")
+  "Second-order partial derivative of the filled pore volume w.r.t. the adsorption 
+  potential and temperature";
diff --git a/SorpLib/Units/DerFilledPoreVolumeByTemperature.mo b/SorpLib/Units/DerFilledPoreVolumeByTemperature.mo
new file mode 100644
index 0000000..a90aaa4
--- /dev/null
+++ b/SorpLib/Units/DerFilledPoreVolumeByTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerFilledPoreVolumeByTemperature = Real (
+  final quantity="DerFilledPoreVolumeByTemperature",
+  final unit="m3/(kg.K)",
+  displayUnit="l/(kg.K)")
+  "First-order partial derivative of the filled pore volume w.r.t. the 
+    temperature";
diff --git a/SorpLib/Units/DerIsobaricExpansionCoefficientByPressure.mo b/SorpLib/Units/DerIsobaricExpansionCoefficientByPressure.mo
new file mode 100644
index 0000000..d4eb14a
--- /dev/null
+++ b/SorpLib/Units/DerIsobaricExpansionCoefficientByPressure.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerIsobaricExpansionCoefficientByPressure = Real (
+  final quantity="DerIsobaricExpansionCoefficientByPressure",
+  final unit="1/(K.Pa)",
+  displayUnit="1/(K.Pa)")
+  "First-order partial derivative of the isobaric expansion coefficient w.r.t. 
+    the pressure";
diff --git a/SorpLib/Units/DerIsobaricExpansionCoefficientByTemperature.mo b/SorpLib/Units/DerIsobaricExpansionCoefficientByTemperature.mo
new file mode 100644
index 0000000..12e9ed3
--- /dev/null
+++ b/SorpLib/Units/DerIsobaricExpansionCoefficientByTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerIsobaricExpansionCoefficientByTemperature = Real (
+  final quantity="DerIsobaricExpansionCoefficientByTemperature",
+  final unit="1/(K2)",
+  displayUnit="1/(K2)")
+  "First-order partial derivative of the isobaric expansion coefficient w.r.t. 
+    the temperature";
diff --git a/SorpLib/Units/DerMolarAdsorptionPotentialByPressure.mo b/SorpLib/Units/DerMolarAdsorptionPotentialByPressure.mo
new file mode 100644
index 0000000..ee89d94
--- /dev/null
+++ b/SorpLib/Units/DerMolarAdsorptionPotentialByPressure.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerMolarAdsorptionPotentialByPressure =Real (
+  final quantity="DerMolarAdsorptionPotentialByPressure",
+  final unit="J/(mol.Pa)",
+  displayUnit="kJ/(mol.Pa)")
+  "First-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure";
diff --git a/SorpLib/Units/DerMolarAdsorptionPotentialByPressurePressure.mo b/SorpLib/Units/DerMolarAdsorptionPotentialByPressurePressure.mo
new file mode 100644
index 0000000..47211e7
--- /dev/null
+++ b/SorpLib/Units/DerMolarAdsorptionPotentialByPressurePressure.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerMolarAdsorptionPotentialByPressurePressure = Real (
+  final quantity="DerMolarAdsorptionPotentialByPressurePressure",
+  final unit="J/(mol.Pa2)",
+  displayUnit="kJ/(mol.Pa2)")
+  "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    pressure";
diff --git a/SorpLib/Units/DerMolarAdsorptionPotentialByPressureTemperature.mo b/SorpLib/Units/DerMolarAdsorptionPotentialByPressureTemperature.mo
new file mode 100644
index 0000000..5c87146
--- /dev/null
+++ b/SorpLib/Units/DerMolarAdsorptionPotentialByPressureTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerMolarAdsorptionPotentialByPressureTemperature = Real (
+  final quantity="DerMolarAdsorptionPotentialByPressureTemperature",
+  final unit="J/(mol.Pa.K)",
+  displayUnit="kJ/(mol.Pa.K)")
+  "Second-order partial derivative of the molar adsorption potential w.r.t. 
+  pressure and temperature";
diff --git a/SorpLib/Units/DerMolarAdsorptionPotentialByTemperature.mo b/SorpLib/Units/DerMolarAdsorptionPotentialByTemperature.mo
new file mode 100644
index 0000000..0281c02
--- /dev/null
+++ b/SorpLib/Units/DerMolarAdsorptionPotentialByTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerMolarAdsorptionPotentialByTemperature =Real (
+  final quantity="DerMolarAdsorptionPotentialByTemperature",
+  final unit="J/(mol.K)",
+  displayUnit="kJ/(mol.K)")
+  "First-order partial derivative of the molar adsorption potential w.r.t. 
+    temperature";
diff --git a/SorpLib/Units/DerMolarAdsorptionPotentialByTemperatureTemperature.mo b/SorpLib/Units/DerMolarAdsorptionPotentialByTemperatureTemperature.mo
new file mode 100644
index 0000000..a80dffe
--- /dev/null
+++ b/SorpLib/Units/DerMolarAdsorptionPotentialByTemperatureTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerMolarAdsorptionPotentialByTemperatureTemperature = Real (
+  final quantity="DerMolarAdsorptionPotentialByTemperatureTemperature",
+  final unit="J/(mol.K2)",
+  displayUnit="kJ/(mol.K2)")
+  "Second-order partial derivative of the molar adsorption potential w.r.t. 
+    temperature";
diff --git a/SorpLib/Units/DerMolarEnthalpyByPressure.mo b/SorpLib/Units/DerMolarEnthalpyByPressure.mo
new file mode 100644
index 0000000..0489458
--- /dev/null
+++ b/SorpLib/Units/DerMolarEnthalpyByPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerMolarEnthalpyByPressure =  Real (
+  final quantity="DerMolarEnthalpyByPressure",
+  final unit="J/(mol.Pa)",
+  displayUnit="kJ/(mol.Pa)")
+  "First-order partial derivative of the molar enthalpy w.r.t. the presssure";
diff --git a/SorpLib/Units/DerMolarEnthalpyByUptake.mo b/SorpLib/Units/DerMolarEnthalpyByUptake.mo
new file mode 100644
index 0000000..9245d41
--- /dev/null
+++ b/SorpLib/Units/DerMolarEnthalpyByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerMolarEnthalpyByUptake =    Real (
+  final quantity="DerMolarEnthalpyByUptake",
+  final unit="J.kg/(mol.kg)",
+  displayUnit="kJ.kg/(mol.kg)")
+  "First-order partial derivative of the molar enthalpy w.r.t. the uptake";
diff --git a/SorpLib/Units/DerPressureByTemperatureTemperature.mo b/SorpLib/Units/DerPressureByTemperatureTemperature.mo
new file mode 100644
index 0000000..18a8c62
--- /dev/null
+++ b/SorpLib/Units/DerPressureByTemperatureTemperature.mo
@@ -0,0 +1,5 @@
+within SorpLib.Units;
+type DerPressureByTemperatureTemperature = Real (
+  final quantity="DerPressureByTemperatureTemperature",
+  final unit="Pa/(K2)")
+  "Second-order partial derivative of the pressure w.r.t. the temperature";
diff --git a/SorpLib/Units/DerPressureByUptake.mo b/SorpLib/Units/DerPressureByUptake.mo
new file mode 100644
index 0000000..e81088c
--- /dev/null
+++ b/SorpLib/Units/DerPressureByUptake.mo
@@ -0,0 +1,5 @@
+within SorpLib.Units;
+type DerPressureByUptake = Real (
+  final quantity="DerPressureByUptake",
+  final unit="Pa.kg/(kg)")
+  "First-order partial derivative of the pressure w.r.t. the uptake";
diff --git a/SorpLib/Units/DerSpecificEnthalpyByPressure.mo b/SorpLib/Units/DerSpecificEnthalpyByPressure.mo
new file mode 100644
index 0000000..f0196bf
--- /dev/null
+++ b/SorpLib/Units/DerSpecificEnthalpyByPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificEnthalpyByPressure = Real (
+  final quantity="DerSpecificEnthalpyByPressure",
+  final unit="J/(kg.Pa)",
+  displayUnit="kJ/(kg.Pa)")
+  "First-order partial derivative of specific enthalpy w.r.t. pressure";
diff --git a/SorpLib/Units/DerSpecificEnthalpyByUptake.mo b/SorpLib/Units/DerSpecificEnthalpyByUptake.mo
new file mode 100644
index 0000000..f622bcb
--- /dev/null
+++ b/SorpLib/Units/DerSpecificEnthalpyByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificEnthalpyByUptake = Real (
+  final quantity="DerSpecificEnthalpyByUptake",
+  final unit="J.kg/(kg.kg)",
+  displayUnit="kJ.kg/(kg.kg)")
+  "First-order partial derivative of specific enthalpy w.r.t. uptake";
diff --git a/SorpLib/Units/DerSpecificEntropyByPressure.mo b/SorpLib/Units/DerSpecificEntropyByPressure.mo
new file mode 100644
index 0000000..c445a37
--- /dev/null
+++ b/SorpLib/Units/DerSpecificEntropyByPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificEntropyByPressure = Real (
+  final quantity="DerSpecificEntropyByPressure",
+  final unit="J/(kg.K.Pa)",
+  displayUnit="kJ/(kg.K.Pa)")
+  "First-order partial derivative of specific entropy w.r.t. pressure";
diff --git a/SorpLib/Units/DerSpecificEntropyByTemperature.mo b/SorpLib/Units/DerSpecificEntropyByTemperature.mo
new file mode 100644
index 0000000..16c6a12
--- /dev/null
+++ b/SorpLib/Units/DerSpecificEntropyByTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificEntropyByTemperature = Real (
+  final quantity="DerSpecificEntropyByTemperature",
+  final unit="J/(kg.K2)",
+  displayUnit="kJ/(kg.K2)")
+  "First-order partial derivative of specific temperature w.r.t. pressure";
diff --git a/SorpLib/Units/DerSpecificEntropyByUptake.mo b/SorpLib/Units/DerSpecificEntropyByUptake.mo
new file mode 100644
index 0000000..cffe4b1
--- /dev/null
+++ b/SorpLib/Units/DerSpecificEntropyByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificEntropyByUptake = Real (
+  final quantity="DerSpecificEntropyByUptake",
+  final unit="J.kg/(kg2.K)",
+  displayUnit="kJ.kg/(kg2.K)")
+  "First-order partial derivative of specific entropy w.r.t. uptake";
diff --git a/SorpLib/Units/DerSpecificHeatCapacityByTemperature.mo b/SorpLib/Units/DerSpecificHeatCapacityByTemperature.mo
new file mode 100644
index 0000000..cb1fb9f
--- /dev/null
+++ b/SorpLib/Units/DerSpecificHeatCapacityByTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerSpecificHeatCapacityByTemperature = Real (
+  final quantity="DerSpecificHeatCapacityByTemperature",
+  final unit="J/(kg.K2)",
+  displayUnit="kJ/(kg.K2)")
+  "First-order partial derivative of the specific heat capacity w.r.t. the 
+    temperature";
diff --git a/SorpLib/Units/DerSpecificHeatCapacityByTemperatureTemperature.mo b/SorpLib/Units/DerSpecificHeatCapacityByTemperatureTemperature.mo
new file mode 100644
index 0000000..7e396aa
--- /dev/null
+++ b/SorpLib/Units/DerSpecificHeatCapacityByTemperatureTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerSpecificHeatCapacityByTemperatureTemperature = Real (
+  final quantity="DerSpecificHeatCapacityByTemperature",
+  final unit="J/(kg.K3)",
+  displayUnit="kJ/(kg.K3)")
+  "Second-order partial derivative of the specific heat capacity w.r.t. the 
+    temperature";
diff --git a/SorpLib/Units/DerSpecificVolumeByPressure.mo b/SorpLib/Units/DerSpecificVolumeByPressure.mo
new file mode 100644
index 0000000..f246908
--- /dev/null
+++ b/SorpLib/Units/DerSpecificVolumeByPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificVolumeByPressure = Real (
+  final quantity="DerSpecificVolumeByPressure",
+  final unit="m3/(kg.Pa)",
+  displayUnit="m3/(kg.Pa)")
+  "First-order partial derivative of the specific volume w.r.t. the pressure";
diff --git a/SorpLib/Units/DerSpecificVolumeByPressureTemperature.mo b/SorpLib/Units/DerSpecificVolumeByPressureTemperature.mo
new file mode 100644
index 0000000..b668621
--- /dev/null
+++ b/SorpLib/Units/DerSpecificVolumeByPressureTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerSpecificVolumeByPressureTemperature = Real (
+  final quantity="DerSpecificVolumeByPressureTemperature",
+  final unit="m3/(kg.Pa.K)",
+  displayUnit="m3/(kg.Pa.K)")
+  "Second-order partial derivative of the specific volume w.r.t. the pressure 
+    and temperature";
diff --git a/SorpLib/Units/DerSpecificVolumeByTemperature.mo b/SorpLib/Units/DerSpecificVolumeByTemperature.mo
new file mode 100644
index 0000000..367188a
--- /dev/null
+++ b/SorpLib/Units/DerSpecificVolumeByTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificVolumeByTemperature = Real (
+  final quantity="DerSpecificVolumeByTemperature",
+  final unit="m3/(kg.K)",
+  displayUnit="m3/(kg.K)")
+  "First-order partial derivative of the specific volume w.r.t. the temperature";
diff --git a/SorpLib/Units/DerSpecificVolumeByTemperatureTemperature.mo b/SorpLib/Units/DerSpecificVolumeByTemperatureTemperature.mo
new file mode 100644
index 0000000..66f824f
--- /dev/null
+++ b/SorpLib/Units/DerSpecificVolumeByTemperatureTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificVolumeByTemperatureTemperature = Real (
+  final quantity="DerSpecificVolumeByTemperatureTemperature",
+  final unit="m3/(kg.K2)",
+  displayUnit="m3/(kg.K2)")
+  "Second-order partial derivative of the specific volume w.r.t. the temperature";
diff --git a/SorpLib/Units/DerSpecificVolumeByUptake.mo b/SorpLib/Units/DerSpecificVolumeByUptake.mo
new file mode 100644
index 0000000..53c1c67
--- /dev/null
+++ b/SorpLib/Units/DerSpecificVolumeByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerSpecificVolumeByUptake =   Real (
+  final quantity="DerSpecificVolumeByUptake",
+  final unit="m3.kg/(kg.kg)",
+  displayUnit="m3.kg/(kg.kg)")
+  "First-order partial derivative of the specific volume w.r.t. the uptake";
diff --git a/SorpLib/Units/DerThermalConductivityByTemperature.mo b/SorpLib/Units/DerThermalConductivityByTemperature.mo
new file mode 100644
index 0000000..027f039
--- /dev/null
+++ b/SorpLib/Units/DerThermalConductivityByTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerThermalConductivityByTemperature =  Real (
+  final quantity="DerThermalConductivityByTemperature",
+  final unit="W/(m.K2)",
+  displayUnit="W/(m.K2)")
+  "First-order partial derivative of the thermal conductivity w.r.t. the 
+    temperature";
diff --git a/SorpLib/Units/DerThermalConductivityByTemperatureTemperature.mo b/SorpLib/Units/DerThermalConductivityByTemperatureTemperature.mo
new file mode 100644
index 0000000..826d63f
--- /dev/null
+++ b/SorpLib/Units/DerThermalConductivityByTemperatureTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerThermalConductivityByTemperatureTemperature = Real (
+  final quantity="DerThermalConductivityByTemperature",
+  final unit="W/(m.K3)",
+  displayUnit="W/(m.K3)")
+  "Second-order partial derivative of the thermal conductivity w.r.t. the 
+    temperature";
diff --git a/SorpLib/Units/DerUptakeByMolarFraction.mo b/SorpLib/Units/DerUptakeByMolarFraction.mo
new file mode 100644
index 0000000..3233a45
--- /dev/null
+++ b/SorpLib/Units/DerUptakeByMolarFraction.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeByMolarFraction = Real (
+  final quantity="DerUptakeByMolarFraction",
+  final unit="kg.mol/(kg.mol)",
+  displayUnit="kg.mol/(kg.mol)")
+  "First-order partial derivative of the uptake w.r.t. molar fraction";
diff --git a/SorpLib/Units/DerUptakeByPressure.mo b/SorpLib/Units/DerUptakeByPressure.mo
new file mode 100644
index 0000000..cf8bced
--- /dev/null
+++ b/SorpLib/Units/DerUptakeByPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeByPressure = Real (
+  final quantity="DerUptakeByPressure",
+  final unit="kg/(kg.Pa)",
+  displayUnit="kg/(kg.Pa)")
+  "First-order partial derivative of the uptake w.r.t. pressure";
diff --git a/SorpLib/Units/DerUptakeByPressurePressure.mo b/SorpLib/Units/DerUptakeByPressurePressure.mo
new file mode 100644
index 0000000..7fb7df7
--- /dev/null
+++ b/SorpLib/Units/DerUptakeByPressurePressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeByPressurePressure = Real (
+  final quantity="DerUptakeByPressurePressure",
+  final unit="kg/(kg.Pa2)",
+  displayUnit="kg/(kg.Pa2)")
+  "Second-order partial derivative of the uptake w.r.t. pressure";
diff --git a/SorpLib/Units/DerUptakeByPressureTemperature.mo b/SorpLib/Units/DerUptakeByPressureTemperature.mo
new file mode 100644
index 0000000..5b6796f
--- /dev/null
+++ b/SorpLib/Units/DerUptakeByPressureTemperature.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type DerUptakeByPressureTemperature = Real (
+  final quantity="DerUptakeByPressureTemperature",
+  final unit="kg/(kg.Pa.K)",
+  displayUnit="kg/(kg.Pa.K)")
+  "Second-order partial derivative of the uptake w.r.t. pressure and 
+    temperature";
diff --git a/SorpLib/Units/DerUptakeByTemperature.mo b/SorpLib/Units/DerUptakeByTemperature.mo
new file mode 100644
index 0000000..1d3c45b
--- /dev/null
+++ b/SorpLib/Units/DerUptakeByTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeByTemperature = Real (
+  final quantity="DerUptakeByTemperature",
+  final unit="kg/(kg.K)",
+  displayUnit="kg/(kg.K)")
+  "First-order partial derivative of the uptake w.r.t. temperature";
diff --git a/SorpLib/Units/DerUptakeByTemperatureTemperature.mo b/SorpLib/Units/DerUptakeByTemperatureTemperature.mo
new file mode 100644
index 0000000..8dab74c
--- /dev/null
+++ b/SorpLib/Units/DerUptakeByTemperatureTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeByTemperatureTemperature = Real (
+  final quantity="DerUptakeByTemperatureTemperature",
+  final unit="kg/(kg.K2)",
+  displayUnit="kg/(kg.K2)")
+  "Second-order partial derivative of the uptake w.r.t. temperature";
diff --git a/SorpLib/Units/DerUptakeSpecificEnthalpyByPressure.mo b/SorpLib/Units/DerUptakeSpecificEnthalpyByPressure.mo
new file mode 100644
index 0000000..936c4fa
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificEnthalpyByPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificEnthalpyByPressure = Real (
+  final quantity="DerUptakeSpecificEnthalpyByPressure",
+  final unit="J.kg/(kg.kg.Pa)",
+  displayUnit="kJ.kg/(kg.kg.Pa)")
+  "First-order partial derivative of specific enthalpy times the uptake w.r.t. pressure";
diff --git a/SorpLib/Units/DerUptakeSpecificEnthalpyByTemperature.mo b/SorpLib/Units/DerUptakeSpecificEnthalpyByTemperature.mo
new file mode 100644
index 0000000..793a7c2
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificEnthalpyByTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificEnthalpyByTemperature = Real (
+  final quantity="DerUptakeSpecificEnthalpyByTemperature",
+  final unit="J.kg/(kg.kg.K)",
+  displayUnit="kJ.kg/(kg.kg.K)")
+  "First-order partial derivative of specific enthalpy times the uptake w.r.t. temperature";
diff --git a/SorpLib/Units/DerUptakeSpecificEnthalpyByUptake.mo b/SorpLib/Units/DerUptakeSpecificEnthalpyByUptake.mo
new file mode 100644
index 0000000..74de2dd
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificEnthalpyByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificEnthalpyByUptake = Real (
+  final quantity="DerUptakeSpecificEnthalpyByUptake",
+  final unit="J.kg.kg/(kg.kg.kg)",
+  displayUnit="kJ.kg.kg/(kg.kg.kg)")
+  "First-order partial derivative of specific enthalpy time the uptake w.r.t. uptake";
diff --git a/SorpLib/Units/DerUptakeSpecificEntropyByPressure.mo b/SorpLib/Units/DerUptakeSpecificEntropyByPressure.mo
new file mode 100644
index 0000000..541bc9e
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificEntropyByPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificEntropyByPressure = Real (
+  final quantity="DerUptakeSpecificEntropyByPressure",
+  final unit="J.kg/(kg.kg.K.Pa)",
+  displayUnit="kJ.kg/(kg.kg.K.Pa)")
+  "First-order partial derivative of specific entropy times the uptake w.r.t. pressure";
diff --git a/SorpLib/Units/DerUptakeSpecificEntropyByTemperature.mo b/SorpLib/Units/DerUptakeSpecificEntropyByTemperature.mo
new file mode 100644
index 0000000..b98612b
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificEntropyByTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificEntropyByTemperature = Real (
+  final quantity="DerUptakeSpecificEntropyByTemperature",
+  final unit="J.kg/(kg.kg.K2)",
+  displayUnit="kJ.kg/(kg.kg.K2)")
+  "First-order partial derivative of specific temperature times the uptake w.r.t. pressure";
diff --git a/SorpLib/Units/DerUptakeSpecificEntropyByUptake.mo b/SorpLib/Units/DerUptakeSpecificEntropyByUptake.mo
new file mode 100644
index 0000000..97856af
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificEntropyByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificEntropyByUptake = Real (
+  final quantity="DerUptakeSpecificEntropyByUptake",
+  final unit="J.kg.kg/(kg2.kg.K)",
+  displayUnit="kJ.kg.kg/(kg2.kg.K)")
+  "First-order partial derivative of specific entropy times the uptake w.r.t. uptake";
diff --git a/SorpLib/Units/DerUptakeSpecificVolumeByPressure.mo b/SorpLib/Units/DerUptakeSpecificVolumeByPressure.mo
new file mode 100644
index 0000000..8b4bc87
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificVolumeByPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificVolumeByPressure = Real (
+  final quantity="DerUptakeSpecificVolumeByPressure",
+  final unit="m3.kg/(kg.kg.Pa)",
+  displayUnit="m3.kg/(kg.kg.Pa)")
+  "First-order partial derivative of the specific volume time the uptake w.r.t. the pressure";
diff --git a/SorpLib/Units/DerUptakeSpecificVolumeByTemperature.mo b/SorpLib/Units/DerUptakeSpecificVolumeByTemperature.mo
new file mode 100644
index 0000000..95bda8d
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificVolumeByTemperature.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificVolumeByTemperature = Real (
+  final quantity="DerUptakeSpecificVolumeByTemperature",
+  final unit="m3.kg/(kg.kg.K)",
+  displayUnit="m3.kg/(kg.kg.K)")
+  "First-order partial derivative of the specific volume time the uptake w.r.t. the temperature";
diff --git a/SorpLib/Units/DerUptakeSpecificVolumeByUptake.mo b/SorpLib/Units/DerUptakeSpecificVolumeByUptake.mo
new file mode 100644
index 0000000..ee38302
--- /dev/null
+++ b/SorpLib/Units/DerUptakeSpecificVolumeByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type DerUptakeSpecificVolumeByUptake = Real (
+  final quantity="DerUptakeSpecificVolumeByUptake",
+  final unit="m3.kg.kg/(kg.kg.kg)",
+  displayUnit="m3.kg.kg/(kg.kg.kg)")
+  "First-order partial derivative of the specific volume time the uptake w.r.t. the uptake";
diff --git a/SorpLib/Units/FilledPoreVolume.mo b/SorpLib/Units/FilledPoreVolume.mo
new file mode 100644
index 0000000..8216ff5
--- /dev/null
+++ b/SorpLib/Units/FilledPoreVolume.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type FilledPoreVolume = Real (
+  final quantity="FilledPoreVolume",
+  final unit="m3/kg",
+  displayUnit="l/kg",
+  min=0)
+  "Filled pore volume";
diff --git a/SorpLib/Units/IntegralMolarHeatCapacityByUptake.mo b/SorpLib/Units/IntegralMolarHeatCapacityByUptake.mo
new file mode 100644
index 0000000..6550434
--- /dev/null
+++ b/SorpLib/Units/IntegralMolarHeatCapacityByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type IntegralMolarHeatCapacityByUptake=Real (
+  final quantity="IntegralMolarHeatCapacityByUptake",
+  final unit="J.kg/(mol.kg.K)",
+  displayUnit="kJ.kg/(mol.kg.K)")
+  "Integral of the molar heat capacity w.r.t. the uptake";
diff --git a/SorpLib/Units/IntegralSpecificHeatCapacityByUptake.mo b/SorpLib/Units/IntegralSpecificHeatCapacityByUptake.mo
new file mode 100644
index 0000000..495dc02
--- /dev/null
+++ b/SorpLib/Units/IntegralSpecificHeatCapacityByUptake.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type IntegralSpecificHeatCapacityByUptake = Real (
+  final quantity="IntegralSpecificHeatCapacityByUptake",
+  final unit="J/(kg.K)",
+  displayUnit="kJ/(kg.K)")
+  "Integral of the specific heat capacity w.r.t. the uptake";
diff --git a/SorpLib/Units/MolarAdsorptionPotential.mo b/SorpLib/Units/MolarAdsorptionPotential.mo
new file mode 100644
index 0000000..9a8a8db
--- /dev/null
+++ b/SorpLib/Units/MolarAdsorptionPotential.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type MolarAdsorptionPotential =Real (
+  final quantity="MolarAdsorptionPotential",
+  final unit="J/mol",
+  displayUnit="kJ/mol",
+  min=0) "Molar adsorption potential";
diff --git a/SorpLib/Units/MolarUptake.mo b/SorpLib/Units/MolarUptake.mo
new file mode 100644
index 0000000..1b38f38
--- /dev/null
+++ b/SorpLib/Units/MolarUptake.mo
@@ -0,0 +1,7 @@
+within SorpLib.Units;
+type MolarUptake = Real (
+  final quantity="MolarUptake",
+  final unit="mol/kg",
+  displayUnit="mol/kg",
+  min=0,
+  nominal=0.5) "Equilibrium molar uptake";
diff --git a/SorpLib/Units/ReducedSpreadingPressure.mo b/SorpLib/Units/ReducedSpreadingPressure.mo
new file mode 100644
index 0000000..fcc2c2c
--- /dev/null
+++ b/SorpLib/Units/ReducedSpreadingPressure.mo
@@ -0,0 +1,6 @@
+within SorpLib.Units;
+type ReducedSpreadingPressure = Real (
+  final quantity="ReducedSpreadingPressure",
+  final unit="mol/kg",
+  displayUnit="mol/kg")
+  "Reduced spreading pressure";
diff --git a/SorpLib/Units/Uptake.mo b/SorpLib/Units/Uptake.mo
new file mode 100644
index 0000000..6262592
--- /dev/null
+++ b/SorpLib/Units/Uptake.mo
@@ -0,0 +1,8 @@
+within SorpLib.Units;
+type Uptake = Real (
+  final quantity="Uptake",
+  final unit="kg/kg",
+  displayUnit="kg/kg",
+  min=0,
+  nominal=0.5)
+  "Equilibrium uptake";
diff --git a/SorpLib/Units/package.mo b/SorpLib/Units/package.mo
new file mode 100644
index 0000000..9547cae
--- /dev/null
+++ b/SorpLib/Units/package.mo
@@ -0,0 +1,53 @@
+within SorpLib;
+package Units "Package containing definitions of units"
+extends Modelica.Icons.Package;
+
+annotation (Icon(graphics={
+      Polygon(
+        fillColor = {128,128,128},
+        pattern = LinePattern.None,
+        fillPattern = FillPattern.Solid,
+        points={{-84,-42},{-84,-42},{-59,48},{-56.5,60.5},{-69,58},{-69,63},{
+            -39,75.5},{-36.5,58},{-54,-2},{-54,-2},{-34,13},{-24,25.5},{-36.5,
+            25.5},{-36.5,25.5},{-36.5,30.5},{-36.5,30.5},{-1.5,30.5},{-1.5,30.5},
+            {-1.5,25.5},{-1.5,25.5},{-11.5,25.5},{-34,5.5},{-34,5.5},{-29,-27},
+            {-21.5,-30.75},{-14,-27},{-9,-28.25},{-9,-34.5},{-20.25,-43.25},{
+            -35.25,-45.75},{-44,-35.75},{-49,-7},{-49,-7},{-56.5,-12},{-56.5,
+            -12},{-64,-42},{-64,-42}},
+        smooth = Smooth.Bezier),
+      Polygon(
+        fillColor = {128,128,128},
+        pattern = LinePattern.None,
+        fillPattern = FillPattern.Solid,
+        points={{83.5,28},{58.5,28},{58.5,28},{51,31.75},{32.25,33},{12.25,23},
+            {3.5,4.25},{7.25,-9.5},{18.5,-14.5},{18.5,-14.5},{2.25,-24.5},{2.25,
+            -37},{12.25,-40.75},{12.25,-40.75},{17.25,-43.25},{17.25,-43.25},{
+            41,-50.75},{43.5,-63.25},{28.5,-72},{8.5,-67},{3.5,-53.25},{17.25,
+            -43.25},{17.25,-43.25},{12.25,-40.75},{12.25,-40.75},{2.25,-43.25},
+            {-10.25,-52},{-7.75,-70.75},{26,-78.25},{61,-64.5},{59.75,-37},{
+            23.5,-28.25},{18.5,-22},{23.5,-17},{23.5,-17},{26,-9.5},{26,-9.5},{
+            23.5,-4.5},{24.75,9.25},{32.25,25.5},{43.5,28},{49.75,20.5},{47.25,
+            6.75},{41,-8.25},{31,-13.25},{26,-9.5},{26,-9.5},{23.5,-17},{23.5,
+            -17},{39.75,-18.25},{61,-8.25},{68.5,8},{66,18},{66,18},{76,18}},
+        smooth = Smooth.Bezier)}), Documentation(revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>", info="<html>
+<p>
+This package contains definitions of types representing units used 
+within the Modelica library SorpLib. These types are used for type 
+checking (i.e., units) when implementing model equations. 
+</p>
+
+<h4>Adding new units</h4>
+<p>
+Before adding new units, please check if the unit is already 
+implemented in the 
+<a href=\"modelica://Modelica.Units\">Modelica standard library</a>.
+</p>
+</html>"));
+end Units;
diff --git a/SorpLib/Units/package.order b/SorpLib/Units/package.order
new file mode 100644
index 0000000..d737761
--- /dev/null
+++ b/SorpLib/Units/package.order
@@ -0,0 +1,54 @@
+MolarUptake
+Uptake
+DerUptakeByPressure
+DerUptakeByMolarFraction
+DerUptakeByTemperature
+DerUptakeByPressurePressure
+DerUptakeByTemperatureTemperature
+DerUptakeByPressureTemperature
+ReducedSpreadingPressure
+AdsorptionPotential
+MolarAdsorptionPotential
+DerMolarAdsorptionPotentialByPressure
+DerMolarAdsorptionPotentialByTemperature
+DerMolarAdsorptionPotentialByPressurePressure
+DerMolarAdsorptionPotentialByTemperatureTemperature
+DerMolarAdsorptionPotentialByPressureTemperature
+FilledPoreVolume
+DerFilledPoreVolumeByTemperature
+DerFilledPoreVolumeByAdsorptionPotential
+DerFilledPoreVolumeByAdsorptionPotentialAdsorptionPotential
+DerFilledPoreVolumeByAdsorptionPotentialTemperature
+DerPressureByUptake
+DerPressureByTemperatureTemperature
+DerDensityByTemperature
+DerDensityByTemperatureTemperature
+DerSpecificVolumeByUptake
+DerSpecificVolumeByPressure
+DerSpecificVolumeByTemperature
+DerSpecificVolumeByPressureTemperature
+DerSpecificVolumeByTemperatureTemperature
+DerSpecificEnthalpyByUptake
+DerSpecificEnthalpyByPressure
+DerMolarEnthalpyByPressure
+DerMolarEnthalpyByUptake
+DerSpecificEntropyByUptake
+DerSpecificEntropyByPressure
+DerSpecificEntropyByTemperature
+DerIsobaricExpansionCoefficientByPressure
+DerIsobaricExpansionCoefficientByTemperature
+DerSpecificHeatCapacityByTemperature
+DerSpecificHeatCapacityByTemperatureTemperature
+DerThermalConductivityByTemperature
+DerThermalConductivityByTemperatureTemperature
+IntegralMolarHeatCapacityByUptake
+IntegralSpecificHeatCapacityByUptake
+DerUptakeSpecificVolumeByUptake
+DerUptakeSpecificVolumeByPressure
+DerUptakeSpecificVolumeByTemperature
+DerUptakeSpecificEnthalpyByUptake
+DerUptakeSpecificEnthalpyByPressure
+DerUptakeSpecificEnthalpyByTemperature
+DerUptakeSpecificEntropyByUptake
+DerUptakeSpecificEntropyByPressure
+DerUptakeSpecificEntropyByTemperature
diff --git a/SorpLib/UsersGuide/Connectors/package.mo b/SorpLib/UsersGuide/Connectors/package.mo
new file mode 100644
index 0000000..a48db48
--- /dev/null
+++ b/SorpLib/UsersGuide/Connectors/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide;
+package Connectors "Connectors"
+extends Modelica.Icons.Information;
+end Connectors;
diff --git a/SorpLib/UsersGuide/Connectors/package.order b/SorpLib/UsersGuide/Connectors/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/UsersGuide/Contact/package.mo b/SorpLib/UsersGuide/Contact/package.mo
new file mode 100644
index 0000000..fab87ed
--- /dev/null
+++ b/SorpLib/UsersGuide/Contact/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide;
+package Contact "Contact"
+extends Modelica.Icons.Contact;
+end Contact;
diff --git a/SorpLib/UsersGuide/Contact/package.order b/SorpLib/UsersGuide/Contact/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/UsersGuide/Conventions/HTMLDocumentation/NamingConvention/package.mo b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/NamingConvention/package.mo
new file mode 100644
index 0000000..56cdbdf
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/NamingConvention/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide.Conventions.HTMLDocumentation;
+package NamingConvention "Naming convention"
+extends Modelica.Icons.Information;
+end NamingConvention;
diff --git a/SorpLib/UsersGuide/Conventions/HTMLDocumentation/NamingConvention/package.order b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/NamingConvention/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/UsersGuide/Conventions/HTMLDocumentation/StructureFormat/package.mo b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/StructureFormat/package.mo
new file mode 100644
index 0000000..654c6a3
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/StructureFormat/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide.Conventions.HTMLDocumentation;
+package StructureFormat "Structure and format"
+  extends Modelica.Icons.Information;
+end StructureFormat;
diff --git a/SorpLib/UsersGuide/Conventions/HTMLDocumentation/StructureFormat/package.order b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/StructureFormat/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/UsersGuide/Conventions/HTMLDocumentation/package.mo b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/package.mo
new file mode 100644
index 0000000..0e0427a
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide.Conventions;
+package HTMLDocumentation "HTML documentation"
+extends Modelica.Icons.Information;
+end HTMLDocumentation;
diff --git a/SorpLib/UsersGuide/Conventions/HTMLDocumentation/package.order b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/package.order
new file mode 100644
index 0000000..e7738ab
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/HTMLDocumentation/package.order
@@ -0,0 +1,2 @@
+StructureFormat
+NamingConvention
diff --git a/SorpLib/UsersGuide/Conventions/ModelicaCode/NamingConvention/package.mo b/SorpLib/UsersGuide/Conventions/ModelicaCode/NamingConvention/package.mo
new file mode 100644
index 0000000..a4e4402
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/ModelicaCode/NamingConvention/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide.Conventions.ModelicaCode;
+package NamingConvention "Naming convention"
+extends Modelica.Icons.Information;
+end NamingConvention;
diff --git a/SorpLib/UsersGuide/Conventions/ModelicaCode/NamingConvention/package.order b/SorpLib/UsersGuide/Conventions/ModelicaCode/NamingConvention/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/UsersGuide/Conventions/ModelicaCode/StructureFormat/package.mo b/SorpLib/UsersGuide/Conventions/ModelicaCode/StructureFormat/package.mo
new file mode 100644
index 0000000..892fe19
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/ModelicaCode/StructureFormat/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide.Conventions.ModelicaCode;
+package StructureFormat "Structure and format"
+  extends Modelica.Icons.Information;
+end StructureFormat;
diff --git a/SorpLib/UsersGuide/Conventions/ModelicaCode/StructureFormat/package.order b/SorpLib/UsersGuide/Conventions/ModelicaCode/StructureFormat/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/UsersGuide/Conventions/ModelicaCode/package.mo b/SorpLib/UsersGuide/Conventions/ModelicaCode/package.mo
new file mode 100644
index 0000000..1fd130b
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/ModelicaCode/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide.Conventions;
+package ModelicaCode "Modelica code"
+extends Modelica.Icons.Information;
+end ModelicaCode;
diff --git a/SorpLib/UsersGuide/Conventions/ModelicaCode/package.order b/SorpLib/UsersGuide/Conventions/ModelicaCode/package.order
new file mode 100644
index 0000000..e7738ab
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/ModelicaCode/package.order
@@ -0,0 +1,2 @@
+StructureFormat
+NamingConvention
diff --git a/SorpLib/UsersGuide/Conventions/package.mo b/SorpLib/UsersGuide/Conventions/package.mo
new file mode 100644
index 0000000..de5266b
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide;
+package Conventions "Convetions"
+extends Modelica.Icons.Information;
+end Conventions;
diff --git a/SorpLib/UsersGuide/Conventions/package.order b/SorpLib/UsersGuide/Conventions/package.order
new file mode 100644
index 0000000..33b3651
--- /dev/null
+++ b/SorpLib/UsersGuide/Conventions/package.order
@@ -0,0 +1,2 @@
+ModelicaCode
+HTMLDocumentation
diff --git a/SorpLib/UsersGuide/Overview/package.mo b/SorpLib/UsersGuide/Overview/package.mo
new file mode 100644
index 0000000..49410d3
--- /dev/null
+++ b/SorpLib/UsersGuide/Overview/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide;
+package Overview "Overview of SorpLib library"
+extends Modelica.Icons.Information;
+end Overview;
diff --git a/SorpLib/UsersGuide/Overview/package.order b/SorpLib/UsersGuide/Overview/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/UsersGuide/ReleaseNotes/package.mo b/SorpLib/UsersGuide/ReleaseNotes/package.mo
new file mode 100644
index 0000000..4e38b69
--- /dev/null
+++ b/SorpLib/UsersGuide/ReleaseNotes/package.mo
@@ -0,0 +1,4 @@
+within SorpLib.UsersGuide;
+package ReleaseNotes "Release notes"
+extends Modelica.Icons.ReleaseNotes;
+end ReleaseNotes;
diff --git a/SorpLib/UsersGuide/ReleaseNotes/package.order b/SorpLib/UsersGuide/ReleaseNotes/package.order
new file mode 100644
index 0000000..e69de29
diff --git a/SorpLib/UsersGuide/package.mo b/SorpLib/UsersGuide/package.mo
index 5a40f4e..1a8652e 100644
--- a/SorpLib/UsersGuide/package.mo
+++ b/SorpLib/UsersGuide/package.mo
@@ -2,20 +2,9 @@ within SorpLib;
 package UsersGuide "User's Guide"
 extends Modelica.Icons.Information;
 
-annotation (DocumentationClass=true, Documentation(info="<html>
-  <p>
-    <b>SorpLib - Adsorption Energy Systems Library</b> (short <b>SorpLib</b>) is a Modelica model library for simulating adsorption energy systems, such as adsorption chillers, adsorption heat pumps, adsorption thermal sorage systems, or desiccant systems. The library is being developed at RWTH Aachen University, Institute of Technical Thermodynamics, Sorption Systems Engineering group in Aachen, Germany.
-  </p>
-  <h3>Dependencies</h3>
-  Regarding non-adsorption specific models, the library partly depends on the libraries TIL and TILMedia:
-  <ul>
-  <li>TIL: Component library for thermal systems</li>
-  <li>TILMedia: Thermophysical media properties</li>
-
-  </ul>
-   <p> TIL and TILMedia are commercial libraries provided by <a href='https://www.tlk-thermo.com/index.php/en/'> TLK-Thermo GmbH</a>. 
-  At the moment, it is necessary to have these libraries to use the **SorpLib**. For the future, a light version of TIL and TIL-Media may be freely available.
-  </p>
-
+  annotation (DocumentationClass=true,
+Documentation(info="<html>
+<p>
+</p>
 </html>"));
 end UsersGuide;
diff --git a/SorpLib/UsersGuide/package.order b/SorpLib/UsersGuide/package.order
index e69de29..fdefe73 100644
--- a/SorpLib/UsersGuide/package.order
+++ b/SorpLib/UsersGuide/package.order
@@ -0,0 +1,5 @@
+Overview
+Connectors
+Conventions
+ReleaseNotes
+Contact
diff --git a/SorpLib/package.mo b/SorpLib/package.mo
index 9980378..cc0d6bc 100644
--- a/SorpLib/package.mo
+++ b/SorpLib/package.mo
@@ -1,36 +1,13 @@
 within ;
-package SorpLib "SorpLib"
-  import SI = Modelica.SIunits;
-
-
-
-
-
-
-
-
-
-
-  annotation (
-    version="",
-    preferedView="info",
-    conversion(noneFromVersion=""),
-    uses(
-      TILMedia(version="3.5.0"),
-      TIL(version="3.5.0"),
-      Modelica(version="3.2.2")),
-    Documentation(info="<html>
-<p>
-  <img src=\"modelica://SorpLib/Resources/Images/Sorplib_info.png\">
-</p>
-<p>
-The model library <b>SorpLib</b> is released by RWTH Aachen University, Chair of Technical Thermodynamics under the <a href=\"https://git.rwth-aachen.de/ltt_group/LTT_SorptionEnergySystems_library/blob/develop/LICENSE.md\"> BSD 3-Clause License</a>.<br>
-Copyright &copy; 2010-2017, RWTH Aachen University, Chair of Technical Thermodynamics.
-</p>
-</html>",        revisions=""),
-    Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{100,100}},    grid={1,1}), graphics={
-                         Bitmap(
-        extent={{-162,-128},{123,134}},
-                                      fileName="modelica://SorpLib/Resources/Images/Sorplib_logo.png")}),
-    Diagram(coordinateSystem(extent={{-1,-60},{80,40}})));
+package SorpLib "SorpLib 2.0 - Adsorption Systems Library"
+  extends SorpLib.Icons.SorpLibPackage;
+
+  annotation (uses(Modelica(version="4.0.0")), Documentation(revisions="<html>
+<ul>
+  <li>
+  October 26, 2023, by Mirko Engelpracht:<br/>
+  First implementation after restructuring the library.
+  </li>
+</ul>
+</html>"));
 end SorpLib;
diff --git a/SorpLib/package.order b/SorpLib/package.order
index f5e41cd..7765b77 100644
--- a/SorpLib/package.order
+++ b/SorpLib/package.order
@@ -1,5 +1,10 @@
 UsersGuide
 Media
+Basics
 Components
-Applications
-Internals
+Modules
+Numerics
+Icons
+Choices
+Units
+Examples
-- 
GitLab