Compare commits
1 Commits
cffbd51d92
...
2fb73e6713
| Author | SHA1 | Date | |
|---|---|---|---|
| 2fb73e6713 |
2
index.js
2
index.js
@@ -13,7 +13,6 @@ const logger = require('./src/helper/logger.js');
|
|||||||
const validation = require('./src/helper/validationUtils.js');
|
const validation = require('./src/helper/validationUtils.js');
|
||||||
const configUtils = require('./src/helper/configUtils.js');
|
const configUtils = require('./src/helper/configUtils.js');
|
||||||
const assertions = require('./src/helper/assertionUtils.js')
|
const assertions = require('./src/helper/assertionUtils.js')
|
||||||
const coolprop = require('./src/coolprop-node/src/index.js');
|
|
||||||
|
|
||||||
// Domain-specific modules
|
// Domain-specific modules
|
||||||
const { MeasurementContainer } = require('./src/measurements/index.js');
|
const { MeasurementContainer } = require('./src/measurements/index.js');
|
||||||
@@ -40,7 +39,6 @@ module.exports = {
|
|||||||
MeasurementContainer,
|
MeasurementContainer,
|
||||||
nrmse,
|
nrmse,
|
||||||
state,
|
state,
|
||||||
coolprop,
|
|
||||||
convert,
|
convert,
|
||||||
MenuManager,
|
MenuManager,
|
||||||
childRegistrationUtils,
|
childRegistrationUtils,
|
||||||
|
|||||||
2
src/coolprop-node/.gitattributes
vendored
2
src/coolprop-node/.gitattributes
vendored
@@ -1,2 +0,0 @@
|
|||||||
# Auto detect text files and perform LF normalization
|
|
||||||
* text=auto
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2024 Craig Zych
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
# CoolProp-Node
|
|
||||||
|
|
||||||
A Node.js wrapper for CoolProp providing an easy-to-use interface for thermodynamic calculations and refrigerant properties. Unlike all the other CoolProp npm packages I've seen, this one should actually work. Please report any issues.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install coolprop-node
|
|
||||||
```
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- Easy-to-use async interface for CoolProp
|
|
||||||
- Unit conversion support (Temperature: K/C/F, Pressure: Pa/kPa/bar/psi)
|
|
||||||
- Automatic initialization
|
|
||||||
- Configurable defaults
|
|
||||||
- Comprehensive error handling
|
|
||||||
|
|
||||||
## Dependencies
|
|
||||||
No External Dependencies, as CoolProp.js and CoolProp.wasm are bundled with the package.
|
|
||||||
- [CoolProp](https://github.com/CoolProp/CoolProp) for the powerful thermodynamic library
|
|
||||||
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
```javascript
|
|
||||||
const nodeprop = require('coolprop-node');
|
|
||||||
async function example() {
|
|
||||||
// Initialize with defaults (optional)
|
|
||||||
await nodeprop.init({
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
// Calculate superheat
|
|
||||||
const result = await nodeprop.calculateSuperheat({
|
|
||||||
temperature: 25, // 25°C
|
|
||||||
pressure: 10, // 10 bar
|
|
||||||
refrigerant: 'R404A' // optional if set in init
|
|
||||||
});
|
|
||||||
console.log(result);
|
|
||||||
|
|
||||||
// expected output:
|
|
||||||
{
|
|
||||||
type: 'success',
|
|
||||||
superheat: 5.2,
|
|
||||||
saturationTemperature: 19.8,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
units: {
|
|
||||||
temperature: 'C',
|
|
||||||
pressure: 'bar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
example();
|
|
||||||
```
|
|
||||||
|
|
||||||
## API Reference
|
|
||||||
|
|
||||||
### nodeprop.init(config)
|
|
||||||
Initializes the wrapper with optional configuration.
|
|
||||||
###### Note: Calling `init()` is optional. The library will initialize automatically when you make your first call to any function, but you must provide a `refrigerant` parameter in that first call.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
await nodeprop.init({
|
|
||||||
refrigerant: 'R404A', // Required on first init
|
|
||||||
tempUnit: 'C', // Optional, defaults to 'K'
|
|
||||||
pressureUnit: 'bar' // Optional, defaults to 'Pa'
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### nodeprop.calculateSuperheat(input)
|
|
||||||
Calculates superheat for a given refrigerant.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const result = await nodeprop.calculateSuperheat({
|
|
||||||
temperature: 25, // 25°C
|
|
||||||
pressure: 10, // 10 bar
|
|
||||||
refrigerant: 'R404A' // optional if set in init
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
returns:
|
|
||||||
{
|
|
||||||
type: 'success',
|
|
||||||
superheat: 5.2,
|
|
||||||
saturationTemperature: 19.8,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
units: {
|
|
||||||
temperature: 'C',
|
|
||||||
pressure: 'bar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### nodeprop.getSaturationTemperature(input)
|
|
||||||
Calculates saturation temperature for a given refrigerant.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const result = await nodeprop.calculateSaturationTemperature({
|
|
||||||
temperature: 25, // 25°C
|
|
||||||
pressure: 10, // 10 bar
|
|
||||||
refrigerant: 'R404A' // optional if set in init
|
|
||||||
});
|
|
||||||
|
|
||||||
returns:
|
|
||||||
{
|
|
||||||
type: 'success',
|
|
||||||
temperature: 19.8,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
units: {
|
|
||||||
temperature: 'C',
|
|
||||||
pressure: 'bar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### nodeprop.getSaturationPressure(input)
|
|
||||||
Calculates saturation pressure for a given refrigerant.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const result = await nodeprop.calculateSaturationPressure({
|
|
||||||
temperature: 25, // 25°C
|
|
||||||
refrigerant: 'R404A' // optional if set in init
|
|
||||||
});
|
|
||||||
|
|
||||||
returns:
|
|
||||||
{
|
|
||||||
type: 'success',
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
units: {
|
|
||||||
temperature: 'C',
|
|
||||||
pressure: 'bar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### nodeprop.calculateSubcooling(input)
|
|
||||||
Calculates subcooling for a given refrigerant.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const result = await nodeprop.calculateSubcooling({
|
|
||||||
temperature: 25, // 25°C
|
|
||||||
pressure: 10, // 10 bar
|
|
||||||
refrigerant: 'R404A' // optional if set in init
|
|
||||||
});
|
|
||||||
|
|
||||||
returns:
|
|
||||||
{
|
|
||||||
type: 'success',
|
|
||||||
subcooling: 5.2,
|
|
||||||
saturationTemperature: 19.8,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
units: {
|
|
||||||
temperature: 'C',
|
|
||||||
pressure: 'bar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### nodeprop.calculateSuperheat(input)
|
|
||||||
Calculates superheat for a given refrigerant.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const result = await nodeprop.calculateSuperheat({
|
|
||||||
temperature: 25, // 25°C
|
|
||||||
pressure: 10, // 10 bar
|
|
||||||
refrigerant: 'R404A' // optional if set in init
|
|
||||||
});
|
|
||||||
|
|
||||||
returns:
|
|
||||||
{
|
|
||||||
type: 'success',
|
|
||||||
superheat: 5.2,
|
|
||||||
saturationTemperature: 19.8,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
units: {
|
|
||||||
temperature: 'C',
|
|
||||||
pressure: 'bar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### nodeprop.getProperties(input)
|
|
||||||
Gets all properties for a given refrigerant.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const result = await nodeprop.getProperties({
|
|
||||||
temperature: 25, // 25°C
|
|
||||||
pressure: 10, // 10 bar
|
|
||||||
refrigerant: 'R404A' // optional if set in init
|
|
||||||
});
|
|
||||||
|
|
||||||
returns:
|
|
||||||
{
|
|
||||||
type: 'success',
|
|
||||||
properties: {
|
|
||||||
temperature: 25, // in configured temperature unit (e.g., °C)
|
|
||||||
pressure: 10, // in configured pressure unit (e.g., bar)
|
|
||||||
density: 1234.56, // in kg/m³
|
|
||||||
enthalpy: 400000, // in J/kg
|
|
||||||
entropy: 1750, // in J/kg/K
|
|
||||||
quality: 1, // dimensionless (0-1)
|
|
||||||
conductivity: 0.013, // in W/m/K
|
|
||||||
viscosity: 1.2e-5, // in Pa·s
|
|
||||||
specificHeat: 850 // in J/kg/K
|
|
||||||
},
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
units: {
|
|
||||||
temperature: 'C',
|
|
||||||
pressure: 'bar',
|
|
||||||
density: 'kg/m³',
|
|
||||||
enthalpy: 'J/kg',
|
|
||||||
entropy: 'J/kg/K',
|
|
||||||
quality: 'dimensionless',
|
|
||||||
conductivity: 'W/m/K',
|
|
||||||
viscosity: 'Pa·s',
|
|
||||||
specificHeat: 'J/kg/K'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### nodeprop.PropsSI
|
|
||||||
Direct access to CoolProp's PropsSI function.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const PropsSI = await nodeprop.getPropsSI();
|
|
||||||
const result = PropsSI('H', 'T', 298.15, 'P', 101325, 'R134a');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Error Handling
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const result = await nodeprop.calculateSuperheat({
|
|
||||||
temperature: 25, // 25°C
|
|
||||||
pressure: 10, // 10 bar
|
|
||||||
refrigerant: 'R404' // Invalid refrigerant. Must be supported by CoolProp, but R404 is not even a valid refrigerant.
|
|
||||||
});
|
|
||||||
|
|
||||||
returns:
|
|
||||||
{
|
|
||||||
type: 'error',
|
|
||||||
message: 'Invalid refrigerant'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Acknowledgements
|
|
||||||
|
|
||||||
- [CoolProp](https://github.com/CoolProp/CoolProp) for the powerful thermodynamic library
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
const coolprop = require('./src/index.js');
|
|
||||||
|
|
||||||
// Function to generate random number between min and max
|
|
||||||
function getRandomNumber(min, max) {
|
|
||||||
return min + Math.random() * (max - min);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate 1000 combinations of temperature and pressure
|
|
||||||
function generateCombinations(count) {
|
|
||||||
const combinations = [];
|
|
||||||
|
|
||||||
// For R744 (CO2), using realistic ranges from test files
|
|
||||||
// Temperature range: -40°F to 32°F
|
|
||||||
// Pressure range: 131 psig to 491 psig
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
const temperature = getRandomNumber(-40, 32);
|
|
||||||
const pressure = getRandomNumber(131, 491);
|
|
||||||
|
|
||||||
combinations.push({
|
|
||||||
temperature,
|
|
||||||
pressure,
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'F',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return combinations;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function runBenchmark() {
|
|
||||||
console.log('Generating 1000 temperature and pressure combinations...');
|
|
||||||
const combinations = generateCombinations(1000);
|
|
||||||
console.log('Combinations generated.');
|
|
||||||
|
|
||||||
// Pre-initialize the library
|
|
||||||
console.log('Initializing library...');
|
|
||||||
await coolprop.init({
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'F',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
console.log('Library initialized.');
|
|
||||||
|
|
||||||
// Run benchmark
|
|
||||||
console.log('Starting benchmark...');
|
|
||||||
const startTime = performance.now();
|
|
||||||
|
|
||||||
const results = [];
|
|
||||||
for (let i = 0; i < combinations.length; i++) {
|
|
||||||
const result = await coolprop.calculateSuperheat(combinations[i]);
|
|
||||||
results.push(result);
|
|
||||||
|
|
||||||
// Show progress every 100 calculations
|
|
||||||
if ((i + 1) % 100 === 0) {
|
|
||||||
console.log(`Processed ${i + 1} / ${combinations.length} calculations`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const endTime = performance.now();
|
|
||||||
const totalTime = endTime - startTime;
|
|
||||||
const avgTime = totalTime / combinations.length;
|
|
||||||
|
|
||||||
// Report results
|
|
||||||
console.log('\nBenchmark Results:');
|
|
||||||
console.log(`Total time: ${totalTime.toFixed(2)} ms`);
|
|
||||||
console.log(`Average time per calculation: ${avgTime.toFixed(2)} ms`);
|
|
||||||
console.log(`Calculations per second: ${(1000 / avgTime).toFixed(2)}`);
|
|
||||||
|
|
||||||
// Count success and error results
|
|
||||||
const successful = results.filter(r => r.type === 'success').length;
|
|
||||||
const failed = results.filter(r => r.type === 'error').length;
|
|
||||||
console.log(`\nSuccessful calculations: ${successful}`);
|
|
||||||
console.log(`Failed calculations: ${failed}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the benchmark
|
|
||||||
runBenchmark().catch(error => {
|
|
||||||
console.error('Benchmark failed:', error);
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "coolprop-node",
|
|
||||||
"version": "1.0.20",
|
|
||||||
"main": "src/index.js",
|
|
||||||
"scripts": {
|
|
||||||
"test": "jest",
|
|
||||||
"test:watch": "jest --watch"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"coolprop",
|
|
||||||
"thermodynamics",
|
|
||||||
"fluid properties",
|
|
||||||
"refrigerant",
|
|
||||||
"refrigeration",
|
|
||||||
"refprop"
|
|
||||||
],
|
|
||||||
"author": "Craig Zych",
|
|
||||||
"license": "MIT",
|
|
||||||
"description": "A Node.js wrapper for CoolProp providing an easy-to-use interface for thermodynamic calculations and refrigerant properties. Unlike all the other CoolProp npm packages I've seen, this one should actually work. Please report any issues. ",
|
|
||||||
"devDependencies": {
|
|
||||||
"jest": "^29.7.0"
|
|
||||||
},
|
|
||||||
"jest": {
|
|
||||||
"testEnvironment": "node",
|
|
||||||
"verbose": true
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/Craigzyc/coolprop-node.git"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
// Load and configure the CoolProp module
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const vm = require('vm');
|
|
||||||
|
|
||||||
// Mock XMLHttpRequest
|
|
||||||
class XMLHttpRequest {
|
|
||||||
open(method, url) {
|
|
||||||
this.method = method;
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
send() {
|
|
||||||
try {
|
|
||||||
// Convert the URL to a local file path
|
|
||||||
const localPath = path.join(__dirname, '..', 'coolprop', path.basename(this.url));
|
|
||||||
const data = fs.readFileSync(localPath);
|
|
||||||
|
|
||||||
this.status = 200;
|
|
||||||
this.response = data;
|
|
||||||
this.responseType = 'arraybuffer';
|
|
||||||
|
|
||||||
if (this.onload) {
|
|
||||||
this.onload();
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
if (this.onerror) {
|
|
||||||
this.onerror(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the coolprop.js file
|
|
||||||
const coolpropJs = fs.readFileSync(path.join(__dirname, '../coolprop/coolprop.js'), 'utf8');
|
|
||||||
|
|
||||||
// Create a context for the module
|
|
||||||
const context = {
|
|
||||||
window: {},
|
|
||||||
self: {},
|
|
||||||
Module: {
|
|
||||||
onRuntimeInitialized: function() {
|
|
||||||
context.Module.initialized = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
importScripts: () => {},
|
|
||||||
console: console,
|
|
||||||
location: {
|
|
||||||
href: 'file://' + __dirname,
|
|
||||||
pathname: __dirname,
|
|
||||||
},
|
|
||||||
document: {
|
|
||||||
currentScript: { src: '' }
|
|
||||||
},
|
|
||||||
XMLHttpRequest: XMLHttpRequest
|
|
||||||
};
|
|
||||||
|
|
||||||
// Make self reference the context itself
|
|
||||||
context.self = context;
|
|
||||||
// Make window reference the context itself
|
|
||||||
context.window = context;
|
|
||||||
|
|
||||||
// Execute coolprop.js in our custom context
|
|
||||||
vm.createContext(context);
|
|
||||||
vm.runInContext(coolpropJs, context);
|
|
||||||
|
|
||||||
// Wait for initialization
|
|
||||||
function waitForInit(timeout = 5000) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const start = Date.now();
|
|
||||||
const check = () => {
|
|
||||||
if (context.Module.initialized) {
|
|
||||||
resolve(context.Module);
|
|
||||||
} else if (Date.now() - start > timeout) {
|
|
||||||
reject(new Error('CoolProp initialization timed out'));
|
|
||||||
} else {
|
|
||||||
setTimeout(check, 100);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
check();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
init: () => waitForInit(),
|
|
||||||
PropsSI: (...args) => {
|
|
||||||
if (!context.Module.initialized) {
|
|
||||||
throw new Error('CoolProp not initialized. Call init() first');
|
|
||||||
}
|
|
||||||
return context.Module.PropsSI(...args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,419 +0,0 @@
|
|||||||
const coolprop = require('./cp.js');
|
|
||||||
const customRefs = require('./refData.js');
|
|
||||||
|
|
||||||
class CoolPropWrapper {
|
|
||||||
constructor() {
|
|
||||||
this.initialized = false;
|
|
||||||
this.defaultRefrigerant = null;
|
|
||||||
this.defaultTempUnit = 'K'; // K, C, F
|
|
||||||
this.defaultPressureUnit = 'Pa' // Pa, kPa, bar, psi
|
|
||||||
this.customRef = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temperature conversion helpers
|
|
||||||
_convertTempToK(value, unit = this.defaultTempUnit) {
|
|
||||||
switch(unit.toUpperCase()) {
|
|
||||||
case 'K': return value;
|
|
||||||
case 'C': return value + 273.15;
|
|
||||||
case 'F': return (value + 459.67) * 5/9;
|
|
||||||
default: throw new Error('Unsupported temperature unit');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_convertTempFromK(value, unit = this.defaultTempUnit) {
|
|
||||||
switch(unit.toUpperCase()) {
|
|
||||||
case 'K': return value;
|
|
||||||
case 'C': return value - 273.15;
|
|
||||||
case 'F': return value * 9/5 - 459.67;
|
|
||||||
default: throw new Error('Unsupported temperature unit');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_convertDeltaTempFromK(value, unit = this.defaultTempUnit) {
|
|
||||||
switch(unit.toUpperCase()) {
|
|
||||||
case 'K': return value;
|
|
||||||
case 'C': return value;
|
|
||||||
case 'F': return (value * 1.8);
|
|
||||||
default: throw new Error('Unsupported temperature unit');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pressure conversion helpers
|
|
||||||
_convertPressureToPa(value, unit = this.defaultPressureUnit) {
|
|
||||||
switch(unit.toUpperCase()) {
|
|
||||||
case 'PAA': return value; // Absolute Pascal
|
|
||||||
case 'PAG':
|
|
||||||
case 'PA': return value + 101325; // Gauge Pascal
|
|
||||||
case 'KPAA': return value * 1000; // Absolute kiloPascal
|
|
||||||
case 'KPAG':
|
|
||||||
case 'KPA': return value * 1000 + 101325; // Gauge kiloPascal
|
|
||||||
case 'BARA': return value * 100000; // Absolute bar
|
|
||||||
case 'BARG':
|
|
||||||
case 'BAR': return value * 100000 + 101325; // Gauge bar
|
|
||||||
case 'PSIA': return value * 6894.76; // Absolute PSI
|
|
||||||
case 'PSIG':
|
|
||||||
case 'PSI': return value * 6894.76 + 101325;// Gauge PSI
|
|
||||||
default: throw new Error('Unsupported pressure unit');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_convertPressureFromPa(value, unit = this.defaultPressureUnit) {
|
|
||||||
switch(unit.toUpperCase()) {
|
|
||||||
case 'PAA': return value; // Absolute Pascal
|
|
||||||
case 'PAG':
|
|
||||||
case 'PA': return value - 101325; // Gauge Pascal
|
|
||||||
case 'KPAA': return value / 1000; // Absolute kiloPascal
|
|
||||||
case 'KPAG':
|
|
||||||
case 'KPA': return (value - 101325) / 1000; // Gauge kiloPascal
|
|
||||||
case 'BARA': return value / 100000; // Absolute bar
|
|
||||||
case 'BARG':
|
|
||||||
case 'BAR': return (value - 101325) / 100000;// Gauge bar
|
|
||||||
case 'PSIA': return value / 6894.76; // Absolute PSI
|
|
||||||
case 'PSIG':
|
|
||||||
case 'PSI': return (value - 101325) / 6894.76;// Gauge PSI
|
|
||||||
default: throw new Error('Unsupported pressure unit');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async init(config = {}) {
|
|
||||||
try {
|
|
||||||
// If already initialized, only update defaults if provided
|
|
||||||
if (this.initialized) {
|
|
||||||
if (config.refrigerant) this.defaultRefrigerant = config.refrigerant;
|
|
||||||
if (config.tempUnit) {
|
|
||||||
if (!['K', 'C', 'F'].includes(config.tempUnit.toUpperCase())) {
|
|
||||||
return { type: 'error', message: 'Invalid temperature unit. Must be K, C, or F' };
|
|
||||||
}
|
|
||||||
this.defaultTempUnit = config.tempUnit;
|
|
||||||
}
|
|
||||||
if (config.pressureUnit) {
|
|
||||||
if (!['PA', 'PAA', 'KPA', 'KPAA', 'BAR', 'BARA', 'PSI', 'PSIA'].includes(config.pressureUnit.toUpperCase())) {
|
|
||||||
return { type: 'error', message: 'Invalid pressure unit. Must be Pa, Paa, kPa, kPaa, bar, bara, psi, or psia' };
|
|
||||||
}
|
|
||||||
this.defaultPressureUnit = config.pressureUnit;
|
|
||||||
}
|
|
||||||
return { type: 'success', message: 'Default settings updated' };
|
|
||||||
}
|
|
||||||
|
|
||||||
// First time initialization
|
|
||||||
if (!config.refrigerant) {
|
|
||||||
throw new Error('Refrigerant must be specified during initialization');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate temperature unit if provided
|
|
||||||
if (config.tempUnit && !['K', 'C', 'F'].includes(config.tempUnit.toUpperCase())) {
|
|
||||||
throw new Error('Invalid temperature unit. Must be K, C, or F');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate pressure unit if provided
|
|
||||||
if (config.pressureUnit && !['PA', 'PAA', 'KPA', 'KPAA', 'BAR', 'BARA', 'PSI', 'PSIA'].includes(config.pressureUnit.toUpperCase())) {
|
|
||||||
throw new Error('Invalid pressure unit. Must be Pa, Paa, kPa, kPaa, bar, bara, psi, or psia');
|
|
||||||
}
|
|
||||||
|
|
||||||
await coolprop.init();
|
|
||||||
this.initialized = true;
|
|
||||||
this.defaultRefrigerant = config.refrigerant;
|
|
||||||
this.defaultTempUnit = config.tempUnit || this.defaultTempUnit;
|
|
||||||
this.defaultPressureUnit = config.pressureUnit || this.defaultPressureUnit;
|
|
||||||
return { type: 'success', message: 'Initialized successfully' };
|
|
||||||
} catch (error) {
|
|
||||||
return { type: 'error', message: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async _ensureInit(config = {}) {
|
|
||||||
// Initialize CoolProp if not already done
|
|
||||||
if (!this.initialized) {
|
|
||||||
if (!config.refrigerant && !this.defaultRefrigerant) {
|
|
||||||
throw new Error('Refrigerant must be specified either during initialization or in the method call');
|
|
||||||
}
|
|
||||||
await coolprop.init();
|
|
||||||
this.initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate temperature unit if provided
|
|
||||||
if (config.tempUnit && !['K', 'C', 'F'].includes(config.tempUnit.toUpperCase())) {
|
|
||||||
throw new Error('Invalid temperature unit. Must be K, C, or F');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate pressure unit if provided
|
|
||||||
if (config.pressureUnit && !['PA', 'PAA', 'PAG', 'KPA', 'KPAA', 'KPAG', 'BAR', 'BARA', 'BARG', 'PSI', 'PSIA', 'PSIG'].includes(config.pressureUnit.toUpperCase())) {
|
|
||||||
throw new Error('Invalid pressure unit. Must be Pa, Paa, Pag, kPa, kPaa, kPag, bar, bara, barg, psi, psia, or psig');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate refrigerant if provided
|
|
||||||
if (config.refrigerant && typeof config.refrigerant !== 'string') {
|
|
||||||
throw new Error('Invalid refrigerant type');
|
|
||||||
}
|
|
||||||
if (config.refrigerant && Object.keys(customRefs).includes(config.refrigerant)) {
|
|
||||||
this.customRef = true;
|
|
||||||
this.defaultRefrigerant = config.refrigerant;
|
|
||||||
//console.log(`Using custom refrigerant flag for ${this.defaultRefrigerant}`);
|
|
||||||
}else if(this.customRef && config.refrigerant){
|
|
||||||
this.customRef = false;
|
|
||||||
//console.log(`Cleared custom refrigerant flag`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update instance variables with new config values if provided
|
|
||||||
if (config.refrigerant) this.defaultRefrigerant = config.refrigerant;
|
|
||||||
if (config.tempUnit) this.defaultTempUnit = config.tempUnit.toUpperCase();
|
|
||||||
if (config.pressureUnit) this.defaultPressureUnit = config.pressureUnit.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
async getConfig() {
|
|
||||||
return {
|
|
||||||
refrigerant: this.defaultRefrigerant,
|
|
||||||
tempUnit: this.defaultTempUnit,
|
|
||||||
pressureUnit: this.defaultPressureUnit
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async setConfig(config) {
|
|
||||||
await this.init(config);
|
|
||||||
return {
|
|
||||||
type: 'success',
|
|
||||||
message: 'Config updated successfully',
|
|
||||||
config: await this.getConfig()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method for linear interpolation/extrapolation
|
|
||||||
_interpolateSaturationTemperature(pressurePa, saturationData, pressureType = 'liquid') {
|
|
||||||
const data = saturationData.sort((a, b) => a[pressureType] - b[pressureType]); // Sort by specified pressure type
|
|
||||||
|
|
||||||
// If pressure is below the lowest data point, extrapolate using first two points
|
|
||||||
if (pressurePa <= data[0][pressureType]) {
|
|
||||||
if (data.length < 2) return data[0].K;
|
|
||||||
const p1 = data[0], p2 = data[1];
|
|
||||||
const slope = (p2.K - p1.K) / (p2[pressureType] - p1[pressureType]);
|
|
||||||
return p1.K + slope * (pressurePa - p1[pressureType]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If pressure is above the highest data point, extrapolate using last two points
|
|
||||||
if (pressurePa >= data[data.length - 1][pressureType]) {
|
|
||||||
if (data.length < 2) return data[data.length - 1].K;
|
|
||||||
const p1 = data[data.length - 2], p2 = data[data.length - 1];
|
|
||||||
const slope = (p2.K - p1.K) / (p2[pressureType] - p1[pressureType]);
|
|
||||||
return p1.K + slope * (pressurePa - p1[pressureType]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the two adjacent points for interpolation
|
|
||||||
for (let i = 0; i < data.length - 1; i++) {
|
|
||||||
if (pressurePa >= data[i][pressureType] && pressurePa <= data[i + 1][pressureType]) {
|
|
||||||
const p1 = data[i], p2 = data[i + 1];
|
|
||||||
|
|
||||||
// Linear interpolation
|
|
||||||
const slope = (p2.K - p1.K) / (p2[pressureType] - p1[pressureType]);
|
|
||||||
return p1.K + slope * (pressurePa - p1[pressureType]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback (shouldn't reach here)
|
|
||||||
return data[0].K;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper method for linear interpolation/extrapolation of saturation pressure
|
|
||||||
_interpolateSaturationPressure(tempK, saturationData, pressureType = 'liquid') {
|
|
||||||
const data = saturationData.sort((a, b) => a.K - b.K); // Sort by temperature
|
|
||||||
|
|
||||||
// If temperature is below the lowest data point, extrapolate using first two points
|
|
||||||
if (tempK <= data[0].K) {
|
|
||||||
if (data.length < 2) return data[0][pressureType];
|
|
||||||
const p1 = data[0], p2 = data[1];
|
|
||||||
const slope = (p2[pressureType] - p1[pressureType]) / (p2.K - p1.K);
|
|
||||||
return p1[pressureType] + slope * (tempK - p1.K);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If temperature is above the highest data point, extrapolate using last two points
|
|
||||||
if (tempK >= data[data.length - 1].K) {
|
|
||||||
if (data.length < 2) return data[data.length - 1][pressureType];
|
|
||||||
const p1 = data[data.length - 2], p2 = data[data.length - 1];
|
|
||||||
const slope = (p2[pressureType] - p1[pressureType]) / (p2.K - p1.K);
|
|
||||||
return p1[pressureType] + slope * (tempK - p1.K);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the two adjacent points for interpolation
|
|
||||||
for (let i = 0; i < data.length - 1; i++) {
|
|
||||||
if (tempK >= data[i].K && tempK <= data[i + 1].K) {
|
|
||||||
const p1 = data[i], p2 = data[i + 1];
|
|
||||||
|
|
||||||
// Linear interpolation
|
|
||||||
const slope = (p2[pressureType] - p1[pressureType]) / (p2.K - p1.K);
|
|
||||||
return p1[pressureType] + slope * (tempK - p1.K);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback (shouldn't reach here)
|
|
||||||
return data[0][pressureType];
|
|
||||||
}
|
|
||||||
|
|
||||||
async getSaturationTemperature({ pressure, refrigerant = this.defaultRefrigerant, pressureUnit = this.defaultPressureUnit, tempUnit = this.defaultTempUnit }) {
|
|
||||||
try {
|
|
||||||
await this._ensureInit({ refrigerant, pressureUnit, tempUnit });
|
|
||||||
const pressurePa = this._convertPressureToPa(pressure, pressureUnit);
|
|
||||||
let tempK;
|
|
||||||
if(this.customRef){
|
|
||||||
tempK = this._interpolateSaturationTemperature(pressurePa, customRefs[refrigerant].saturation);
|
|
||||||
}else{
|
|
||||||
tempK = coolprop.PropsSI('T', 'P', pressurePa, 'Q', 0, this.customRefString || refrigerant);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'success',
|
|
||||||
temperature: this._convertTempFromK(tempK, tempUnit),
|
|
||||||
refrigerant,
|
|
||||||
units: {
|
|
||||||
temperature: tempUnit,
|
|
||||||
pressure: pressureUnit
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
return { type: 'error', message: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async getSaturationPressure({ temperature, refrigerant = this.defaultRefrigerant, tempUnit = this.defaultTempUnit, pressureUnit = this.defaultPressureUnit }) {
|
|
||||||
try {
|
|
||||||
await this._ensureInit({ refrigerant, tempUnit, pressureUnit });
|
|
||||||
const tempK = this._convertTempToK(temperature, tempUnit);
|
|
||||||
let pressurePa;
|
|
||||||
|
|
||||||
if(this.customRef){
|
|
||||||
pressurePa = this._interpolateSaturationPressure(tempK, customRefs[refrigerant].saturation);
|
|
||||||
}else{
|
|
||||||
pressurePa = coolprop.PropsSI('P', 'T', tempK, 'Q', 0, this.customRefString || refrigerant);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'success',
|
|
||||||
pressure: this._convertPressureFromPa(pressurePa, pressureUnit),
|
|
||||||
refrigerant,
|
|
||||||
units: {
|
|
||||||
temperature: tempUnit,
|
|
||||||
pressure: pressureUnit
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
return { type: 'error', message: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async calculateSubcooling({ temperature, pressure, refrigerant = this.defaultRefrigerant, tempUnit = this.defaultTempUnit, pressureUnit = this.defaultPressureUnit }) {
|
|
||||||
try {
|
|
||||||
await this._ensureInit({ refrigerant, tempUnit, pressureUnit });
|
|
||||||
const tempK = this._convertTempToK(temperature, tempUnit);
|
|
||||||
const pressurePa = this._convertPressureToPa(pressure, pressureUnit);
|
|
||||||
let satTempK;
|
|
||||||
if(this.customRef){
|
|
||||||
// Use liquid pressure for subcooling
|
|
||||||
satTempK = this._interpolateSaturationTemperature(pressurePa, customRefs[refrigerant].saturation, 'liquid');
|
|
||||||
}else{
|
|
||||||
satTempK = coolprop.PropsSI('T', 'P', pressurePa, 'Q', 0, this.customRefString || refrigerant);
|
|
||||||
}
|
|
||||||
const subcooling = satTempK - tempK;
|
|
||||||
const result = {
|
|
||||||
type: 'success',
|
|
||||||
subcooling: Math.max(0, this._convertDeltaTempFromK(subcooling, tempUnit)), // can't have less than 0 degrees subcooling
|
|
||||||
saturationTemperature: this._convertTempFromK(satTempK, tempUnit),
|
|
||||||
refrigerant,
|
|
||||||
units: {
|
|
||||||
temperature: tempUnit,
|
|
||||||
pressure: pressureUnit
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if(result.subcooling == Infinity && result.saturationTemperature == Infinity) {
|
|
||||||
return { type: 'error', message: 'Subcooling is infinity', note: 'If the pressures are in an expected range that this should work, please check your refrigerant type works in coolprop. "R507" for example is not supported, as it needs to be "R507a"'};
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
return { type: 'error', message: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async calculateSuperheat({ temperature, pressure, refrigerant = this.defaultRefrigerant, tempUnit = this.defaultTempUnit, pressureUnit = this.defaultPressureUnit }) {
|
|
||||||
try {
|
|
||||||
await this._ensureInit({ refrigerant, tempUnit, pressureUnit });
|
|
||||||
const tempK = this._convertTempToK(temperature, tempUnit);
|
|
||||||
const pressurePa = this._convertPressureToPa(pressure, pressureUnit);
|
|
||||||
//console.log(`In calculateSuperheat, pressurePa: ${pressurePa}, pressure: ${pressure}, pressureUnit: ${pressureUnit}, refrigerant: ${this.customRefString || refrigerant}`);
|
|
||||||
let satTempK;
|
|
||||||
if(this.customRef){
|
|
||||||
// Use vapor pressure for superheat
|
|
||||||
satTempK = this._interpolateSaturationTemperature(pressurePa, customRefs[refrigerant].saturation, 'vapor');
|
|
||||||
}else{
|
|
||||||
satTempK = coolprop.PropsSI('T', 'P', pressurePa, 'Q', 1, this.customRefString || refrigerant);
|
|
||||||
}
|
|
||||||
const superheat = tempK - satTempK;
|
|
||||||
//console.log(`superheat: ${superheat}, calculatedSuperheat: ${this._convertDeltaTempFromK(superheat, tempUnit)}, calculatedSatTempK: ${this._convertTempFromK(satTempK, tempUnit)}, tempK: ${tempK}, tempUnit: ${tempUnit}, pressurePa: ${pressurePa}, pressureUnit: ${pressureUnit}`);
|
|
||||||
const result = {
|
|
||||||
type: 'success',
|
|
||||||
superheat: Math.max(0, this._convertDeltaTempFromK(superheat, tempUnit)), // can't have less than 0 degrees superheat
|
|
||||||
saturationTemperature: this._convertTempFromK(satTempK, tempUnit),
|
|
||||||
refrigerant,
|
|
||||||
units: {
|
|
||||||
temperature: tempUnit,
|
|
||||||
pressure: pressureUnit
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if(result.superheat == Infinity && result.saturationTemperature == Infinity) {
|
|
||||||
return { type: 'error', message: 'Superheat is infinity', note: 'If the pressures are in an expected range that this should work, please check your refrigerant type works in coolprop. "R507" for example is not supported, as it needs to be "R507a"'};
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
return { type: 'error', message: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getProperties({ temperature, pressure, refrigerant = this.defaultRefrigerant, tempUnit = this.defaultTempUnit, pressureUnit = this.defaultPressureUnit }) {
|
|
||||||
try {
|
|
||||||
await this._ensureInit({ refrigerant, tempUnit, pressureUnit });
|
|
||||||
const tempK = this._convertTempToK(temperature, tempUnit);
|
|
||||||
const pressurePa = this._convertPressureToPa(pressure, pressureUnit);
|
|
||||||
if(this.customRef){
|
|
||||||
return { type: 'error', message: 'Custom refrigerants are not supported for getProperties' };
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = {
|
|
||||||
temperature: this._convertTempFromK(tempK, tempUnit),
|
|
||||||
pressure: this._convertPressureFromPa(pressurePa, pressureUnit),
|
|
||||||
density: coolprop.PropsSI('D', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant),
|
|
||||||
enthalpy: coolprop.PropsSI('H', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant),
|
|
||||||
entropy: coolprop.PropsSI('S', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant),
|
|
||||||
quality: coolprop.PropsSI('Q', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant),
|
|
||||||
conductivity: coolprop.PropsSI('L', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant),
|
|
||||||
viscosity: coolprop.PropsSI('V', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant),
|
|
||||||
specificHeat: coolprop.PropsSI('C', 'T', tempK, 'P', pressurePa, this.customRefString || refrigerant)
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'success',
|
|
||||||
properties: props,
|
|
||||||
refrigerant,
|
|
||||||
units: {
|
|
||||||
temperature: tempUnit,
|
|
||||||
pressure: pressureUnit,
|
|
||||||
density: 'kg/m³',
|
|
||||||
enthalpy: 'J/kg',
|
|
||||||
entropy: 'J/kg/K',
|
|
||||||
quality: 'dimensionless',
|
|
||||||
conductivity: 'W/m/K',
|
|
||||||
viscosity: 'Pa·s',
|
|
||||||
specificHeat: 'J/kg/K'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
return { type: 'error', message: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Direct access to CoolProp functions
|
|
||||||
async getPropsSI() {
|
|
||||||
if(!this.initialized) {
|
|
||||||
await coolprop.init();
|
|
||||||
}
|
|
||||||
return coolprop.PropsSI;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new CoolPropWrapper();
|
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
module.exports.R448a = {
|
|
||||||
saturation: [{
|
|
||||||
//values in kelvin, pascal
|
|
||||||
"K": 233.15,
|
|
||||||
"liquid": 135137.24,
|
|
||||||
"vapor": 101352.93
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 238.71,
|
|
||||||
"liquid": 173058.40,
|
|
||||||
"vapor": 131689.86
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 244.26,
|
|
||||||
"liquid": 218563.80,
|
|
||||||
"vapor": 168921.55
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 249.82,
|
|
||||||
"liquid": 273032.38,
|
|
||||||
"vapor": 214426.94
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 255.37,
|
|
||||||
"liquid": 337153.62,
|
|
||||||
"vapor": 268895.52
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 260.93,
|
|
||||||
"liquid": 412306.47,
|
|
||||||
"vapor": 333016.76
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 266.48,
|
|
||||||
"liquid": 499869.88,
|
|
||||||
"vapor": 408859.09
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 272.04,
|
|
||||||
"liquid": 599843.86,
|
|
||||||
"vapor": 496422.50
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 277.59,
|
|
||||||
"liquid": 714986.30,
|
|
||||||
"vapor": 598464.91
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 283.15,
|
|
||||||
"liquid": 845986.68,
|
|
||||||
"vapor": 714986.30
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 288.71,
|
|
||||||
"liquid": 990776.58,
|
|
||||||
"vapor": 845986.68
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 294.26,
|
|
||||||
"liquid": 1163145.51,
|
|
||||||
"vapor": 997671.34
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 299.82,
|
|
||||||
"liquid": 1349303.94,
|
|
||||||
"vapor": 1170040.26
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 305.37,
|
|
||||||
"liquid": 1556146.65,
|
|
||||||
"vapor": 1363093.46
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 310.93,
|
|
||||||
"liquid": 1783673.64,
|
|
||||||
"vapor": 1576830.93
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 316.48,
|
|
||||||
"liquid": 2038779.64,
|
|
||||||
"vapor": 1818147.42
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 322.04,
|
|
||||||
"liquid": 2314569.92,
|
|
||||||
"vapor": 2087042.94
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 327.59,
|
|
||||||
"liquid": 2617939.23,
|
|
||||||
"vapor": 2383517.49
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 333.15,
|
|
||||||
"liquid": 2955782.33,
|
|
||||||
"vapor": 2714465.83
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 338.71,
|
|
||||||
"liquid": 3321204.45,
|
|
||||||
"vapor": 3086782.71
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
module.exports.R448A = module.exports.R448a;
|
|
||||||
|
|
||||||
module.exports.R449A = {
|
|
||||||
saturation: [
|
|
||||||
{
|
|
||||||
// values in kelvin, pascal
|
|
||||||
"K": 233.15,
|
|
||||||
"liquid": 134447.82,
|
|
||||||
"vapor": 101352.97
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 235.93,
|
|
||||||
"liquid": 152374.20,
|
|
||||||
"vapor": 115121.57
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 238.71,
|
|
||||||
"liquid": 171679.52,
|
|
||||||
"vapor": 131689.92
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 241.48,
|
|
||||||
"liquid": 193052.21,
|
|
||||||
"vapor": 148949.73
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 244.26,
|
|
||||||
"liquid": 216503.85,
|
|
||||||
"vapor": 168255.05
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 247.04,
|
|
||||||
"liquid": 242702.42,
|
|
||||||
"vapor": 189627.74
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 249.82,
|
|
||||||
"liquid": 270979.90,
|
|
||||||
"vapor": 213768.86
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 252.59,
|
|
||||||
"liquid": 301336.31,
|
|
||||||
"vapor": 240051.48
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 255.37,
|
|
||||||
"liquid": 334440.63,
|
|
||||||
"vapor": 267609.92
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 258.15,
|
|
||||||
"liquid": 370292.86,
|
|
||||||
"vapor": 298655.80
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 260.93,
|
|
||||||
"liquid": 408892.90,
|
|
||||||
"vapor": 331760.12
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 263.71,
|
|
||||||
"liquid": 450240.76,
|
|
||||||
"vapor": 367612.35
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 266.48,
|
|
||||||
"liquid": 495036.08,
|
|
||||||
"vapor": 406831.32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 269.26,
|
|
||||||
"liquid": 542579.32,
|
|
||||||
"vapor": 448868.64
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 272.04,
|
|
||||||
"liquid": 594279.82,
|
|
||||||
"vapor": 493663.96
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 274.82,
|
|
||||||
"liquid": 649728.18,
|
|
||||||
"vapor": 542579.32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 277.59,
|
|
||||||
"liquid": 708053.32,
|
|
||||||
"vapor": 594969.28
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 280.37,
|
|
||||||
"liquid": 770873.08,
|
|
||||||
"vapor": 650767.64
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 283.15,
|
|
||||||
"liquid": 839126.92,
|
|
||||||
"vapor": 710801.16
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 285.93,
|
|
||||||
"liquid": 912814.72,
|
|
||||||
"vapor": 774989.44
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 288.71,
|
|
||||||
"liquid": 983940.92,
|
|
||||||
"vapor": 845977.32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 291.48,
|
|
||||||
"liquid": 1066606.52,
|
|
||||||
"vapor": 914889.32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 294.26,
|
|
||||||
"liquid": 1151351.00,
|
|
||||||
"vapor": 990835.62
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 297.04,
|
|
||||||
"liquid": 1238843.30,
|
|
||||||
"vapor": 1073501.22
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 299.82,
|
|
||||||
"liquid": 1335552.20,
|
|
||||||
"vapor": 1165089.32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 302.59,
|
|
||||||
"liquid": 1432261.10,
|
|
||||||
"vapor": 1256677.42
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 305.37,
|
|
||||||
"liquid": 1535864.72,
|
|
||||||
"vapor": 1357134.12
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 308.15,
|
|
||||||
"liquid": 1646363.00,
|
|
||||||
"vapor": 1457590.92
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 310.93,
|
|
||||||
"liquid": 1763756.02,
|
|
||||||
"vapor": 1568089.12
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 313.71,
|
|
||||||
"liquid": 1887043.62,
|
|
||||||
"vapor": 1678587.32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 316.48,
|
|
||||||
"liquid": 2017225.92,
|
|
||||||
"vapor": 1802217.02
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 319.26,
|
|
||||||
"liquid": 2147408.22,
|
|
||||||
"vapor": 1934952.12
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 322.04,
|
|
||||||
"liquid": 2291329.82,
|
|
||||||
"vapor": 2072621.52
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 324.82,
|
|
||||||
"liquid": 2435251.42,
|
|
||||||
"vapor": 2217185.62
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 327.59,
|
|
||||||
"liquid": 2592912.32,
|
|
||||||
"vapor": 2368644.42
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 330.37,
|
|
||||||
"liquid": 2750573.22,
|
|
||||||
"vapor": 2526305.32
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 333.15,
|
|
||||||
"liquid": 2925424.52,
|
|
||||||
"vapor": 2690860.82
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 335.93,
|
|
||||||
"liquid": 3100275.92,
|
|
||||||
"vapor": 2871668.52
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"K": 338.71,
|
|
||||||
"liquid": 3288922.02,
|
|
||||||
"vapor": 3059370.92
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
|
|
||||||
module.exports.R449a = module.exports.R449A;
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
const coolprop = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('R448a Real Values', () => {
|
|
||||||
it('should calculate superheat correctly at -40°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -35, // 5K above saturation temp of -40°C
|
|
||||||
pressure: 0, // saturation pressure at -40°C (from chart)
|
|
||||||
refrigerant: 'R448a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat - 5)).toBeLessThan(0.2); // Should be ~5K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate superheat correctly at -20°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -15, // 5K above saturation temp of -20°C
|
|
||||||
pressure: 21.0, // saturation pressure at -20°C (from chart)
|
|
||||||
refrigerant: 'R448a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
//console.log(result);
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat - 5)).toBeLessThan(0.2); // Should be ~5K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 30°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 25, // 5K below saturation temp of 30°C
|
|
||||||
pressure: 198.1, // saturation pressure at 30°C (from chart)
|
|
||||||
refrigerant: 'R448a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.2); // Should be ~5K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 40°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 35, // 5K below saturation temp of 40°C
|
|
||||||
pressure: 258.0, // saturation pressure at 40°C (from chart)
|
|
||||||
refrigerant: 'R448a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.2); // Should be ~5K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero superheat at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 0, // Exact saturation temperature
|
|
||||||
pressure: 60.1, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R448a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat)).toBeLessThan(0.2); // Should be ~0K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero subcooling at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 20, // Exact saturation temperature
|
|
||||||
pressure: 148.5, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R448a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling)).toBeLessThan(0.2); // Should be ~0K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('It should also work with R448A (capital A)', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 20, // Exact saturation temperature
|
|
||||||
pressure: 148.5, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R448A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling)).toBeLessThan(0.2); // Should be ~0K subcooling
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
const coolprop = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('R449a Real Values', () => {
|
|
||||||
it('should calculate superheat correctly at -40°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -35, // 5K above saturation temp of -40°C
|
|
||||||
pressure: 0, // saturation pressure at -40°C (from chart)
|
|
||||||
refrigerant: 'R449a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat - 5)).toBeLessThan(0.2); // Should be ~5K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate superheat correctly at -20°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -15, // 5K above saturation temp of -20°C
|
|
||||||
pressure: 20.96, // saturation pressure at -20°C (from chart)
|
|
||||||
refrigerant: 'R449a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
//console.log(result);
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat - 5)).toBeLessThan(0.2); // Should be ~5K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 30°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 25, // 5K below saturation temp of 30°C
|
|
||||||
pressure: 195, // saturation pressure at 30°C (from chart)
|
|
||||||
refrigerant: 'R449a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.2); // Should be ~5K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 40°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 35, // 5K below saturation temp of 40°C
|
|
||||||
pressure: 254.2, // saturation pressure at 40°C (from chart)
|
|
||||||
refrigerant: 'R449a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.2); // Should be ~5K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero superheat at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 0, // Exact saturation temperature
|
|
||||||
pressure: 74.05, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R449a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat)).toBeLessThan(0.2); // Should be ~0K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero subcooling at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 20, // Exact saturation temperature
|
|
||||||
pressure: 146.0, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R449a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling)).toBeLessThan(0.2); // Should be ~0K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('It should also work with R449A (capital A)', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 20, // Exact saturation temperature
|
|
||||||
pressure: 146.0, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R449A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling)).toBeLessThan(0.2); // Should be ~0K subcooling
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
const coolprop = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('R507 Real Values', () => {
|
|
||||||
it('should calculate superheat correctly at -40°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -35, // 5K above saturation temp of -40°C
|
|
||||||
pressure: 5.4, // saturation pressure at -40°C (from chart)
|
|
||||||
refrigerant: 'R507a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat - 5)).toBeLessThan(0.1); // Should be ~5K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate superheat correctly at -20°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -15, // 5K above saturation temp of -20°C
|
|
||||||
pressure: 30.9, // saturation pressure at -20°C (from chart)
|
|
||||||
refrigerant: 'R507a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat - 5)).toBeLessThan(0.1); // Should be ~5K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 30°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 25, // 5K below saturation temp of 30°C
|
|
||||||
pressure: 196.9, // saturation pressure at 30°C (from chart)
|
|
||||||
refrigerant: 'R507a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.1); // Should be ~5K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 40°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 35, // 5K below saturation temp of 40°C
|
|
||||||
pressure: 256.2, // saturation pressure at 40°C (from chart)
|
|
||||||
refrigerant: 'R507a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.1); // Should be ~5K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero superheat at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 0, // Exact saturation temperature
|
|
||||||
pressure: 75.8, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R507a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat)).toBeLessThan(0.1); // Should be ~0K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero subcooling at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 20, // Exact saturation temperature
|
|
||||||
pressure: 148, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R507a',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling)).toBeLessThan(0.1); // Should be ~0K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 30°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 25, // 5K below saturation temp of 30°C
|
|
||||||
pressure: 196.9, // saturation pressure at 30°C (from chart)
|
|
||||||
refrigerant: 'R507',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('error');
|
|
||||||
expect(result.message).toBe('Subcooling is infinity');
|
|
||||||
expect(result.note).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
const coolprop = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('R744 (CO2) Real Values', () => {
|
|
||||||
it('should calculate superheat correctly at -40°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -35, // 5K above saturation temp of -40°C
|
|
||||||
pressure: 9.03, // saturation pressure at -40°C (from chart)
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat - 5)).toBeLessThan(0.1); // Should be ~5K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 0°C saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: -5, // 5K below saturation temp of 0°C
|
|
||||||
pressure: 33.84, // saturation pressure at 0°C (from chart)
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.1); // Should be ~5K subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero superheat at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -20, // Exact saturation temperature
|
|
||||||
pressure: 18.68, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat)).toBeLessThan(0.1); // Should be ~0K superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero subcooling at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 10, // Exact saturation temperature
|
|
||||||
pressure: 44.01, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling)).toBeLessThan(0.1); // Should be ~0K subcooling
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
const coolprop = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('R744 (CO2) Real Values', () => {
|
|
||||||
it('should calculate superheat correctly at -40°F saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: -35, // 5°F above saturation temp of -40°F
|
|
||||||
pressure: 131, // saturation pressure at -40°F (from chart)
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'F', // Changed to F
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat - 5)).toBeLessThan(0.1); // Should be ~5°F superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling correctly at 32°F saturation', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 27, // 5°F below saturation temp of 32°F
|
|
||||||
pressure: 490.8, // saturation pressure at 32°F (from chart)
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'F', // Changed to F
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling - 5)).toBeLessThan(0.1); // Should be ~5°F subcooling
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero superheat at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 32, // Exact saturation temperature
|
|
||||||
pressure: 490.8, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'F', // Changed to F
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.superheat)).toBeLessThan(0.1); // Should be ~0°F superheat
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate zero subcooling at saturation point', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 32, // Exact saturation temperature
|
|
||||||
pressure: 490.8, // Matching saturation pressure from chart
|
|
||||||
refrigerant: 'R744',
|
|
||||||
tempUnit: 'F', // Changed to F
|
|
||||||
pressureUnit: 'psig'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(Math.abs(result.subcooling)).toBeLessThan(0.1); // Should be ~0°F subcooling
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,296 +0,0 @@
|
|||||||
const coolprop = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('CoolProp Wrapper', () => {
|
|
||||||
describe('Initialization', () => {
|
|
||||||
it('should fail without refrigerant', async () => {
|
|
||||||
const result = await coolprop.init({});
|
|
||||||
expect(result.type).toBe('error');
|
|
||||||
expect(result.message).toContain('Refrigerant must be specified');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail with invalid temperature unit', async () => {
|
|
||||||
const result = await coolprop.init({ refrigerant: 'R404A', tempUnit: 'X' });
|
|
||||||
expect(result.type).toBe('error');
|
|
||||||
expect(result.message).toContain('Invalid temperature unit');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should fail with invalid pressure unit', async () => {
|
|
||||||
const result = await coolprop.init({ refrigerant: 'R404A', pressureUnit: 'X' });
|
|
||||||
expect(result.type).toBe('error');
|
|
||||||
expect(result.message).toContain('Invalid pressure unit');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should succeed with valid config', async () => {
|
|
||||||
const result = await coolprop.init({
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
console.log(result);
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Auto-initialization', () => {
|
|
||||||
it('should work without explicit init', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 25,
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(result.superheat).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Unit Conversions', () => {
|
|
||||||
it('should correctly convert temperature units', async () => {
|
|
||||||
const resultC = await coolprop.getSaturationTemperature({
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
pressureUnit: 'bar',
|
|
||||||
tempUnit: 'C'
|
|
||||||
});
|
|
||||||
|
|
||||||
const resultF = await coolprop.getSaturationTemperature({
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
pressureUnit: 'bar',
|
|
||||||
tempUnit: 'F'
|
|
||||||
});
|
|
||||||
|
|
||||||
const resultK = await coolprop.getSaturationTemperature({
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
pressureUnit: 'bar',
|
|
||||||
tempUnit: 'K'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(Math.abs((resultC.temperature * 9/5 + 32) - resultF.temperature)).toBeLessThan(0.01);
|
|
||||||
expect(Math.abs((resultC.temperature + 273.15) - resultK.temperature)).toBeLessThan(0.01);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly convert pressure units', async () => {
|
|
||||||
const resultBar = await coolprop.getSaturationPressure({
|
|
||||||
temperature: 25,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
const resultPsi = await coolprop.getSaturationPressure({
|
|
||||||
temperature: 25,
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'psi'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(Math.abs((resultBar.pressure * 14.5038) - resultPsi.pressure)).toBeLessThan(0.1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Refrigerant Calculations', () => {
|
|
||||||
const refrigerants = ['R404A', 'R134a', 'R507A', 'R744'];
|
|
||||||
|
|
||||||
refrigerants.forEach(refrigerant => {
|
|
||||||
describe(refrigerant, () => {
|
|
||||||
it('should calculate superheat', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 25,
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant,
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(result.superheat).toBeDefined();
|
|
||||||
expect(result.refrigerant).toBe(refrigerant);
|
|
||||||
expect(result.units).toEqual(expect.objectContaining({
|
|
||||||
temperature: 'C',
|
|
||||||
pressure: 'bar'
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should calculate subcooling', async () => {
|
|
||||||
const result = await coolprop.calculateSubcooling({
|
|
||||||
temperature: 20,
|
|
||||||
pressure: 20,
|
|
||||||
refrigerant,
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(result.subcooling).toBeDefined();
|
|
||||||
expect(result.refrigerant).toBe(refrigerant);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should get all properties', async () => {
|
|
||||||
const result = await coolprop.getProperties({
|
|
||||||
temperature: 25,
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant,
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
expect(result.type).toBe('success');
|
|
||||||
expect(result.properties).toBeDefined();
|
|
||||||
expect(result.refrigerant).toBe(refrigerant);
|
|
||||||
|
|
||||||
// Check all required properties exist
|
|
||||||
const requiredProps = [
|
|
||||||
'temperature', 'pressure', 'density', 'enthalpy',
|
|
||||||
'entropy', 'quality', 'conductivity', 'viscosity', 'specificHeat'
|
|
||||||
];
|
|
||||||
requiredProps.forEach(prop => {
|
|
||||||
expect(result.properties[prop]).toBeDefined();
|
|
||||||
expect(typeof result.properties[prop]).toBe('number');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Default Override Behavior', () => {
|
|
||||||
beforeAll(async () => {
|
|
||||||
await coolprop.init({
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should use defaults when no overrides provided', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 25,
|
|
||||||
pressure: 10
|
|
||||||
});
|
|
||||||
expect(result.refrigerant).toBe('R404A');
|
|
||||||
expect(result.units.temperature).toBe('C');
|
|
||||||
expect(result.units.pressure).toBe('bar');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow refrigerant override', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 25,
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant: 'R134a'
|
|
||||||
});
|
|
||||||
expect(result.refrigerant).toBe('R134a');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow unit overrides', async () => {
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 77,
|
|
||||||
pressure: 145,
|
|
||||||
tempUnit: 'F',
|
|
||||||
pressureUnit: 'psi'
|
|
||||||
});
|
|
||||||
expect(result.units.temperature).toBe('F');
|
|
||||||
expect(result.units.pressure).toBe('psi');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Default Settings Management', () => {
|
|
||||||
it('should allow updating defaults after initialization', async () => {
|
|
||||||
// Initial setup
|
|
||||||
await coolprop.init({
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update defaults
|
|
||||||
const updateResult = await coolprop.init({
|
|
||||||
refrigerant: 'R134a',
|
|
||||||
tempUnit: 'F',
|
|
||||||
pressureUnit: 'psi'
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(updateResult.type).toBe('success');
|
|
||||||
expect(updateResult.message).toBe('Default settings updated');
|
|
||||||
|
|
||||||
// Verify new defaults are used
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 77,
|
|
||||||
pressure: 145
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.refrigerant).toBe('R134a');
|
|
||||||
expect(result.units.temperature).toBe('F');
|
|
||||||
expect(result.units.pressure).toBe('psi');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should update the coolprop instance if refrigerant is changed', async () => {
|
|
||||||
// Set initial defaults
|
|
||||||
await coolprop.init({
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
const config = await coolprop.getConfig();
|
|
||||||
|
|
||||||
// First call with overrides
|
|
||||||
const result1 = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 25,
|
|
||||||
pressure: 10,
|
|
||||||
refrigerant: 'R507A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Second call using defaults
|
|
||||||
const result2 = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 25,
|
|
||||||
pressure: 10
|
|
||||||
});
|
|
||||||
const config2 = await coolprop.getConfig();
|
|
||||||
expect(config.refrigerant).toBe('R404A');
|
|
||||||
expect(config2.refrigerant).toBe('R507A');
|
|
||||||
expect(result1.refrigerant).toBe('R507A');
|
|
||||||
expect(result2.refrigerant).toBe('R507A');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should allow partial updates of defaults', async () => {
|
|
||||||
// Initial setup
|
|
||||||
await coolprop.init({
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update only temperature unit
|
|
||||||
await coolprop.init({
|
|
||||||
tempUnit: 'F'
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await coolprop.calculateSuperheat({
|
|
||||||
temperature: 77,
|
|
||||||
pressure: 10
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.refrigerant).toBe('R404A'); // unchanged
|
|
||||||
expect(result.units.temperature).toBe('F'); // updated
|
|
||||||
expect(result.units.pressure).toBe('bar'); // unchanged
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should validate units when updating defaults', async () => {
|
|
||||||
await coolprop.init({
|
|
||||||
refrigerant: 'R404A',
|
|
||||||
tempUnit: 'C',
|
|
||||||
pressureUnit: 'bar'
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await coolprop.init({
|
|
||||||
tempUnit: 'X' // invalid unit
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(result.type).toBe('error');
|
|
||||||
expect(result.message).toContain('Invalid temperature unit');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
const coolprop = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('Pressure Conversion Chain Tests', () => {
|
|
||||||
|
|
||||||
test('bar -> pa -> bara -> pa -> bar conversion chain', () => {
|
|
||||||
const startValue = 2; // 2 bar gauge
|
|
||||||
|
|
||||||
const toPa = coolprop._convertPressureToPa(startValue, 'bar');
|
|
||||||
// console.log('bar to Pa:', toPa);
|
|
||||||
|
|
||||||
const toBara = coolprop._convertPressureFromPa(toPa, 'bara');
|
|
||||||
// console.log('Pa to bara:', toBara);
|
|
||||||
|
|
||||||
const backToPa = coolprop._convertPressureToPa(toBara, 'bara');
|
|
||||||
// console.log('bara to Pa:', backToPa);
|
|
||||||
|
|
||||||
const backToBar = coolprop._convertPressureFromPa(backToPa, 'bar');
|
|
||||||
// console.log('Pa to bar:', backToBar);
|
|
||||||
|
|
||||||
expect(Math.round(backToBar * 1000) / 1000).toBe(startValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('psi -> pa -> psia -> pa -> psi conversion chain', () => {
|
|
||||||
const startValue = 30; // 30 psi gauge
|
|
||||||
|
|
||||||
const toPa = coolprop._convertPressureToPa(startValue, 'psi');
|
|
||||||
// console.log('psi to Pa:', toPa);
|
|
||||||
|
|
||||||
const toPsia = coolprop._convertPressureFromPa(toPa, 'psia');
|
|
||||||
// console.log('Pa to psia:', toPsia);
|
|
||||||
|
|
||||||
const backToPa = coolprop._convertPressureToPa(toPsia, 'psia');
|
|
||||||
// console.log('psia to Pa:', backToPa);
|
|
||||||
|
|
||||||
const backToPsi = coolprop._convertPressureFromPa(backToPa, 'psi');
|
|
||||||
// console.log('Pa to psi:', backToPsi);
|
|
||||||
|
|
||||||
expect(Math.round(backToPsi * 1000) / 1000).toBe(startValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('kpa -> pa -> kpaa -> pa -> kpa conversion chain', () => {
|
|
||||||
const startValue = 200; // 200 kPa gauge
|
|
||||||
|
|
||||||
const toPa = coolprop._convertPressureToPa(startValue, 'kpa');
|
|
||||||
// console.log('kpa to Pa:', toPa);
|
|
||||||
|
|
||||||
const toKpaa = coolprop._convertPressureFromPa(toPa, 'kpaa');
|
|
||||||
// console.log('Pa to kpaa:', toKpaa);
|
|
||||||
|
|
||||||
const backToPa = coolprop._convertPressureToPa(toKpaa, 'kpaa');
|
|
||||||
// console.log('kpaa to Pa:', backToPa);
|
|
||||||
|
|
||||||
const backToKpa = coolprop._convertPressureFromPa(backToPa, 'kpa');
|
|
||||||
// console.log('Pa to kpa:', backToKpa);
|
|
||||||
|
|
||||||
expect(Math.round(backToKpa * 1000) / 1000).toBe(startValue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
const coolProp = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('PropsSI Direct Access', () => {
|
|
||||||
let PropsSI;
|
|
||||||
|
|
||||||
beforeAll(async () => {
|
|
||||||
// Get the PropsSI function
|
|
||||||
PropsSI = await coolProp.getPropsSI();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should initialize and return PropsSI function', async () => {
|
|
||||||
expect(typeof PropsSI).toBe('function');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should calculate saturation temperature of R134a at 1 bar', () => {
|
|
||||||
const pressure = 100000; // 1 bar in Pa
|
|
||||||
const temp = PropsSI('T', 'P', pressure, 'Q', 0, 'R134a');
|
|
||||||
expect(temp).toBeCloseTo(246.79, 1); // ~246.79 K at 1 bar
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should calculate density of R134a at specific conditions', () => {
|
|
||||||
const temp = 300; // 300 K
|
|
||||||
const pressure = 100000; // 1 bar in Pa
|
|
||||||
const density = PropsSI('D', 'T', temp, 'P', pressure, 'R134a');
|
|
||||||
expect(density).toBeGreaterThan(0)
|
|
||||||
expect(density).toBeLessThan(Infinity);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should throw error for invalid refrigerant', () => {
|
|
||||||
const temp = 300;
|
|
||||||
const pressure = 100000;
|
|
||||||
expect(() => {
|
|
||||||
let result = PropsSI('D', 'T', temp, 'P', pressure, 'INVALID_REFRIGERANT');
|
|
||||||
if(result == Infinity) {
|
|
||||||
throw new Error('Infinity due to invalid refrigerant');
|
|
||||||
}
|
|
||||||
}).toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should throw error for invalid input parameter', () => {
|
|
||||||
const temp = 300;
|
|
||||||
const pressure = 100000;
|
|
||||||
expect(() => {
|
|
||||||
let result = PropsSI('INVALID_PARAM', 'T', temp, 'P', pressure, 'R134a');
|
|
||||||
if(result == Infinity) {
|
|
||||||
throw new Error('Infinity due to invalid input parameter');
|
|
||||||
}
|
|
||||||
}).toThrow();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
const coolprop = require('../src/index.js');
|
|
||||||
|
|
||||||
describe('Temperature Conversion Tests', () => {
|
|
||||||
|
|
||||||
describe('Regular Temperature Conversions', () => {
|
|
||||||
const testCases = [
|
|
||||||
{
|
|
||||||
startUnit: 'C',
|
|
||||||
startValue: 25,
|
|
||||||
expectedK: 298.15,
|
|
||||||
conversions: {
|
|
||||||
F: 77,
|
|
||||||
K: 298.15,
|
|
||||||
C: 25
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
startUnit: 'F',
|
|
||||||
startValue: 77,
|
|
||||||
expectedK: 298.15,
|
|
||||||
conversions: {
|
|
||||||
F: 77,
|
|
||||||
K: 298.15,
|
|
||||||
C: 25
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
startUnit: 'K',
|
|
||||||
startValue: 298.15,
|
|
||||||
expectedK: 298.15,
|
|
||||||
conversions: {
|
|
||||||
F: 77,
|
|
||||||
K: 298.15,
|
|
||||||
C: 25
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
testCases.forEach(({ startUnit, startValue, expectedK, conversions }) => {
|
|
||||||
test(`${startValue}${startUnit} conversion chain`, () => {
|
|
||||||
// First convert to Kelvin
|
|
||||||
const toK = coolprop._convertTempToK(startValue, startUnit);
|
|
||||||
expect(Math.round(toK * 100) / 100).toBe(expectedK);
|
|
||||||
|
|
||||||
// Then convert from Kelvin to each unit
|
|
||||||
Object.entries(conversions).forEach(([unit, expected]) => {
|
|
||||||
const converted = coolprop._convertTempFromK(toK, unit);
|
|
||||||
expect(Math.round(converted * 100) / 100).toBe(expected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Delta Temperature Conversions', () => {
|
|
||||||
const testCases = [
|
|
||||||
{
|
|
||||||
startValue: 10, // 10K temperature difference
|
|
||||||
expected: {
|
|
||||||
K: 10,
|
|
||||||
C: 10,
|
|
||||||
F: 18 // 10K = 18°F difference
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
testCases.forEach(({ startValue, expected }) => {
|
|
||||||
test(`${startValue}K delta conversion to all units`, () => {
|
|
||||||
Object.entries(expected).forEach(([unit, expectedValue]) => {
|
|
||||||
const converted = coolprop._convertDeltaTempFromK(startValue, unit);
|
|
||||||
expect(Math.round(converted * 100) / 100).toBe(expectedValue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Common Temperature Points', () => {
|
|
||||||
const commonPoints = [
|
|
||||||
{
|
|
||||||
description: 'Water freezing point',
|
|
||||||
C: 0,
|
|
||||||
F: 32,
|
|
||||||
K: 273.15
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: 'Water boiling point',
|
|
||||||
C: 100,
|
|
||||||
F: 212,
|
|
||||||
K: 373.15
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: 'Room temperature',
|
|
||||||
C: 20,
|
|
||||||
F: 68,
|
|
||||||
K: 293.15
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: 'Typical refrigeration evaporator',
|
|
||||||
C: 5,
|
|
||||||
F: 41,
|
|
||||||
K: 278.15
|
|
||||||
},
|
|
||||||
{
|
|
||||||
description: 'Typical refrigeration condenser',
|
|
||||||
C: 35,
|
|
||||||
F: 95,
|
|
||||||
K: 308.15
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
commonPoints.forEach(point => {
|
|
||||||
test(`${point.description} conversions`, () => {
|
|
||||||
// Test conversion to Kelvin from each unit
|
|
||||||
const fromC = coolprop._convertTempToK(point.C, 'C');
|
|
||||||
const fromF = coolprop._convertTempToK(point.F, 'F');
|
|
||||||
|
|
||||||
expect(Math.round(fromC * 100) / 100).toBe(point.K);
|
|
||||||
expect(Math.round(fromF * 100) / 100).toBe(point.K);
|
|
||||||
|
|
||||||
// Test conversion from Kelvin to each unit
|
|
||||||
const toC = coolprop._convertTempFromK(point.K, 'C');
|
|
||||||
const toF = coolprop._convertTempFromK(point.K, 'F');
|
|
||||||
|
|
||||||
expect(Math.round(toC * 100) / 100).toBe(point.C);
|
|
||||||
expect(Math.round(toF * 100) / 100).toBe(point.F);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -163,7 +163,7 @@ class MeasurementContainer {
|
|||||||
|
|
||||||
// Emit the exact event your parent expects
|
// Emit the exact event your parent expects
|
||||||
this.emitter.emit(`${this._currentType}.${this._currentVariant}.${this._currentPosition}`, eventData);
|
this.emitter.emit(`${this._currentType}.${this._currentVariant}.${this._currentPosition}`, eventData);
|
||||||
console.log(`Emitted event: ${this._currentType}.${this._currentVariant}.${this._currentPosition}`, eventData);
|
console.log(`Emitted event: ${this._currentType}.${this._currentVariant}.${this._currentPosition}`);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user