C内核流量计算方法优化,前端文件名称读取优化

This commit is contained in:
lujingze committed 2026-09-11 08:48:56 +00:00
1 parent 5d5a2e1843
commit 808c484f5b
94 files changed
+20163 -4418

No files matched your search

@@ -3,7 +3,7 @@
"id": "test_mql_full_branches-historical-v1",
"description": "Historical slow-region and 2.05 s production regression target with three locked-environment repeats and approved state goldens.",
"source": {
"path": "tests/data/test_mql-full-branches-01-04.xml",
"path": "tests/baselines/simulation/test_mql_full_branches/sources/test_mql-full-branches-01-04.xml",
"sha256": "2fb95e65f5de0c85a6a17802aef74ea004087323fd00fd8d01acf0184ff71d48",
"bytes": 58860,
"xmlIsAuthoritative": true,
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,388 @@
/* Submodel PNCH012 skeleton created by AME Submodel editing utility
mar. oct. 9 14:41:15 2018 */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ameutils.h"
/* *******************************************************************************
TITLE : PNCH012
--------------------------------------------------------------------------------
DESCRIPTION :
This submodel represents a pneumatic chamber with a variable volume
and pressure dynamics.
Each port receives a mass flow rate and an enthalpy flow rate as
input and gives the pressure and the temperature of the chamber as
output. Each port receives also the volume and volume variation as
input. The total volume is calculated by summing the four volume
inputs and a dead volume which is a parameter of PNCH012.
The model takes into account heat exchange. It express the variation
of internal energy U using the first law of thermodynamics applied to
an open system. Therefore, this model should be preferred to the simple
polytropic chamber PNCH011.
The total volume of the chamber is limited to a lower value equal to
the dead volume divided by 100.
--------------------------------------------------------------------------------
USAGE :
Use this submodel to simulate a pneumatic chamber in a jack, spool
valve or any pneumatic chamber in which the volume can vary.
This submodel can be directly connected to any pneumatic PCD
component or standard pneumatic component.
The submodels PNGD001, PNGD002, PNGD003, PNGD004 or PNRGD00 should be
included in your circuit to define the characteristics of the gas.
--------------------------------------------------------------------------------
PARAMETER SETTINGS:
The dead volume is the volume of the pneumatic fluid when all the input
volumes are zero. It is essential that this volume must be greater
than zero.
--------------------------------------------------------------------------------
DATE OF CREATION / AUTHOR :
2002 FS from PNCH12
--------------------------------------------------------------------------------
INDEX OF REVISIONS :
2008 OBA - Real gas improvements : the mass and volume were considered as
internal state variable, they are now coded as internal basic
variable. The mass initialisation was removed as it was linked
to the perfect gas formulation.
--------------------------------------------------------------------------------
LIST OF FUNCTIONS USED :
pn2getatp : get atmospheric pressure
firstc_ : checks if this is the first call to this submodel
pn2vol_ : pneumatic chamber with heat exchange
stepdn_ : reduce simulation step
--------------------------------------------------------------------------------
SOURCE :
This material contains trade secrets or otherwise confidential
information owned by Siemens Industry Software Inc. or its
affiliates (collectively, "Siemens"), or its licensors. Access to
and use of this information is strictly limited as set forth in the
Customer's applicable agreements with Siemens.
Unpublished work. Copyright 2023 Siemens
******************************************************************************* */
#define _SUBMODELNAME_ "PNCH012"
/* >>>>>>>>>>>>Insert Private Code Here. */
/* <<<<<<<<<<<<End of Private Code. */
/* There are 4 real parameters:
cvol0 dead volume [L -> m**3]
kth thermal exchange coefficient [J/m**2/K/s -> W/m**2/K]
sth thermal exchange area [m**2]
extemp external temperature [K]
*/
/* There is 1 integer parameter:
gi gas type index
*/
void pnch012in_(int *n, double rp[4], int ip[1], double c[2]
, int ic[2], double *temp, double *press, double *dvol1
, double *vol1, double *dvol2, double *vol2, double *dvol3
, double *vol3, double *dvol4, double *vol4)
{
int loop, error;
/* >>>>>>>>>>>>Extra Initialization Function Declarations Here. */
/* <<<<<<<<<<<<End of Extra Initialization declarations. */
int gi;
double cvol0, kth, sth, extemp;
gi = ip[0];
cvol0 = rp[0];
kth = rp[1];
sth = rp[2];
extemp = rp[3];
loop = 0;
error = 0;
/* Assign default values to input(s) with default. */
*dvol1 = 0.00000000000000e+000;
*vol1 = 0.00000000000000e+000;
*dvol2 = 0.00000000000000e+000;
*vol2 = 0.00000000000000e+000;
*dvol3 = 0.00000000000000e+000;
*vol3 = 0.00000000000000e+000;
*dvol4 = 0.00000000000000e+000;
*vol4 = 0.00000000000000e+000;
/*
If necessary, check values of the following:
rp[0..3]
*temp
*press
*/
/* >>>>>>>>>>>>Initialization Function Check Statements. */
pn2_valid_gas_(&gi, &error);
if (cvol0 <= 0.0)
{
error = 2;
amefprintf(stderr, "\nVolume chamber must be strictly positive.\n");
}
if (kth < 0.0)
{
error = 2;
amefprintf(stderr, "\nthermal exchange coefficient must be positive.\n");
}
if (sth < 0.0)
{
error = 2;
amefprintf(stderr, "\nthermal exchange area must be positive.\n");
}
if (extemp <= 0.0)
{
error = 2;
amefprintf(stderr, "\nExternal temperature must be strictly positive.\n");
}
if (*temp <= 0.0)
{
error = 2;
amefprintf(stderr, "\nInitial temperature must be strictly positive.\n");
}
/* <<<<<<<<<<<<End of Initialization Check Statements. */
/* Integer parameter checking: */
if (gi < 1 || gi > 99)
{
amefprintf(stderr, "\ngas type index must be in range [1..99].\n");
error = 2;
}
if(error == 1)
{
amefprintf(stderr, "\nWarning in %s instance %d.\n", _SUBMODELNAME_, *n);
}
else if(error == 2)
{
amefprintf(stderr, "\nFatal error in %s instance %d.\n", _SUBMODELNAME_, *n);
amefprintf(stderr, "Terminating the program.\n");
AmeExit(1);
}
/* Common -> SI units conversions. */
rp[0] *= 1.00000000000000e-003;
cvol0 = rp[0];
/* >>>>>>>>>>>>Initialization Function Executable Statements. */
c[0] = cvol0 / 100;
/* Set initial value for the test of limited volume :
ic[1] = 1 when the chamber volume is limited to cvol0 / 100 else ic[1] = 0*/
ic[1] = 0;
/* set atmospheric pressure */
c[1] = pn2getatp_();
/* <<<<<<<<<<<<End of Initialization Executable Statements. */
}
/* There are 4 ports.
Port 1 has 6 variables:
1 temp temperature [K] explicit state (derivative `dtemp')
2 press pressure [Pa] explicit state (derivative `dpress')
3 dh1 enthalpy flow rate at port 1 [J/s -> W] basic variable input
4 dm1 mass flow rate at port 1 [g/s -> kg/s] basic variable input
5 dvol1 derivative of volume at port 1 [L/min -> m**3/s] basic variable input with default 0.000000e+000
6 vol1 volume at port 1 [cm**3 -> m**3] basic variable input with default 0.000000e+000
Port 2 has 6 variables:
1 temp2 duplicate of temp
2 press2 duplicate of press
3 dh2 enthalpy flow rate at port 2 [J/s -> W] basic variable input
4 dm2 mass flow rate at port 2 [g/s -> kg/s] basic variable input
5 dvol2 derivative of volume at port 2 [L/min -> m**3/s] basic variable input with default 0.000000e+000
6 vol2 volume at port 2 [cm**3 -> m**3] basic variable input with default 0.000000e+000
Port 3 has 6 variables:
1 temp3 duplicate of temp
2 press3 duplicate of press
3 dh3 enthalpy flow rate at port 3 [J/s -> W] basic variable input
4 dm3 mass flow rate at port 3 [g/s -> kg/s] basic variable input
5 dvol3 derivative of volume at port 3 [L/min -> m**3/s] basic variable input with default 0.000000e+000
6 vol3 volume at port 3 [cm**3 -> m**3] basic variable input with default 0.000000e+000
Port 4 has 6 variables:
1 temp4 duplicate of temp
2 press4 duplicate of press
3 dh4 enthalpy flow rate at port 4 [J/s -> W] basic variable input
4 dm4 mass flow rate at port 4 [g/s -> kg/s] basic variable input
5 dvol4 derivative of volume at port 4 [L/min -> m**3/s] basic variable input with default 0.000000e+000
6 vol4 volume at port 4 [cm**3 -> m**3] basic variable input with default 0.000000e+000
*/
/* There are 2 internal variables.
1 vol volume of pneumatic chamber [cm**3 -> m**3] basic variable
2 mgas1 mass of gas in chamber [g -> kg] basic variable
*/
void pnch012_(int *n, double *temp, double *dtemp, double *press
, double *dpress, double *dh1, double *dm1, double *dvol1
, double *vol1, double *dh2, double *dm2, double *dvol2
, double *vol2, double *dh3, double *dm3, double *dvol3
, double *vol3, double *dh4, double *dm4, double *dvol4
, double *vol4, double *vol, double *mgas1, double rp[4]
, int ip[1], double c[2], int ic[2])
{
int loop;
/* >>>>>>>>>>>>Extra Calculation Function Declarations Here. */
double dvol;
double sdm, sdh;
double dq;
double pressa;
/* <<<<<<<<<<<<End of Extra Calculation declarations. */
int gi;
double cvol0, kth, sth, extemp;
gi = ip[0];
cvol0 = rp[0];
kth = rp[1];
sth = rp[2];
extemp = rp[3];
loop = 0;
/* Common -> SI units conversions. */
*dm1 *= 1.00000000000000e-003;
*dvol1 *= 1.66666666666667e-005;
*vol1 *= 1.00000000000000e-006;
*dm2 *= 1.00000000000000e-003;
*dvol2 *= 1.66666666666667e-005;
*vol2 *= 1.00000000000000e-006;
*dm3 *= 1.00000000000000e-003;
*dvol3 *= 1.66666666666667e-005;
*vol3 *= 1.00000000000000e-006;
*dm4 *= 1.00000000000000e-003;
*dvol4 *= 1.66666666666667e-005;
*vol4 *= 1.00000000000000e-006;
/*
Set all submodel outputs below:
*dtemp = ??;
*dpress = ??;
*vol = ??;
*mgas1 = ??;
*/
/* >>>>>>>>>>>>Calculation Function Executable Statements. */
/* set absolute pressure */
pressa = *press + c[1];
/*** sum of the volume variation and volume ***/
dvol = *dvol1 + *dvol2 + *dvol3 + *dvol4;
/*** setup the initial mass of the gaz inside of the chamber ***/
*vol = *vol1 + *vol2 + *vol3 + *vol4 + cvol0;
/*** sum of the flows ***/
sdm = *dm1 + *dm2 + *dm3 + *dm4; /* mass flow */
sdh = *dh1 + *dh2 + *dh3 + *dh4; /* heat flow */
/*** V, M, T and P can not be lower than zero ***/
*vol = llimit_(vol, &c[0], &ic[0]);
if (ic[0] == -1)
{
dvol = 0.;
if (ic[1] == 0)
{
amefprintf(stderr, "\nWarning in %s instance %d chamber volume is limited by cvol0 / 100 = %g cm**3.\n", _SUBMODELNAME_, *n, c[0]*1E+6);
ic[1] = 1;
}
}
if (*vol < c[0]/10)
{
*vol = c[0]/10;
}
if ( (*mgas1 <= 1.0e-10) && (!firstc_()) )
{
/* panic step reduction */
stepdn_();
*mgas1 = 1.0e-10;
}
if (pressa <= 1.0e-10)
{
/* panic step reduction */
stepdn_();
*press = 1.0e-10 - c[1];
}
if (*temp <= 1.0e-10)
{
/* panic step reduction */
stepdn_();
*temp = 1.0e-10;
}
/*** temperature & pressure variation ***/
dq = kth*sth*(extemp-*temp);
pn2vol_(dtemp, dpress, mgas1, temp, &pressa,
&sdm, &sdh, vol, &dvol, &dq, &gi);
/* <<<<<<<<<<<<End of Calculation Executable Statements. */
/* SI -> Common units conversions. */
*dm1 /= 1.00000000000000e-003;
*dvol1 /= 1.66666666666667e-005;
*vol1 /= 1.00000000000000e-006;
*dm2 /= 1.00000000000000e-003;
*dvol2 /= 1.66666666666667e-005;
*vol2 /= 1.00000000000000e-006;
*dm3 /= 1.00000000000000e-003;
*dvol3 /= 1.66666666666667e-005;
*vol3 /= 1.00000000000000e-006;
*dm4 /= 1.00000000000000e-003;
*dvol4 /= 1.66666666666667e-005;
*vol4 /= 1.00000000000000e-006;
*vol /= 1.00000000000000e-006;
*mgas1 /= 1.00000000000000e-003;
}
@@ -0,0 +1,356 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE SPE>
<SPE DOC_VERSION="2" AME_VERSION="16.0.0 - 68387-65635 2017">
<SUBMODEL>
<SUB_TYPE>0</SUB_TYPE>
<SUB_ID_MAX>33</SUB_ID_MAX>
<DEFAULT_ICON>pn_c1</DEFAULT_ICON>
<SUB_LABEL>variable volume pneumatic chamber with heat exchange (preferred)</SUB_LABEL>
<SUB_UNIT>0</SUB_UNIT>
<R_STORES_NUMBER>2</R_STORES_NUMBER>
<I_STORES_NUMBER>2</I_STORES_NUMBER>
<OUTPUT_TYPE>1</OUTPUT_TYPE>
<RPARAMS_LIST>
<RPARAM>
<SUB_ID>27</SUB_ID>
<TITLE>dead volume</TITLE>
<VARNAME>cvol0</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+00</DEF_VALUE>
<VALUE>1.00000000000000e+00</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+005</MAX_VALUE>
<UNITS>L</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>28</SUB_ID>
<TITLE>thermal exchange coefficient</TITLE>
<VARNAME>kth</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>0.00000000000000e+00</DEF_VALUE>
<VALUE>0.00000000000000e+00</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<UNITS>J/m**2/K/s</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>29</SUB_ID>
<TITLE>thermal exchange area</TITLE>
<VARNAME>sth</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e-01</DEF_VALUE>
<VALUE>1.00000000000000e-01</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+002</MAX_VALUE>
<UNITS>m**2</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>30</SUB_ID>
<TITLE>external temperature</TITLE>
<VARNAME>extemp</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>2.93150000000000e+02</DEF_VALUE>
<VALUE>2.93150000000000e+02</VALUE>
<MIN_VALUE>1.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+003</MAX_VALUE>
<UNITS>K</UNITS>
</RPARAM>
</RPARAMS_LIST>
<IPARAMS_LIST>
<IPARAM>
<SUB_ID>31</SUB_ID>
<TITLE>gas type index</TITLE>
<VARNAME>gi</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>99</MAX_VALUE>
</IPARAM>
</IPARAMS_LIST>
<IVARS_LIST>
<IVAR>
<SUB_ID>32</SUB_ID>
<TITLE>volume of pneumatic chamber</TITLE>
<VARNAME>vol</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>cm**3</UNITS>
</IVAR>
<IVAR>
<SUB_ID>33</SUB_ID>
<TITLE>mass of gas in chamber</TITLE>
<VARNAME>mgas1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>g</UNITS>
</IVAR>
</IVARS_LIST>
<EVARS_LIST>
<PORT>
<EVAR>
<SUB_ID>1</SUB_ID>
<TITLE>temperature</TITLE>
<VARNAME>temp</VARNAME>
<VARNAME2>dtemp</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>K</UNITS>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+003</MAX_VALUE>
<DEF_VALUE>2.93150000000000e+002</DEF_VALUE>
<VALUE>2.93150000000000e+002</VALUE>
</EVAR>
<EVAR>
<SUB_ID>2</SUB_ID>
<TITLE>pressure</TITLE>
<VARNAME>press</VARNAME>
<VARNAME2>dpress</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>Pa</UNITS>
<MIN_VALUE>-1.01300000000000e+005</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+012</MAX_VALUE>
<DEF_VALUE>0.00000000000000e+000</DEF_VALUE>
<VALUE>0.00000000000000e+000</VALUE>
</EVAR>
<EVAR>
<SUB_ID>3</SUB_ID>
<TITLE>enthalpy flow rate at port 1</TITLE>
<VARNAME>dh1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>4</SUB_ID>
<TITLE>mass flow rate at port 1</TITLE>
<VARNAME>dm1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>5</SUB_ID>
<TITLE>derivative of volume at port 1</TITLE>
<VARNAME>dvol1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>3</IO>
<UNITS>L/min</UNITS>
<DEF_VALUE>0</DEF_VALUE>
</EVAR>
<EVAR>
<SUB_ID>6</SUB_ID>
<TITLE>volume at port 1</TITLE>
<VARNAME>vol1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>3</IO>
<UNITS>cm**3</UNITS>
<DEF_VALUE>0</DEF_VALUE>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>7</SUB_ID>
<VARNAME>temp2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>0</PRIMARY_PORT>
<PRIMARY_VAR>0</PRIMARY_VAR>
<DUP_TYPE>0</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>8</SUB_ID>
<VARNAME>press2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>0</PRIMARY_PORT>
<PRIMARY_VAR>1</PRIMARY_VAR>
<DUP_TYPE>0</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>9</SUB_ID>
<TITLE>enthalpy flow rate at port 2</TITLE>
<VARNAME>dh2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>10</SUB_ID>
<TITLE>mass flow rate at port 2</TITLE>
<VARNAME>dm2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>11</SUB_ID>
<TITLE>derivative of volume at port 2</TITLE>
<VARNAME>dvol2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>3</IO>
<UNITS>L/min</UNITS>
<DEF_VALUE>0</DEF_VALUE>
</EVAR>
<EVAR>
<SUB_ID>12</SUB_ID>
<TITLE>volume at port 2</TITLE>
<VARNAME>vol2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>3</IO>
<UNITS>cm**3</UNITS>
<DEF_VALUE>0</DEF_VALUE>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>13</SUB_ID>
<VARNAME>temp3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>0</PRIMARY_PORT>
<PRIMARY_VAR>0</PRIMARY_VAR>
<DUP_TYPE>0</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>14</SUB_ID>
<VARNAME>press3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>0</PRIMARY_PORT>
<PRIMARY_VAR>1</PRIMARY_VAR>
<DUP_TYPE>0</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>15</SUB_ID>
<TITLE>enthalpy flow rate at port 3</TITLE>
<VARNAME>dh3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>16</SUB_ID>
<TITLE>mass flow rate at port 3</TITLE>
<VARNAME>dm3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>17</SUB_ID>
<TITLE>derivative of volume at port 3</TITLE>
<VARNAME>dvol3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>3</IO>
<UNITS>L/min</UNITS>
<DEF_VALUE>0</DEF_VALUE>
</EVAR>
<EVAR>
<SUB_ID>18</SUB_ID>
<TITLE>volume at port 3</TITLE>
<VARNAME>vol3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>3</IO>
<UNITS>cm**3</UNITS>
<DEF_VALUE>0</DEF_VALUE>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>19</SUB_ID>
<VARNAME>temp4</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>0</PRIMARY_PORT>
<PRIMARY_VAR>0</PRIMARY_VAR>
<DUP_TYPE>0</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>20</SUB_ID>
<VARNAME>press4</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>0</PRIMARY_PORT>
<PRIMARY_VAR>1</PRIMARY_VAR>
<DUP_TYPE>0</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>21</SUB_ID>
<TITLE>enthalpy flow rate at port 4</TITLE>
<VARNAME>dh4</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>22</SUB_ID>
<TITLE>mass flow rate at port 4</TITLE>
<VARNAME>dm4</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>23</SUB_ID>
<TITLE>derivative of volume at port 4</TITLE>
<VARNAME>dvol4</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>3</IO>
<UNITS>L/min</UNITS>
<DEF_VALUE>0</DEF_VALUE>
</EVAR>
<EVAR>
<SUB_ID>24</SUB_ID>
<TITLE>volume at port 4</TITLE>
<VARNAME>vol4</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>3</IO>
<UNITS>cm**3</UNITS>
<DEF_VALUE>0</DEF_VALUE>
</EVAR>
</PORT>
</EVARS_LIST>
<SUBIDS_RESET>0</SUBIDS_RESET>
</SUBMODEL>
</SPE>
@@ -0,0 +1,348 @@
/* Submodel PNL0001 skeleton created by AME Submodel editing utility
mer. juin 20 14:20:39 2018 */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ameutils.h"
/* *******************************************************************************
TITLE : PNL0001 (C-R)
------------------------------------------------------------------------------
DESCRIPTION :
PNL0001 is a submodel of a pneumatic pipe with only compressibility
and friction effects taking into account heat exchange.
The compressibility of the gas is taken into account by using a
simple polytropic model or a more complex one taking into account
heat exchange.
The polytropic model is a simplified form of the general internal
energy model based on the first law of thermodynamics. The polytropic
approach is obtained by representing the thermal exchange phenomena
by a polytropic constant k. In that case, the temperature and
pressure are no more independent variables.
The reduction of the complexity of the model implies a lack of
accuracy. For general studies, you'd better use the heat exchange
approach.
Pipe friction is taken into account using a friction factor based on
the Reynolds number and the relative roughness.
The temperature and pressure in the volume are state variables.
------------------------------------------------------------------------------
USAGE :
Use this submodel to simulate a pneumatic pipe with compressibility
and friction effects, when the Mach number is low, ie gas velocity
< 0.3 * speed of sound .
The submodels PNGD001 or PNGD002 should be included in your circuit to
define the characteristics of the gas.
------------------------------------------------------------------------------
PARAMETER SETTINGS :
------------------------------------------------------------------------------
DATE OF CREATION / AUTHOR :
2002 FS from PNL01 SN.
------------------------------------------------------------------------------
REVISIONS :
------------------------------------------------------------------------------
LIST OF FUNCTIONS USED :
pn2getatp_() : get atmospheric pressure
pn2ri_() : get perfect gas constant
pn2vol1_() : polytropic model for chambers
pn2vol_() : heat exchange model for chambers
pn2pipefr_() : frictional coeffitient in pneumatic pipes
------------------------------------------------------------------------------
SOURCE :
This material contains trade secrets or otherwise confidential
information owned by Siemens Industry Software Inc. or its
affiliates (collectively, "Siemens"), or its licensors. Access to
and use of this information is strictly limited as set forth in the
Customer's applicable agreements with Siemens.
Unpublished work. Copyright 2023 Siemens
******************************************************************************* */
#define _SUBMODELNAME_ "PNL0001"
/* >>>>>>>>>>>>Insert Private Code Here. */
#define TABFR 0 /* real store 0, 1 & 2 are used by pn2pipefr */
#define PATM 3
#define AREA 4
#define VOL 5
#define AREAEX 6
#define SPL_FR 0
/* <<<<<<<<<<<<End of Private Code. */
/* There are 6 real parameters:
diam diameter of pipe [mm -> m]
le pipe length [m]
rr relative roughness [null]
k polytropic constant [null]
kth thermal exchange coefficient [J/m**2/K/s -> W/m**2/K]
extemp external temperature [K]
*/
/* There are 2 integer parameters:
gi gas type index
mode model
*/
void pnl0001in_(int *n, double rp[6], int ip[2], double c[7]
, int ic[1], double *t2, double *p2)
{
int loop, error;
/* >>>>>>>>>>>>Extra Initialization Function Declarations Here. */
/* <<<<<<<<<<<<End of Extra Initialization declarations. */
int gi, mode;
double diam, le, rr, k, kth, extemp;
gi = ip[0];
mode = ip[1];
diam = rp[0];
le = rp[1];
rr = rp[2];
k = rp[3];
kth = rp[4];
extemp = rp[5];
loop = 0;
error = 0;
/*
If necessary, check values of the following:
rp[0..5]
*t2
*p2
*/
/* >>>>>>>>>>>>Initialization Function Check Statements. */
pn2_valid_gas_(&gi, &error);
if (*p2 < -GPATMOS)
{
error = 2;
amefprintf(stderr, "\nInitial pressure at port 2 should be > 0 [barA].\n");
}
if (*t2 <= 0.0)
{
error = 2;
amefprintf(stderr, "\nInitial temperature at port 2 should be > 0 [K].\n");
}
if (diam <= 0.0)
{
error = 2;
amefprintf(stderr, "\nDiameter of pipe should be > 0 [mm].\n");
}
if (le <= 0.0)
{
error = 2;
amefprintf(stderr, "\nPipe length should be > 0 [m].\n");
}
if (rr < 0.0)
{
error = 2;
amefprintf(stderr, "\nRelative roughness should be >= 0.\n");
}
if (mode == 1)
{
if (k <= 0.)
{
error = 2;
amefprintf(stderr, "\nPolytropic constant should be > 0.\n");
}
}
else
{
if (kth < 0.)
{
error = 2;
amefprintf(stderr, "\nThermal exchange coefficient should be >= 0 [J/m**2/K/s].\n");
}
if (extemp <= 0.)
{
error = 2;
amefprintf(stderr, "\nExternal temperature should be > 0 [K].\n");
}
}
/* <<<<<<<<<<<<End of Initialization Check Statements. */
/* Integer parameter checking: */
if (gi < 1 || gi > 99)
{
amefprintf(stderr, "\ngas type index must be in range [1..99].\n");
error = 2;
}
if (mode < 1 || mode > 2)
{
amefprintf(stderr, "\nmodel must be in range [1..2].\n");
error = 2;
}
SUBMODEL_HANDLE_AND_RESET_ERROR(_SUBMODELNAME_, n, error)
/* Common -> SI units conversions. */
rp[0] *= 1.00000000000000e-003;
diam = rp[0];
/* >>>>>>>>>>>>Initialization Function Executable Statements. */
/* get atmospheric pressure */
c[PATM] = pn2getatp_();
/* Compute the cross-sectional area of pipe. */
c[AREA] = M_PI * (diam) * (diam) / 4.0;
/* Compute volume of pipe. */
c[VOL] = c[AREA] * le;
/* Compute exchange area of pipe. */
c[AREAEX] = M_PI * diam * le;
/* <<<<<<<<<<<<End of Initialization Executable Statements. */
}
/* There are 2 ports.
Port 1 has 4 variables:
1 dh1 enthalpy flow rate at port 1 [J/s -> W] basic variable output
2 dm1 mass flow rate at port 1 [g/s -> kg/s] basic variable output
3 t1 temperature at port 1 [K] basic variable input
4 p1 pressure at port 1 [Pa] basic variable input
Port 2 has 4 variables:
1 t2 temperature at port 2 [K] explicit state (derivative `dt2')
2 p2 pressure at port 2 [Pa] explicit state (derivative `dp2')
3 dh2 enthalpy flow rate at port 2 [J/s -> W] basic variable input
4 dm2 mass flow rate at port 2 [g/s -> kg/s] basic variable input
*/
/* There are 5 internal variables.
1 mgas mass of gas in pipe [g -> kg] basic variable
2 re Reynolds number [null] basic variable
3 cm mass flow parameter (cm) [(kg*K/J)**(1/2)] basic variable
4 v mean gas velocity [m/s] basic variable
5 ff friction factor [null] basic variable
*/
void pnl0001_(int *n, double *dh1, double *dm1, double *t1, double *p1
, double *t2, double *dt2, double *p2, double *dp2, double *dh2
, double *dm2, double *mgas, double *re, double *cm, double *v
, double *ff, double rp[6], int ip[2], double c[7], int ic[1])
{
int loop;
/* >>>>>>>>>>>>Extra Calculation Function Declarations Here. */
static double zero = 0.0;
double sdh;
double dh2i, dm2i;
double dq;
double pa1, pa2, dmgas;
double r;
int dummyreg;
/* <<<<<<<<<<<<End of Extra Calculation declarations. */
int gi, mode;
double diam, le, rr, k, kth, extemp;
gi = ip[0];
mode = ip[1];
diam = rp[0];
le = rp[1];
rr = rp[2];
k = rp[3];
kth = rp[4];
extemp = rp[5];
loop = 0;
/* Common -> SI units conversions. */
*dm2 *= 1.00000000000000e-003;
/*
Set all submodel outputs below:
*dh1 = ??;
*dm1 = ??;
*dt2 = ??;
*dp2 = ??;
*mgas = ??;
*re = ??;
*cm = ??;
*v = ??;
*ff = ??;
*/
/* >>>>>>>>>>>>Calculation Function Executable Statements. */
/* set absolute pressures */
pa1 = *p1 + c[PATM];
pa2 = *p2 + c[PATM];
/* Compute flows through the pipe */
pn2pipefr_(&pa1, t1, &pa2, t2, &diam, &rr, &le, &c[AREA], re, v,ff,
dh1, dm1, &dh2i, &dm2i, cm, &c[TABFR], &gi, &ic[SPL_FR], &dummyreg);
/* Compute mass variation */
dmgas = (*dm2) + dm2i;
/* sum of enthalpy flows */
sdh = (*dh2) + dh2i;
/*** temperature & pressure variation ***/
if (mode == 1) /* Polytropic model. */
{
r = pn2ri_(&gi);
/* Compute initial mass of gas inside the pipe */
*mgas = (pa2) * c[VOL] / ((*t2) * r);
pn2vol1_(dt2, dp2, t2, &pa2,
&dmgas, mgas, &zero, &c[VOL], &k, &gi);
}
else /* Heat exchange. */
{
dq = kth * c[AREAEX] * (extemp - *t2);
pn2vol_(dt2, dp2, mgas, t2, &pa2,
&dmgas, &sdh, &c[VOL], &zero, &dq, &gi);
}
/* <<<<<<<<<<<<End of Calculation Executable Statements. */
/* SI -> Common units conversions. */
*dm1 /= 1.00000000000000e-003;
*dm2 /= 1.00000000000000e-003;
*mgas /= 1.00000000000000e-003;
}
@@ -0,0 +1,257 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE SPE>
<SPE DOC_VERSION="2" AME_VERSION="16.0.0 - 68387-65635 2017">
<SUBMODEL>
<SUB_TYPE>0</SUB_TYPE>
<SUB_ID_MAX>22</SUB_ID_MAX>
<DEFAULT_ICON>p2port</DEFAULT_ICON>
<SUB_LABEL>Compressibility + friction submodel of pneumatic pipe (C-R)</SUB_LABEL>
<SUB_UNIT>0</SUB_UNIT>
<R_STORES_NUMBER>7</R_STORES_NUMBER>
<I_STORES_NUMBER>1</I_STORES_NUMBER>
<OUTPUT_TYPE>1</OUTPUT_TYPE>
<RPARAMS_LIST>
<RPARAM>
<SUB_ID>14</SUB_ID>
<TITLE>diameter of pipe</TITLE>
<VARNAME>diam</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+01</DEF_VALUE>
<VALUE>1.00000000000000e+01</VALUE>
<MIN_VALUE>1.00000000000000e-003</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+007</MAX_VALUE>
<UNITS>mm</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>15</SUB_ID>
<TITLE>pipe length</TITLE>
<VARNAME>le</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+00</DEF_VALUE>
<VALUE>1.00000000000000e+00</VALUE>
<MIN_VALUE>1.00000000000000e-006</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+004</MAX_VALUE>
<UNITS>m</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>16</SUB_ID>
<TITLE>relative roughness</TITLE>
<VARNAME>rr</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e-05</DEF_VALUE>
<VALUE>1.00000000000000e-05</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e-001</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>17</SUB_ID>
<TITLE>polytropic constant</TITLE>
<VARNAME>k</VARNAME>
<VISIBILITY>(mode == 1)</VISIBILITY>
<DEF_VALUE>1.35000000000000e+00</DEF_VALUE>
<VALUE>1.35000000000000e+00</VALUE>
<MIN_VALUE>5.00000000000000e-001</MIN_VALUE>
<MAX_VALUE>2.00000000000000e+000</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>18</SUB_ID>
<TITLE>thermal exchange coefficient</TITLE>
<VARNAME>kth</VARNAME>
<VISIBILITY>(mode == 2)</VISIBILITY>
<DEF_VALUE>0.00000000000000e+00</DEF_VALUE>
<VALUE>0.00000000000000e+00</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<UNITS>J/m**2/K/s</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>19</SUB_ID>
<TITLE>external temperature</TITLE>
<VARNAME>extemp</VARNAME>
<VISIBILITY>(mode == 2)</VISIBILITY>
<DEF_VALUE>2.93150000000000e+02</DEF_VALUE>
<VALUE>2.93150000000000e+02</VALUE>
<MIN_VALUE>1.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+003</MAX_VALUE>
<UNITS>K</UNITS>
</RPARAM>
</RPARAMS_LIST>
<IPARAMS_LIST>
<IPARAM>
<SUB_ID>20</SUB_ID>
<TITLE>gas type index</TITLE>
<VARNAME>gi</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>99</MAX_VALUE>
</IPARAM>
<IPARAM>
<SUB_ID>21</SUB_ID>
<TITLE>model</TITLE>
<VARNAME>mode</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>2</DEF_VALUE>
<VALUE>2</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>2</MAX_VALUE>
<ENUM_LIST>
<ENUM>
<ENUM_STRING>polytropic</ENUM_STRING>
</ENUM>
<ENUM>
<ENUM_STRING>with thermal exchange</ENUM_STRING>
</ENUM>
</ENUM_LIST>
</IPARAM>
</IPARAMS_LIST>
<IVARS_LIST>
<IVAR>
<SUB_ID>22</SUB_ID>
<TITLE>mass of gas in pipe</TITLE>
<VARNAME>mgas</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>g</UNITS>
</IVAR>
<IVAR>
<SUB_ID>10</SUB_ID>
<TITLE>Reynolds number</TITLE>
<VARNAME>re</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
<IVAR>
<SUB_ID>11</SUB_ID>
<TITLE>mass flow parameter (cm)</TITLE>
<VARNAME>cm</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>(kg*K/J)**(1/2)</UNITS>
</IVAR>
<IVAR>
<SUB_ID>12</SUB_ID>
<TITLE>mean gas velocity</TITLE>
<VARNAME>v</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>m/s</UNITS>
</IVAR>
<IVAR>
<SUB_ID>13</SUB_ID>
<TITLE>friction factor</TITLE>
<VARNAME>ff</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
</IVARS_LIST>
<EVARS_LIST>
<PORT>
<EVAR>
<SUB_ID>1</SUB_ID>
<TITLE>enthalpy flow rate at port 1</TITLE>
<VARNAME>dh1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>2</SUB_ID>
<TITLE>mass flow rate at port 1</TITLE>
<VARNAME>dm1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>3</SUB_ID>
<TITLE>temperature at port 1</TITLE>
<VARNAME>t1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>4</SUB_ID>
<TITLE>pressure at port 1</TITLE>
<VARNAME>p1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>5</SUB_ID>
<TITLE>temperature at port 2</TITLE>
<VARNAME>t2</VARNAME>
<VARNAME2>dt2</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>K</UNITS>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+004</MAX_VALUE>
<DEF_VALUE>2.93150000000000e+002</DEF_VALUE>
<VALUE>2.93150000000000e+002</VALUE>
</EVAR>
<EVAR>
<SUB_ID>6</SUB_ID>
<TITLE>pressure at port 2</TITLE>
<VARNAME>p2</VARNAME>
<VARNAME2>dp2</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>Pa</UNITS>
<MIN_VALUE>-1.01300000000000e+005</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+012</MAX_VALUE>
<DEF_VALUE>0.00000000000000e+000</DEF_VALUE>
<VALUE>0.00000000000000e+000</VALUE>
</EVAR>
<EVAR>
<SUB_ID>7</SUB_ID>
<TITLE>enthalpy flow rate at port 2</TITLE>
<VARNAME>dh2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>8</SUB_ID>
<TITLE>mass flow rate at port 2</TITLE>
<VARNAME>dm2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>g/s</UNITS>
</EVAR>
</PORT>
</EVARS_LIST>
<SUBIDS_RESET>0</SUBIDS_RESET>
</SUBMODEL>
</SPE>
@@ -0,0 +1,368 @@
/* Submodel PNL0002 skeleton created by AME Submodel editing utility
mer. juin 20 14:35:13 2018 */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ameutils.h"
/* *******************************************************************************
TITLE : PNL0002 (R-C-R)
------------------------------------------------------------------------------
DESCRIPTION :
PNL0002 is a submodel of a pneumatic pipe with only compressibility
and friction effects taking into account heat exchange.
The compressibility of the gas is taken into account by using a
simple polytropic model or a more complex one taking into account
heat exchange.
The polytropic model is a simplified form of the general internal
energy model based on the first law of thermodynamics. The polytropic
approach is obtained by representing the thermal exchange phenomena
by a polytropic constant k. In that case, the temperature and
pressure are no more independent variables.
The reduction of the complexity of the model implies a lack of
accuracy. For general studies, you'd better use the heat exchange
approach.
Pipe friction is taken into account using a friction factor based on
the Reynolds number and the relative roughness.
The temperature and pressure in the middle volume are state variables.
------------------------------------------------------------------------------
USAGE :
Use this submodel to simulate a pneumatic pipe with compressibility
and friction effects, when the Mach number is low, ie gas velocity
< 0.3 * speed of sound .
PNL0002 is basically similar to PNL0001 and PNL0003 differing only in the
input and output requirements.
The submodels PNGD01 or PNGD02 should be included in your circuit to
define the characteristics of the gas.
------------------------------------------------------------------------------
PARAMETER SETTINGS :
------------------------------------------------------------------------------
DATE OF CREATION / AUTHOR :
2002 FS from PNL02 SN.
------------------------------------------------------------------------------
REVISIONS :
------------------------------------------------------------------------------
LIST OF FUNCTIONS USED :
pn2getatp_() : get atmospheric pressure
pn2ri_() : get perfect gas constant
pn2vol1_() : polytropic model for chambers
pn2vol_() : heat exchange model for chambers
pn2pipefr_() : frictional coeffitient in pneumatic pipes
------------------------------------------------------------------------------
SOURCE :
This material contains trade secrets or otherwise confidential
information owned by Siemens Industry Software Inc. or its
affiliates (collectively, "Siemens"), or its licensors. Access to
and use of this information is strictly limited as set forth in the
Customer's applicable agreements with Siemens.
Unpublished work. Copyright 2023 Siemens
******************************************************************************* */
#define _SUBMODELNAME_ "PNL0002"
/* >>>>>>>>>>>>Insert Private Code Here. */
#define TABFR 0 /* real store 0, 1 & 2 are used by pn2pipefr */
#define PATM 3
#define AREA 4
#define VOL 5
#define HALFLE 6
#define AREAEX 7
#define SPL_FR 0
/* <<<<<<<<<<<<End of Private Code. */
/* There are 6 real parameters:
diam diameter of pipe [mm -> m]
le pipe length [m]
rr relative roughness [null]
k polytropic constant [null]
kth thermal exchange coefficient [J/m**2/K/s -> W/m**2/K]
extemp external temperature [K]
*/
/* There are 2 integer parameters:
gi gas type index
mode model
*/
void pnl0002in_(int *n, double rp[6], int ip[2], double c[8]
, int ic[1], double *tctr, double *pctr)
{
int loop, error;
/* >>>>>>>>>>>>Extra Initialization Function Declarations Here. */
/* <<<<<<<<<<<<End of Extra Initialization declarations. */
int gi, mode;
double diam, le, rr, k, kth, extemp;
gi = ip[0];
mode = ip[1];
diam = rp[0];
le = rp[1];
rr = rp[2];
k = rp[3];
kth = rp[4];
extemp = rp[5];
loop = 0;
error = 0;
/*
If necessary, check values of the following:
rp[0..5]
*tctr
*pctr
*/
/* >>>>>>>>>>>>Initialization Function Check Statements. */
pn2_valid_gas_(&gi, &error);
if (*pctr < -GPATMOS)
{
error = 2;
amefprintf(stderr, "\nInitial pressure at center of pipe should be > 0 [barA].\n");
}
if (*tctr <= 0.0)
{
error = 2;
amefprintf(stderr, "\nInitial temperature at center of pipe should be > 0 [K].\n");
}
if (diam <= 0.0)
{
error = 2;
amefprintf(stderr, "\nDiameter of pipe should be > 0 [mm].\n");
}
if (le <= 0.0)
{
error = 2;
amefprintf(stderr, "\nPipe length should be > 0 [m].\n");
}
if (rr < 0.0)
{
error = 2;
amefprintf(stderr, "\nRelative roughness should be >= 0.\n");
}
if (mode == 1)
{
if (k <= 0.)
{
error = 2;
amefprintf(stderr, "\nPolytropic constant should be > 0.\n");
}
}
else
{
if (kth < 0.)
{
error = 2;
amefprintf(stderr, "\nThermal exchange coefficient should be >= 0 [J/m**2/K/s].\n");
}
if (extemp <= 0.)
{
error = 2;
amefprintf(stderr, "\nExternal temperature should be > 0 [K].\n");
}
}
/* <<<<<<<<<<<<End of Initialization Check Statements. */
/* Integer parameter checking: */
if (gi < 1 || gi > 99)
{
amefprintf(stderr, "\ngas type index must be in range [1..99].\n");
error = 2;
}
if (mode < 1 || mode > 2)
{
amefprintf(stderr, "\nmodel must be in range [1..2].\n");
error = 2;
}
SUBMODEL_HANDLE_AND_RESET_ERROR(_SUBMODELNAME_, n, error)
/* Common -> SI units conversions. */
rp[0] *= 1.00000000000000e-003;
diam = rp[0];
/* >>>>>>>>>>>>Initialization Function Executable Statements. */
/* get atmospheric pressure */
c[PATM] = pn2getatp_();
/* Compute the cross-sectional area of pipe. */
c[AREA] = M_PI * (diam) * (diam) / 4.0;
/* Compute volume of pipe. */
c[VOL] = c[AREA] * le;
/* Divide the restriction in 2 identical restrictions */
c[HALFLE] = 0.5 * le;
/* Compute exchange area of pipe. */
c[AREAEX] = M_PI * diam * le;
/* <<<<<<<<<<<<End of Initialization Executable Statements. */
}
/* There are 2 ports.
Port 1 has 4 variables:
1 dh1 enthalpy flow rate at port 1 [J/s -> W] basic variable output
2 dm1 mass flow rate at port 1 [g/s -> kg/s] basic variable output
3 t1 temperature at port 1 [K] basic variable input
4 p1 pressure at port 1 [Pa] basic variable input
Port 2 has 4 variables:
1 dh2 enthalpy flow rate at port 2 [J/s -> W] basic variable output
2 dm2 mass flow rate at port 2 [g/s -> kg/s] basic variable output
3 t2 temperature at port 2 [K] basic variable input
4 p2 pressure at port 2 [Pa] basic variable input
*/
/* There are 7 internal variables.
1 tctr temperature at center of pipe [K] explicit state (derivative `dtctr')
2 pctr pressure at center of pipe [Pa] explicit state (derivative `dpctr')
3 mgas mass of gas in pipe [g -> kg] basic variable
4 re mean Reynolds number [null] basic variable
5 cm mean mass flow parameter [(kg*K/J)**(1/2)] basic variable
6 v mean gas velocity [m/s] basic variable
7 ff mean friction factor [null] basic variable
*/
void pnl0002_(int *n, double *dh1, double *dm1, double *t1, double *p1
, double *dh2, double *dm2, double *t2, double *p2, double *tctr
, double *dtctr, double *pctr, double *dpctr, double *mgas
, double *re, double *cm, double *v, double *ff, double rp[6]
, int ip[2], double c[8], int ic[1])
{
int loop;
/* >>>>>>>>>>>>Extra Calculation Function Declarations Here. */
static double zero = 0.0;
double sdh;
double dh1i, dm1i;
double dh2i, dm2i;
double ff1, ff2, re1, re2, cm1, cm2;
double dq;
double pa1, pa2, pactr;
double v1, v2;
double dmgas;
double r;
int dummyreg;
/* <<<<<<<<<<<<End of Extra Calculation declarations. */
int gi, mode;
double diam, le, rr, k, kth, extemp;
gi = ip[0];
mode = ip[1];
diam = rp[0];
le = rp[1];
rr = rp[2];
k = rp[3];
kth = rp[4];
extemp = rp[5];
loop = 0;
/*
Set all submodel outputs below:
*dh1 = ??;
*dm1 = ??;
*dh2 = ??;
*dm2 = ??;
*dtctr = ??;
*dpctr = ??;
*mgas = ??;
*re = ??;
*cm = ??;
*v = ??;
*ff = ??;
*/
/* >>>>>>>>>>>>Calculation Function Executable Statements. */
/* set absolute pressure */
pa1 = *p1 + c[PATM];
pa2 = *p2 + c[PATM];
pactr = *pctr + c[PATM];
/* Compute flows through the pipe */
pn2pipefr_(&pa1, t1, &pactr, tctr, &diam, &rr, &c[HALFLE], &c[AREA], &re1, &v1, &ff1,
dh1, dm1, &dh1i, &dm1i, &cm1, &c[TABFR], &gi, &ic[SPL_FR], &dummyreg);
pn2pipefr_(&pactr, tctr, &pa2, t2, &diam, &rr, &c[HALFLE], &c[AREA], &re2, &v2, &ff2,
&dh2i, &dm2i, dh2, dm2, &cm2, &c[TABFR], &gi, &ic[SPL_FR], &dummyreg);
/* Mean variables */
*ff = 0.5 * (ff1 + ff2);
*re = 0.5 * (re1 + re2);
*cm = 0.5 * (cm1 + cm2);
*v = 0.5 * (fabs(v1) + fabs(v2));
/* Compute mass variation */
dmgas = dm1i + dm2i;
/* sum of enthalpy flows */
sdh = dh1i + dh2i;
/*** temperature & pressure variation ***/
if (mode == 1) /* Polytropic model. */
{
r = pn2ri_(&gi);
*mgas = (pactr) * c[VOL] / ((*tctr) * r);
pn2vol1_(dtctr, dpctr, tctr, &pactr,
&dmgas, mgas, &zero, &c[VOL], &k, &gi);
}
else /* Heat exchange. */
{
dq = kth * c[AREAEX] * (extemp-*tctr);
pn2vol_(dtctr, dpctr, mgas, tctr, &pactr,
&dmgas, &sdh, &c[VOL], &zero, &dq, &gi);
}
/* <<<<<<<<<<<<End of Calculation Executable Statements. */
/* SI -> Common units conversions. */
*dm1 /= 1.00000000000000e-003;
*dm2 /= 1.00000000000000e-003;
*mgas /= 1.00000000000000e-003;
}
@@ -0,0 +1,275 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE SPE>
<SPE DOC_VERSION="2" AME_VERSION="16.0.0 - 68387-65635 2017">
<SUBMODEL>
<SUB_TYPE>0</SUB_TYPE>
<SUB_ID_MAX>24</SUB_ID_MAX>
<DEFAULT_ICON>p2port</DEFAULT_ICON>
<SUB_LABEL>Compressibility + friction submodel of pneumatic pipe (R-C-R)</SUB_LABEL>
<SUB_UNIT>0</SUB_UNIT>
<R_STORES_NUMBER>8</R_STORES_NUMBER>
<I_STORES_NUMBER>1</I_STORES_NUMBER>
<OUTPUT_TYPE>1</OUTPUT_TYPE>
<RPARAMS_LIST>
<RPARAM>
<SUB_ID>16</SUB_ID>
<TITLE>diameter of pipe</TITLE>
<VARNAME>diam</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+01</DEF_VALUE>
<VALUE>1.00000000000000e+01</VALUE>
<MIN_VALUE>1.00000000000000e-003</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+007</MAX_VALUE>
<UNITS>mm</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>17</SUB_ID>
<TITLE>pipe length</TITLE>
<VARNAME>le</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+00</DEF_VALUE>
<VALUE>1.00000000000000e+00</VALUE>
<MIN_VALUE>1.00000000000000e-006</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+004</MAX_VALUE>
<UNITS>m</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>18</SUB_ID>
<TITLE>relative roughness</TITLE>
<VARNAME>rr</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e-05</DEF_VALUE>
<VALUE>1.00000000000000e-05</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e-001</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>19</SUB_ID>
<TITLE>polytropic constant</TITLE>
<VARNAME>k</VARNAME>
<VISIBILITY>(mode == 1)</VISIBILITY>
<DEF_VALUE>1.35000000000000e+00</DEF_VALUE>
<VALUE>1.35000000000000e+00</VALUE>
<MIN_VALUE>5.00000000000000e-001</MIN_VALUE>
<MAX_VALUE>2.00000000000000e+000</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>20</SUB_ID>
<TITLE>thermal exchange coefficient</TITLE>
<VARNAME>kth</VARNAME>
<VISIBILITY>(mode == 2)</VISIBILITY>
<DEF_VALUE>0.00000000000000e+00</DEF_VALUE>
<VALUE>0.00000000000000e+00</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<UNITS>J/m**2/K/s</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>21</SUB_ID>
<TITLE>external temperature</TITLE>
<VARNAME>extemp</VARNAME>
<VISIBILITY>(mode == 2)</VISIBILITY>
<DEF_VALUE>2.93150000000000e+02</DEF_VALUE>
<VALUE>2.93150000000000e+02</VALUE>
<MIN_VALUE>1.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+003</MAX_VALUE>
<UNITS>K</UNITS>
</RPARAM>
</RPARAMS_LIST>
<IPARAMS_LIST>
<IPARAM>
<SUB_ID>22</SUB_ID>
<TITLE>gas type index</TITLE>
<VARNAME>gi</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>99</MAX_VALUE>
</IPARAM>
<IPARAM>
<SUB_ID>23</SUB_ID>
<TITLE>model</TITLE>
<VARNAME>mode</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>2</DEF_VALUE>
<VALUE>2</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>2</MAX_VALUE>
<ENUM_LIST>
<ENUM>
<ENUM_STRING>polytropic</ENUM_STRING>
</ENUM>
<ENUM>
<ENUM_STRING>with thermal exchange</ENUM_STRING>
</ENUM>
</ENUM_LIST>
</IPARAM>
</IPARAMS_LIST>
<IVARS_LIST>
<IVAR>
<SUB_ID>9</SUB_ID>
<TITLE>temperature at center of pipe</TITLE>
<VARNAME>tctr</VARNAME>
<VARNAME2>dtctr</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>K</UNITS>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<DEF_VALUE>2.931500e+02</DEF_VALUE>
<VALUE>2.931500e+02</VALUE>
</IVAR>
<IVAR>
<SUB_ID>10</SUB_ID>
<TITLE>pressure at center of pipe</TITLE>
<VARNAME>pctr</VARNAME>
<VARNAME2>dpctr</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>Pa</UNITS>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<DEF_VALUE>1.013000e+00</DEF_VALUE>
<VALUE>1.013000e+00</VALUE>
</IVAR>
<IVAR>
<SUB_ID>24</SUB_ID>
<TITLE>mass of gas in pipe</TITLE>
<VARNAME>mgas</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>g</UNITS>
</IVAR>
<IVAR>
<SUB_ID>12</SUB_ID>
<TITLE>mean Reynolds number</TITLE>
<VARNAME>re</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
<IVAR>
<SUB_ID>13</SUB_ID>
<TITLE>mean mass flow parameter</TITLE>
<VARNAME>cm</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>(kg*K/J)**(1/2)</UNITS>
</IVAR>
<IVAR>
<SUB_ID>14</SUB_ID>
<TITLE>mean gas velocity</TITLE>
<VARNAME>v</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>m/s</UNITS>
</IVAR>
<IVAR>
<SUB_ID>15</SUB_ID>
<TITLE>mean friction factor</TITLE>
<VARNAME>ff</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
</IVARS_LIST>
<EVARS_LIST>
<PORT>
<EVAR>
<SUB_ID>1</SUB_ID>
<TITLE>enthalpy flow rate at port 1</TITLE>
<VARNAME>dh1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>2</SUB_ID>
<TITLE>mass flow rate at port 1</TITLE>
<VARNAME>dm1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>3</SUB_ID>
<TITLE>temperature at port 1</TITLE>
<VARNAME>t1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>4</SUB_ID>
<TITLE>pressure at port 1</TITLE>
<VARNAME>p1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>5</SUB_ID>
<TITLE>enthalpy flow rate at port 2</TITLE>
<VARNAME>dh2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>6</SUB_ID>
<TITLE>mass flow rate at port 2</TITLE>
<VARNAME>dm2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>7</SUB_ID>
<TITLE>temperature at port 2</TITLE>
<VARNAME>t2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>8</SUB_ID>
<TITLE>pressure at port 2</TITLE>
<VARNAME>p2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
</EVARS_LIST>
<SUBIDS_RESET>0</SUBIDS_RESET>
</SUBMODEL>
</SPE>
@@ -0,0 +1,399 @@
/* Submodel PNL0003 skeleton created by AME Submodel editing utility
mer. juin 20 14:17:28 2018 */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ameutils.h"
/* *******************************************************************************
TITLE : PNL0003 (C-R-C)
------------------------------------------------------------------------------
DESCRIPTION :
PNL0003 is a submodel of a pneumatic pipe with only compressibility
and friction effects taking into account heat exchange.
The compressibility of the gas is taken into account by using a
simple polytropic model or a more complex one taking into account
heat exchange.
The polytropic model is a simplified form of the general internal
energy model based on the first law of thermodynamics. The polytropic
approach is obtained by representing the thermal exchange phenomena
by a polytropic constant k. In that case, the temperature and
pressure are no more independent variables.
The reduction of the complexity of the model implies a lack of
accuracy. For general studies, you'd better use the heat exchange
approach.
Pipe friction is taken into account using a friction factor based on
the Reynolds number and the relative roughness.
The temperature and pressure in each two volumes are state variables.
------------------------------------------------------------------------------
USAGE :
Use this submodel to simulate a pneumatic pipe with compressibility
and friction effects, when the Mach number is low, ie gas velocity
< 0.3 * speed of sound .
PNL0003 is basically similar to PNL0001 and PNL0002 differing only in the
input and output requirements.
The submodels PNGD01 or PNGD02 should be included in your circuit to
define the characteristics of the gas.
------------------------------------------------------------------------------
PARAMETER SETTINGS :
------------------------------------------------------------------------------
DATE OF CREATION / AUTHOR :
2002 FS from PNL03 SN.
------------------------------------------------------------------------------
REVISIONS :
------------------------------------------------------------------------------
LIST OF FUNCTIONS USED :
pn2getatp_() : get atmospheric pressure
pn2ri_() : get perfect gas constant
pn2vol1_() : polytropic model for chambers
pn2vol_() : heat exchange model for chambers
pn2pipefr_() : frictional coefficient in pneumatic pipes
------------------------------------------------------------------------------
SOURCE :
This material contains trade secrets or otherwise confidential
information owned by Siemens Industry Software Inc. or its
affiliates (collectively, "Siemens"), or its licensors. Access to
and use of this information is strictly limited as set forth in the
Customer's applicable agreements with Siemens.
Unpublished work. Copyright 2023 Siemens
******************************************************************************* */
#define _SUBMODELNAME_ "PNL0003"
/* >>>>>>>>>>>>Insert Private Code Here. */
#define TABFR 0 /* real store 0, 1 & 2 are used by pn2pipefr */
#define PATM 3
#define AREA 4
#define HALFVOL 5
#define HALFAREAEX 6
#define SPL_FR 0
/* <<<<<<<<<<<<End of Private Code. */
/* There are 6 real parameters:
diam diameter of pipe [mm -> m]
le pipe length [m]
rr relative roughness [null]
k polytropic constant [null]
kth thermal exchange coefficient [J/m**2/K/s -> W/m**2/K]
extemp external temperature [K]
*/
/* There are 2 integer parameters:
gi gas type index
mode model
*/
void pnl0003in_(int *n, double rp[6], int ip[2], double c[7]
, int ic[1], double *t1, double *p1, double *t2, double *p2)
{
int loop, error;
/* >>>>>>>>>>>>Extra Initialization Function Declarations Here. */
double vol, areaex;
/* <<<<<<<<<<<<End of Extra Initialization declarations. */
int gi, mode;
double diam, le, rr, k, kth, extemp;
gi = ip[0];
mode = ip[1];
diam = rp[0];
le = rp[1];
rr = rp[2];
k = rp[3];
kth = rp[4];
extemp = rp[5];
loop = 0;
error = 0;
/*
If necessary, check values of the following:
rp[0..5]
*t1
*p1
*t2
*p2
*/
/* >>>>>>>>>>>>Initialization Function Check Statements. */
pn2_valid_gas_(&gi, &error);
if (*p1 < -GPATMOS)
{
error = 2;
amefprintf(stderr, "\nInitial pressure at port 1 should be > 0 [barA].\n");
}
if (*t1 <= 0.0)
{
error = 2;
amefprintf(stderr, "\nInitial temperature at port 1 should be > 0 [K].\n");
}
if (*p2 < -GPATMOS)
{
error = 2;
amefprintf(stderr, "\nInitial pressure at port 2 should be > 0 [barA].\n");
}
if (*t2 <= 0.0)
{
error = 2;
amefprintf(stderr, "\nInitial temperature at port 2 should be > 0 [K].\n");
}
if (diam <= 0.0)
{
error = 2;
amefprintf(stderr, "\nDiameter of pipe should be > 0 [mm].\n");
}
if (le <= 0.0)
{
error = 2;
amefprintf(stderr, "\nPipe length should be > 0 [m].\n");
}
if (rr < 0.0)
{
error = 2;
amefprintf(stderr, "\nRelative roughness should be >= 0.\n");
}
if (mode == 1)
{
if (k <= 0.)
{
error = 2;
amefprintf(stderr, "\nPolytropic constant should be > 0.\n");
}
}
else
{
if (kth < 0.)
{
error = 2;
amefprintf(stderr, "\nThermal exchange coefficient should be >= 0 [J/m**2/K/s].\n");
}
if (extemp <= 0.)
{
error = 2;
amefprintf(stderr, "\nExternal temperature should be > 0 [K].\n");
}
}
/* <<<<<<<<<<<<End of Initialization Check Statements. */
/* Integer parameter checking: */
if (gi < 1 || gi > 99)
{
amefprintf(stderr, "\ngas type index must be in range [1..99].\n");
error = 2;
}
if (mode < 1 || mode > 2)
{
amefprintf(stderr, "\nmodel must be in range [1..2].\n");
error = 2;
}
SUBMODEL_HANDLE_AND_RESET_ERROR(_SUBMODELNAME_, n, error)
/* Common -> SI units conversions. */
rp[0] *= 1.00000000000000e-003;
diam = rp[0];
/* >>>>>>>>>>>>Initialization Function Executable Statements. */
/* set atmospheric pressure */
c[PATM] = pn2getatp_();
/* Compute the cross-sectional area of pipe. */
c[AREA] = M_PI * (diam) * (diam) / 4.0;
/* Compute volume of pipe. */
vol = c[AREA] * le;
/* Divide the volume in 2 identical volumes */
c[HALFVOL] = 0.5 * vol;
/* Compute exchange area of pipe. */
areaex = M_PI * diam * le;
/* Divide the exchange area of pipe in 2 identical areas */
c[HALFAREAEX] = 0.5 * areaex;
/* <<<<<<<<<<<<End of Initialization Executable Statements. */
}
/* There are 2 ports.
Port 1 has 4 variables:
1 t1 temperature at port 1 [K] explicit state (derivative `dt1')
2 p1 pressure at port 1 [Pa] explicit state (derivative `dp1')
3 dh1 enthalpy flow rate at port 1 [J/s -> W] basic variable input
4 dm1 mass flow rate at port 1 [g/s -> kg/s] basic variable input
Port 2 has 4 variables:
1 t2 temperature at port 2 [K] explicit state (derivative `dt2')
2 p2 pressure at port 2 [Pa] explicit state (derivative `dp2')
3 dh2 enthalpy flow rate at port 2 [J/s -> W] basic variable input
4 dm2 mass flow rate at port 2 [g/s -> kg/s] basic variable input
*/
/* There are 7 internal variables.
1 dhctr enthalpy flow at center of pipe [J/s -> W] basic variable
2 dmctr mass flow at center of pipe [g/s -> kg/s] basic variable
3 mgas mass of gas in pipe [g -> kg] basic variable
4 re Reynolds number [null] basic variable
5 cm mass flow parameter (cm) [(kg*K/J)**(1/2)] basic variable
6 v mean gas velocity [m/s] basic variable
7 ff friction factor [null] basic variable
*/
void pnl0003_(int *n, double *t1, double *dt1, double *p1, double *dp1
, double *dh1, double *dm1, double *t2, double *dt2, double *p2
, double *dp2, double *dh2, double *dm2, double *dhctr
, double *dmctr, double *mgas, double *re, double *cm, double *v
, double *ff, double rp[6], int ip[2], double c[7], int ic[1])
{
int loop;
/* >>>>>>>>>>>>Extra Calculation Function Declarations Here. */
static double zero = 0.0;
double dh1i, dm1i;
double dh2i, dm2i;
double sdh1, sdm1;
double sdh2, sdm2;
double m1, m2;
double dq1, dq2;
double pa1, pa2;
double dmgas;
double r;
int dummyreg;
/* <<<<<<<<<<<<End of Extra Calculation declarations. */
int gi, mode;
double diam, le, rr, k, kth, extemp;
gi = ip[0];
mode = ip[1];
diam = rp[0];
le = rp[1];
rr = rp[2];
k = rp[3];
kth = rp[4];
extemp = rp[5];
loop = 0;
/* Common -> SI units conversions. */
*dm1 *= 1.00000000000000e-003;
*dm2 *= 1.00000000000000e-003;
/*
Set all submodel outputs below:
*dt1 = ??;
*dp1 = ??;
*dt2 = ??;
*dp2 = ??;
*dhctr = ??;
*dmctr = ??;
*mgas = ??;
*re = ??;
*cm = ??;
*v = ??;
*ff = ??;
*/
/* >>>>>>>>>>>>Calculation Function Executable Statements. */
/* set absolute pressures */
pa1 = *p1 + c[PATM];
pa2 = *p2 + c[PATM];
/* Compute flow through the pipe */
pn2pipefr_(&pa1, t1, &pa2, t2, &diam, &rr, &le, &c[AREA], re, v, ff,
&dh1i, &dm1i, &dh2i, &dm2i, cm, &c[TABFR], &gi, &ic[SPL_FR], &dummyreg);
/* Enthalpy flow and mass flow at center of pipe */
*dhctr = dh1i; /* = -dh2i */
*dmctr = dm1i; /* = -dm2i */
/* Compute the sum of the flows inside each volume */
sdm1 = *dm1 + dm1i;
sdh1 = *dh1 + dh1i;
sdm2 = *dm2 + dm2i;
sdh2 = *dh2 + dh2i;
dmgas = sdm1 + sdm2;
/*** temperature & pressure variation ***/
if (mode == 1) /* Polytropic model. */
{
r = pn2ri_(&gi);
/* Current mass in each volume */
m1 = pa1 * c[HALFVOL] / (*t1 * r);
m2 = pa2 * c[HALFVOL] / (*t2 * r);
pn2vol1_(dt1, dp1, t1, &pa1,
&sdm1, &m1, &zero, &c[HALFVOL], &k,&gi);
pn2vol1_(dt2, dp2, t2, &pa2,
&sdm2, &m2, &zero, &c[HALFVOL], &k,&gi);
}
else /* Heat exchange. */
{
dq1 = kth * c[HALFAREAEX] * (extemp - *t1);
pn2vol_(dt1, dp1, &m1, t1, &pa1,
&sdm1, &sdh1, &c[HALFVOL], &zero, &dq1, &gi);
dq2 = kth * c[HALFAREAEX] * (extemp - *t2);
pn2vol_(dt2, dp2, &m2, t2, &pa2,
&sdm2, &sdh2, &c[HALFVOL], &zero, &dq2, &gi);
}
*mgas = m1 + m2;
/* <<<<<<<<<<<<End of Calculation Executable Statements. */
/* SI -> Common units conversions. */
*dm1 /= 1.00000000000000e-003;
*dm2 /= 1.00000000000000e-003;
*dmctr /= 1.00000000000000e-003;
*mgas /= 1.00000000000000e-003;
}
@@ -0,0 +1,285 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE SPE>
<SPE DOC_VERSION="2" AME_VERSION="16.0.0 - 68387-65635 2017">
<SUBMODEL>
<SUB_TYPE>0</SUB_TYPE>
<SUB_ID_MAX>24</SUB_ID_MAX>
<DEFAULT_ICON>p2port</DEFAULT_ICON>
<SUB_LABEL>Compressibility + friction submodel of pneumatic pipe (C-R-C)</SUB_LABEL>
<SUB_UNIT>0</SUB_UNIT>
<R_STORES_NUMBER>7</R_STORES_NUMBER>
<I_STORES_NUMBER>1</I_STORES_NUMBER>
<OUTPUT_TYPE>1</OUTPUT_TYPE>
<RPARAMS_LIST>
<RPARAM>
<SUB_ID>16</SUB_ID>
<TITLE>diameter of pipe</TITLE>
<VARNAME>diam</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+01</DEF_VALUE>
<VALUE>1.00000000000000e+01</VALUE>
<MIN_VALUE>1.00000000000000e-003</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+007</MAX_VALUE>
<UNITS>mm</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>17</SUB_ID>
<TITLE>pipe length</TITLE>
<VARNAME>le</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+00</DEF_VALUE>
<VALUE>1.00000000000000e+00</VALUE>
<MIN_VALUE>1.00000000000000e-006</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+004</MAX_VALUE>
<UNITS>m</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>18</SUB_ID>
<TITLE>relative roughness</TITLE>
<VARNAME>rr</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e-05</DEF_VALUE>
<VALUE>1.00000000000000e-05</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e-001</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>19</SUB_ID>
<TITLE>polytropic constant</TITLE>
<VARNAME>k</VARNAME>
<VISIBILITY>(mode == 1)</VISIBILITY>
<DEF_VALUE>1.35000000000000e+00</DEF_VALUE>
<VALUE>1.35000000000000e+00</VALUE>
<MIN_VALUE>5.00000000000000e-001</MIN_VALUE>
<MAX_VALUE>2.00000000000000e+000</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>20</SUB_ID>
<TITLE>thermal exchange coefficient</TITLE>
<VARNAME>kth</VARNAME>
<VISIBILITY>(mode == 2)</VISIBILITY>
<DEF_VALUE>0.00000000000000e+00</DEF_VALUE>
<VALUE>0.00000000000000e+00</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<UNITS>J/m**2/K/s</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>21</SUB_ID>
<TITLE>external temperature</TITLE>
<VARNAME>extemp</VARNAME>
<VISIBILITY>(mode == 2)</VISIBILITY>
<DEF_VALUE>2.93150000000000e+02</DEF_VALUE>
<VALUE>2.93150000000000e+02</VALUE>
<MIN_VALUE>1.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+003</MAX_VALUE>
<UNITS>K</UNITS>
</RPARAM>
</RPARAMS_LIST>
<IPARAMS_LIST>
<IPARAM>
<SUB_ID>22</SUB_ID>
<TITLE>gas type index</TITLE>
<VARNAME>gi</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>99</MAX_VALUE>
</IPARAM>
<IPARAM>
<SUB_ID>23</SUB_ID>
<TITLE>model</TITLE>
<VARNAME>mode</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>2</DEF_VALUE>
<VALUE>2</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>2</MAX_VALUE>
<ENUM_LIST>
<ENUM>
<ENUM_STRING>polytropic</ENUM_STRING>
</ENUM>
<ENUM>
<ENUM_STRING>with thermal exchange</ENUM_STRING>
</ENUM>
</ENUM_LIST>
</IPARAM>
</IPARAMS_LIST>
<IVARS_LIST>
<IVAR>
<SUB_ID>9</SUB_ID>
<TITLE>enthalpy flow at center of pipe</TITLE>
<VARNAME>dhctr</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>J/s</UNITS>
</IVAR>
<IVAR>
<SUB_ID>10</SUB_ID>
<TITLE>mass flow at center of pipe</TITLE>
<VARNAME>dmctr</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>g/s</UNITS>
</IVAR>
<IVAR>
<SUB_ID>24</SUB_ID>
<TITLE>mass of gas in pipe</TITLE>
<VARNAME>mgas</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>g</UNITS>
</IVAR>
<IVAR>
<SUB_ID>12</SUB_ID>
<TITLE>Reynolds number</TITLE>
<VARNAME>re</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
<IVAR>
<SUB_ID>13</SUB_ID>
<TITLE>mass flow parameter (cm)</TITLE>
<VARNAME>cm</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>(kg*K/J)**(1/2)</UNITS>
</IVAR>
<IVAR>
<SUB_ID>14</SUB_ID>
<TITLE>mean gas velocity</TITLE>
<VARNAME>v</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>m/s</UNITS>
</IVAR>
<IVAR>
<SUB_ID>15</SUB_ID>
<TITLE>friction factor</TITLE>
<VARNAME>ff</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
</IVARS_LIST>
<EVARS_LIST>
<PORT>
<EVAR>
<SUB_ID>1</SUB_ID>
<TITLE>temperature at port 1</TITLE>
<VARNAME>t1</VARNAME>
<VARNAME2>dt1</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>K</UNITS>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<DEF_VALUE>2.93150000000000e+002</DEF_VALUE>
<VALUE>2.93150000000000e+002</VALUE>
</EVAR>
<EVAR>
<SUB_ID>2</SUB_ID>
<TITLE>pressure at port 1</TITLE>
<VARNAME>p1</VARNAME>
<VARNAME2>dp1</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>Pa</UNITS>
<MIN_VALUE>-1.01300000000000e+005</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+012</MAX_VALUE>
<DEF_VALUE>0.00000000000000e+000</DEF_VALUE>
<VALUE>0.00000000000000e+000</VALUE>
</EVAR>
<EVAR>
<SUB_ID>3</SUB_ID>
<TITLE>enthalpy flow rate at port 1</TITLE>
<VARNAME>dh1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>4</SUB_ID>
<TITLE>mass flow rate at port 1</TITLE>
<VARNAME>dm1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>g/s</UNITS>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>5</SUB_ID>
<TITLE>temperature at port 2</TITLE>
<VARNAME>t2</VARNAME>
<VARNAME2>dt2</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>K</UNITS>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+004</MAX_VALUE>
<DEF_VALUE>2.93150000000000e+002</DEF_VALUE>
<VALUE>2.93150000000000e+002</VALUE>
</EVAR>
<EVAR>
<SUB_ID>6</SUB_ID>
<TITLE>pressure at port 2</TITLE>
<VARNAME>p2</VARNAME>
<VARNAME2>dp2</VARNAME2>
<VISIBILITY>True</VISIBILITY>
<TYPE>1</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>Pa</UNITS>
<MIN_VALUE>-1.01300000000000e+005</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+012</MAX_VALUE>
<DEF_VALUE>0.00000000000000e+000</DEF_VALUE>
<VALUE>0.00000000000000e+000</VALUE>
</EVAR>
<EVAR>
<SUB_ID>7</SUB_ID>
<TITLE>enthalpy flow rate at port 2</TITLE>
<VARNAME>dh2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>8</SUB_ID>
<TITLE>mass flow rate at port 2</TITLE>
<VARNAME>dm2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>g/s</UNITS>
</EVAR>
</PORT>
</EVARS_LIST>
<SUBIDS_RESET>0</SUBIDS_RESET>
</SUBMODEL>
</SPE>
@@ -0,0 +1,224 @@
/* Submodel PNL00R skeleton created by AME Submodel editing utility
ven. 5. août 14:34:41 2016 */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ameutils.h"
/* *******************************************************************************
TITLE : PNL00R
------------------------------------------------------------------------------
DESCRIPTION :
PNL00R is a submodel of a pneumatic pipe with only friction effects.
Pipe friction is taken into account using a friction factor based on
the Reynolds number and the relative roughness.
------------------------------------------------------------------------------
USAGE :
Use this submodel to simulate a pneumatic pipe with friction effects,
when the Mach number is low, ie gas velocity < 0.3 * speed of sound .
The submodels PNGD001 or PNGD002 should be included in your circuit to
define the characteristics of the gas.
------------------------------------------------------------------------------
PARAMETER SETTINGS :
------------------------------------------------------------------------------
DATE OF CREATION / AUTHOR :
2002 FS from PNL0R SN
------------------------------------------------------------------------------
REVISIONS :
------------------------------------------------------------------------------
LIST OF FUNCTIONS USED :
pn2pipefr_() : frictional coefficient in pneumatic pipes
pn2getatp_() : get atmospheric pressure
------------------------------------------------------------------------------
SOURCE :
This material contains trade secrets or otherwise confidential
information owned by Siemens Industry Software Inc. or its
affiliates (collectively, "Siemens"), or its licensors. Access to
and use of this information is strictly limited as set forth in the
Customer's applicable agreements with Siemens.
Unpublished work. Copyright 2023 Siemens
******************************************************************************* */
#define _SUBMODELNAME_ "PNL00R"
/* >>>>>>>>>>>>Insert Private Code Here. */
#define TABFR 0 /* real store 0, 1 & 2 are used by pn2pipefr */
#define PATM 3
#define AREA 4
#define SPL_FR 0
/* <<<<<<<<<<<<End of Private Code. */
/* There are 3 real parameters:
diam diameter of pipe [mm -> m]
le pipe length [m]
rr relative roughness [null]
*/
/* There is 1 integer parameter:
gi gas type index
*/
void pnl00rin_(int *n, double rp[3], int ip[1], double c[5], int ic[1])
{
int loop, error;
/* >>>>>>>>>>>>Extra Initialization Function Declarations Here. */
/* <<<<<<<<<<<<End of Extra Initialization declarations. */
int gi;
double diam, le, rr;
gi = ip[0];
diam = rp[0];
le = rp[1];
rr = rp[2];
loop = 0;
error = 0;
/*
If necessary, check values of the following:
rp[0..2]
*/
/* >>>>>>>>>>>>Initialization Function Check Statements. */
pn2_valid_gas_(&gi, &error);
if (diam <= 0.0)
{
error = 2;
amefprintf(stderr, "\nDiameter of pipe should be > 0 [mm].\n");
}
if (le <= 0.0)
{
error = 2;
amefprintf(stderr, "\nPipe length should be > 0 [m].\n");
}
if (rr < 0.0)
{
error = 2;
amefprintf(stderr, "\nRelative roughness should be >= 0.\n");
}
/* <<<<<<<<<<<<End of Initialization Check Statements. */
/* Integer parameter checking: */
if (gi < 1 || gi > 99)
{
amefprintf(stderr, "\ngas type index must be in range [1..99].\n");
error = 2;
}
SUBMODEL_HANDLE_AND_RESET_ERROR(_SUBMODELNAME_, n, error)
/* Common -> SI units conversions. */
rp[0] *= 1.00000000000000e-003;
diam = rp[0];
/* >>>>>>>>>>>>Initialization Function Executable Statements. */
c[PATM] = pn2getatp_();
/* Compute the cross-sectional area of pipe. */
c[AREA] = M_PI * (diam) * (diam) / 4.0;
/* <<<<<<<<<<<<End of Initialization Executable Statements. */
}
/* There are 2 ports.
Port 1 has 4 variables:
1 dh1 duplicate of dh2 (sign reversed)
2 dm1 duplicate of dm2 (sign reversed)
3 t1 temperature at port 1 [K] basic variable input
4 p1 pressure at port 1 [Pa] basic variable input
Port 2 has 4 variables:
1 dh2 enthalpy flow rate at port 2 [J/s -> W] basic variable output
2 dm2 mass flow rate at port 2 [g/s -> kg/s] basic variable output
3 t2 temperature at port 2 [K] basic variable input
4 p2 pressure at port 2 [Pa] basic variable input
*/
/* There are 4 internal variables.
1 re Reynolds number [null] basic variable
2 cm mass flow parameter (cm) [(kg*K/J)**(1/2)] basic variable
3 v mean gas velocity [m/s] basic variable
4 ff friction factor [null] basic variable
*/
void pnl00r_(int *n, double *t1, double *p1, double *dh2, double *dm2
, double *t2, double *p2, double *re, double *cm, double *v
, double *ff, double rp[3], int ip[1], double c[5], int ic[1])
{
int loop;
/* >>>>>>>>>>>>Extra Calculation Function Declarations Here. */
double pa1, pa2;
double dh1loc, dm1loc;
int dummyreg;
/* <<<<<<<<<<<<End of Extra Calculation declarations. */
int gi;
double diam, le, rr;
gi = ip[0];
diam = rp[0];
le = rp[1];
rr = rp[2];
loop = 0;
/*
Set all submodel outputs below:
*dh2 = ??;
*dm2 = ??;
*re = ??;
*cm = ??;
*v = ??;
*ff = ??;
*/
/* >>>>>>>>>>>>Calculation Function Executable Statements. */
/* set absolute pressure */
pa1 = *p1 + c[PATM];
pa2 = *p2 + c[PATM];
/* Compute flow through the pipe */
pn2pipefr_(&pa2, t2, &pa1, t1, &diam, &rr, &le, &c[AREA], re, v, ff,
dh2, dm2, &dh1loc, &dm1loc, cm, &c[TABFR], &gi, &ic[SPL_FR], &dummyreg);
/* <<<<<<<<<<<<End of Calculation Executable Statements. */
/* SI -> Common units conversions. */
*dm2 /= 1.00000000000000e-003;
}
@@ -0,0 +1,185 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE SPE>
<SPE DOC_VERSION="2" AME_VERSION="14.0.0 - 42489-40361 2015">
<SUBMODEL>
<SUB_TYPE>0</SUB_TYPE>
<SUB_ID_MAX>18</SUB_ID_MAX>
<DEFAULT_ICON>p2port</DEFAULT_ICON>
<SUB_LABEL>Friction submodel of pneumatic pipe (R)</SUB_LABEL>
<SUB_UNIT>0</SUB_UNIT>
<R_STORES_NUMBER>5</R_STORES_NUMBER>
<I_STORES_NUMBER>1</I_STORES_NUMBER>
<OUTPUT_TYPE>1</OUTPUT_TYPE>
<RPARAMS_LIST>
<RPARAM>
<SUB_ID>13</SUB_ID>
<TITLE>diameter of pipe</TITLE>
<VARNAME>diam</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+01</DEF_VALUE>
<VALUE>1.00000000000000e+01</VALUE>
<MIN_VALUE>1.00000000000000e-003</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+007</MAX_VALUE>
<UNITS>mm</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>14</SUB_ID>
<TITLE>pipe length</TITLE>
<VARNAME>le</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e+00</DEF_VALUE>
<VALUE>1.00000000000000e+00</VALUE>
<MIN_VALUE>1.00000000000000e-006</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+004</MAX_VALUE>
<UNITS>m</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>15</SUB_ID>
<TITLE>relative roughness</TITLE>
<VARNAME>rr</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1.00000000000000e-05</DEF_VALUE>
<VALUE>1.00000000000000e-05</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e-001</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
</RPARAMS_LIST>
<IPARAMS_LIST>
<IPARAM>
<SUB_ID>16</SUB_ID>
<TITLE>gas type index</TITLE>
<VARNAME>gi</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>99</MAX_VALUE>
</IPARAM>
</IPARAMS_LIST>
<IVARS_LIST>
<IVAR>
<SUB_ID>9</SUB_ID>
<TITLE>Reynolds number</TITLE>
<VARNAME>re</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
<IVAR>
<SUB_ID>10</SUB_ID>
<TITLE>mass flow parameter (cm)</TITLE>
<VARNAME>cm</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>(kg*K/J)**(1/2)</UNITS>
</IVAR>
<IVAR>
<SUB_ID>11</SUB_ID>
<TITLE>mean gas velocity</TITLE>
<VARNAME>v</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>m/s</UNITS>
</IVAR>
<IVAR>
<SUB_ID>12</SUB_ID>
<TITLE>friction factor</TITLE>
<VARNAME>ff</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
</IVARS_LIST>
<EVARS_LIST>
<PORT>
<EVAR>
<SUB_ID>17</SUB_ID>
<VARNAME>dh1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>1</PRIMARY_PORT>
<PRIMARY_VAR>0</PRIMARY_VAR>
<DUP_TYPE>1</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>18</SUB_ID>
<VARNAME>dm1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>1</PRIMARY_PORT>
<PRIMARY_VAR>1</PRIMARY_VAR>
<DUP_TYPE>1</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>3</SUB_ID>
<TITLE>temperature at port 1</TITLE>
<VARNAME>t1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>4</SUB_ID>
<TITLE>pressure at port 1</TITLE>
<VARNAME>p1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>5</SUB_ID>
<TITLE>enthalpy flow rate at port 2</TITLE>
<VARNAME>dh2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>6</SUB_ID>
<TITLE>mass flow rate at port 2</TITLE>
<VARNAME>dm2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>7</SUB_ID>
<TITLE>temperature at port 2</TITLE>
<VARNAME>t2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>8</SUB_ID>
<TITLE>pressure at port 2</TITLE>
<VARNAME>p2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
</EVARS_LIST>
<SUBIDS_RESET>0</SUBIDS_RESET>
</SUBMODEL>
</SPE>
@@ -0,0 +1,240 @@
/* Submodel PNOR001 skeleton created by AME Submodel editing utility
lun. 10. juil. 17:22:57 2017 */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ameutils.h"
/* *******************************************************************************
TITLE : PNOR001
------------------------------------------------------------------------------
DATE OF CREATION / AUTHOR :
2002 : Created by FS from PNOR01
------------------------------------------------------------------------------
SOURCE :
This material contains trade secrets or otherwise confidential
information owned by Siemens Industry Software Inc. or its
affiliates (collectively, "Siemens"), or its licensors. Access to
and use of this information is strictly limited as set forth in the
Customer's applicable agreements with Siemens.
Unpublished work. Copyright 2023 Siemens
******************************************************************************* */
#define _SUBMODELNAME_ "PNOR001"
/* >>>>>>>>>>>>Insert Private Code Here. */
/* real stores */
#define PATM 0
#define AREA 1
#define CQ 2
/* integer stores */
#define DISC_ORIF 0
/* <<<<<<<<<<<<End of Private Code. */
/* There are 4 real parameters:
cq flow coefficient (Cq) [null]
area orifice area [mm**2 -> m**2]
Cv flow coefficient (Cv) [null]
Kv flow coefficient (Kv) [null]
*/
/* There are 2 integer parameters:
gi gas type index
flowset flow coefficient setting
*/
void pnor001in_(int *n, double rp[4], int ip[2], double c[3]
, int ic[1])
{
int loop, error;
/* >>>>>>>>>>>>Extra Initialization Function Declarations Here. */
/* <<<<<<<<<<<<End of Extra Initialization declarations. */
int gi, flowset;
double cq, area, Cv, Kv;
gi = ip[0];
flowset = ip[1];
cq = rp[0];
area = rp[1];
Cv = rp[2];
Kv = rp[3];
loop = 0;
error = 0;
/*
If necessary, check values of the following:
rp[0..3]
*/
/* >>>>>>>>>>>>Initialization Function Check Statements. */
pn2_valid_gas_(&gi, &error);
if (flowset == 1)
{
if (area < 0.0)
{
error = 2;
amefprintf(stderr, "\nOrifice area should be positive.\n");
}
if (cq <= 0.0)
{
error = 2;
amefprintf(stderr, "\nFlow coefficient should be strictly positive.\n");
}
}
else if (flowset == 2)
{
if (Cv < 0.0)
{
error = 2;
amefprintf(stderr, "\nFlow coefficient (Cv) should be positive (value is %g).\n", Cv);
}
}
else
{
if (Kv < 0.0)
{
error = 2;
amefprintf(stderr, "\nFlow coefficient (Kv) should be positive (value is %g).\n", Kv);
}
}
/* <<<<<<<<<<<<End of Initialization Check Statements. */
/* Integer parameter checking: */
if (gi < 1 || gi > 99)
{
amefprintf(stderr, "\ngas type index must be in range [1..99].\n");
error = 2;
}
if (flowset < 1 || flowset > 3)
{
amefprintf(stderr, "\nflow coefficient setting must be in range [1..3].\n");
error = 2;
}
SUBMODEL_HANDLE_AND_RESET_ERROR(_SUBMODELNAME_, n, error)
/* Common -> SI units conversions. */
rp[1] *= 1.00000000000000e-006;
area = rp[1];
/* >>>>>>>>>>>>Initialization Function Executable Statements. */
/* get atmospheric pressure */
c[PATM] = pn2getatp_();
if (flowset == 1)
{
c[CQ] = cq;
c[AREA] = area;
}
else
{
/* calculation of equivalent area with Cv or Kv.
Default value of cq; the same value will be used in pn2rcqfix. */
c[CQ] = 0.72;
if (flowset == 2) /* Cv */
orif_areafromcv_(&Cv, &c[CQ], &c[AREA]);
else
orif_areafromkv_(&Kv, &c[CQ], &c[AREA]);
}
/* <<<<<<<<<<<<End of Initialization Executable Statements. */
}
/* There are 2 ports.
Port 1 has 4 variables:
1 dh1 enthalpy flow rate at port 1 [J/s -> W] basic variable output
2 dm1 mass flow rate at port 1 [g/s -> kg/s] basic variable output
3 temp1 temperature at port 1 [K] basic variable input
4 press1 pressure at port 1 [Pa] basic variable input
Port 2 has 4 variables:
1 dh2 duplicate of dh1 (sign reversed)
2 dm2 duplicate of dm1 (sign reversed)
3 temp2 temperature at port 2 [K] basic variable input
4 press2 pressure at port 2 [Pa] basic variable input
*/
/* There are 2 internal variables.
1 cm mass flow parameter (cm) [(kg*K/J)**(1/2)] basic variable
2 gasvel vena contracta gas velocity [m/s] basic variable
*/
void pnor001_(int *n, double *dh1, double *dm1, double *temp1
, double *press1, double *temp2, double *press2, double *cm
, double *gasvel, double rp[4], int ip[2], double c[3]
, int ic[1])
{
int loop;
/* >>>>>>>>>>>>Extra Calculation Function Declarations Here. */
double pressa1, pressa2;
/* <<<<<<<<<<<<End of Extra Calculation declarations. */
int gi, flowset;
double cq, area, Cv, Kv;
gi = ip[0];
flowset = ip[1];
cq = rp[0];
area = rp[1];
Cv = rp[2];
Kv = rp[3];
loop = 0;
/*
Set all submodel outputs below:
*dh1 = ??;
*dm1 = ??;
*cm = ??;
*gasvel = ??;
*/
/* >>>>>>>>>>>>Calculation Function Executable Statements. */
/* set absolute pressures */
pressa1 = *press1 + c[PATM];
pressa2 = *press2 + c[PATM];
/* calculation of the flows */
pn2rcqfix_( dh1, dm1, temp1, &pressa1, temp2, &pressa2, &c[AREA], &c[CQ], &gi,
cm, gasvel, &ic[DISC_ORIF]);
/* <<<<<<<<<<<<End of Calculation Executable Statements. */
/* SI -> Common units conversions. */
*dm1 /= 1.00000000000000e-003;
}
@@ -0,0 +1,199 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE SPE>
<SPE DOC_VERSION="2" AME_VERSION="14.0.0 - 42489-40361 2015">
<SUBMODEL>
<SUB_TYPE>0</SUB_TYPE>
<SUB_ID_MAX>18</SUB_ID_MAX>
<DEFAULT_ICON>pn_orifice</DEFAULT_ICON>
<SUB_LABEL>pneumatic orifice (constant flow coefficient)</SUB_LABEL>
<SUB_UNIT>0</SUB_UNIT>
<R_STORES_NUMBER>3</R_STORES_NUMBER>
<I_STORES_NUMBER>1</I_STORES_NUMBER>
<OUTPUT_TYPE>1</OUTPUT_TYPE>
<RPARAMS_LIST>
<RPARAM>
<SUB_ID>12</SUB_ID>
<TITLE>flow coefficient (Cq)</TITLE>
<VARNAME>cq</VARNAME>
<VISIBILITY>flowset==1</VISIBILITY>
<DEF_VALUE>7.20000000000000e-01</DEF_VALUE>
<VALUE>7.20000000000000e-01</VALUE>
<MIN_VALUE>1.00000000000000e-010</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+000</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>11</SUB_ID>
<TITLE>orifice area</TITLE>
<VARNAME>area</VARNAME>
<VISIBILITY>flowset==1</VISIBILITY>
<DEF_VALUE>5.00000000000000e+00</DEF_VALUE>
<VALUE>5.00000000000000e+00</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<UNITS>mm**2</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>17</SUB_ID>
<TITLE>flow coefficient (Cv)</TITLE>
<VARNAME>Cv</VARNAME>
<VISIBILITY>flowset==2</VISIBILITY>
<DEF_VALUE>5.00000000000000e-01</DEF_VALUE>
<VALUE>5.00000000000000e-01</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+030</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>18</SUB_ID>
<TITLE>flow coefficient (Kv)</TITLE>
<VARNAME>Kv</VARNAME>
<VISIBILITY>flowset==3</VISIBILITY>
<DEF_VALUE>4.00000000000000e-01</DEF_VALUE>
<VALUE>4.00000000000000e-01</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+030</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
</RPARAMS_LIST>
<IPARAMS_LIST>
<IPARAM>
<SUB_ID>13</SUB_ID>
<TITLE>gas type index</TITLE>
<VARNAME>gi</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>99</MAX_VALUE>
</IPARAM>
<IPARAM>
<SUB_ID>14</SUB_ID>
<TITLE>flow coefficient setting</TITLE>
<VARNAME>flowset</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>3</MAX_VALUE>
<ENUM_LIST>
<ENUM>
<ENUM_STRING>Cq</ENUM_STRING>
</ENUM>
<ENUM>
<ENUM_STRING>Cv</ENUM_STRING>
</ENUM>
<ENUM>
<ENUM_STRING>Kv</ENUM_STRING>
</ENUM>
</ENUM_LIST>
</IPARAM>
</IPARAMS_LIST>
<IVARS_LIST>
<IVAR>
<SUB_ID>9</SUB_ID>
<TITLE>mass flow parameter (cm)</TITLE>
<VARNAME>cm</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>(kg*K/J)**(1/2)</UNITS>
</IVAR>
<IVAR>
<SUB_ID>10</SUB_ID>
<TITLE>vena contracta gas velocity</TITLE>
<VARNAME>gasvel</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>m/s</UNITS>
</IVAR>
</IVARS_LIST>
<EVARS_LIST>
<PORT>
<EVAR>
<SUB_ID>1</SUB_ID>
<TITLE>enthalpy flow rate at port 1</TITLE>
<VARNAME>dh1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>2</SUB_ID>
<TITLE>mass flow rate at port 1</TITLE>
<VARNAME>dm1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>3</SUB_ID>
<TITLE>temperature at port 1</TITLE>
<VARNAME>temp1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>4</SUB_ID>
<TITLE>pressure at port 1</TITLE>
<VARNAME>press1</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>5</SUB_ID>
<VARNAME>dh2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>0</PRIMARY_PORT>
<PRIMARY_VAR>0</PRIMARY_VAR>
<DUP_TYPE>1</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>6</SUB_ID>
<VARNAME>dm2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>0</PRIMARY_PORT>
<PRIMARY_VAR>1</PRIMARY_VAR>
<DUP_TYPE>1</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>7</SUB_ID>
<TITLE>temperature at port 2</TITLE>
<VARNAME>temp2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>8</SUB_ID>
<TITLE>pressure at port 2</TITLE>
<VARNAME>press2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
</EVARS_LIST>
<SUBIDS_RESET>0</SUBIDS_RESET>
</SUBMODEL>
</SPE>
@@ -0,0 +1,254 @@
/* Submodel PNVO001 skeleton created by AME Submodel editing utility
ven. 6. oct. 11:10:58 2017 */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "ameutils.h"
/* *******************************************************************************
TITLE : PNVO001
------------------------------------------------------------------------------
DATE OF CREATION / AUTHOR :
2002 : Created by FS from PNVO01
------------------------------------------------------------------------------
SOURCE :
This material contains trade secrets or otherwise confidential
information owned by Siemens Industry Software Inc. or its
affiliates (collectively, "Siemens"), or its licensors. Access to
and use of this information is strictly limited as set forth in the
Customer's applicable agreements with Siemens.
Unpublished work. Copyright 2023 Siemens
******************************************************************************* */
#define _SUBMODELNAME_ "PNVO001"
/* >>>>>>>>>>>>Insert Private Code Here. */
/* real stores */
#define PATM 0
#define AREAMAX 1
#define CQ 2
/* integer stores */
#define DISC_LIMIT 0
#define DISC_ORIF 1
/* <<<<<<<<<<<<End of Private Code. */
/* There are 4 real parameters:
cq flow coefficient (Cq) [null]
area0 orifice area at maximum opening [mm**2 -> m**2]
Cv maximum flow coefficient (Cv) [null]
Kv maximum flow coefficient (Kv) [null]
*/
/* There are 2 integer parameters:
gi gas type index
flowset flow coefficient setting
*/
void pnvo001in_(int *n, double rp[4], int ip[2], double c[3]
, int ic[2])
{
int loop, error;
/* >>>>>>>>>>>>Extra Initialization Function Declarations Here. */
/* <<<<<<<<<<<<End of Extra Initialization declarations. */
int gi, flowset;
double cq, area0, Cv, Kv;
gi = ip[0];
flowset = ip[1];
cq = rp[0];
area0 = rp[1];
Cv = rp[2];
Kv = rp[3];
loop = 0;
error = 0;
/*
If necessary, check values of the following:
rp[0..3]
*/
/* >>>>>>>>>>>>Initialization Function Check Statements. */
pn2_valid_gas_(&gi, &error);
if (flowset == 1)
{
if (area0 < 0.0)
{
error = 2;
amefprintf(stderr, "\nOrifice area at maximum opening should be positive.\n");
}
if (cq <= 0.0 )
{
error = 2;
amefprintf(stderr, "\nFlow coefficient should be strictly positive.\n");
}
}
else if (flowset == 2)
{
if (Cv < 0.0)
{
error = 2;
amefprintf(stderr, "\nMaximum flow coefficient (Cv) should be positive (value is %g).\n", Cv);
}
}
else
{
if (Kv < 0.0)
{
error = 2;
amefprintf(stderr, "\nMaximum flow coefficient (Kv) should be positive (value is %g).\n", Kv);
}
}
/* <<<<<<<<<<<<End of Initialization Check Statements. */
/* Integer parameter checking: */
if (gi < 1 || gi > 99)
{
amefprintf(stderr, "\ngas type index must be in range [1..99].\n");
error = 2;
}
if (flowset < 1 || flowset > 3)
{
amefprintf(stderr, "\nflow coefficient setting must be in range [1..3].\n");
error = 2;
}
SUBMODEL_HANDLE_AND_RESET_ERROR(_SUBMODELNAME_, n, error)
/* Common -> SI units conversions. */
rp[1] *= 1.00000000000000e-006;
area0 = rp[1];
/* >>>>>>>>>>>>Initialization Function Executable Statements. */
/* get atmospheric pressure */
c[PATM] = pn2getatp_();
if (flowset == 1)
{
c[CQ] = cq;
c[AREAMAX] = area0;
}
else
{
/* calculation of equivalent maximal area with Cv or Kv.
Default value of cq; the same value will be used in pn2rcqfix. */
c[CQ] = 0.72;
if (flowset == 2) /* Cv */
orif_areafromcv_(&Cv, &c[CQ], &c[AREAMAX]);
else
orif_areafromkv_(&Kv, &c[CQ], &c[AREAMAX]);
}
/* <<<<<<<<<<<<End of Initialization Executable Statements. */
}
/* There are 3 ports.
Port 1 has 1 variable:
1 res input signal [null] basic variable input
Port 2 has 4 variables:
1 dh2 enthalpy flow rate at port 2 [J/s -> W] basic variable output
2 dm2 mass flow rate at port 2 [g/s -> kg/s] basic variable output
3 temp2 temperature at port 2 [K] basic variable input
4 press2 pressure at port 2 [Pa] basic variable input
Port 3 has 4 variables:
1 dh3 duplicate of dh2 (sign reversed)
2 dm3 duplicate of dm2 (sign reversed)
3 temp3 temperature at port 3 [K] basic variable input
4 press3 pressure at port 3 [Pa] basic variable input
*/
/* There are 3 internal variables.
1 xv fractional opening [null] basic variable
2 cm mass flow parameter (cm) [(kg*K/J)**(1/2)] basic variable
3 gasvel vena contracta gas velocity [m/s] basic variable
*/
void pnvo001_(int *n, double *res, double *dh2, double *dm2
, double *temp2, double *press2, double *temp3, double *press3
, double *xv, double *cm, double *gasvel, double rp[4]
, int ip[2], double c[3], int ic[2])
{
int loop;
/* >>>>>>>>>>>>Extra Calculation Function Declarations Here. */
double marea; /* modulated area */
double pressa2, pressa3;
static double zero = 0.0, one = 1.0;
/* <<<<<<<<<<<<End of Extra Calculation declarations. */
int gi, flowset;
double cq, area0, Cv, Kv;
gi = ip[0];
flowset = ip[1];
cq = rp[0];
area0 = rp[1];
Cv = rp[2];
Kv = rp[3];
loop = 0;
/*
Set all submodel outputs below:
*dh2 = ??;
*dm2 = ??;
*xv = ??;
*cm = ??;
*gasvel = ??;
*/
/* >>>>>>>>>>>>Calculation Function Executable Statements. */
/* set absolute pressure */
pressa2 = *press2 + c[PATM];
pressa3 = *press3 + c[PATM];
*xv = dlimit_(res, &zero, &one, &ic[DISC_LIMIT]);
/* limitation of the modulated area */
marea = *xv * c[AREAMAX];
/*** calculation of the flows ***/
pn2rcqfix_( dh2, dm2, temp2, &pressa2, temp3, &pressa3, &marea, &c[CQ], &gi,
cm, gasvel, &ic[DISC_ORIF] );
/* <<<<<<<<<<<<End of Calculation Executable Statements. */
/* SI -> Common units conversions. */
*dm2 /= 1.00000000000000e-003;
}
@@ -0,0 +1,220 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE SPE>
<SPE DOC_VERSION="2" AME_VERSION="14.0.0 - 42489-40361 2015">
<SUBMODEL>
<SUB_TYPE>0</SUB_TYPE>
<SUB_ID_MAX>20</SUB_ID_MAX>
<DEFAULT_ICON>pn_morifice</DEFAULT_ICON>
<SUB_LABEL>modulated pneumatic orifice (constant flow coefficient)</SUB_LABEL>
<SUB_UNIT>0</SUB_UNIT>
<R_STORES_NUMBER>3</R_STORES_NUMBER>
<I_STORES_NUMBER>2</I_STORES_NUMBER>
<OUTPUT_TYPE>1</OUTPUT_TYPE>
<RPARAMS_LIST>
<RPARAM>
<SUB_ID>12</SUB_ID>
<TITLE>flow coefficient (Cq)</TITLE>
<VARNAME>cq</VARNAME>
<VISIBILITY>flowset==1</VISIBILITY>
<DEF_VALUE>7.20000000000000e-01</DEF_VALUE>
<VALUE>7.20000000000000e-01</VALUE>
<MIN_VALUE>1.00000000000000e-010</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+000</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>13</SUB_ID>
<TITLE>orifice area at maximum opening</TITLE>
<VARNAME>area0</VARNAME>
<VISIBILITY>flowset==1</VISIBILITY>
<DEF_VALUE>5.00000000000000e+00</DEF_VALUE>
<VALUE>5.00000000000000e+00</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+006</MAX_VALUE>
<UNITS>mm**2</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>18</SUB_ID>
<TITLE>maximum flow coefficient (Cv)</TITLE>
<VARNAME>Cv</VARNAME>
<VISIBILITY>flowset==2</VISIBILITY>
<DEF_VALUE>5.00000000000000e-01</DEF_VALUE>
<VALUE>5.00000000000000e-01</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+030</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
<RPARAM>
<SUB_ID>19</SUB_ID>
<TITLE>maximum flow coefficient (Kv)</TITLE>
<VARNAME>Kv</VARNAME>
<VISIBILITY>flowset==3</VISIBILITY>
<DEF_VALUE>4.00000000000000e-01</DEF_VALUE>
<VALUE>4.00000000000000e-01</VALUE>
<MIN_VALUE>0.00000000000000e+000</MIN_VALUE>
<MAX_VALUE>1.00000000000000e+030</MAX_VALUE>
<UNITS>null</UNITS>
</RPARAM>
</RPARAMS_LIST>
<IPARAMS_LIST>
<IPARAM>
<SUB_ID>14</SUB_ID>
<TITLE>gas type index</TITLE>
<VARNAME>gi</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>99</MAX_VALUE>
</IPARAM>
<IPARAM>
<SUB_ID>15</SUB_ID>
<TITLE>flow coefficient setting</TITLE>
<VARNAME>flowset</VARNAME>
<VISIBILITY>True</VISIBILITY>
<DEF_VALUE>1</DEF_VALUE>
<VALUE>1</VALUE>
<MIN_VALUE>1</MIN_VALUE>
<MAX_VALUE>3</MAX_VALUE>
<ENUM_LIST>
<ENUM>
<ENUM_STRING>Cq</ENUM_STRING>
</ENUM>
<ENUM>
<ENUM_STRING>Cv</ENUM_STRING>
</ENUM>
<ENUM>
<ENUM_STRING>Kv</ENUM_STRING>
</ENUM>
</ENUM_LIST>
</IPARAM>
</IPARAMS_LIST>
<IVARS_LIST>
<IVAR>
<SUB_ID>20</SUB_ID>
<TITLE>fractional opening</TITLE>
<VARNAME>xv</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>null</UNITS>
</IVAR>
<IVAR>
<SUB_ID>10</SUB_ID>
<TITLE>mass flow parameter (cm)</TITLE>
<VARNAME>cm</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>(kg*K/J)**(1/2)</UNITS>
</IVAR>
<IVAR>
<SUB_ID>11</SUB_ID>
<TITLE>vena contracta gas velocity</TITLE>
<VARNAME>gasvel</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<UNITS>m/s</UNITS>
</IVAR>
</IVARS_LIST>
<EVARS_LIST>
<PORT>
<EVAR>
<SUB_ID>1</SUB_ID>
<TITLE>input signal</TITLE>
<VARNAME>res</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>null</UNITS>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>2</SUB_ID>
<TITLE>enthalpy flow rate at port 2</TITLE>
<VARNAME>dh2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>J/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>3</SUB_ID>
<TITLE>mass flow rate at port 2</TITLE>
<VARNAME>dm2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>2</IO>
<UNITS>g/s</UNITS>
</EVAR>
<EVAR>
<SUB_ID>4</SUB_ID>
<TITLE>temperature at port 2</TITLE>
<VARNAME>temp2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>5</SUB_ID>
<TITLE>pressure at port 2</TITLE>
<VARNAME>press2</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
<PORT>
<EVAR>
<SUB_ID>6</SUB_ID>
<VARNAME>dh3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>1</PRIMARY_PORT>
<PRIMARY_VAR>0</PRIMARY_VAR>
<DUP_TYPE>1</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>7</SUB_ID>
<VARNAME>dm3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>4</TYPE>
<PRIMARY_PORT>1</PRIMARY_PORT>
<PRIMARY_VAR>1</PRIMARY_VAR>
<DUP_TYPE>1</DUP_TYPE>
</EVAR>
<EVAR>
<SUB_ID>8</SUB_ID>
<TITLE>temperature at port 3</TITLE>
<VARNAME>temp3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>K</UNITS>
</EVAR>
<EVAR>
<SUB_ID>9</SUB_ID>
<TITLE>pressure at port 3</TITLE>
<VARNAME>press3</VARNAME>
<VISIBILITY>True</VISIBILITY>
<TYPE>0</TYPE>
<DIMENSION>1</DIMENSION>
<IO>1</IO>
<UNITS>Pa</UNITS>
</EVAR>
</PORT>
</EVARS_LIST>
<SUBIDS_RESET>0</SUBIDS_RESET>
</SUBMODEL>
</SPE>
File diff suppressed because it is too large. Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+140
View File
@@ -0,0 +1,140 @@
# test_mql
本目录记录 AMESim 模型 `test_mql.ame` 向 `app.simulation` 迁移时使用的源模型信息、结果对齐约定和当前进度。
## 目标
迁移目标不是复制 AMESim `.results` 中的观测值,而是建立真实的 Python 仿真链路:
`组件方程 -> SimulationNetwork/系统装配 -> closure -> snapshot/端口写回 -> RHS -> solver -> reporting/comparison`
Python 输出只有通过 AMESim baseline 对比后才能作为数值一致性依据。duplicate、反号或派生观测可以用于验证端口方向,但不能替代组件方程和网络闭合。
## 模型与源数据
- AMESim 源模型:`AmesimModels/test_mql.ame`
- Python 系统类:`app.simulation.examples.test_mql.system.TestMqlSystem`
- 结构运行入口:`app.simulation.examples.test_mql.run`
- 132 状态比较入口:`app.simulation.examples.test_mql.run_full_state_comparison`
- AMESim 组件数:117
- LINE 连接数:84
- 连续状态数:132
- 离散状态数:24
- 全局参数:`D1=20`、`D2=20`、`D3=14`、`P0=153`、`Pdq=1`、`V=15`、`cf=0.45`
`.ame` 文件是 tar 包,迁移和校验主要使用其中的:
- `test_mql_.cir`:组件、连接、参数表达式和生成代码线索。
- `test_mql_.param` / `test_mql_.data`:参数和结果配套数据。
- `test_mql_.modelinfo` / `test_mql_.sim`:状态数和仿真设置。
- `test_mql_.var` / `test_mql_.results`:AMESim `Data_Path` 目录和 baseline 时序。
当前结果解析器可读取 1002 个时间点和 1116 个保存变量,无需先转换成 CSV。
## 当前实现
当前已经完成:
- AMESim 组件、LINE 连接、直接组件接触、全局参数和变量目录解析。
- 氦气 Peng-Robinson 物性;内部使用绝对压力,AMESim `press` 按相对 `101300 Pa` 的表压输出。
- `PNCH023 / PNCH012 / PNOR001 / PNVO001` 气动组件。
- `PNL0001 / PNL0002 / PNL0003 / PNL00R` 管路动态或阻性关系。
- `PN3NODE2 / P4NODE2` 代数节点、真实邻接拓扑、canonical flow 和端口写回。
- `PNRP17 / MECMAS21 / LSTP00A / LMECHN1 / UD00 / FORC` 当前工况可确认的机械行为。
- 112 个气动状态和 20 个机械状态组成的 132 状态总闭包。
- 活塞运动学、变容气室机械反馈、气动力、外力、端止动和质量约束耦合。
- 关键 `Data_Path` 序列导出、schema validation、AMESim 插值 comparison、误差排序、端点诊断和变容气室 RHS 拆解。
主要实现位置:
- `app/simulation/examples/test_mql/system.py`
- `app/simulation/examples/test_mql/closure.py`
- `app/simulation/examples/test_mql/pneumatic.py`
- `app/simulation/examples/test_mql/mechanical.py`
- `app/simulation/examples/test_mql/lines.py`
- `app/simulation/examples/test_mql/primitives/`
- `app/simulation/examples/test_mql/structural_network.py`
- `app/simulation/reporting/amesim_results.py`
- `app/simulation/reporting/test_mql_comparison.py`
- `app/simulation/examples/test_mql/run_full_state_comparison.py`
## 当前对比结果
默认 comparison 已从区间内插值的 `t=1e-5 s` 改为与 AMESim
首个保存时刻精确对齐的 `t=0.01 s`,当前比较 13 个关键信号,并
新增 `xv@pn_morifice_1`、`dm2@pn_morifice_1` 的结构化 PNVO 诊断。
事件前 `t=0.01 s` 对比:
- `press@pn_c1_8`:Python `-1286.601221 Pa`,AMESim
`-1288.253185 Pa`,绝对误差约 `1.651964 Pa`。
- `dm1@pneumatic_69`:Python `-0.002485112 g/s`,AMESim
`-0.002054255 g/s`;换算后的 canonical 流量绝对误差约
`4.30857e-7 kg/s`。
- `xv@pn_morifice_1` 和 `dm2@pn_morifice_1` 在两侧均为 0,确认
STEP0 事件前 PNVO 保持关闭。
- `vol1@pn_brp2_8` 绝对误差约 `8.76e-5`,机械位移、速度和加速度
仍保持较小误差;当前较明显的累计差异集中在 PNL0001 流量和
PNCH012 压力/能量链路。
新增 `--pnvo-event-boundary` 诊断:先积分到 `0.04 s` 的左极限,
再按 STEP0 的右连续语义在事件时刻读取开度和流量。结果为:
- `xv@pn_morifice_1`:Python/AMESim 均为 `1`。
- `dm2@pn_morifice_1`:Python `502.945005 g/s`,AMESim
`497.823823 g/s`,绝对误差约 `5.121182 g/s`,相对约 `1.03%`。
- `press@pn_c1_8` 绝对误差约 `55.4815 Pa`;
`dm1@pneumatic_69` 绝对误差约 `0.00281880 g/s`。
这说明 PNVO 开启瞬间的开度语义和主流量量级已经对齐,但事件前
累积压力/支路流量仍有偏差。常规积分直接跨越事件到 `0.05 s` 时,
当前进程会被系统终止,尚未形成可信的事件后结果;不能据此声明
完整 `0.04 -> 0.05 s` 窗口已经可运行。
## 下一步
1. 优先定位 `0 -> 0.04 s` 累积的 `pneumatic_69` 流量与
`pn_c1_8` 压力偏差,区分 PNL0001 阻力和 PNCH012 能量方程。
2. 采用显式事件分段或针对事件后的局部数值策略,解决跨越
`t=0.04 s` 后积分进程被终止的问题,再验证 `t=0.05 s` 保存点。
3. 保留 `press@pn_c1_8`、`dm1@pneumatic_69`、PNVO `xv/dm2`
和 chamber RHS breakdown 作为同一条诊断链。
4. 在完整开启窗口稳定后,再判断是否需要校准 PNVO 流量系数。
`pn_c1_8` 的直接主线是 `pneumatic_69`;`pneumatic_96`
属于另一条固定气室支路,不是该诊断对象。
## 运行与验证
运行默认短时域 comparison:
```bash
python3 -m app.simulation.examples.test_mql.run_full_state_comparison
```
运行 PNVO 事件边界诊断:
```bash
python3 -m app.simulation.examples.test_mql.run_full_state_comparison --pnvo-event-boundary
```
运行相关测试:
```bash
python3 -m unittest tests.test_run_test_mql_full_state_comparison tests.test_test_mql_pnl0001_segment
```
运行全量测试:
```bash
python3 -m unittest discover -s tests -t .
```
## 对齐约定
- 组件 alias 和输出名优先保持 AMESim 原名及 `Data_Path`。
- `PortState.m_flow > 0` 表示流入当前组件。
- closure 先定义 canonical flow,再按各组件端口方向写回 `m_flow`。
- AMESim 管路质量流量通常以 `g/s` 保存,Python 内部统一使用 `kg/s`。
- CSV 是人工检查和交换格式,不是读取 AMESim baseline 的前置条件。
- 未完成真实 Python 输出对比前,不使用“与 AMESim 完全一致”之类结论。
+24
View File
@@ -0,0 +1,24 @@
# 浏览器四路、八路测试工程
本目录中的 JSON/XML 仅保留以下两个可由网页“导入工程 JSON”识别的工程文件。已逐项核对对应 AME 图纸的元件、公开物理参数及端口连接;AME 单位与工程 SI 单位之间的换算已纳入检查。
| 浏览器工程 | Amesim 原文件 | 元件 / 参数 / 连接 |
|---|---|---|
| [test-mql-4-corrected.json](test-mql-4-corrected.json) | [test_mql_4.ame](test_mql_4.ame) | 81 / 582 / 90 |
| [test-mql-8-corrected.json](test-mql-8-corrected.json) | [test_mql.ame](test_mql.ame) | 157 / 1092 / 178 |
网页当前只支持导入工程 JSON;XML 可从网页下载,用作后端输入。网页使用原生 BDF 和当前默认 `rtol=1e-8`,与 AME 内部积分器及历史数值设置不能视为相同。这里的参数对齐指模型物理参数与初值,不声称不同仿真器所有数值输出完全一致。
2026-09-11 整理时,两份工程内容保持不变。其他 JSON/XML 已按用途移出本目录,移动前后字节数及 SHA256 相同:
| 原文件 | 当前路径 | 用途 |
|---|---|---|
| native-python-reference.json | [原生数值基准](../baselines/native/native-python-reference.json) | 50 网络冻结参考 |
| test-mql-4-amesim-reference.json | [四路 Amesim 曲线基准](../baselines/simulation/test_mql_4/test-mql-4-amesim-reference.json) | 72 曲线、57 时刻 |
| test-mql-4-corrected.xml | [四路执行 XML](../fixtures/amesim/test-mql-4-corrected.xml) | 与四路 JSON 同步的后端输入 |
| test-mql-8.json / test-mql-8.xml | [旧 JSON](../fixtures/legacy/test-mql-8.json) / [旧 XML](../fixtures/legacy/test-mql-8.xml) | 修正前输入及布局来源 |
| test_mql-full-branches-01-04.xml | [历史分支基准输入](../baselines/simulation/test_mql_full_branches/sources/test_mql-full-branches-01-04.xml) | 历史回归清单绑定的输入 |
| native-skill-test.xml | [原生通用测试输入](../fixtures/native-skill-test.xml) | 原生编译、执行与 CI 检查 |
| fixtures/high_stiffness_explicit_rk45.xml | [高刚度 RK45 输入](../fixtures/high_stiffness_explicit_rk45.xml) | 独立刚度回归用例 |
AME 原文件及本目录中其他类型的资料保持原位。历史运行记录保留当时路径;活动测试、审计脚本、CI 和当前交付说明已更新到新路径。
@@ -1,325 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<System name="demo-system" schemaVersion="3" unitSystem="SI">
<Simulation tStart="0" tStop="10" sampleStep="0.02" maxStep="0.02" method="RK45"/>
<Components>
<Component id="amesim_pnch023_1" type="amesim_pnch023" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="cvol" value="0.057"/>
<Parameter name="kth" value="0"/>
<Parameter name="sth" value="0.1"/>
<Parameter name="extemp" value="293.15"/>
<Parameter name="p0" value="15300000"/>
<Parameter name="T0" value="293.15"/>
</Component>
<Component id="amesim_pnvo001_1" type="amesim_pnvo001" modelVersion="0.2.0">
<Parameter name="gi" value="1"/>
<Parameter name="cq" value="0.45"/>
<Parameter name="area0" value="0.0000785"/>
<Parameter name="Cv" value="0.5"/>
<Parameter name="Kv" value="0.4"/>
<Parameter name="flowset" value="1"/>
<Parameter name="opening0" value="0"/>
</Component>
<Component id="amesim_step0_1" type="amesim_step0" modelVersion="0.1.0">
<Parameter name="initial" value="0"/>
<Parameter name="final" value="1"/>
<Parameter name="time" value="0.04"/>
</Component>
<Component id="amesim_pnch012_1" type="amesim_pnch012" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="cvol0" value="0.015"/>
<Parameter name="kth" value="1500"/>
<Parameter name="sth" value="0.7"/>
<Parameter name="extemp" value="293.15"/>
<Parameter name="p0" value="100000"/>
<Parameter name="T0" value="293.15"/>
<Parameter name="vol1" value="0"/>
<Parameter name="vol2" value="0"/>
<Parameter name="vol3" value="0"/>
<Parameter name="vol4" value="0"/>
<Parameter name="dvol1" value="0"/>
<Parameter name="dvol2" value="0"/>
<Parameter name="dvol3" value="0"/>
<Parameter name="dvol4" value="0"/>
</Component>
<Component id="amesim_pnpl01_2" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_3" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_4" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_ud00_1" type="amesim_ud00" modelVersion="0.2.0">
<Parameter name="tstart" value="0"/>
<Parameter name="start1" value="100000000000000000"/>
<Parameter name="end1" value="100000000000000000"/>
<Parameter name="t1" value="0.8"/>
<Parameter name="start2" value="49000"/>
<Parameter name="end2" value="49000"/>
<Parameter name="t2" value="10"/>
<Parameter name="start3" value="1"/>
<Parameter name="end3" value="1"/>
<Parameter name="t3" value="0"/>
<Parameter name="start4" value="1"/>
<Parameter name="end4" value="1"/>
<Parameter name="t4" value="0"/>
<Parameter name="start5" value="1"/>
<Parameter name="end5" value="1"/>
<Parameter name="t5" value="0"/>
<Parameter name="start6" value="1"/>
<Parameter name="end6" value="1"/>
<Parameter name="t6" value="0"/>
<Parameter name="start7" value="1"/>
<Parameter name="end7" value="1"/>
<Parameter name="t7" value="0"/>
<Parameter name="start8" value="1"/>
<Parameter name="end8" value="1"/>
<Parameter name="t8" value="0"/>
<Parameter name="nstages" value="2"/>
<Parameter name="iscyclic" value="0"/>
</Component>
<Component id="amesim_forc_1" type="amesim_forc" modelVersion="0.2.0">
<Parameter name="direction" value="1"/>
</Component>
<Component id="amesim_pnrp17_1" type="amesim_pnrp17" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="dp" value="0.2"/>
<Parameter name="dr" value="0.001"/>
<Parameter name="x0" value="0"/>
</Component>
<Component id="amesim_helium_medium_1" type="amesim_helium_medium" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="property_model" value="0"/>
</Component>
<Component id="amesim_pnch012_2" type="amesim_pnch012" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="cvol0" value="0.015"/>
<Parameter name="kth" value="1500"/>
<Parameter name="sth" value="0.7"/>
<Parameter name="extemp" value="293.15"/>
<Parameter name="p0" value="100000"/>
<Parameter name="T0" value="293.15"/>
<Parameter name="vol1" value="0"/>
<Parameter name="vol2" value="0"/>
<Parameter name="vol3" value="0"/>
<Parameter name="vol4" value="0"/>
<Parameter name="dvol1" value="0"/>
<Parameter name="dvol2" value="0"/>
<Parameter name="dvol3" value="0"/>
<Parameter name="dvol4" value="0"/>
</Component>
<Component id="amesim_pnpl01_6" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_7" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_8" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_9" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_mecmas21_2" type="amesim_mecmas21" modelVersion="0.2.0">
<Parameter name="mass" value="50"/>
<Parameter name="fstick" value="0"/>
<Parameter name="fcoul" value="0"/>
<Parameter name="rvisc" value="0"/>
<Parameter name="wind" value="0"/>
<Parameter name="dvel" value="0.000001"/>
<Parameter name="restdvel" value="0.000001"/>
<Parameter name="restcoeff" value="0.65"/>
<Parameter name="astrib" value="0.001"/>
<Parameter name="xmin" value="-1"/>
<Parameter name="Kbmin" value="1000000000"/>
<Parameter name="Dbmin" value="10000"/>
<Parameter name="Pdmin" value="0.0001"/>
<Parameter name="xmax" value="0.8"/>
<Parameter name="Kbmax" value="1000000000"/>
<Parameter name="Dbmax" value="10000"/>
<Parameter name="Pdmax" value="0.0001"/>
<Parameter name="theta" value="0"/>
<Parameter name="useFriction" value="1"/>
<Parameter name="stoptype" value="4"/>
<Parameter name="discContactOption" value="1"/>
<Parameter name="strib" value="1"/>
<Parameter name="frictionType" value="1"/>
<Parameter name="v0" value="0"/>
<Parameter name="x0" value="0"/>
</Component>
<Component id="amesim_f000_1" type="amesim_f000" modelVersion="0.1.0"/>
<Component id="amesim_f000_2" type="amesim_f000" modelVersion="0.1.0"/>
<Component id="amesim_lstp00a_1" type="amesim_lstp00a" modelVersion="0.2.0">
<Parameter name="na" value="10"/>
<Parameter name="gap0" value="0"/>
<Parameter name="kcont" value="100000000000"/>
<Parameter name="G" value="85700000000"/>
<Parameter name="sdiam" value="0.02"/>
<Parameter name="wdiam" value="0.002"/>
<Parameter name="rcont" value="100000000000"/>
<Parameter name="Pdis" value="1e-7"/>
<Parameter name="stiffmode" value="1"/>
<Parameter name="discContactOption" value="1"/>
</Component>
<Component id="amesim_forc_2" type="amesim_forc" modelVersion="0.2.0">
<Parameter name="direction" value="1"/>
</Component>
<Component id="amesim_ud00_2" type="amesim_ud00" modelVersion="0.2.0">
<Parameter name="tstart" value="0"/>
<Parameter name="start1" value="1000000000000"/>
<Parameter name="end1" value="1000000000000"/>
<Parameter name="t1" value="0.8"/>
<Parameter name="start2" value="0"/>
<Parameter name="end2" value="0"/>
<Parameter name="t2" value="10"/>
<Parameter name="start3" value="1"/>
<Parameter name="end3" value="1"/>
<Parameter name="t3" value="0"/>
<Parameter name="start4" value="1"/>
<Parameter name="end4" value="1"/>
<Parameter name="t4" value="0"/>
<Parameter name="start5" value="1"/>
<Parameter name="end5" value="1"/>
<Parameter name="t5" value="0"/>
<Parameter name="start6" value="1"/>
<Parameter name="end6" value="1"/>
<Parameter name="t6" value="0"/>
<Parameter name="start7" value="1"/>
<Parameter name="end7" value="1"/>
<Parameter name="t7" value="0"/>
<Parameter name="start8" value="1"/>
<Parameter name="end8" value="1"/>
<Parameter name="t8" value="0"/>
<Parameter name="nstages" value="2"/>
<Parameter name="iscyclic" value="0"/>
</Component>
<Component id="amesim_mecmas21_5" type="amesim_mecmas21" modelVersion="0.2.0">
<Parameter name="mass" value="170000"/>
<Parameter name="fstick" value="0"/>
<Parameter name="fcoul" value="0"/>
<Parameter name="rvisc" value="0"/>
<Parameter name="wind" value="0"/>
<Parameter name="dvel" value="0.000001"/>
<Parameter name="restdvel" value="0.000001"/>
<Parameter name="restcoeff" value="0.65"/>
<Parameter name="astrib" value="0.001"/>
<Parameter name="xmin" value="0"/>
<Parameter name="Kbmin" value="1000000000"/>
<Parameter name="Dbmin" value="10000"/>
<Parameter name="Pdmin" value="0.0001"/>
<Parameter name="xmax" value="0.37"/>
<Parameter name="Kbmax" value="1000000000"/>
<Parameter name="Dbmax" value="10000"/>
<Parameter name="Pdmax" value="0.0001"/>
<Parameter name="theta" value="0"/>
<Parameter name="useFriction" value="1"/>
<Parameter name="stoptype" value="1"/>
<Parameter name="discContactOption" value="1"/>
<Parameter name="strib" value="1"/>
<Parameter name="frictionType" value="1"/>
<Parameter name="v0" value="0"/>
<Parameter name="x0" value="0"/>
</Component>
<Component id="amesim_mecmas21_7" type="amesim_mecmas21" modelVersion="0.2.0">
<Parameter name="mass" value="90000"/>
<Parameter name="fstick" value="0"/>
<Parameter name="fcoul" value="0"/>
<Parameter name="rvisc" value="0"/>
<Parameter name="wind" value="0"/>
<Parameter name="dvel" value="0.000001"/>
<Parameter name="restdvel" value="0.000001"/>
<Parameter name="restcoeff" value="0.65"/>
<Parameter name="astrib" value="0.001"/>
<Parameter name="xmin" value="-0.72"/>
<Parameter name="Kbmin" value="1000000000"/>
<Parameter name="Dbmin" value="10000"/>
<Parameter name="Pdmin" value="0.0001"/>
<Parameter name="xmax" value="0"/>
<Parameter name="Kbmax" value="1000000000"/>
<Parameter name="Dbmax" value="10000"/>
<Parameter name="Pdmax" value="0.0001"/>
<Parameter name="theta" value="0"/>
<Parameter name="useFriction" value="1"/>
<Parameter name="stoptype" value="1"/>
<Parameter name="discContactOption" value="1"/>
<Parameter name="strib" value="1"/>
<Parameter name="frictionType" value="1"/>
<Parameter name="v0" value="0"/>
<Parameter name="x0" value="0"/>
</Component>
</Components>
<Connections>
<Connection id="edge-amesim_pnch023_1-port_2-amesim_pnvo001_1-port_2-1786524999267">
<Endpoint component="amesim_pnch023_1" port="port_2"/>
<Endpoint component="amesim_pnvo001_1" port="port_2"/>
</Connection>
<Connection id="edge-amesim_pnvo001_1-port_3-amesim_pnch012_1-port_1-1786525009973">
<Endpoint component="amesim_pnvo001_1" port="port_3"/>
<Endpoint component="amesim_pnch012_1" port="port_1"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_2-port_1-amesim_pnch012_1-port_2-1786525035706-0">
<Endpoint component="amesim_pnpl01_2" port="port_1"/>
<Endpoint component="amesim_pnch012_1" port="port_2"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_3-port_1-amesim_pnch012_1-port_3-1786525054054-0">
<Endpoint component="amesim_pnpl01_3" port="port_1"/>
<Endpoint component="amesim_pnch012_1" port="port_3"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_4-port_1-amesim_pnch012_1-port_4-1786525061349-0">
<Endpoint component="amesim_pnpl01_4" port="port_1"/>
<Endpoint component="amesim_pnch012_1" port="port_4"/>
</Connection>
<Connection id="edge-amesim_step0_1-out-amesim_pnvo001_1-res-1786525074494">
<Endpoint component="amesim_step0_1" port="out"/>
<Endpoint component="amesim_pnvo001_1" port="res"/>
</Connection>
<Connection id="edge-amesim_ud00_1-out-amesim_forc_1-res-1786525088412">
<Endpoint component="amesim_ud00_1" port="out"/>
<Endpoint component="amesim_forc_1" port="res"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_6-port_1-amesim_pnch023_1-port_1-1786525164428-0">
<Endpoint component="amesim_pnpl01_6" port="port_1"/>
<Endpoint component="amesim_pnch023_1" port="port_1"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_7-port_1-amesim_pnch012_2-port_1-1786525181969-0">
<Endpoint component="amesim_pnpl01_7" port="port_1"/>
<Endpoint component="amesim_pnch012_2" port="port_1"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_8-port_1-amesim_pnch012_2-port_4-1786525185493-0">
<Endpoint component="amesim_pnpl01_8" port="port_1"/>
<Endpoint component="amesim_pnch012_2" port="port_4"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_9-port_1-amesim_pnch012_2-port_2-1786525188482-0">
<Endpoint component="amesim_pnpl01_9" port="port_1"/>
<Endpoint component="amesim_pnch012_2" port="port_2"/>
</Connection>
<Connection id="edge-contact-amesim_f000_1-port_1-amesim_mecmas21_2-port_2-1786525202665-0">
<Endpoint component="amesim_f000_1" port="port_1"/>
<Endpoint component="amesim_mecmas21_2" port="port_2"/>
</Connection>
<Connection id="edge-amesim_mecmas21_2-port_1-amesim_pnrp17_1-port_2-1786525203778">
<Endpoint component="amesim_mecmas21_2" port="port_1"/>
<Endpoint component="amesim_pnrp17_1" port="port_2"/>
</Connection>
<Connection id="edge-amesim_pnrp17_1-port_5-amesim_lstp00a_1-port_1-1786525213548">
<Endpoint component="amesim_pnrp17_1" port="port_5"/>
<Endpoint component="amesim_lstp00a_1" port="port_1"/>
</Connection>
<Connection id="edge-amesim_ud00_2-out-amesim_forc_2-res-1786525226761">
<Endpoint component="amesim_ud00_2" port="out"/>
<Endpoint component="amesim_forc_2" port="res"/>
</Connection>
<Connection id="edge-contact-amesim_pnrp17_1-port_4-amesim_f000_2-port_1-1786525729832-0">
<Endpoint component="amesim_pnrp17_1" port="port_4"/>
<Endpoint component="amesim_f000_2" port="port_1"/>
</Connection>
<Connection id="edge-contact-amesim_pnrp17_1-port_1-amesim_pnch012_2-port_3-1786525729832-1">
<Endpoint component="amesim_pnrp17_1" port="port_1"/>
<Endpoint component="amesim_pnch012_2" port="port_3"/>
</Connection>
<Connection id="edge-amesim_forc_1-port_2-amesim_mecmas21_7-port_2-1786525915163">
<Endpoint component="amesim_forc_1" port="port_2"/>
<Endpoint component="amesim_mecmas21_7" port="port_2"/>
</Connection>
<Connection id="edge-amesim_mecmas21_7-port_1-amesim_pnrp17_1-port_3-1786525916652">
<Endpoint component="amesim_mecmas21_7" port="port_1"/>
<Endpoint component="amesim_pnrp17_1" port="port_3"/>
</Connection>
<Connection id="edge-amesim_mecmas21_5-port_1-amesim_forc_2-port_2-1786525922010">
<Endpoint component="amesim_mecmas21_5" port="port_1"/>
<Endpoint component="amesim_forc_2" port="port_2"/>
</Connection>
<Connection id="edge-amesim_lstp00a_1-port_2-amesim_mecmas21_5-port_2-1786525924224">
<Endpoint component="amesim_lstp00a_1" port="port_2"/>
<Endpoint component="amesim_mecmas21_5" port="port_2"/>
</Connection>
</Connections>
</System>
-325
View File
@@ -1,325 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<System name="skill-test" schemaVersion="3" unitSystem="SI">
<Simulation tStart="0" tStop="10" sampleStep="0.02" maxStep="0.001" method="RK45"/>
<Components>
<Component id="amesim_pnch023_1" type="amesim_pnch023" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="cvol" value="0.057"/>
<Parameter name="kth" value="0"/>
<Parameter name="sth" value="0.1"/>
<Parameter name="extemp" value="293.15"/>
<Parameter name="p0" value="15300000"/>
<Parameter name="T0" value="293.15"/>
</Component>
<Component id="amesim_pnvo001_1" type="amesim_pnvo001" modelVersion="0.2.0">
<Parameter name="gi" value="1"/>
<Parameter name="cq" value="0.45"/>
<Parameter name="area0" value="0.0000785"/>
<Parameter name="Cv" value="0.5"/>
<Parameter name="Kv" value="0.4"/>
<Parameter name="flowset" value="1"/>
<Parameter name="opening0" value="0"/>
</Component>
<Component id="amesim_step0_1" type="amesim_step0" modelVersion="0.1.0">
<Parameter name="initial" value="0"/>
<Parameter name="final" value="1"/>
<Parameter name="time" value="0.04"/>
</Component>
<Component id="amesim_pnch012_1" type="amesim_pnch012" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="cvol0" value="0.015"/>
<Parameter name="kth" value="1500"/>
<Parameter name="sth" value="0.7"/>
<Parameter name="extemp" value="293.15"/>
<Parameter name="p0" value="100000"/>
<Parameter name="T0" value="293.15"/>
<Parameter name="vol1" value="0"/>
<Parameter name="vol2" value="0"/>
<Parameter name="vol3" value="0"/>
<Parameter name="vol4" value="0"/>
<Parameter name="dvol1" value="0"/>
<Parameter name="dvol2" value="0"/>
<Parameter name="dvol3" value="0"/>
<Parameter name="dvol4" value="0"/>
</Component>
<Component id="amesim_pnpl01_2" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_3" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_4" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_ud00_1" type="amesim_ud00" modelVersion="0.2.0">
<Parameter name="tstart" value="0"/>
<Parameter name="start1" value="100000000000000000"/>
<Parameter name="end1" value="100000000000000000"/>
<Parameter name="t1" value="0.8"/>
<Parameter name="start2" value="49000"/>
<Parameter name="end2" value="49000"/>
<Parameter name="t2" value="10"/>
<Parameter name="start3" value="1"/>
<Parameter name="end3" value="1"/>
<Parameter name="t3" value="0"/>
<Parameter name="start4" value="1"/>
<Parameter name="end4" value="1"/>
<Parameter name="t4" value="0"/>
<Parameter name="start5" value="1"/>
<Parameter name="end5" value="1"/>
<Parameter name="t5" value="0"/>
<Parameter name="start6" value="1"/>
<Parameter name="end6" value="1"/>
<Parameter name="t6" value="0"/>
<Parameter name="start7" value="1"/>
<Parameter name="end7" value="1"/>
<Parameter name="t7" value="0"/>
<Parameter name="start8" value="1"/>
<Parameter name="end8" value="1"/>
<Parameter name="t8" value="0"/>
<Parameter name="nstages" value="2"/>
<Parameter name="iscyclic" value="0"/>
</Component>
<Component id="amesim_forc_1" type="amesim_forc" modelVersion="0.2.0">
<Parameter name="direction" value="1"/>
</Component>
<Component id="amesim_pnrp17_1" type="amesim_pnrp17" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="dp" value="0.2"/>
<Parameter name="dr" value="0.001"/>
<Parameter name="x0" value="0"/>
</Component>
<Component id="amesim_helium_medium_1" type="amesim_helium_medium" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="property_model" value="0"/>
</Component>
<Component id="amesim_pnch012_2" type="amesim_pnch012" modelVersion="0.1.0">
<Parameter name="gi" value="1"/>
<Parameter name="cvol0" value="0.015"/>
<Parameter name="kth" value="1500"/>
<Parameter name="sth" value="0.7"/>
<Parameter name="extemp" value="293.15"/>
<Parameter name="p0" value="100000"/>
<Parameter name="T0" value="293.15"/>
<Parameter name="vol1" value="0"/>
<Parameter name="vol2" value="0"/>
<Parameter name="vol3" value="0"/>
<Parameter name="vol4" value="0"/>
<Parameter name="dvol1" value="0"/>
<Parameter name="dvol2" value="0"/>
<Parameter name="dvol3" value="0"/>
<Parameter name="dvol4" value="0"/>
</Component>
<Component id="amesim_pnpl01_6" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_7" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_8" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_pnpl01_9" type="amesim_pnpl01" modelVersion="0.1.0"/>
<Component id="amesim_mecmas21_2" type="amesim_mecmas21" modelVersion="0.2.0">
<Parameter name="mass" value="50"/>
<Parameter name="fstick" value="0"/>
<Parameter name="fcoul" value="0"/>
<Parameter name="rvisc" value="0"/>
<Parameter name="wind" value="0"/>
<Parameter name="dvel" value="0.000001"/>
<Parameter name="restdvel" value="0.000001"/>
<Parameter name="restcoeff" value="0.65"/>
<Parameter name="astrib" value="0.001"/>
<Parameter name="xmin" value="-1"/>
<Parameter name="Kbmin" value="1000000000"/>
<Parameter name="Dbmin" value="10000"/>
<Parameter name="Pdmin" value="0.0001"/>
<Parameter name="xmax" value="0.8"/>
<Parameter name="Kbmax" value="1000000000"/>
<Parameter name="Dbmax" value="10000"/>
<Parameter name="Pdmax" value="0.0001"/>
<Parameter name="theta" value="0"/>
<Parameter name="useFriction" value="1"/>
<Parameter name="stoptype" value="4"/>
<Parameter name="discContactOption" value="1"/>
<Parameter name="strib" value="1"/>
<Parameter name="frictionType" value="1"/>
<Parameter name="v0" value="0"/>
<Parameter name="x0" value="0"/>
</Component>
<Component id="amesim_f000_1" type="amesim_f000" modelVersion="0.1.0"/>
<Component id="amesim_f000_2" type="amesim_f000" modelVersion="0.1.0"/>
<Component id="amesim_lstp00a_1" type="amesim_lstp00a" modelVersion="0.2.0">
<Parameter name="na" value="10"/>
<Parameter name="gap0" value="0"/>
<Parameter name="kcont" value="100000000000"/>
<Parameter name="G" value="85700000000"/>
<Parameter name="sdiam" value="0.02"/>
<Parameter name="wdiam" value="0.002"/>
<Parameter name="rcont" value="100000000000"/>
<Parameter name="Pdis" value="1e-7"/>
<Parameter name="stiffmode" value="1"/>
<Parameter name="discContactOption" value="1"/>
</Component>
<Component id="amesim_forc_2" type="amesim_forc" modelVersion="0.2.0">
<Parameter name="direction" value="1"/>
</Component>
<Component id="amesim_ud00_2" type="amesim_ud00" modelVersion="0.2.0">
<Parameter name="tstart" value="0"/>
<Parameter name="start1" value="1000000000000"/>
<Parameter name="end1" value="1000000000000"/>
<Parameter name="t1" value="0.8"/>
<Parameter name="start2" value="0"/>
<Parameter name="end2" value="0"/>
<Parameter name="t2" value="10"/>
<Parameter name="start3" value="1"/>
<Parameter name="end3" value="1"/>
<Parameter name="t3" value="0"/>
<Parameter name="start4" value="1"/>
<Parameter name="end4" value="1"/>
<Parameter name="t4" value="0"/>
<Parameter name="start5" value="1"/>
<Parameter name="end5" value="1"/>
<Parameter name="t5" value="0"/>
<Parameter name="start6" value="1"/>
<Parameter name="end6" value="1"/>
<Parameter name="t6" value="0"/>
<Parameter name="start7" value="1"/>
<Parameter name="end7" value="1"/>
<Parameter name="t7" value="0"/>
<Parameter name="start8" value="1"/>
<Parameter name="end8" value="1"/>
<Parameter name="t8" value="0"/>
<Parameter name="nstages" value="2"/>
<Parameter name="iscyclic" value="0"/>
</Component>
<Component id="amesim_mecmas21_5" type="amesim_mecmas21" modelVersion="0.2.0">
<Parameter name="mass" value="170000"/>
<Parameter name="fstick" value="0"/>
<Parameter name="fcoul" value="0"/>
<Parameter name="rvisc" value="0"/>
<Parameter name="wind" value="0"/>
<Parameter name="dvel" value="0.000001"/>
<Parameter name="restdvel" value="0.000001"/>
<Parameter name="restcoeff" value="0.65"/>
<Parameter name="astrib" value="0.001"/>
<Parameter name="xmin" value="0"/>
<Parameter name="Kbmin" value="1000000000"/>
<Parameter name="Dbmin" value="10000"/>
<Parameter name="Pdmin" value="0.0001"/>
<Parameter name="xmax" value="0.37"/>
<Parameter name="Kbmax" value="1000000000"/>
<Parameter name="Dbmax" value="10000"/>
<Parameter name="Pdmax" value="0.0001"/>
<Parameter name="theta" value="0"/>
<Parameter name="useFriction" value="1"/>
<Parameter name="stoptype" value="1"/>
<Parameter name="discContactOption" value="1"/>
<Parameter name="strib" value="1"/>
<Parameter name="frictionType" value="1"/>
<Parameter name="v0" value="0"/>
<Parameter name="x0" value="0"/>
</Component>
<Component id="amesim_mecmas21_7" type="amesim_mecmas21" modelVersion="0.2.0">
<Parameter name="mass" value="90000"/>
<Parameter name="fstick" value="0"/>
<Parameter name="fcoul" value="0"/>
<Parameter name="rvisc" value="0"/>
<Parameter name="wind" value="0"/>
<Parameter name="dvel" value="0.000001"/>
<Parameter name="restdvel" value="0.000001"/>
<Parameter name="restcoeff" value="0.65"/>
<Parameter name="astrib" value="0.001"/>
<Parameter name="xmin" value="-0.72"/>
<Parameter name="Kbmin" value="1000000000"/>
<Parameter name="Dbmin" value="10000"/>
<Parameter name="Pdmin" value="0.0001"/>
<Parameter name="xmax" value="0"/>
<Parameter name="Kbmax" value="1000000000"/>
<Parameter name="Dbmax" value="10000"/>
<Parameter name="Pdmax" value="0.0001"/>
<Parameter name="theta" value="0"/>
<Parameter name="useFriction" value="1"/>
<Parameter name="stoptype" value="1"/>
<Parameter name="discContactOption" value="1"/>
<Parameter name="strib" value="1"/>
<Parameter name="frictionType" value="1"/>
<Parameter name="v0" value="0"/>
<Parameter name="x0" value="0"/>
</Component>
</Components>
<Connections>
<Connection id="edge-amesim_pnch023_1-port_2-amesim_pnvo001_1-port_2-1786524999267">
<Endpoint component="amesim_pnch023_1" port="port_2"/>
<Endpoint component="amesim_pnvo001_1" port="port_2"/>
</Connection>
<Connection id="edge-amesim_pnvo001_1-port_3-amesim_pnch012_1-port_1-1786525009973">
<Endpoint component="amesim_pnvo001_1" port="port_3"/>
<Endpoint component="amesim_pnch012_1" port="port_1"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_2-port_1-amesim_pnch012_1-port_2-1786525035706-0">
<Endpoint component="amesim_pnpl01_2" port="port_1"/>
<Endpoint component="amesim_pnch012_1" port="port_2"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_3-port_1-amesim_pnch012_1-port_3-1786525054054-0">
<Endpoint component="amesim_pnpl01_3" port="port_1"/>
<Endpoint component="amesim_pnch012_1" port="port_3"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_4-port_1-amesim_pnch012_1-port_4-1786525061349-0">
<Endpoint component="amesim_pnpl01_4" port="port_1"/>
<Endpoint component="amesim_pnch012_1" port="port_4"/>
</Connection>
<Connection id="edge-amesim_step0_1-out-amesim_pnvo001_1-res-1786525074494">
<Endpoint component="amesim_step0_1" port="out"/>
<Endpoint component="amesim_pnvo001_1" port="res"/>
</Connection>
<Connection id="edge-amesim_ud00_1-out-amesim_forc_1-res-1786525088412">
<Endpoint component="amesim_ud00_1" port="out"/>
<Endpoint component="amesim_forc_1" port="res"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_6-port_1-amesim_pnch023_1-port_1-1786525164428-0">
<Endpoint component="amesim_pnpl01_6" port="port_1"/>
<Endpoint component="amesim_pnch023_1" port="port_1"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_7-port_1-amesim_pnch012_2-port_1-1786525181969-0">
<Endpoint component="amesim_pnpl01_7" port="port_1"/>
<Endpoint component="amesim_pnch012_2" port="port_1"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_8-port_1-amesim_pnch012_2-port_4-1786525185493-0">
<Endpoint component="amesim_pnpl01_8" port="port_1"/>
<Endpoint component="amesim_pnch012_2" port="port_4"/>
</Connection>
<Connection id="edge-contact-amesim_pnpl01_9-port_1-amesim_pnch012_2-port_2-1786525188482-0">
<Endpoint component="amesim_pnpl01_9" port="port_1"/>
<Endpoint component="amesim_pnch012_2" port="port_2"/>
</Connection>
<Connection id="edge-amesim_mecmas21_2-port_1-amesim_pnrp17_1-port_2-1786525203778">
<Endpoint component="amesim_mecmas21_2" port="port_1"/>
<Endpoint component="amesim_pnrp17_1" port="port_2"/>
</Connection>
<Connection id="edge-amesim_pnrp17_1-port_5-amesim_lstp00a_1-port_1-1786525213548">
<Endpoint component="amesim_pnrp17_1" port="port_5"/>
<Endpoint component="amesim_lstp00a_1" port="port_1"/>
</Connection>
<Connection id="edge-amesim_ud00_2-out-amesim_forc_2-res-1786525226761">
<Endpoint component="amesim_ud00_2" port="out"/>
<Endpoint component="amesim_forc_2" port="res"/>
</Connection>
<Connection id="edge-contact-amesim_pnrp17_1-port_1-amesim_pnch012_2-port_3-1786525729832-1">
<Endpoint component="amesim_pnrp17_1" port="port_1"/>
<Endpoint component="amesim_pnch012_2" port="port_3"/>
</Connection>
<Connection id="edge-amesim_forc_1-port_2-amesim_mecmas21_7-port_2-1786525915163">
<Endpoint component="amesim_forc_1" port="port_2"/>
<Endpoint component="amesim_mecmas21_7" port="port_2"/>
</Connection>
<Connection id="edge-amesim_mecmas21_7-port_1-amesim_pnrp17_1-port_3-1786525916652">
<Endpoint component="amesim_mecmas21_7" port="port_1"/>
<Endpoint component="amesim_pnrp17_1" port="port_3"/>
</Connection>
<Connection id="edge-amesim_mecmas21_5-port_1-amesim_forc_2-port_2-1786525922010">
<Endpoint component="amesim_mecmas21_5" port="port_1"/>
<Endpoint component="amesim_forc_2" port="port_2"/>
</Connection>
<Connection id="edge-amesim_lstp00a_1-port_2-amesim_mecmas21_5-port_2-1786525924224">
<Endpoint component="amesim_lstp00a_1" port="port_2"/>
<Endpoint component="amesim_mecmas21_5" port="port_2"/>
</Connection>
<Connection id="edge-contact-amesim_f000_2-port_1-amesim_pnrp17_1-port_4-1788429018340-0">
<Endpoint component="amesim_f000_2" port="port_1"/>
<Endpoint component="amesim_pnrp17_1" port="port_4"/>
</Connection>
<Connection id="edge-contact-amesim_f000_1-port_1-amesim_mecmas21_2-port_2-1788429022851-0">
<Endpoint component="amesim_f000_1" port="port_1"/>
<Endpoint component="amesim_mecmas21_2" port="port_2"/>
</Connection>
</Connections>
</System>
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,6 +1,6 @@
{
"projectSchemaVersion": 1,
"name": "test-mql-8",
"name": "test-mql-8-corrected",
"nodes": [
{
"id": "pn_gas_data",
@@ -2679,7 +2679,7 @@
"parameters": {},
"parameterUnits": {},
"parameterScientificNotation": {},
"rotation": 0,
"rotation": 180,
"mirrored": false
}
},
@@ -2732,7 +2732,7 @@
"parameters": {},
"parameterUnits": {},
"parameterScientificNotation": {},
"rotation": 0,
"rotation": 180,
"mirrored": false
}
},
@@ -2785,7 +2785,7 @@
"parameters": {},
"parameterUnits": {},
"parameterScientificNotation": {},
"rotation": 0,
"rotation": 180,
"mirrored": false
}
},
@@ -2838,7 +2838,7 @@
"parameters": {},
"parameterUnits": {},
"parameterScientificNotation": {},
"rotation": 0,
"rotation": 180,
"mirrored": false
}
},
@@ -2891,7 +2891,7 @@
"parameters": {},
"parameterUnits": {},
"parameterScientificNotation": {},
"rotation": 0,
"rotation": 180,
"mirrored": false
}
},
@@ -2944,7 +2944,7 @@
"parameters": {},
"parameterUnits": {},
"parameterScientificNotation": {},
"rotation": 0,
"rotation": 180,
"mirrored": false
}
},
@@ -2997,7 +2997,7 @@
"parameters": {},
"parameterUnits": {},
"parameterScientificNotation": {},
"rotation": 0,
"rotation": 180,
"mirrored": false
}
},
@@ -7368,7 +7368,7 @@
}
],
"parameters": {
"mass": 90000,
"mass": 100.0,
"fstick": 0,
"fcoul": 0,
"rvisc": 0,
@@ -7377,17 +7377,17 @@
"restdvel": 1e-06,
"restcoeff": 0.65,
"astrib": 0.001,
"xmin": -0.72,
"xmin": -1.0,
"Kbmin": 1000000000,
"Dbmin": 10000,
"Pdmin": 0.0001,
"xmax": 0,
"xmax": 1.0,
"Kbmax": 1000000000,
"Dbmax": 10000,
"Pdmax": 0.0001,
"theta": 0,
"useFriction": 1,
"stoptype": 1,
"stoptype": 4.0,
"discContactOption": 1,
"strib": 1,
"frictionType": 1,
@@ -8768,7 +8768,7 @@
"source": "amesim_pnvo001_1",
"target": "amesim_p4node2_1",
"sourceHandle": "port_2",
"targetHandle": "port_3",
"targetHandle": "port_4",
"data": {
"isContactEdge": false
}
@@ -8778,7 +8778,7 @@
"source": "amesim_pnvo001_2",
"target": "amesim_p4node2_2",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"targetHandle": "port_4",
"data": {
"isContactEdge": false
}
@@ -8788,7 +8788,7 @@
"source": "amesim_pnvo001_3",
"target": "amesim_p4node2_3",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"targetHandle": "port_4",
"data": {
"isContactEdge": false
}
@@ -8798,7 +8798,7 @@
"source": "amesim_pnvo001_4",
"target": "amesim_p4node2_4",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"targetHandle": "port_4",
"data": {
"isContactEdge": false
}
@@ -8807,7 +8807,7 @@
"id": "edge-amesim_p4node2_2-port_4-amesim_pnl0002_2-port_1-1786949195556",
"source": "amesim_p4node2_2",
"target": "amesim_pnl0002_2",
"sourceHandle": "port_4",
"sourceHandle": "port_1",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -8818,7 +8818,7 @@
"source": "amesim_pnl0002_2",
"target": "amesim_p4node2_3",
"sourceHandle": "port_2",
"targetHandle": "port_1",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
}
@@ -8828,26 +8828,26 @@
"source": "amesim_pnl0002_3",
"target": "amesim_p4node2_3",
"sourceHandle": "port_1",
"targetHandle": "port_4",
"targetHandle": "port_1",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
"id": "edge-contact-amesim_p4node2_4-port_1-amesim_pnl0002_3-port_2-1786949205596-0",
"source": "amesim_p4node2_4",
"target": "amesim_pnl0002_3",
"sourceHandle": "port_1",
"sourceHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
"id": "edge-amesim_p4node2_4-port_4-amesim_pnl0002_4-port_1-1786949231675",
"source": "amesim_p4node2_4",
"target": "amesim_pnl0002_4",
"sourceHandle": "port_4",
"sourceHandle": "port_1",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -8858,7 +8858,7 @@
"source": "amesim_pnl0002_4",
"target": "amesim_p4node2_5",
"sourceHandle": "port_2",
"targetHandle": "port_1",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
}
@@ -8867,20 +8867,20 @@
"id": "edge-contact-amesim_p4node2_5-port_4-amesim_pnl0002_5-port_1-1786949246412-0",
"source": "amesim_p4node2_5",
"target": "amesim_pnl0002_5",
"sourceHandle": "port_4",
"sourceHandle": "port_1",
"targetHandle": "port_1",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
"id": "edge-contact-amesim_p4node2_6-port_1-amesim_pnl0002_5-port_2-1786949247647-0",
"source": "amesim_p4node2_6",
"target": "amesim_pnl0002_5",
"sourceHandle": "port_1",
"sourceHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -8888,7 +8888,7 @@
"source": "amesim_pnl0002_6",
"target": "amesim_p4node2_6",
"sourceHandle": "port_1",
"targetHandle": "port_4",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
}
@@ -8898,7 +8898,7 @@
"source": "amesim_pnl0002_6",
"target": "amesim_p4node2_7",
"sourceHandle": "port_2",
"targetHandle": "port_1",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
}
@@ -8908,26 +8908,26 @@
"source": "amesim_pnl0002_7",
"target": "amesim_p4node2_7",
"sourceHandle": "port_1",
"targetHandle": "port_4",
"targetHandle": "port_1",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
"id": "edge-contact-amesim_p4node2_8-port_1-amesim_pnl0002_7-port_2-1786949266454-0",
"source": "amesim_p4node2_8",
"target": "amesim_pnl0002_7",
"sourceHandle": "port_1",
"sourceHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
"id": "edge-amesim_p4node2_2-port_3-amesim_pnl0001_14-port_2-1786949362056",
"source": "amesim_p4node2_2",
"target": "amesim_pnl0001_14",
"sourceHandle": "port_3",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"data": {
"isContactEdge": false
@@ -8937,7 +8937,7 @@
"id": "edge-amesim_p4node2_3-port_3-amesim_pnl0001_15-port_2-1786949364233",
"source": "amesim_p4node2_3",
"target": "amesim_pnl0001_15",
"sourceHandle": "port_3",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"data": {
"isContactEdge": false
@@ -8947,7 +8947,7 @@
"id": "edge-amesim_p4node2_4-port_3-amesim_pnl0001_16-port_2-1786949365198",
"source": "amesim_p4node2_4",
"target": "amesim_pnl0001_16",
"sourceHandle": "port_3",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"data": {
"isContactEdge": false
@@ -8957,7 +8957,7 @@
"id": "edge-amesim_p4node2_5-port_3-amesim_pnl0001_17-port_2-1786949374542",
"source": "amesim_p4node2_5",
"target": "amesim_pnl0001_17",
"sourceHandle": "port_3",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"data": {
"isContactEdge": false
@@ -8967,7 +8967,7 @@
"id": "edge-amesim_p4node2_6-port_3-amesim_pnl0001_18-port_2-1786949377180",
"source": "amesim_p4node2_6",
"target": "amesim_pnl0001_18",
"sourceHandle": "port_3",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"data": {
"isContactEdge": false
@@ -8977,7 +8977,7 @@
"id": "edge-amesim_p4node2_7-port_3-amesim_pnl0001_19-port_2-1786949380063",
"source": "amesim_p4node2_7",
"target": "amesim_pnl0001_19",
"sourceHandle": "port_3",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"data": {
"isContactEdge": false
@@ -8987,7 +8987,7 @@
"id": "edge-amesim_p4node2_8-port_3-amesim_pnl0001_20-port_2-1786949381164",
"source": "amesim_p4node2_8",
"target": "amesim_pnl0001_20",
"sourceHandle": "port_3",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"data": {
"isContactEdge": false
@@ -9018,9 +9018,9 @@
"source": "amesim_pnpl01_2",
"target": "amesim_pnch012_8",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9038,9 +9038,9 @@
"source": "amesim_pnpl01_4",
"target": "amesim_pnch012_9",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9068,9 +9068,9 @@
"source": "amesim_pnpl01_6",
"target": "amesim_pnch012_10",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9098,9 +9098,9 @@
"source": "amesim_pnpl01_8",
"target": "amesim_pnch012_11",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9128,9 +9128,9 @@
"source": "amesim_pnpl01_10",
"target": "amesim_pnch012_12",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9158,9 +9158,9 @@
"source": "amesim_pnpl01_12",
"target": "amesim_pnch012_13",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9188,9 +9188,9 @@
"source": "amesim_pnpl01_14",
"target": "amesim_pnch012_14",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9218,9 +9218,9 @@
"source": "amesim_pnpl01_16",
"target": "amesim_pnch012_15",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9237,7 +9237,7 @@
"id": "edge-amesim_pnch012_15-port_2-amesim_pnrp17_1-port_1-1786949561970",
"source": "amesim_pnch012_15",
"target": "amesim_pnrp17_1",
"sourceHandle": "port_2",
"sourceHandle": "port_3",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -9247,7 +9247,7 @@
"id": "edge-amesim_pnch012_14-port_2-amesim_pnrp17_2-port_1-1786949570722",
"source": "amesim_pnch012_14",
"target": "amesim_pnrp17_2",
"sourceHandle": "port_2",
"sourceHandle": "port_3",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -9257,7 +9257,7 @@
"id": "edge-amesim_pnch012_13-port_2-amesim_pnrp17_3-port_1-1786949575918",
"source": "amesim_pnch012_13",
"target": "amesim_pnrp17_3",
"sourceHandle": "port_2",
"sourceHandle": "port_3",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -9267,7 +9267,7 @@
"id": "edge-amesim_pnch012_12-port_2-amesim_pnrp17_4-port_1-1786949579000",
"source": "amesim_pnch012_12",
"target": "amesim_pnrp17_4",
"sourceHandle": "port_2",
"sourceHandle": "port_3",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -9277,7 +9277,7 @@
"id": "edge-amesim_pnch012_11-port_2-amesim_pnrp17_5-port_1-1786949583304",
"source": "amesim_pnch012_11",
"target": "amesim_pnrp17_5",
"sourceHandle": "port_2",
"sourceHandle": "port_3",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -9287,7 +9287,7 @@
"id": "edge-amesim_pnch012_10-port_2-amesim_pnrp17_6-port_1-1786949586596",
"source": "amesim_pnch012_10",
"target": "amesim_pnrp17_6",
"sourceHandle": "port_2",
"sourceHandle": "port_3",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -9297,7 +9297,7 @@
"id": "edge-amesim_pnch012_9-port_2-amesim_pnrp17_7-port_1-1786949589317",
"source": "amesim_pnch012_9",
"target": "amesim_pnrp17_7",
"sourceHandle": "port_2",
"sourceHandle": "port_3",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -9307,7 +9307,7 @@
"id": "edge-amesim_pnch012_8-port_2-amesim_pnrp17_8-port_1-1786949590677",
"source": "amesim_pnch012_8",
"target": "amesim_pnrp17_8",
"sourceHandle": "port_2",
"sourceHandle": "port_3",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
@@ -9667,7 +9667,7 @@
"id": "edge-amesim_lmechn1_3-port_1-amesim_pnrp17_1-port_3-1786949849269",
"source": "amesim_lmechn1_3",
"target": "amesim_pnrp17_1",
"sourceHandle": "port_1",
"sourceHandle": "port_8",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
@@ -9677,7 +9677,7 @@
"id": "edge-amesim_lmechn1_3-port_2-amesim_pnrp17_2-port_3-1786949850839",
"source": "amesim_lmechn1_3",
"target": "amesim_pnrp17_2",
"sourceHandle": "port_2",
"sourceHandle": "port_7",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
@@ -9687,7 +9687,7 @@
"id": "edge-amesim_lmechn1_3-port_3-amesim_pnrp17_3-port_3-1786949852383",
"source": "amesim_lmechn1_3",
"target": "amesim_pnrp17_3",
"sourceHandle": "port_3",
"sourceHandle": "port_6",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
@@ -9697,7 +9697,7 @@
"id": "edge-amesim_lmechn1_3-port_4-amesim_pnrp17_4-port_3-1786949854874",
"source": "amesim_lmechn1_3",
"target": "amesim_pnrp17_4",
"sourceHandle": "port_4",
"sourceHandle": "port_5",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
@@ -9707,7 +9707,7 @@
"id": "edge-amesim_lmechn1_3-port_5-amesim_pnrp17_5-port_3-1786949858405",
"source": "amesim_lmechn1_3",
"target": "amesim_pnrp17_5",
"sourceHandle": "port_5",
"sourceHandle": "port_4",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
@@ -9717,7 +9717,7 @@
"id": "edge-amesim_lmechn1_3-port_6-amesim_pnrp17_6-port_3-1786949862365",
"source": "amesim_lmechn1_3",
"target": "amesim_pnrp17_6",
"sourceHandle": "port_6",
"sourceHandle": "port_3",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
@@ -9727,7 +9727,7 @@
"id": "edge-amesim_lmechn1_3-port_7-amesim_pnrp17_7-port_3-1786949896879",
"source": "amesim_lmechn1_3",
"target": "amesim_pnrp17_7",
"sourceHandle": "port_7",
"sourceHandle": "port_2",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
@@ -9737,7 +9737,7 @@
"id": "edge-amesim_lmechn1_3-port_8-amesim_pnrp17_8-port_3-1786949898922",
"source": "amesim_lmechn1_3",
"target": "amesim_pnrp17_8",
"sourceHandle": "port_8",
"sourceHandle": "port_1",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
@@ -9778,7 +9778,7 @@
"source": "amesim_lstp00a_1",
"target": "amesim_lmechn1_4",
"sourceHandle": "port_2",
"targetHandle": "port_8",
"targetHandle": "port_1",
"data": {
"isContactEdge": false
}
@@ -9788,7 +9788,7 @@
"source": "amesim_lstp00a_2",
"target": "amesim_lmechn1_4",
"sourceHandle": "port_2",
"targetHandle": "port_7",
"targetHandle": "port_2",
"data": {
"isContactEdge": false
}
@@ -9798,7 +9798,7 @@
"source": "amesim_lstp00a_3",
"target": "amesim_lmechn1_4",
"sourceHandle": "port_2",
"targetHandle": "port_6",
"targetHandle": "port_3",
"data": {
"isContactEdge": false
}
@@ -9808,7 +9808,7 @@
"source": "amesim_lstp00a_4",
"target": "amesim_lmechn1_4",
"sourceHandle": "port_2",
"targetHandle": "port_5",
"targetHandle": "port_4",
"data": {
"isContactEdge": false
}
@@ -9818,7 +9818,7 @@
"source": "amesim_lstp00a_5",
"target": "amesim_lmechn1_4",
"sourceHandle": "port_2",
"targetHandle": "port_4",
"targetHandle": "port_5",
"data": {
"isContactEdge": false
}
@@ -9828,7 +9828,7 @@
"source": "amesim_lstp00a_6",
"target": "amesim_lmechn1_4",
"sourceHandle": "port_2",
"targetHandle": "port_3",
"targetHandle": "port_6",
"data": {
"isContactEdge": false
}
@@ -9838,7 +9838,7 @@
"source": "amesim_lstp00a_7",
"target": "amesim_lmechn1_4",
"sourceHandle": "port_2",
"targetHandle": "port_2",
"targetHandle": "port_7",
"data": {
"isContactEdge": false
}
@@ -9848,7 +9848,7 @@
"source": "amesim_lstp00a_8",
"target": "amesim_lmechn1_4",
"sourceHandle": "port_2",
"targetHandle": "port_1",
"targetHandle": "port_8",
"data": {
"isContactEdge": false
}
@@ -9978,9 +9978,9 @@
"source": "amesim_pnl0002_1",
"target": "amesim_p4node2_2",
"sourceHandle": "port_2",
"targetHandle": "port_1",
"targetHandle": "port_3",
"data": {
"isContactEdge": true
"isContactEdge": false
}
},
{
@@ -9997,20 +9997,10 @@
"id": "edge-amesim_p4node2_1-port_4-amesim_pnl0002_8-port_2-1786972824427",
"source": "amesim_p4node2_1",
"target": "amesim_pnl0002_8",
"sourceHandle": "port_4",
"sourceHandle": "port_3",
"targetHandle": "port_2",
"data": {
"isContactEdge": false,
"routePoints": [
{
"x": 19.87945415380198,
"y": 52.17994257325029
},
{
"x": 199.87521088533356,
"y": 52.17994257325029
}
]
"isContactEdge": false
}
},
{
@@ -10020,37 +10010,17 @@
"sourceHandle": "port_2",
"targetHandle": "port_2",
"data": {
"isContactEdge": false,
"routePoints": [
{
"x": 80.32926682952949,
"y": 139.08364630171945
},
{
"x": 80.32926682952949,
"y": 181.8752425865067
}
]
"isContactEdge": false
}
},
{
"id": "edge-amesim_p4node2_8-port_4-amesim_pnl0002_8-port_1-1786972860850",
"source": "amesim_p4node2_8",
"target": "amesim_pnl0002_8",
"sourceHandle": "port_4",
"sourceHandle": "port_1",
"targetHandle": "port_1",
"data": {
"isContactEdge": false,
"routePoints": [
{
"x": 21.87942245262885,
"y": 1602.5991575147043
},
{
"x": 199.87521088533356,
"y": 1602.5991575147043
}
]
"isContactEdge": false
}
},
{
@@ -10058,7 +10028,7 @@
"source": "amesim_pnl0001_21",
"target": "amesim_p4node2_5",
"sourceHandle": "port_1",
"targetHandle": "port_2",
"targetHandle": "port_4",
"data": {
"isContactEdge": false
}
@@ -10098,19 +10068,9 @@
"source": "amesim_pnl0001_27",
"target": "amesim_p4node2_8",
"sourceHandle": "port_1",
"targetHandle": "port_2",
"targetHandle": "port_4",
"data": {
"isContactEdge": false,
"routePoints": [
{
"x": -8.800000000000004,
"y": 1512
},
{
"x": -8.800000000000004,
"y": 1449.5999999999997
}
]
"isContactEdge": false
}
},
{
@@ -10138,19 +10098,9 @@
"source": "amesim_pnl0001_26",
"target": "amesim_p4node2_7",
"sourceHandle": "port_1",
"targetHandle": "port_2",
"targetHandle": "port_4",
"data": {
"isContactEdge": false,
"routePoints": [
{
"x": -8.800000000000004,
"y": 1350
},
{
"x": -8.800000000000004,
"y": 1344
}
]
"isContactEdge": false
}
},
{
@@ -10178,27 +10128,17 @@
"source": "amesim_pnl0001_25",
"target": "amesim_p4node2_6",
"sourceHandle": "port_1",
"targetHandle": "port_2",
"targetHandle": "port_4",
"data": {
"isContactEdge": false,
"routePoints": [
{
"x": -9.800000000000004,
"y": 1116
},
{
"x": -9.800000000000004,
"y": 1054.8
}
]
"isContactEdge": false
}
}
],
"simulation": {
"t_start": 0,
"t_stop": 10,
"t_start": 0.0,
"t_stop": 10.0,
"step": 0.01,
"max_step": 0.02,
"max_step": 1e+30,
"method": "BDF"
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,91 @@
"""Compare identical native models with the old fixed-point, previous and current pipe solvers.
Run with Python 3.12 from the repository; generated programs/results stay in --output-dir.
The baseline ref is an explicit Git revision, never a frozen numerical result substituted for execution.
"""
from __future__ import annotations
import argparse
from hashlib import sha256
import json
from pathlib import Path
import statistics
import subprocess
import sys
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
from app.main import compile_system_xml_network
from app.simulation.backends import simulation_config
from app.simulation.native_codegen import build as builder
from app.simulation.native_codegen.compiler import compile_native_program
from app.simulation.native_codegen.input import load_input
from app.simulation.native_codegen.runner import execute_native
OLD_ITERATION = '''double rough_limit=pipe_rough_limit(rr);
double base=area*p*cm/sqrt(T),q=sqrt(d/(length*.02))*base;
for(int i=0;i<(kind==0?64:16);i++) {
double next=sqrt(d/(length*pipe_friction_prepared(4*fabs(q)/den,rr,rough_limit)))*base;
if(fabs(next-q)<=fmax(1e-12,fabs(q)*1e-9)) return sign*next;
q=.5*(q+next);
}
return sign*q;'''
NEW_CALL = '''double base=area*p*cm/sqrt(T),K=pow(4*base/den,2)*d/length;
return sign*native_pipe_resistance(K,rr,den/4,NULL)*den/4;'''
def main():
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('input',type=Path)
parser.add_argument('--output-dir',type=Path,required=True)
parser.add_argument('--baseline-ref',default='5d5a2e1')
parser.add_argument('--runs',type=int,default=3)
args=parser.parse_args()
if args.runs<1:parser.error('--runs must be positive')
out=args.output_dir.resolve();out.mkdir(parents=True,exist_ok=True)
if (out/'summary.json').exists():parser.error('Choose a fresh output directory')
revision=subprocess.check_output(['git','rev-parse',args.baseline_ref],cwd=ROOT,text=True).strip()
xml,doc=load_input(args.input)
program=compile_native_program(compile_system_xml_network(doc))
config=simulation_config(doc.simulation)
(out/'input.xml').write_bytes(xml)
(out/('input'+args.input.suffix)).write_bytes(args.input.read_bytes())
paths=subprocess.check_output(['git','ls-tree','-r','--name-only',revision,'native'],cwd=ROOT,text=True).splitlines()
variants={}
original_native=builder.NATIVE
try:
for variant in ('fixed-point','previous-newton','guarded-newton'):
directory=out/variant
for name in paths:
if variant=='guarded-newton':data=(ROOT/name).read_bytes()
else:data=subprocess.check_output(['git','show',f'{revision}:{name}'],cwd=ROOT)
target=directory/name;target.parent.mkdir(parents=True,exist_ok=True);target.write_bytes(data)
if variant=='fixed-point':
target=directory/'native/components/kernels.c';source=target.read_text()
if source.count(NEW_CALL)!=1:raise ValueError('Baseline pipe flow layout does not match the audited fixed-point substitution')
target.write_text(source.replace(NEW_CALL,OLD_ITERATION))
builder.NATIVE=directory/'native'
variants[variant]=builder.build_native(program,cache_dir=out/'cache')
finally:builder.NATIVE=original_native
rows=[]
for index in range(args.runs+1):
order=list(variants)
if index%2:order.reverse()
for variant in order:
data=execute_native(variants[variant],config,doc.simulation.sample_step,
run_dir=out/variant/('warmup' if index==0 else f'run-{index}'),timeout=120)
row={key:value for key,value in data.items() if key not in ('series','final','finalState')}
row.update(variant=variant,run=index)
rows.append(row);print(json.dumps(row,ensure_ascii=False),flush=True)
if not data['success']:raise RuntimeError(f'{variant} did not complete: {data["message"]}')
summary={'baselineRef':revision,'input':str(args.input.resolve()),
'inputSha256':sha256(args.input.read_bytes()).hexdigest(),'xmlSha256':sha256(xml).hexdigest(),
'settings':vars(config),'sampleStep':doc.simulation.sample_step,'rows':rows,
'variants':{name:{'sourceSha256':sha256((out/name/'native/components/kernels.c').read_bytes()).hexdigest(),
'buildKey':build.manifest['buildKey'],
'medianSolveSeconds':statistics.median(row['solveSeconds'] for row in rows if row['variant']==name and row['run']>0),
'medianProcessSeconds':statistics.median(row['processWallSeconds'] for row in rows if row['variant']==name and row['run']>0)}
for name,build in variants.items()}}
(out/'summary.json').write_text(json.dumps(summary,ensure_ascii=False,indent=2)+'\n')
print(json.dumps(summary['variants'],ensure_ascii=False,indent=2))
if __name__=='__main__':main()
@@ -0,0 +1,89 @@
// Real browser/HTTP/native execution. No API routes or result data are mocked.
import { chromium } from '../../frontend/node_modules/playwright/index.mjs';
import fs from 'node:fs/promises';
import path from 'node:path';
import { performance } from 'node:perf_hooks';
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
const [input, output, baseURL = 'http://127.0.0.1:8011', runCount = '3'] = process.argv.slice(2);
if (!input || !output) throw new Error('Usage: node browser_native_simulation.mjs MODEL.json OUTPUT_DIR [URL] [RUNS]');
await fs.mkdir(output, { recursive: true });
const inputText = await fs.readFile(input, 'utf8');
const project = JSON.parse(inputText);
const curveNodeId = project.nodes.find(node => node.id === 'amesim_pnl0002_10')?.id
?? project.nodes.find(node => node.data.modelType === 'amesim_pnl0002')?.id;
if (!curveNodeId) throw new Error('Curve verification requires a PNL0002 component.');
await fs.writeFile(path.join(output, 'input.json'), inputText);
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext({ viewport: { width: 1600, height: 1000 }, acceptDownloads: true });
const page = await context.newPage();
page.setDefaultTimeout(30000);
const errors = [];
page.on('pageerror', error => errors.push(String(error)));
const rows = [];
try {
await page.goto(baseURL);
await page.locator('input[type="file"][accept*=".json"]').setInputFiles(path.resolve(input));
await page.getByRole('textbox', { name: '工程', exact: true }).waitFor();
await page.waitForFunction(name => document.querySelector('input[aria-label="工程"]')?.value === name || [...document.querySelectorAll('input')].some(input => input.value === name), path.basename(input, path.extname(input)));
await page.screenshot({ path: path.join(output, 'model.png'), fullPage: true });
for (let i = 0; i <= Number(runCount); i++) {
const oldMarker = await page.evaluate(() => sessionStorage.getItem('system-simulation-flow:latest-result'));
const responsePromise = page.waitForResponse(response => response.url().endsWith('/api/system-xml/simulate-stream'), { timeout: 180000 });
const started = performance.now();
await page.getByRole('button', { name: '运行仿真', exact: true }).click();
const response = await responsePromise;
await response.finished();
if (!response.ok()) throw new Error(`Simulation HTTP ${response.status()}`);
const receivedMs = performance.now() - started;
await page.waitForFunction(old => {
const marker = sessionStorage.getItem('system-simulation-flow:latest-result');
return marker && marker !== old && JSON.parse(marker).storage === 'indexeddb';
}, oldMarker, { timeout: 180000 });
await page.getByRole('button', { name: '运行仿真', exact: true }).waitFor({ state: 'visible' });
await page.waitForFunction(() => !document.querySelector('button[aria-label="运行仿真"]')?.disabled);
await page.getByRole('tab', { name: /^结果/ }).click();
await page.getByRole('button', { name: '下载结果文件', exact: true }).waitFor();
const readyMs = performance.now() - started;
await page.waitForFunction(old => {
const marker = sessionStorage.getItem('system-simulation-flow:latest-result');
return marker && marker !== old && JSON.parse(marker).storage === 'indexeddb';
}, oldMarker);
const downloadPromise = page.waitForEvent('download');
await page.getByRole('button', { name: '下载结果文件', exact: true }).click();
await (await downloadPromise).saveAs(path.join(output, `run-${i}.simresult`));
const exported = JSON.parse(await fs.readFile(path.join(output, `run-${i}.simresult`), 'utf8'));
const result = exported.snapshot.result;
if (!result.success) throw new Error(result.message);
assert.equal(result.diagnostics.integration.rtol, 1e-8);
assert.equal(result.simulatedUntil, project.simulation.t_stop);
const row = { run: i, receivedMs, readyMs, sampleCount: result.series.time.length,
...result.diagnostics.native };
rows.push(row);
console.log(JSON.stringify(row));
if (i < Number(runCount)) await page.getByRole('tab', { name: '建模', exact: true }).click();
}
await page.getByRole('button', { name: '适应系统图窗口', exact: true }).click();
await page.locator(`.results-system-panel .react-flow__node[data-id=${JSON.stringify(curveNodeId)}]`).click();
await page.locator('.results-variable-list button').filter({ has: page.locator('small', { hasText: /^K$/ }) }).first().click();
await page.locator('.results-chart-panel .result-chart-window svg').first().waitFor();
const csvDownload = page.waitForEvent('download');
await page.getByRole('button', { name: '下载结果 CSV', exact: true }).click();
await (await csvDownload).saveAs(path.join(output, 'result.csv'));
await page.screenshot({ path: path.join(output, 'result.png'), fullPage: true });
await page.reload();
await page.getByRole('tab', { name: /^结果/ }).click();
await page.getByRole('button', { name: '下载结果文件', exact: true }).waitFor();
const restored = page.waitForEvent('download');
await page.getByRole('button', { name: '下载结果文件', exact: true }).click();
await (await restored).saveAs(path.join(output, 'restored.simresult'));
const restoredData = JSON.parse(await fs.readFile(path.join(output, 'restored.simresult'), 'utf8'));
const lastData = JSON.parse(await fs.readFile(path.join(output, `run-${runCount}.simresult`), 'utf8'));
assert.deepEqual(restoredData.snapshot.result, lastData.snapshot.result);
await fs.writeFile(path.join(output, 'summary.json'), JSON.stringify({ input: path.resolve(input), inputSha256: createHash('sha256').update(inputText).digest('hex'), baseURL, browser: browser.version(), rows, errors, restored: true, restoredResultIdentical: true, csvExported: true }, null, 2));
if (errors.length) throw new Error(`Browser errors: ${errors.join('\n')}`);
} catch (error) {
await page.screenshot({ path: path.join(output, 'failure.png'), fullPage: true });
await fs.writeFile(path.join(output, 'failure.txt'), `${error.stack}\nPage errors: ${JSON.stringify(errors)}\n${await page.locator('body').innerText()}`);
throw error;
} finally { await context.close(); await browser.close(); }
+92
View File
@@ -0,0 +1,92 @@
"""Compare real native/browser results to the frozen 72-curve Amesim reference.
Run with Python + NumPy. --plot additionally requires Matplotlib, available in
this workstation's system Python. Outputs stay in the requested artifact folder.
"""
from __future__ import annotations
import argparse
import csv
import hashlib
import json
from pathlib import Path
import numpy as np
ROOT = Path(__file__).resolve().parents[2]
LIMITS = {'pressure': 250., 'temperature': .015, 'displacement': 2e-6,
'velocity': 1e-5, 'mass_flow': 3e-5}
UNITS = {'pressure': 'Pa', 'temperature': 'K', 'displacement': 'm',
'velocity': 'm/s', 'mass_flow': 'kg/s'}
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('result', type=Path)
parser.add_argument('--reference', type=Path, default=ROOT/'tests/baselines/simulation/test_mql_4/test-mql-4-amesim-reference.json')
parser.add_argument('--output-dir', type=Path, required=True)
parser.add_argument('--plot', action='store_true')
args = parser.parse_args()
ref = json.loads(args.reference.read_text())
data = json.loads(args.result.read_text())
if 'snapshot' in data:
data = data['snapshot']['result']
series = data['series']; times = np.array(series['time']); ref_times = np.array(ref['times'])
if not data['success'] or times[-1] < ref_times[-1] or times[0] > ref_times[0]:
raise ValueError('A completed result covering all reference times is required.')
if np.any(np.diff(times) < 0):
raise ValueError('Native sample times are not ordered.')
finite = all(np.all(np.isfinite(values)) for values in series.values())
rows = []; grouped = {}
for key, curve in ref['series'].items():
actual = np.interp(ref_times, times, series[key]); error = actual - curve['values']
worst = int(np.argmax(abs(error))); quantity = curve['quantity']
row = {'key': key, 'quantity': quantity, 'unit': UNITS[quantity],
'maxAbsoluteError': float(abs(error[worst])), 'rmsError': float(np.sqrt(np.mean(error**2))),
'worstTime': float(ref_times[worst]), 'limit': LIMITS[quantity],
'passed': bool(np.max(abs(error)) <= LIMITS[quantity])}
rows.append(row)
if quantity not in grouped or row['maxAbsoluteError'] > grouped[quantity]['maxAbsoluteError']:
grouped[quantity] = row
masses = np.array([v for k, v in series.items() if k.rsplit('.', 1)[-1] in ('m', 'm1', 'm2')])
total = np.sum(masses, axis=0)
mass_drift = float(np.max(abs(total-total[0])))
force_peaks = sorted(({'key': k, 'peakAbsolute': max(map(abs, v))} for k, v in series.items()
if k.startswith('amesim_lstp00a_') and k.endswith('.f')),
key=lambda row: row['peakAbsolute'], reverse=True)
summary = {'resultPath': str(args.result.resolve()),
'resultSha256': hashlib.sha256(args.result.read_bytes()).hexdigest(),
'referencePath': str(args.reference.resolve()),
'referenceSha256': hashlib.sha256(args.reference.read_bytes()).hexdigest(),
'referenceSource': ref['source'], 'freshAmesimRun': False,
'referenceCurveCount': len(rows), 'referenceTimeCount': len(ref_times),
'nativeSampleCount': len(times), 'allSamplesFinite': bool(finite),
'massStateCount': len(masses), 'maxTotalMassDriftKg': mass_drift,
'groupedWorstErrors': grouped, 'curves': rows, 'contactForcePeaksOutsideReferenceScope': force_peaks,
'passed': bool(finite and mass_drift <= 1e-10 and all(row['passed'] for row in rows))}
args.output_dir.mkdir(parents=True, exist_ok=True)
(args.output_dir/'comparison.json').write_text(json.dumps(summary, ensure_ascii=False, indent=2)+'\n')
with (args.output_dir/'curve-errors.csv').open('w', newline='') as output:
writer = csv.DictWriter(output, fieldnames=list(rows[0])); writer.writeheader(); writer.writerows(rows)
if args.plot:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
fig, axes = plt.subplots(5, 2, figsize=(13, 15), constrained_layout=True)
for (quantity, row), (left, right) in zip(grouped.items(), axes):
key = row['key']; values = ref['series'][key]['values']
actual = np.interp(ref_times, times, series[key])
left.plot(times, series[key], linewidth=1, label='Native, rtol=1e-8')
left.plot(ref_times, values, '.', markersize=3, label='Saved Amesim reference')
left.set_title(key, fontsize=9); left.set_ylabel(UNITS[quantity]); left.legend(fontsize=7)
right.plot(ref_times, actual-values, '.-', linewidth=.8, markersize=3)
right.axhline(row['limit'], color='gray', linestyle='--', linewidth=.6)
right.axhline(-row['limit'], color='gray', linestyle='--', linewidth=.6)
right.set_title(f'{quantity}: sampled difference and acceptance limits', fontsize=9)
right.set_ylabel(UNITS[quantity])
for ax in (left, right): ax.grid(alpha=.2); ax.set_xlabel('Time [s]')
fig.suptitle('Four-branch model: 72 curves checked at 57 stored Amesim times\nWorst curve per quantity; contact force is outside this reference', fontsize=12)
fig.savefig(args.output_dir/'comparison.svg'); fig.savefig(args.output_dir/'comparison.png', dpi=140)
print(json.dumps({k: summary[k] for k in ('passed', 'nativeSampleCount', 'maxTotalMassDriftKg', 'groupedWorstErrors')}, indent=2))
if not summary['passed']: raise SystemExit(1)
if __name__ == '__main__': main()
+403
View File
@@ -0,0 +1,403 @@
"""Audit the AME diagram against the corrected XML; emit an aligned browser project.
Run from the repository root with .venv/bin/python. Does not run Amesim or use
the stale eight-branch compiled/result cache inside the four-branch archive.
"""
from __future__ import annotations
import argparse
from collections import Counter, defaultdict
from copy import deepcopy
import hashlib
import json
from pathlib import Path
import re
import sys
if '--check' in sys.argv:
sys.dont_write_bytecode = True
import struct
import tarfile
import xml.etree.ElementTree as ET
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT))
from app.simulation.registry import get_component_model_spec
from tests.test_test_mql_ame_contract import (
_blocks, _required_element_text, _element_text, _resolve_globals,
_public_model_type, _expected_parameters, _value_fields,
)
OUT = ROOT / 'test/solver-newton-20260911/mql4'
AME = ROOT / 'tests/data/test_mql_4.ame'
XML = ROOT / 'tests/fixtures/amesim/test-mql-4-corrected.xml'
REFERENCE = ROOT / 'tests/baselines/simulation/test_mql_4/test-mql-4-amesim-reference.json'
PROJECT = ROOT / 'tests/data/test-mql-4-corrected.json'
def sha(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
def public_port(model, index):
if index == 0 and model in {'amesim_pnvo001', 'amesim_forc'}:
return 'res'
if index == 0 and model in {'amesim_step0', 'amesim_ud00'}:
return 'out'
return f'port_{index + 1}'
def parameter_key(values):
return tuple(sorted((key, format(float(value), '.12g')) for key, value in values.items()))
def audit_source():
with tarfile.open(AME) as archive:
def read(suffix):
names = [name for name in archive.getnames() if name.endswith(suffix)]
if len(names) != 1:
raise ValueError((suffix, names))
return archive.extractfile(names[0]).read().decode('latin1')
cir = read('.cir')
sim = read('.sim')
modelinfo = read('.modelinfo')
variables = read('.var')
perf = read('.ameperf')
result_name = next(name for name in archive.getnames() if name.endswith('.results'))
result_data = archive.extractfile(result_name).read()
result_points, result_columns = struct.unpack('<2i', result_data[:8])
member_hashes = {}
for suffix in ['.cir', '.sim', '.modelinfo', '.var', '.results']:
name = next(name for name in archive.getnames() if name.endswith(suffix))
data = archive.extractfile(name).read()
member_hashes[name] = {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()}
globals_ = _resolve_globals(cir)
components = _blocks(cir, 'COMP')
lines = _blocks(cir, 'LINE')
nodes = {}
for kind, entities in [('component', components), ('line', lines)]:
for index, body in enumerate(entities):
submodel = _required_element_text(body, 'SUB_NAME')
if submodel == 'DIRECT':
continue
model = _public_model_type(submodel)
nodes[f'{kind}:{index}'] = {
'modelType': model,
'alias': _required_element_text(body, 'ALIAS'),
'parameters': _expected_parameters(body, model, globals_),
'sourceValues': {name: {'expression': value.expression, 'unit': value.unit}
for name, value in _value_fields(body).items()},
'position': _element_text(body, 'COMP_POS') or _element_text(body, 'LINE_POINTS'),
'geometry': _element_text(body, 'COMP_GEOMETRY'),
'outputType': _element_text(body, 'OUTPUT_TYPE'),
}
edges = set()
contacts = set()
for index, body in enumerate(components):
for port_index, port_body in enumerate(_blocks(body, 'COMP_PORT')):
if _required_element_text(port_body, 'PORT_CONNECT') != '1':
continue
for connection in _blocks(port_body, 'CONNECT'):
other = int(_required_element_text(connection, 'CONNECT_ENTITY_NUM'))
other_port = int(_required_element_text(connection, 'CONNECT_ENTITY_PORT'))
contacts.add(((index, port_index), (other, other_port)))
assert all((b, a) in contacts for a, b in contacts)
def endpoint(index, port):
key = f'component:{index}'
return key, public_port(nodes[key]['modelType'], port)
for a, b in contacts:
edges.add(tuple(sorted((endpoint(*a), endpoint(*b)))))
for index, body in enumerate(lines):
assert _required_element_text(body, 'LINE_START_TYPE') == '0'
assert _required_element_text(body, 'LINE_END_TYPE') == '0'
start = endpoint(int(_required_element_text(body, 'LINE_START_ENTITY')),
int(_required_element_text(body, 'LINE_START_PORT')))
end = endpoint(int(_required_element_text(body, 'LINE_END_ENTITY')),
int(_required_element_text(body, 'LINE_END_PORT')))
if _required_element_text(body, 'SUB_NAME') == 'DIRECT':
edges.add(tuple(sorted((start, end))))
else:
key = f'line:{index}'
output_type = _required_element_text(body, 'OUTPUT_TYPE')
assert output_type in {'1', '2'}
first, second = ('port_1', 'port_2') if output_type == '1' else ('port_2', 'port_1')
edges.add(tuple(sorted((start, (key, first)))))
edges.add(tuple(sorted((end, (key, second)))))
count = Counter(node['modelType'] for node in nodes.values())
states = sum(count[model] * size for model, size in {
'amesim_pnch012': 2, 'amesim_pnch023': 2, 'amesim_pnl0001': 2,
'amesim_pnl0002': 2, 'amesim_pnl0003': 4, 'amesim_mecmas21': 2,
}.items())
return nodes, sorted(edges), {
'archiveSha256': sha(AME), 'archiveBytes': AME.stat().st_size,
'members': member_hashes, 'globals': globals_,
'componentCount': len(components), 'modeledLineCount': len(nodes) - len(components),
'directLineCount': len(lines) - (len(nodes) - len(components)),
'contactCount': len(contacts) // 2, 'publicNodeCount': len(nodes),
'publicParameterCount': sum(len(node['parameters']) for node in nodes.values()),
'connectionCount': len(edges), 'typeCounts': dict(count),
'diagramDynamicStateCount': states,
'simulationFileRaw': sim, 'savedSimulationNumericRows': [[float(x) for x in row.split()] for row in sim.splitlines()],
'cachedModelInfo': modelinfo,
'cachedResultsSuitableForFourBranchComparison': False,
'cacheRejectionReason': 'Diagram has 64 states / four pistons; cached modelinfo has 132 states, .ameperf contains eight LSTP00A instances, and .results declares 1116 saved variables while the current .var has only 640 rows.',
'cachedResultHeader': {'pointCount': result_points, 'savedVariableCount': abs(result_columns)},
'variableRowCount': len(variables.splitlines()),
'cachedPerformanceContactInstances': sorted(set(re.findall(r'LSTP00A-([0-9]+)', perf))),
'cachedPistonAliases': sorted(set(re.findall(r'Data_Path=\S+@(pn_brp2[^\s]*)', variables))),
}
def xml_model(root=None):
if root is None:
root = ET.parse(XML).getroot()
nodes = {item.attrib['id']: {
'modelType': item.attrib['type'],
'modelVersion': item.attrib['modelVersion'],
'parameters': {p.attrib['name']: float(p.attrib['value']) for p in item.findall('Parameter')},
} for item in root.findall('./Components/Component')}
edges = [tuple(sorted((ep.attrib['component'], ep.attrib['port']) for ep in item.findall('Endpoint')))
for item in root.findall('./Connections/Connection')]
return nodes, edges, root
def find_mapping(first, first_edges, second, second_edges, *, ports=False, parameters=True):
"""Find an actual graph bijection, preserving node types and all parameters."""
def edge_label(node, port):
if not ports:
return ''
return port
def graph(nodes, edges):
adjacency = {key: defaultdict(Counter) for key in nodes}
for (a, ap), (b, bp) in edges:
adjacency[a][b][(edge_label(a, ap), edge_label(b, bp))] += 1
adjacency[b][a][(edge_label(b, bp), edge_label(a, ap))] += 1
return adjacency
a, b = graph(first, first_edges), graph(second, second_edges)
def signature(nodes, adj, key):
return (nodes[key]['modelType'], parameter_key(nodes[key]['parameters']) if parameters else (),
sum(sum(labels.values()) for labels in adj[key].values()))
candidates = {key: [other for other in second if signature(first, a, key) == signature(second, b, other)]
for key in first}
if any(not options for options in candidates.values()):
return None
mapping = {}
used = set()
def search():
if len(mapping) == len(first):
return dict(mapping)
key = min((key for key in first if key not in mapping),
key=lambda key: (-sum(neighbor in mapping for neighbor in a[key]),
len([other for other in candidates[key] if other not in used]), -len(a[key])))
for other in candidates[key]:
if other in used:
continue
if any(a[key].get(existing, Counter()) != b[other].get(target, Counter())
for existing, target in mapping.items()):
continue
mapping[key] = other
used.add(other)
result = search()
if result is not None:
return result
used.remove(other)
del mapping[key]
return None
return search()
def check_project_contract(project, xml_root):
"""Check generated port metadata and exact JSON/XML execution data, without writes.
This covers the observed nullable optional-field failure and shared physical
data, not a replacement for the complete frontend project parser.
"""
xml_nodes, xml_edges, _ = xml_model(xml_root)
json_nodes = {node['id']: node['data'] for node in project['nodes']}
if len(json_nodes) != len(project['nodes']) or json_nodes.keys() != xml_nodes.keys():
raise ValueError('JSON/XML component IDs differ or JSON contains duplicate IDs.')
for node_id, data in json_nodes.items():
expected = xml_nodes[node_id]
if (data['componentType'] != expected['modelType'] or
data['modelType'] != expected['modelType'] or
data['modelVersion'] != expected['modelVersion']):
raise ValueError(f'{node_id}: JSON/XML model type or version differs.')
if data['parameters'] != expected['parameters']:
raise ValueError(f'{node_id}: JSON/XML parameters differ.')
for port in data['ports']:
# frontend/src/App.tsx:isProjectPortDefinitionValue accepts omission,
# or the literal intoComponent. An explicit null rejects the import.
if ('positiveFlowDirection' in port and
port['positiveFlowDirection'] != 'intoComponent'):
raise ValueError(f"{node_id}.{port['name']}: omit undefined positiveFlowDirection instead of null.")
json_edges = []
for edge in project['edges']:
endpoints = []
for side in ['source', 'target']:
component, port = edge[side], edge[side + 'Handle']
if component not in json_nodes:
raise ValueError(f'Unknown connection component {component}.')
data = json_nodes[component]
active_ports = get_component_model_spec(data['modelType']).active_ports(data['parameters'])
if port not in {item.name for item in active_ports}:
raise ValueError(f'{component}.{port}: connection port is inactive or unknown.')
endpoints.append((component, port))
json_edges.append(tuple(sorted(endpoints)))
if Counter(json_edges) != Counter(xml_edges):
raise ValueError('JSON/XML connection endpoints differ.')
simulation = xml_root.find('Simulation').attrib
for key, xml_key in [('t_start', 'tStart'), ('t_stop', 'tStop'),
('step', 'sampleStep'), ('max_step', 'maxStep')]:
if project['simulation'][key] != float(simulation[xml_key]):
raise ValueError(f'JSON/XML simulation {key} differs.')
if project['simulation']['method'] != simulation['method']:
raise ValueError('JSON/XML integration methods differ.')
return {'valid': True, 'componentCount': len(json_nodes), 'connectionCount': len(json_edges),
'parameterCount': sum(len(data['parameters']) for data in json_nodes.values()),
'optionalPortFieldsValid': True, 'jsonXmlExecutionDataEqual': True}
def generate_project(source, source_edges, target, target_edges, xml_root, mapping):
layout_source = ROOT / 'tests/fixtures/legacy/test-mql-8.json'
layout = json.loads(layout_source.read_text())
layout_nodes = {node['id']: node for node in layout['nodes']}
reverse_mapping = {value: key for key, value in mapping.items()}
nodes = []
for node_id, model in target.items():
source_node = source[reverse_mapping[node_id]]
template = layout_nodes.get(node_id)
if template is None:
template = next(node for node in layout['nodes'] if node['data']['modelType'] == model['modelType'])
node = deepcopy(template)
node['id'] = node_id
node['selected'] = False
node['data']['label'] = source_node['alias']
node['data']['parameters'] = source_node['parameters']
node['data']['modelVersion'] = model['modelVersion']
node['data']['ports'] = get_component_model_spec(model['modelType']).as_catalog_dict()['ports']
for port in node['data']['ports']:
if port.get('positiveFlowDirection') is None:
port.pop('positiveFlowDirection', None)
if model['modelType'] == 'amesim_p4node2':
node['data']['rotation'] = 180
node['data']['mirrored'] = False
if node_id not in layout_nodes:
# The extra closing pipe sits below the four retained branches.
node['position'] = {'x': 80.0, 'y': 900.0}
node['data']['rotation'] = 0
nodes.append(node)
original_by_pair = {}
for edge in layout['edges']:
pair = tuple(sorted((edge['source'], edge['target'])))
original_by_pair[pair] = edge
xml_by_pair = {}
for connection in xml_root.findall('./Connections/Connection'):
pair = tuple(sorted(ep.attrib['component'] for ep in connection.findall('Endpoint')))
xml_by_pair[pair] = connection
edges = []
changed_connections = []
for ((a, ap), (b, bp)) in source_edges:
a, b = mapping[a], mapping[b]
pair = tuple(sorted((a, b)))
existing = original_by_pair.get(pair)
edge = deepcopy(existing) if existing else {'id': 'ame-' + a + '-' + ap + '-' + b + '-' + bp}
if existing and existing['source'] == b:
a, ap, b, bp = b, bp, a, ap
old_connection = xml_by_pair[pair]
old_endpoints = {ep.attrib['component']: ep.attrib['port'] for ep in old_connection.findall('Endpoint')}
changed = old_endpoints != {a: ap, b: bp}
if changed:
changed_connections.append({'components': pair, 'before': old_endpoints, 'after': {a: ap, b: bp}})
edge.update({'source': a, 'target': b, 'sourceHandle': ap, 'targetHandle': bp})
edge.pop('selected', None)
if any(target[node_id]['modelType'] == 'amesim_p4node2' for node_id in [a, b]):
edge.setdefault('data', {}).pop('routePoints', None)
if changed or existing is None:
edge['data'] = {'isContactEdge': False}
edges.append(edge)
for endpoint in old_connection.findall('Endpoint'):
endpoint.attrib['port'] = {a: ap, b: bp}[endpoint.attrib['component']]
parameter_changes = []
for component in xml_root.findall('./Components/Component'):
node_id = component.attrib['id']
parameters = source[reverse_mapping[node_id]]['parameters']
for parameter in component.findall('Parameter'):
key = parameter.attrib['name']
before = float(parameter.attrib['value'])
after = parameters[key]
if abs(before - after) > max(1e-18, abs(after) * 1e-12):
parameter_changes.append({'component': node_id, 'parameter': key, 'before': before, 'after': after})
parameter.attrib['value'] = repr(after)
simulation = {'t_start': 0.0, 't_stop': 10.0, 'step': 0.01, 'max_step': 1e30, 'method': 'BDF'}
project = {'projectSchemaVersion': 1, 'name': 'test-mql-4-AME-aligned', 'nodes': nodes,
'edges': edges, 'simulation': simulation}
check_project_contract(project, xml_root)
PROJECT.write_text(json.dumps(project, indent=2, ensure_ascii=False) + '\n')
generated_xml = OUT / 'aligned-input.xml'
xml_root.attrib['name'] = project['name']
ET.indent(xml_root)
ET.ElementTree(xml_root).write(generated_xml, encoding='utf-8', xml_declaration=True)
XML.write_bytes(generated_xml.read_bytes())
# Check the delivered JSON itself, including every exact endpoint and number.
json_nodes = {node['id']: node['data'] for node in json.loads(PROJECT.read_text())['nodes']}
for source_id, project_id in mapping.items():
assert json_nodes[project_id]['parameters'] == source[source_id]['parameters']
expected_edges = {tuple(sorted(((mapping[a], ap), (mapping[b], bp)))) for ((a, ap), (b, bp)) in source_edges}
actual_edges = {tuple(sorted(((edge['source'], edge['sourceHandle']), (edge['target'], edge['targetHandle'])))) for edge in edges}
assert expected_edges == actual_edges
for edge in edges:
for side in ['source', 'target']:
data = json_nodes[edge[side]]
active_ports = get_component_model_spec(data['modelType']).active_ports(data['parameters'])
assert edge[side + 'Handle'] in {port.name for port in active_ports}
return {'path': str(PROJECT.relative_to(ROOT)), 'sha256': sha(PROJECT),
'xmlPath': str(generated_xml.relative_to(ROOT)), 'xmlSha256': sha(generated_xml),
'nodeCount': len(nodes), 'edgeCount': len(edges), 'parameterCount': sum(len(n['data']['parameters']) for n in nodes),
'allMappedParametersExactlyMatchAme': True, 'allMappedConnectionPortsExactlyMatchAme': True,
'parameterChangesFromLegacyXml': parameter_changes, 'connectionPortChangesFromLegacyXml': changed_connections,
'layoutMetadataSource': {'path': str(layout_source.relative_to(ROOT)), 'sha256': sha(layout_source)},
'simulation': simulation,
'simulationSettingsNote': 'AME archive stores historical fixed-step settings. This JSON uses native BDF; rtol is supplied by the backend and is not stored in the project. Initial validation used 1e-7; the backend default was subsequently changed to 1e-8. The earlier official Standard variable-step reference remains tolerance 1e-7. Inspect actual run diagnostics; solver algorithms are not identical.'}
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--check', action='store_true', help='Validate delivered JSON/XML only; do not generate or write files.')
arguments = parser.parse_args()
if arguments.check:
print(json.dumps(check_project_contract(json.loads(PROJECT.read_text()), ET.parse(XML).getroot()), indent=2))
return
OUT.mkdir(parents=True, exist_ok=True)
source, source_edges, audit = audit_source()
legacy_xml = OUT / 'legacy-corrected-input.xml'
if not legacy_xml.exists():
legacy_xml.write_bytes(XML.read_bytes())
target, target_edges, xml_root = xml_model()
mapping = find_mapping(source, source_edges, target, target_edges)
audit['correctedXml'] = {'path': str(XML.relative_to(ROOT)), 'sha256': sha(XML),
'parameterAndComponentTopologyIsomorphic': mapping is not None}
ref = json.loads(REFERENCE.read_text())
audit['reference'] = {'path': str(REFERENCE.relative_to(ROOT)), 'sha256': sha(REFERENCE),
'source': ref['source'], 'timeCount': len(ref['times']), 'seriesCount': len(ref['series']),
'ameHashMatches': ref['originalAmeSha256'] == sha(AME),
'xmlHashMatches': ref['xmlSha256'] == sha(XML),
'newAmesimRunPerformed': False}
(OUT / 'source-model.json').write_text(json.dumps({'nodes': source, 'edges': source_edges}, indent=2, ensure_ascii=False) + '\n')
if not mapping:
mapping = find_mapping(source, source_edges, target, target_edges, parameters=False)
if mapping:
audit['componentMapping'] = {key: {'alias': source[key]['alias'], 'projectId': value} for key, value in mapping.items()}
transformed = {tuple(sorted(((mapping[a], ap), (mapping[b], bp)))) for ((a, ap), (b, bp)) in source_edges}
target_set = set(target_edges)
audit['correctedXml']['exactPortDifferencesForTopologyMapping'] = {
'ameOnly': sorted(transformed - target_set), 'xmlOnly': sorted(target_set - transformed)}
if mapping:
audit['generatedProject'] = generate_project(source, source_edges, target, target_edges, xml_root, mapping)
audit['correctedXml']['scope'] = 'Input XML snapshot before this generation; generatedProject describes the delivered corrected files.'
audit_text = json.dumps(audit, indent=2, ensure_ascii=False) + '\n'
(OUT / 'model-audit.json').write_text(audit_text)
(ROOT / 'tests/model_audit/test-mql-4-audit.json').write_text(audit_text)
print(json.dumps({key: value for key, value in audit.items() if key not in {'componentMapping', 'members', 'globals'}}, indent=2))
if __name__ == '__main__':
main()
@@ -0,0 +1,101 @@
"""Independent read of AME XML fields; no shared expected-parameter helper."""
from pathlib import Path
import ast, collections, hashlib, json, math, operator, re, sys, tarfile
import xml.etree.ElementTree as ET
ROOT=Path(__file__).resolve().parents[2]
sys.path.insert(0,str(ROOT))
from app.simulation.registry import get_component_model_spec
OUT=ROOT/'test/solver-newton-20260911/mql4/visual-recheck'
OUT.mkdir(parents=True,exist_ok=True)
with tarfile.open(ROOT/'tests/data/test_mql_4.ame') as archive:
cir=archive.extractfile('test_mql_4_.cir').read().decode('latin1')
# AME stores unescaped C-style && in visibility metadata, outside parameter values.
xml_text=re.sub(r'<VISIBILITY>.*?</VISIBILITY>', '<VISIBILITY/>', cir, flags=re.S)
xml_text=re.sub(r'&(?!amp;|lt;|gt;|quot;|apos;|#)', '&amp;', xml_text)
root=ET.fromstring(xml_text)
BINARY={ast.Add:operator.add,ast.Sub:operator.sub,ast.Mult:operator.mul,ast.Div:operator.truediv,ast.Pow:operator.pow}
UNARY={ast.UAdd:operator.pos,ast.USub:operator.neg}
def evaluate(text,names):
def visit(node):
if isinstance(node,ast.Constant) and isinstance(node.value,(int,float)):return float(node.value)
if isinstance(node,ast.Name):return names[node.id]
if isinstance(node,ast.BinOp) and type(node.op) in BINARY:return BINARY[type(node.op)](visit(node.left),visit(node.right))
if isinstance(node,ast.UnaryOp) and type(node.op) in UNARY:return UNARY[type(node.op)](visit(node.operand))
raise ValueError(ast.dump(node))
return visit(ast.parse(text.strip().replace('^','**'),mode='eval').body)
variables={};pending={g.findtext('GLOB_PARAM_NAME').strip():g.findtext('VALUE').strip() for g in root.findall('.//GLOBALPARAM')}
while pending:
count=len(pending)
for key,value in list(pending.items()):
try:variables[key]=evaluate(value,variables)
except KeyError:continue
del pending[key]
assert len(pending)<count,pending
entities={}
for kind in ['COMP','LINE']:
for index,item in enumerate(root.findall('.//'+kind)):
model=item.findtext('./SUBMODEL/SUB_NAME')
if not model or model=='DIRECT':continue
fields={}
for tag in ['RPARAM','IPARAM','IVAR','EVAR']:
for field in item.findall('.//'+tag):
name=field.findtext('VARNAME');value=field.findtext('VALUE')
if name and value:
assert name not in fields,(item.findtext('ALIAS'),name)
fields[name.strip()]={'value':value.strip(),'unit':(field.findtext('UNITS') or '').strip()}
alias=item.findtext('ALIAS').strip()
assert alias not in entities
entities[alias]={'element':item,'fields':fields,'model':model,'source':kind+':'+str(index)}
# Explicit initial-state translations; all other public names are read verbatim.
state_names={
'MECMAS21':{'v0':'v1','x0':'x1'},'PNCH012':{'p0':'press','T0':'temp'},'PNCH023':{'p0':'press','T0':'temp'},
'PNL0001':{'p0':'p2','T0':'t2'},'PNL0002':{'p0':'pctr','T0':'tctr'},
'PNL0003':{'p1_0':'p1','T1_0':'t1','p2_0':'p2','T2_0':'t2'},
'STEP0':{'initial':'out0','final':'out1','time':'t0'},
}
unit_scale={('mm','m'):1e-3,('mm**2','m2'):1e-6,('L','m3'):1e-3,('N/mm','N/m'):1e3,('N/(mm/s)','N/(m/s)'):1e3}
unit_aliases={('null',''),('degree',''),('J/m**2/K/s','W/(m2*K)'),('N/m**2','Pa'),('m**2','m2'),('N/(m/s)**2','N/(m/s)^2')}
project=json.loads((ROOT/'tests/data/test-mql-4-corrected.json').read_text())
rows=[];issues=[];unit_counts=collections.Counter();extras=[]
for node in project['nodes']:
d=node['data'];entry=entities[d['label']];model=entry['model'];fields=entry['fields']
specs=get_component_model_spec(d['modelType']).parameter_by_name
for key,actual in d['parameters'].items():
source=state_names.get(model,{}).get(key,key)
rule='raw field'
if source in fields:
f=fields[source];raw=evaluate(f['value'],variables);source_unit=f['unit'];target_unit=specs[key].unit
if source in {'press','p1','p2','pctr'}:
assert (source_unit,target_unit)==('Pa','Pa')
expected=raw+101300.;rule='gauge Pa + 101300 Pa atmospheric pressure'
elif (source_unit,target_unit) in unit_scale:
expected=raw*unit_scale[source_unit,target_unit];rule='multiply by '+str(unit_scale[source_unit,target_unit])
elif source_unit==target_unit or (source_unit,target_unit) in unit_aliases:
expected=raw
else:raise AssertionError((source,source_unit,target_unit))
unit_counts[(source_unit,target_unit,rule)]+=1
row={'jsonId':node['id'],'ameAlias':d['label'],'sourceEntity':entry['source'],'parameter':key,'sourceField':source,
'rawExpression':f['value'],'rawValue':raw,'sourceUnit':source_unit,'targetUnit':target_unit,'conversion':rule,
'expected':expected,'actual':actual}
else:
if model=='PNCH012' and key in {'vol1','vol2','vol3','vol4','dvol1','dvol2','dvol3','dvol4'}:expected=0.;rule='public extra port-volume inputs default zero'
elif model=='PNVO001' and key=='opening0':expected=1.;rule='public fallback opening parameter; model signal port supplies actual command'
elif model=='FORC' and key=='direction':
geometry=entry['element'].findtext('COMP_GEOMETRY');assert geometry in {'2','8'}
expected=1. if geometry=='2' else -1.;rule='force direction from AME geometry '+geometry
elif model=='PNGD00' and key=='property_model':
codes={name:evaluate(fields[name]['value'],variables) for name in ['fluidType','eosType','gasSetting']}
assert codes=={'fluidType':12.,'eosType':6.,'gasSetting':1.},codes
expected=0.;rule='public helium model selection mapped from explicit AME fluid/eos/gas codes'
else:raise AssertionError((model,key))
row={'jsonId':node['id'],'ameAlias':d['label'],'sourceEntity':entry['source'],'parameter':key,'conversion':rule,'expected':expected,'actual':actual}
extras.append(row)
row['matches']=math.isclose(actual,expected,rel_tol=1e-12,abs_tol=1e-15)
if not row['matches']:issues.append(row)
rows.append(row)
result={'method':'Independent xml.etree XML parsing and arithmetic AST evaluation; does not import or call _expected_parameters or its source-field helpers.',
'nodeCount':len(project['nodes']),'parameterCount':len(rows),'directSourceFieldCount':len(rows)-len(extras),'publicExtraOrGeometryMappedCount':len(extras),
'unitConversionCounts':[{'source':a,'target':b,'rule':c,'count':n} for (a,b,c),n in unit_counts.items()],
'extraParameters':extras,'differences':issues,'parameters':rows}
(OUT/'independent-parameters.json').write_text(json.dumps(result,indent=2,ensure_ascii=False)+'\n')
print(json.dumps({k:v for k,v in result.items() if k not in ['parameters','extraParameters']},indent=2))
@@ -0,0 +1,98 @@
{
"source": "tests/data/test_mql_4.ame:test_mql_4_.cir COMP_PORT/PORT_POS (zero-based component indices)",
"archiveSha256": "99a071896671d634d651a7b21f487662dd7c122af8fd3d60ead404a5afa53ed4",
"components": [
{
"componentIndex": 47,
"alias": "pnnode4_16",
"geometry": 1,
"ports": {
"port_1": {
"x": 10.0,
"y": 19.0
},
"port_2": {
"x": 19.0,
"y": 10.0
},
"port_3": {
"x": 10.0,
"y": 1.0
},
"port_4": {
"x": 1.0,
"y": 10.0
}
}
},
{
"componentIndex": 48,
"alias": "pnnode4_17",
"geometry": 1,
"ports": {
"port_1": {
"x": 10.0,
"y": 19.0
},
"port_2": {
"x": 19.0,
"y": 10.0
},
"port_3": {
"x": 10.0,
"y": 1.0
},
"port_4": {
"x": 1.0,
"y": 10.0
}
}
},
{
"componentIndex": 49,
"alias": "pnnode4_18",
"geometry": 1,
"ports": {
"port_1": {
"x": 10.0,
"y": 19.0
},
"port_2": {
"x": 19.0,
"y": 10.0
},
"port_3": {
"x": 10.0,
"y": 1.0
},
"port_4": {
"x": 1.0,
"y": 10.0
}
}
},
{
"componentIndex": 50,
"alias": "pnnode4_19",
"geometry": 1,
"ports": {
"port_1": {
"x": 10.0,
"y": 19.0
},
"port_2": {
"x": 19.0,
"y": 10.0
},
"port_3": {
"x": 10.0,
"y": 1.0
},
"port_4": {
"x": 1.0,
"y": 10.0
}
}
}
]
}
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -9,7 +9,7 @@ from app.simulation.systems.network import SimulationNetwork
def reference_data():
return json.loads((Path(__file__).parent / 'data/native-python-reference.json').read_text(encoding='utf-8'))
return json.loads((Path(__file__).parent / 'baselines/native/native-python-reference.json').read_text(encoding='utf-8'))
def reference_network(case):
@@ -10,7 +10,6 @@ from app.main import run_system_xml_simulation
FIXTURE_PATH = (
Path(__file__).resolve().parent
/ "data"
/ "fixtures"
/ "high_stiffness_explicit_rk45.xml"
)
+3 -2
View File
@@ -22,7 +22,7 @@ from app.simulation.config import SolverActivityTracker
from app.system_xml import validate_system_xml_document
ROOT = Path(__file__).resolve().parents[1]
FIXTURE = ROOT / "tests/data/native-skill-test.xml"
FIXTURE = ROOT / "tests/fixtures/native-skill-test.xml"
def network(xml=None):
@@ -76,7 +76,8 @@ class NativeExecutionTests(unittest.TestCase):
def test_cache_and_standalone_executable_without_python_path(self):
cached = build_native(self.program)
self.assertTrue(cached.cache_hit)
env = {**os.environ, "PATH": str(Path(os.environ["SystemRoot"]) / "System32")}
isolated_path = str(Path(os.environ["SystemRoot"]) / "System32") if os.name == "nt" else str(self.root / "no-path")
env = {**os.environ, "PATH": isolated_path}
r = subprocess.run([str(cached.executable), "--init"], env=env, cwd=self.root,
capture_output=True, text=True, check=True)
self.assertEqual(len(json.loads(r.stdout)), 12)
+1 -1
View File
@@ -29,7 +29,7 @@ sys.meta_path.insert(0, NoNumericalPython())
from app.main import compile_system_xml_network
from app.simulation.native_codegen.compiler import compile_native_program
from app.system_xml import validate_system_xml_document
doc = validate_system_xml_document(Path('tests/data/native-skill-test.xml').read_bytes()).document
doc = validate_system_xml_document(Path('tests/fixtures/native-skill-test.xml').read_bytes()).document
program = compile_native_program(compile_system_xml_network(doc))
assert len(program.state_keys) == 12
assert len(program.variables) == 175
+3 -3
View File
@@ -152,8 +152,8 @@ int main(void) {
self.assertLess(abs(sum(rates)),1e-10+sum(map(abs,rates))*1e-12)
def test_web_stream_completes_mql4_and_matches_amesim_reference(self):
reference=json.loads((ROOT/'tests/data/test-mql-4-amesim-reference.json').read_text())
xml=(ROOT/'tests/data/test-mql-4-corrected.xml').read_bytes()
reference=json.loads((ROOT/'tests/baselines/simulation/test_mql_4/test-mql-4-amesim-reference.json').read_text())
xml=(ROOT/'tests/fixtures/amesim/test-mql-4-corrected.xml').read_bytes()
events=[json.loads(line) for line in simulation_event_stream(xml)]
self.assertFalse([e for e in events if e['event']=='error'])
self.assertTrue(any(e['event']=='progress' for e in events))
@@ -161,7 +161,7 @@ int main(void) {
self.assertTrue(result['success'],result['message'])
self.assertEqual(result['simulatedUntil'],10)
self.assertEqual(result['diagnostics']['backend'],'native-c')
self.assertEqual(result['diagnostics']['integration']['rtol'],1e-7)
self.assertEqual(result['diagnostics']['integration']['rtol'],1e-8)
self.assertEqual(result['diagnostics']['integration']['method'],'BDF')
self.assertEqual(result['diagnostics']['stateCount'],64)
# Bound the formerly stalled tiny-step failure by work, not machine time.
+237
View File
@@ -0,0 +1,237 @@
"""Standalone pipe-root checks; only a C compiler and Python stdlib are needed."""
import ctypes
import math
import os
from pathlib import Path
import shlex
import shutil
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[1]
LAMINAR_END = 89.96829989
def reference_friction(reynolds, roughness):
"""Independent evaluation of the retained Darcy blend, without its slope."""
laminar = 64 / reynolds
if reynolds <= LAMINAR_END:
return laminar
smooth = (-1.8 * math.log10(6.9 / reynolds)) ** -2
turbulent = smooth
if roughness:
fully_rough = (-2 * math.log10(roughness / 3.7)) ** -2
weight = 1 / (1 + (180 / (reynolds * roughness)) ** 2)
turbulent = (1 - weight) * smooth + weight * fully_rough
transition = ((reynolds - LAMINAR_END) / 2741.96700831) ** 8.37293695
return (laminar + transition * turbulent) / (1 + transition)
def reference_root(constant, roughness):
if constant == 0:
return 0.0
low, high = 0.0, 1.0
while high * high * reference_friction(high, roughness) < constant:
high *= 2
for _ in range(120):
middle = low + (high - low) / 2
if middle == low or middle == high:
break
if middle * middle * reference_friction(middle, roughness) < constant:
low = middle
else:
high = middle
return low + (high - low) / 2
class PipeStatus(ctypes.Structure):
_fields_ = [
('converged', ctypes.c_int),
('iterations', ctypes.c_int),
('bisections', ctypes.c_int),
('relative_residual', ctypes.c_double),
]
class NativePipeSolverTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
command = shlex.split(os.environ.get('CC', ''))
if not command:
compiler = shutil.which('gcc') or shutil.which('clang')
if not compiler:
raise unittest.SkipTest('A native C compiler is required')
command = [compiler]
cls.directory = tempfile.TemporaryDirectory(prefix='native-pipe-solver-')
cls.addClassCleanup(cls.directory.cleanup)
cls.compiler = command
source = (ROOT / 'native/components/kernels.c').read_text()
cls.library = cls.build_library(source, 'ordinary')
# Fault injection only in the temporary test translation unit. The
# resistance equation and public production ABI have no test switches.
prepared = 'static double pipe_friction_prepared('
derivative = 'static double pipe_friction_derivative('
assert source.count(prepared) == source.count(derivative) == 1
injected = 'int test_pipe_fault_mode=0;\n' + source.replace(
prepared, 'static double pipe_friction_prepared_original(', 1)
injected = injected.replace('static double pipe_friction(double', r'''
static double pipe_friction_prepared(double re,double rr,double rough) {
if(test_pipe_fault_mode==5)return 0; /* No upper sign change. */
if(test_pipe_fault_mode==6)return re<2000 ? .01 : 100;
return pipe_friction_prepared_original(re,rr,rough);
}
static double pipe_friction(double''', 1)
injected = injected.replace(
derivative, 'static double pipe_friction_derivative_original(', 1)
injected = injected.replace('static double pipe_checked_solution(', r'''
static double pipe_friction_derivative(double re,double rr,double rough,double *df) {
double f=pipe_friction_derivative_original(re,rr,rough,df);
double slope=2*re*f+re*re*(*df);
if(test_pipe_fault_mode==1)*df=(1e6*slope-2*re*f)/(re*re);
if(test_pipe_fault_mode==2)*df=NAN;
if(test_pipe_fault_mode==3)*df=(-slope-2*re*f)/(re*re);
if(test_pipe_fault_mode==4)return NAN;
if(test_pipe_fault_mode==6){*df=0;return re<2000 ? .01 : 100;}
return f;
}
static double pipe_checked_solution(''', 1)
cls.fault_library = cls.build_library(injected, 'faults')
cls.fault_mode = ctypes.c_int.in_dll(cls.fault_library, 'test_pipe_fault_mode')
@classmethod
def build_library(cls, source, name):
directory = Path(cls.directory.name)
source_path = directory / (name + '.c')
library_path = directory / (name + ('.dll' if os.name == 'nt' else '.so'))
source_path.write_text(source)
command = cls.compiler + [
'-std=c11', '-O3', '-Wall', '-Wextra', '-Werror',
'-ffp-contract=off', '-fno-fast-math', '-shared',
]
if os.name != 'nt':
command.append('-fPIC')
command += ['-I', str(ROOT / 'native/include'), str(source_path),
'-lm', '-o', str(library_path)]
run = subprocess.run(command, capture_output=True, text=True, timeout=60)
if run.returncode:
raise AssertionError(run.stderr)
library = ctypes.CDLL(str(library_path))
if os.name == 'nt':
import _ctypes
cls.addClassCleanup(_ctypes.FreeLibrary, library._handle)
library.native_pipe_resistance.argtypes = [
ctypes.c_double, ctypes.c_double, ctypes.c_double,
ctypes.POINTER(PipeStatus),
]
library.native_pipe_resistance.restype = ctypes.c_double
return library
def solve(self, constant, roughness=0, flow_scale=1, library=None):
# Nonzero sentinel fields ensure every call resets a reused status.
status = PipeStatus(1, 999, 999, -1)
result = (library or self.library).native_pipe_resistance(
constant, roughness, flow_scale, ctypes.byref(status))
return result, status
def assert_root(self, constant, roughness, result, status):
self.assertTrue(status.converged)
self.assertTrue(math.isfinite(result))
self.assertLessEqual(status.relative_residual, 1e-9)
expected = reference_root(constant, roughness)
self.assertLessEqual(abs(result - expected), 1e-12 + expected * 1e-9)
residual = abs(result * result * reference_friction(result, roughness) / constant - 1)
self.assertLessEqual(residual, 1e-9)
def test_independent_bisection_across_reynolds_roughness_and_flow_scales(self):
fallbacks = 0
maximum_iterations = 0
for exponent in range(151):
reynolds = 10 ** (-6 + exponent * .1)
for roughness in (0, 1e-5, 1e-4, 1e-3, 1e-2, .1):
constant = reynolds ** 2 * reference_friction(reynolds, roughness)
for scale in (1e-12, 1e-6, 1):
with self.subTest(reynolds=reynolds, roughness=roughness, scale=scale):
result, status = self.solve(constant, roughness, scale)
self.assert_root(constant, roughness, result, status)
self.assertLess(status.iterations, 20)
fallbacks += status.bisections
maximum_iterations = max(maximum_iterations, status.iterations)
self.assertGreater(fallbacks, 0)
self.assertGreater(maximum_iterations, 0)
def test_laminar_transition_neighbors_and_extreme_flow_scales(self):
for center in (LAMINAR_END, 1000, 2300, LAMINAR_END + 2741.96700831, 4000):
for reynolds in (math.nextafter(center, 0), center, math.nextafter(center, math.inf)):
for roughness in (0, 1e-5, .1):
constant = reynolds ** 2 * reference_friction(reynolds, roughness)
for scale in (1e-300, 1e-12, 1, 1e300):
with self.subTest(reynolds=reynolds, roughness=roughness, scale=scale):
result, status = self.solve(constant, roughness, scale)
self.assert_root(constant, roughness, result, status)
def test_zero_invalid_inputs_and_unrepresentable_values_fail_explicitly(self):
result, status = self.solve(0)
self.assertEqual(result, 0)
self.assertTrue(status.converged)
self.assertEqual(status.relative_residual, 0)
result, status = self.solve(64, 0, 1.7e308)
self.assertEqual(result, 1)
self.assertTrue(status.converged)
for constant, roughness, scale in (
(-1, 0, 1), (math.nan, 0, 1), (math.inf, 0, 1),
(1, -1, 1), (1, math.nan, 1), (1, math.inf, 1),
(1, 0, 0), (1, 0, -1), (1, 0, math.nan), (1, 0, math.inf),
(math.ulp(0.0), 0, 1), # A positive root rounds to zero.
(1e8, 3.7, 1), # Non-finite roughness limit.
(1e100, 0, 1), # Non-finite friction in bracket expansion.
(1e308, 0, 1), # Non-finite starting bound.
(128, 0, 1.7e308), (1e8, 0, 1.7e308),
):
with self.subTest(constant=constant, roughness=roughness, scale=scale):
result, status = self.solve(constant, roughness, scale)
self.assertTrue(math.isnan(result))
self.assertFalse(status.converged)
self.assertLessEqual(status.iterations, 128)
self.assertNotEqual(status.relative_residual, -1)
def test_inaccurate_or_unusable_newton_slopes_trigger_convergent_bisection(self):
try:
for mode in (1, 2, 3):
self.fault_mode.value = mode
for reynolds in (1000, 2800, 1e5, 1e9):
for roughness in (0, .1):
constant = reynolds ** 2 * reference_friction(reynolds, roughness)
with self.subTest(mode=mode, reynolds=reynolds, roughness=roughness):
result, status = self.solve(constant, roughness, library=self.fault_library)
self.assert_root(constant, roughness, result, status)
self.assertGreater(status.bisections, 0)
self.assertLess(status.iterations, 128)
finally:
self.fault_mode.value = 0
def test_nonfinite_equation_missing_bracket_and_float_stagnation_fail(self):
try:
for mode in (4, 5, 6):
self.fault_mode.value = mode
with self.subTest(mode=mode):
result, status = self.solve(1e6, library=self.fault_library)
self.assertTrue(math.isnan(result))
self.assertFalse(status.converged)
if mode == 4:
self.assertEqual(status.iterations, 1)
elif mode == 5:
self.assertEqual(status.iterations, 0)
else:
# A discontinuous equation has no valid root even when
# the bracket narrows to adjacent representable values.
self.assertGreater(status.bisections, 0)
self.assertLess(status.iterations, 128)
finally:
self.fault_mode.value = 0
if __name__ == '__main__':
unittest.main()
+84
View File
@@ -0,0 +1,84 @@
from __future__ import annotations
from copy import deepcopy
import subprocess
import unittest
from xml.etree import ElementTree as ET
from app.main import run_system_xml_simulation
from app.simulation.native_codegen.build import toolchain
from app.simulation.native_codegen.input import project_xml
from app.system_xml import validate_system_xml_document
from tests.test_amesim_pnch012_xml import amesim_pnch012_project
def pressure_project(value: float | str, unit: str = "bar") -> dict:
project = amesim_pnch012_project().model_dump(mode="json")
chamber = project["nodes"][0]["data"]
chamber["parameters"]["p0"] = value
chamber["parameterUnits"]["p0"] = unit
return project
class PressureUnitInputTests(unittest.TestCase):
def test_absolute_bar_expression_exports_si_without_atmospheric_offset(self) -> None:
project = pressure_project("= 0.25 + 0.75")
original = deepcopy(project)
xml = project_xml(project)
root = ET.fromstring(xml)
self.assertEqual(root.attrib["unitSystem"], "SI")
parameter = root.find(
"./Components/Component[@id='chamber_1']/Parameter[@name='p0']"
)
self.assertIsNotNone(parameter)
self.assertEqual(float(parameter.attrib["value"]), 100000.0)
self.assertNotIn("unit", parameter.attrib)
report = validate_system_xml_document(xml)
self.assertTrue(report.valid, report.as_dict())
self.assertEqual(project, original)
def test_saved_numeric_values_are_already_si_with_absolute_bar_display(self) -> None:
for value in (250000.0, "250000"):
with self.subTest(value=value):
self.assertEqual(
project_xml(pressure_project(value)),
project_xml(pressure_project(250000.0, "Pa")),
)
def test_absolute_bar_and_existing_pressure_expression_units_are_equivalent(self) -> None:
expected = project_xml(pressure_project(250000.0, "Pa"))
for unit, expression in (
("bar", "2 + 0.5"),
("kPa", "200 + 50"),
("MPa", "0.2 + 0.05"),
("Pa", "200000 + 50000"),
):
with self.subTest(unit=unit):
self.assertEqual(project_xml(pressure_project(expression, unit)), expected)
def test_absolute_bar_and_pa_simulations_return_identical_si_pressure(self) -> None:
try:
toolchain()
except (OSError, RuntimeError, subprocess.SubprocessError) as exc:
self.skipTest(f"Native toolchain unavailable: {exc}")
absolute_bar = run_system_xml_simulation(
project_xml(pressure_project("2 + 0.5", "bar"))
)
pascals = run_system_xml_simulation(
project_xml(pressure_project(250000.0, "Pa"))
)
self.assertTrue(absolute_bar["success"], absolute_bar["message"])
self.assertTrue(pascals["success"], pascals["message"])
self.assertEqual(absolute_bar["series"], pascals["series"])
self.assertEqual(absolute_bar["series"]["time"], [0.0, 0.001, 0.002])
for pressure in absolute_bar["series"]["chamber_1.p"]:
self.assertAlmostEqual(pressure, 250000.0, places=6)
pressure_metadata = next(
variable for variable in absolute_bar["variables"]
if variable["key"] == "chamber_1.p"
)
self.assertEqual(pressure_metadata["unit"], "Pa")
if __name__ == "__main__":
unittest.main()
@@ -11,9 +11,9 @@ BASELINE_ROOT = REPOSITORY_ROOT / "tests" / "baselines" / "simulation"
GIT_ATTRIBUTES_PATH = REPOSITORY_ROOT / ".gitattributes"
EXPECTED_ATTRIBUTE_RULES = {
("tests/data/test-mql-8.xml", "text", "eol=lf"),
("tests/data/test-mql-8.json", "text", "eol=lf"),
("tests/data/test_mql-full-branches-01-04.xml", "text", "eol=lf"),
("tests/fixtures/legacy/test-mql-8.xml", "text", "eol=lf"),
("tests/fixtures/legacy/test-mql-8.json", "text", "eol=lf"),
("tests/baselines/simulation/test_mql_full_branches/sources/test_mql-full-branches-01-04.xml", "text", "eol=lf"),
("tests/baselines/simulation/**/*.json", "text", "eol=lf"),
}