diff --git a/.github/workflows/mofmt.yml b/.github/workflows/mofmt.yml new file mode 100644 index 0000000..b94bc83 --- /dev/null +++ b/.github/workflows/mofmt.yml @@ -0,0 +1,82 @@ +# Format the Modelica code with mofmt (https://github.com/ErykMroczek/mofmt). +# +# - Pull request from a branch of this repository, or manual run: mofmt is +# applied and a "style: format Modelica code with mofmt" commit is pushed +# to the branch (run "git pull" afterwards). +# - Pull request from a fork, or direct push to master: nothing is pushed, +# the job fails if some files are not formatted. +# +# Commits pushed with GITHUB_TOKEN do not trigger other workflows, so the +# OpenModelica tests are not re-run on the formatting commit. + +name: mofmt + +on: + pull_request: + branches: [master] + paths: ['**.mo', '.github/workflows/mofmt.yml'] + push: + branches: [master] + paths: ['**.mo', '.github/workflows/mofmt.yml'] + workflow_dispatch: + +permissions: + contents: write # needed to push the formatting commit + +concurrency: + group: mofmt-${{ github.ref }} + cancel-in-progress: true + +env: + MOFMT_VERSION: 0.6.0 + +jobs: + mofmt: + runs-on: ubuntu-latest + steps: + # On pull requests, check out the branch itself (not the merge commit) + # so the formatting commit can be pushed to it. + - name: Checkout + uses: actions/checkout@v4 + with: + repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + ref: ${{ github.event.pull_request.head.ref || github.ref }} + + - name: Cache mofmt + id: cache + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/mofmt + key: mofmt-${{ env.MOFMT_VERSION }}-${{ runner.os }} + + - name: Install mofmt + if: steps.cache.outputs.cache-hit != 'true' + run: cargo install mofmt --version "$MOFMT_VERSION" --locked + + # mofmt panics on files starting with a UTF-8 BOM, which some Windows + # editors add. Does nothing on files without BOM. + - name: Strip UTF-8 BOM + run: find . -name '*.mo' -not -path './.git/*' -exec sed -i '1s/^\xEF\xBB\xBF//' {} + + + - name: Format + run: mofmt . + + - name: Commit formatting + if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) + run: | + if git diff --quiet; then echo "Already formatted"; exit 0; fi + git diff --stat + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git commit -am "style: format Modelica code with mofmt" + git push + + # Pull requests from forks have no write access, and master should only + # receive formatted code through pull requests: report only. + - name: Report unformatted files + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) + run: | + if git diff --quiet; then echo "Already formatted"; exit 0; fi + git diff --stat + echo "::error::Some .mo files are not formatted with mofmt $MOFMT_VERSION. Run 'mofmt .' at the repository root." + exit 1 diff --git a/.github/workflows/openmodelica-tests.yml b/.github/workflows/openmodelica-tests.yml new file mode 100644 index 0000000..ddb32ab --- /dev/null +++ b/.github/workflows/openmodelica-tests.yml @@ -0,0 +1,121 @@ +# Test TAeZoSysPro Examples and Tests models with OpenModelica, using +# ModelicaTests (https://gitlab.pam-retd.fr/thermosysproandco/modelicatests), +# and compare them with the master branch of EDF-Lab/TAeZoSysPro: +# - .test/config_new_openmodelica.json tests the checked out version, +# - .test/config_ref_openmodelica.json tests master, cloned by ModelicaTests. +# If the reference cannot be tested (for instance while master still has the +# library at the repository root instead of src/TAeZoSysPro), the checked out +# version is tested alone. The run summary, written by .test/report.py, shows +# the results table of the ModelicaTests HTML report for the tested version, +# and the comparison with the reference (fixed, regression, results changed). +# +# Required repository settings (Settings > Secrets and variables > Actions): +# - secret MODELICATESTS_TOKEN: GitLab token with read_repository access to +# the ModelicaTests project. +# - variable OPENMODELICA_IMAGE (optional): OpenModelica Docker image. +# +# Failing models do not fail the workflow: they are reported in the run +# summary, and in the uploaded HTML/CSV reports and OpenModelica logs. The +# workflow only fails on infrastructure errors (library or MSL not loadable, +# ModelicaTests crash). + +name: OpenModelica tests + +on: + push: + branches: [master] + pull_request: + branches: [master] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test-openmodelica: + # Pull requests from forks have no access to secrets, so the private + # ModelicaTests repository cannot be cloned: skip the job instead of failing. + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + container: + image: ${{ vars.OPENMODELICA_IMAGE || 'openmodelica/openmodelica:v1.26.7-ompython' }} + steps: + # git is needed to clone ModelicaTests; python3-venv is used to avoid + # installing Python packages as root. + - name: Install system dependencies + run: | + apt-get update + apt-get install -y --no-install-recommends git ca-certificates python3-venv + + # The library is in src/TAeZoSysPro: OpenModelica requires the directory + # containing package.mo to be named after the package. + - name: Checkout TAeZoSysPro + uses: actions/checkout@v4 + with: + path: TAeZoSysPro + + - name: Clone ModelicaTests + env: + MODELICATESTS_TOKEN: ${{ secrets.MODELICATESTS_TOKEN }} + run: git clone --depth 1 "https://oauth2:${MODELICATESTS_TOKEN}@gitlab.pam-retd.fr/thermosysproandco/modelicatests.git" modelicatests + + # Copy TAeZoSysPro test configuration files into the ModelicaTests test + # directory, where the runner expects them. + - name: Configure ModelicaTests + run: | + cp TAeZoSysPro/.test/*.json modelicatests/tests/ + cat > modelicatests/tests/local_config.json <<'JSON' + { + "dymola": { + "egg": "", + "exe": "" + }, + "openmodelica": { + "exe": "/usr/bin/omc" + } + } + JSON + + # Docker jobs run as root. OpenModelica refuses to start its ZMQ server + # as root, and omc4py needs that server, so the tests run as ciuser. + # If the run with the reference fails, its outputs are removed and the + # checked out version is tested alone (report.py then skips the comparison). + - name: Run ModelicaTests + run: | + useradd --create-home --shell /bin/bash ciuser + chown -R ciuser:ciuser "$GITHUB_WORKSPACE" + su ciuser -c "cd '$GITHUB_WORKSPACE/modelicatests' && python3 -m venv .venv && . .venv/bin/activate && python -m pip install --upgrade pip && python -m pip install ." + cd modelicatests/tests + su ciuser -c ". ../.venv/bin/activate && python3 run_cli.py config_ref_openmodelica.json config_new_openmodelica.json --ncpus 4 --timeout 120" || { + echo "::warning::ModelicaTests failed with the reference (master), see the log above: testing the checked out version alone." + rm -rf config_ref_openmodelica.csv config_ref_openmodelica.html config_ref_openmodelica-* TMP_* + su ciuser -c ". ../.venv/bin/activate && python3 run_cli.py config_new_openmodelica.json --ncpus 4 --timeout 120" + } + + # Written to a file first: ciuser cannot write to $GITHUB_STEP_SUMMARY. + - name: Write results summary + if: always() + run: | + su ciuser -c "cd '$GITHUB_WORKSPACE/modelicatests/tests' && . ../.venv/bin/activate && python3 '$GITHUB_WORKSPACE/TAeZoSysPro/.test/report.py' config_ref_openmodelica.csv config_new_openmodelica.csv > report.md" + cat modelicatests/tests/report.md >> "$GITHUB_STEP_SUMMARY" + + - name: Upload reports + if: always() + uses: actions/upload-artifact@v4 + with: + name: modelicatests-report + retention-days: 7 + # TMP_*// holds the OpenModelica check, build and simulation + # logs of each model, needed to understand a failure. + path: | + modelicatests/tests/*.csv + modelicatests/tests/*.html + modelicatests/tests/*-junit.xml + modelicatests/tests/report.md + modelicatests/tests/TMP_*/*/*.log + modelicatests/tests/TMP_*/*/*.txt + if-no-files-found: warn diff --git a/.test/config_new_openmodelica.json b/.test/config_new_openmodelica.json new file mode 100644 index 0000000..fde111e --- /dev/null +++ b/.test/config_new_openmodelica.json @@ -0,0 +1,23 @@ +{ + "software": "OpenModelica", + "dymola": { + "advanced_flags":["Advanced.LogNonLinearIterationVariables=true","Advanced.GenerateBlockTimers=true"] + }, + "openmodelica": { + "modelica_version": "3.2.3", + "compiler_flags":{ + "--matchingAlgorithm":"PFPlusExt", + "-d":"initialization,iterationVars,stateselection,backenddaeinfo,stateselection,aliasConflicts,bltdump" + }, + "simflags":{ + "-jacobian":"coloredNumerical" + } + }, + "libs": { + "TAeZoSysPro": { + "path": "../../TAeZoSysPro/src/TAeZoSysPro/package.mo", + "models_filter": "\\.(Examples|Tests)\\.", + "vars_filter": ".*" + } + } +} diff --git a/.test/config_ref_openmodelica.json b/.test/config_ref_openmodelica.json new file mode 100644 index 0000000..d5edcdb --- /dev/null +++ b/.test/config_ref_openmodelica.json @@ -0,0 +1,27 @@ +{ + "software": "OpenModelica", + "dymola": { + "advanced_flags":["Advanced.LogNonLinearIterationVariables=true","Advanced.GenerateBlockTimers=true"] + }, + "openmodelica": { + "modelica_version": "3.2.3", + "compiler_flags":{ + "--matchingAlgorithm":"PFPlusExt", + "-d":"initialization,iterationVars,stateselection,backenddaeinfo,stateselection,aliasConflicts,bltdump" + }, + "simflags":{ + "-jacobian":"coloredNumerical" + } + }, + "libs": { + "TAeZoSysPro": { + "path": { + "url": "https://github.com/EDF-Lab/TAeZoSysPro.git", + "target": "master", + "package_path": "src/TAeZoSysPro/package.mo" + }, + "models_filter": "\\.(Examples|Tests)\\.", + "vars_filter": ".*" + } + } +} diff --git a/.test/report.py b/.test/report.py new file mode 100644 index 0000000..6830d0b --- /dev/null +++ b/.test/report.py @@ -0,0 +1,198 @@ +"""Markdown report of ModelicaTests results, for the GitHub run summary. + +1. Results of the tested configuration: the table of the ModelicaTests HTML + report (.html), with the same columns and legend. +2. Comparison with the reference configuration: status of each model on both + versions and, for models simulated in both, the relative differences between + the final values of the saved variables, computed as in the ModelicaTests + HTML comparison (-.html). The 10 largest differences are listed + for each model whose results changed. Skipped if the reference CSV report + does not exist (reference not tested). + +Column order and relative differences come from ModelicaTests' own +post-processing, so this report matches its HTML files. + +Usage, from the ModelicaTests tests directory (TMP_0 = reference, TMP_1 = tested): + python report.py config_ref_openmodelica.csv config_new_openmodelica.csv > report.md +""" + +import argparse +import math +import os + +import DyMat +import numpy as np +import pandas as pd +from ModelicaTests.postprocessing import compute_relative_diff, sort_columns + +PHASES = ["check", "translate", "simulate"] + +# Plain-text version of the ModelicaTests column names (MathJax is not rendered in the run summary) +LABELS = { + "number_variable": "N_var", + "number_equation": "N_eq", + "translation_time": "T_translation [s]", + "warnings": "warnings", + "initialisation_time": "T_init [s]", + "simulation_time": "T_sim [s]", + "failed_time": "T_failed [s]", +} + +LEGEND = """*Key to abbreviated columns:* +N_var: number of variables · N_eq: number of equations (🟠 when different) · +T_translation: translation time · T_init: initialization time · +T_sim: simulation time · T_failed: simulation failure time +""" + + +def to_bool(value): + """Convert True/False strings and numpy booleans to Python booleans.""" + if isinstance(value, str): + return {"True": True, "False": False}.get(value, value) + return bool(value) if isinstance(value, np.bool_) else value + + +def read_results(csv_file): + """Read a ModelicaTests CSV report.""" + df = pd.read_csv(csv_file, sep=";", header=[0, 1], index_col=0) + df.index.name = None + return df + + +def format_cell(value, field): + """Format a cell as in the ModelicaTests HTML report (colors replaced by symbols).""" + value = to_bool(value) + if value is None or (isinstance(value, float) and math.isnan(value)): + return "–" + if isinstance(value, bool) or field == "success": + return {True: "✅", False: "❌", "TimedOut": "⏱️ TimedOut"}.get(value, str(value)) + if field in ("number_variable", "number_equation"): + return str(int(value)) + if isinstance(value, float): + return f"{value:.3f}" + return str(value) + + +def results_table(df, name): + """Markdown version of the ModelicaTests HTML table of one configuration.""" + columns = sort_columns(df.columns) + header = ["Model"] + [phase if field == "success" else LABELS.get(field, field) for phase, field in columns] + lines = [f"## Results of simulation tests for configuration {name}\n", + f"**{sum(to_bool(v) is True for v in df[('simulate', 'success')])}/{len(df)} models simulated.**\n", + "| " + " | ".join(header) + " |", + "|" + "---|" * len(header)] + for model, row in df.iterrows(): + n_var, n_eq = row.get(("check", "number_variable")), row.get(("check", "number_equation")) + mismatch = pd.notna(n_var) and pd.notna(n_eq) and n_var != n_eq + cells = [] + for phase, field in columns: + cell = format_cell(row[(phase, field)], field) + if mismatch and field in ("number_variable", "number_equation"): + cell = "🟠 " + cell + cells.append(cell) + lines.append(f"| `{model}` | " + " | ".join(cells) + " |") + return "\n".join(lines) + "\n\n" + LEGEND + + +def status(row): + """'OK', or the first failing phase of a model.""" + for phase in PHASES: + value = to_bool(row.get((phase, "success"))) + if value is not True: + return "timeout" if value == "TimedOut" else f"{phase} failed" + return "OK" + + +def final_values(mat_file): + """Return (final time, final values) of a result file, without internal variables.""" + res = DyMat.DyMatFile(mat_file) + names = [n for n in res.names() if not n.startswith(("_", "$"))] + values = pd.Series({n: float(res.data(n)[-1]) for n in names}, dtype=float) + end_time = float(res.abscissa(names[0])[0][-1]) if names else math.nan + return end_time, values + + +def diff_symbol(diff): + """Color scale of the ModelicaTests HTML comparison: green <= 0.1, red >= 0.3.""" + return "🟢" if diff <= 0.1 else "🔴" if diff >= 0.3 else "🟠" + + +def compare(ref_mat, new_mat, rtol, names): + """Return (change description or None, markdown details) for a model simulated in both.""" + (ref_end, ref), (new_end, new) = final_values(ref_mat), final_values(new_mat) + common = ref.index.intersection(new.index) + if common.empty: + return "❔ no saved variable to compare", "" + diff = pd.Series(compute_relative_diff(ref[common], new[common])).sort_values(ascending=False) + if not math.isclose(ref_end, new_end, rel_tol=1e-9): + change = f"🔶 end time changed: {ref_end:g} → {new_end:g} s" + elif diff.iloc[0] > rtol: + change = f"🔶 results changed: `{diff.index[0]}` {diff.iloc[0]:.2e}" + else: + return None, "" + rows = [f"| `{var}` | {ref[var]:.6g} | {new[var]:.6g} | {diff_symbol(d)} {d:.4f} |" for var, d in diff.iloc[:10].items()] + table = "\n".join([f"| Variable | {names[0]} | {names[1]} | Relative diff |", "|---|---|---|---|"] + rows) + return change, table + + +def comparison(ref_df, new_df, names, simu_dir, rtol): + """Markdown comparison of the tested configuration with the reference.""" + rows, details = [], [] # rows: (sort key, model, reference status, tested status, change) + for model in sorted(ref_df.index.union(new_df.index)): + r = status(ref_df.loc[model]) if model in ref_df.index else "absent" + n = status(new_df.loc[model]) if model in new_df.index else "absent" + if r == "absent": + change, key = "🆕 new model", 3 + elif n == "absent": + change, key = "🗑️ removed", 4 + elif r != "OK" and n == "OK": + change, key = "✅ fixed", 1 + elif r == "OK" and n != "OK": + change, key = "❌ regression", 0 + elif r != "OK": + change, key = ("⚠️ still failing" if r == n else "⚠️ fails differently"), 2 + else: + mats = [os.path.join(f"{simu_dir}_{i}", model, f"{model}.mat") for i in (0, 1)] + try: + change, table = compare(*mats, rtol, names) + except Exception as error: # missing or unreadable result file + change, table = f"❔ results not compared ({type(error).__name__})", "" + key = 5 if change else 6 + change = change or "= unchanged" + if table: + details.append(f"
{model}: 10 largest relative differences\n\n{table}\n\n
") + rows.append((key, model, r, n, change)) + + counts = {} + for *_, change in rows: + label = change.split(":")[0].split(" (")[0] + counts[label] = counts.get(label, 0) + 1 + lines = [f"## Comparison of simulation test results for configurations {names[0]} - {names[1]}\n", + " · ".join(f"{label}: {count}" for label, count in counts.items()) + "\n", + f"Results are compared on the final values of all saved variables. Relative difference as in " + f"ModelicaTests: |{names[0]} - {names[1]}| / max(|{names[0]}|, |{names[1]}|, 0.01); " + f"results are reported as changed above {rtol:g}.\n", + f"| Model | {names[0]} | {names[1]} | Change |", + "|---|---|---|---|"] + lines += [f"| `{model}` | {r} | {n} | {change} |" for _, model, r, n, change in sorted(rows)] + return "\n".join(lines + [""] + details) + "\n" + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("ref_csv", help="ModelicaTests CSV report of the reference configuration") + parser.add_argument("new_csv", help="ModelicaTests CSV report of the tested configuration") + parser.add_argument("--simu-dir", default="TMP", help="Simulation directory prefix used by ModelicaTests") + parser.add_argument("--rtol", type=float, default=1e-4, help="Relative difference above which results are reported as changed") + args = parser.parse_args() + + names = [os.path.basename(f).removesuffix(".csv") for f in (args.ref_csv, args.new_csv)] + print(results_table(read_results(args.new_csv), names[1])) + if os.path.exists(args.ref_csv): + print(comparison(read_results(args.ref_csv), read_results(args.new_csv), names, args.simu_dir, args.rtol)) + else: + print(f"## Comparison with {names[0]}\n\n⚠️ Not available: the reference could not be tested (see the job log).") + + +if __name__ == "__main__": + main() diff --git a/FluidDynamics/BasesClasses/MolecularDiffusion.mo b/FluidDynamics/BasesClasses/MolecularDiffusion.mo deleted file mode 100644 index 047e51a..0000000 --- a/FluidDynamics/BasesClasses/MolecularDiffusion.mo +++ /dev/null @@ -1,326 +0,0 @@ -within TAeZoSysPro.FluidDynamics.BasesClasses; -model MolecularDiffusion - - //Media delcaration - replaceable package Medium = TAeZoSysPro.Media.MyMedia; - - // User defined parameters - parameter Modelica.SIunits.Thickness Th = 1 "Thickness between concentration potential difference"; - parameter Modelica.SIunits.CrossSection A = 0; - parameter Modelica.SIunits.DiffusionCoefficient D=25*1e-6; - - // Internal variables - Real grad_X[Medium.nX](each quantity="spatial gradient",each unit="m-1") "gradient of mass fraction"; - Modelica.SIunits.MassFlowRate[Medium.nX] m_flow; - Modelica.SIunits.Density d_mean; - Modelica.SIunits.Temperature T_mean; - Modelica.SIunits.SpecificEnthalpy[Medium.nX] h; - Real J[Medium.nX](each quantity="mass flux rate",each unit="kg.m-2.s-1") "Gradient of mass fraction"; - Modelica.SIunits.MassFraction[Medium.nX] X_a; - Modelica.SIunits.MassFraction[Medium.nX] X_b; - - // Imported modules - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b flowPort_b(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -equation - X_a = flowPort_a.d / sum(flowPort_a.d); - X_b = flowPort_b.d / sum(flowPort_b.d); - d_mean = 1/2 * (sum(flowPort_a.d) + sum(flowPort_b.d)); - T_mean = 1/2 * (flowPort_a.T + flowPort_b.T); - h[1] = Medium.enthalpyOfCondensingGas(T_mean); - h[2] = Medium.enthalpyOfNonCondensingGas(T_mean); - - // - - // for a binary gas mixture - grad_X = 1 / Th * ( X_b - X_a); - J[1] = - d_mean * D * grad_X[1]; - J[2] = - J[1]; - m_flow = J * A; - - -// Port handovers - flowPort_a.m_flow = m_flow; - flowPort_a.H_flow = m_flow * h; - flowPort_a.m_flow = - flowPort_b.m_flow; - flowPort_a.H_flow + flowPort_b.H_flow = 0.0; - - annotation ( - Documentation(info = " - - - MolecularDiffusion - - - - -

- This components allows to model the mass flow rate induced by the gradient of concentration of species within a binary gas mixture. - The mass flow rate of species derives from the Fick's equation. -

- -

- The physical model under this module uses the following assumptions: -

    -
  • the total concentration of the mixture is approximately constant
  • -
-

- - - -

- Where: -

    -
  • m_flow j is the mass flow rate of the species 'j' [kg.m-2.s-1]
  • -
  • ρ is the density of the mixture [kg.m-3]
  • -
  • Dij binary coefficient of diffusion from 'i' to 'j' [m2.s-1]
  • -
  • cj mass fraction of the species 'j' [-]
  • -
-

- -

- The quantities contained in the equation are such that Dij = Dji (symmetry of the interaction between particles i and j) and ci + cj = 1 (by definition of the mass fraction). - It is deduce that diffusion does not globally transport mass, it only distributes it differently: -

- - - -

- Therefore an to avoid mass transport, the global density used in the equations above are computed at the middle of the diffusion length. -

- - -"), - Icon(graphics={ - Ellipse(origin = {-52, 80}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, 68}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, 56}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, 20}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, 44}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, 32}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, -40}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, -28}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, -52}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, -16}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, -4}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, 8}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, -76}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-52, -64}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-40, 62}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-30, 74}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-30, 50}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, 64}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-40, 38}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-30, 26}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-40, 14}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-30, 2}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-40, -10}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-30, -22}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-40, -34}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-30, -46}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-40, -58}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-30, -70}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, 40}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, 16}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, -8}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, -32}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, -56}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, -78}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, 86}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-40, 86}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-40, -80}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Rectangle(fillColor = {0, 170, 255}, extent = {{-56, 88}, {62, -84}}), - Ellipse(origin = {54, 80}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, 8}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, -4}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, -16}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, 32}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, 44}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, 20}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, 56}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, 68}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, -28}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, -40}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, -52}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, -64}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {54, -76}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {42, 86}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {42, 62}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {42, 38}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {42, 14}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {42, -10}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {42, -34}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {42, -58}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {42, -80}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {30, 74}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {30, 50}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {30, 26}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {30, 2}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {30, -22}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {30, -46}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {30, -70}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, 86}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, 64}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, 40}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, 16}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, -8}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, -32}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, -56}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, -78}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {24, 64}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {24, 42}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {24, 18}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {24, -6}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {24, -30}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {24, -54}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, 76}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, 54}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, 30}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, 6}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, -18}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, -42}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {10, -66}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {24, -76}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {46, 74}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {46, 26}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {46, -22}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {46, -70}, fillColor = {0, 85, 255}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, 76}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, 54}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, 30}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, 6}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, -18}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, -42}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-12, -66}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-24, 64}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-24, 40}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-24, 16}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-24, -8}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-24, -32}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-24, -56}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-24, -80}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-24, 86}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-44, 74}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-44, 26}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-44, -22}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Ellipse(origin = {-44, -70}, fillColor = {255, 0, 0}, - fillPattern = FillPattern.Solid, extent = {{-2, 2}, {4, -4}}, endAngle = 360), - Line(origin = {0, 2}, points = {{0, 86}, {0, -86}}, pattern = LinePattern.Dot)}, coordinateSystem(initialScale = 0.1))); -end MolecularDiffusion; diff --git a/FluidDynamics/Components/Buildings/BurstMembrane.mo b/FluidDynamics/Components/Buildings/BurstMembrane.mo deleted file mode 100644 index 34405b9..0000000 --- a/FluidDynamics/Components/Buildings/BurstMembrane.mo +++ /dev/null @@ -1,95 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Buildings; - -model BurstMembrane - replaceable package Medium = TAeZoSysPro.Media.MyMedia "Medium in the component" annotation (choicesAllMatching = true); - - // User defined parameters - parameter Modelica.SIunits.PressureDifference dp_burst = 7000 "Pressure difference to which the disk burst"; - - // Internal variables - Boolean bursted "Bursted membrane" ; - Modelica.SIunits.PressureDifference dp ; - Medium.MassFlowRate m_flow ; - - // Imported modules - Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0), iconTransformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(extent = {{110, -10}, {90, 10}}, rotation = 0), iconTransformation(extent = {{110, -10}, {90, 10}}, rotation = 0))); - -initial equation - bursted = false ; - -equation - - dp = port_a.p - port_b.p ; - - if pre(bursted) then - dp = 0.0; - else - m_flow = 0.0 ; - end if ; - - when dp >= dp_burst then - bursted = true ; - end when ; - -// Port handover - // Mass balance (no storage) - port_a.m_flow = m_flow ; - port_a.m_flow + port_b.m_flow = 0; - - // Transport of substances - port_a.Xi_outflow = inStream(port_b.Xi_outflow); - port_b.Xi_outflow = inStream(port_a.Xi_outflow); - - port_a.C_outflow = inStream(port_b.C_outflow); - port_b.C_outflow = inStream(port_a.C_outflow); - - // Isenthalpic state transformation (no storage and no loss of energy) - port_a.h_outflow = inStream(port_b.h_outflow); - port_b.h_outflow = inStream(port_a.h_outflow); - - annotation( - Icon(graphics = {Rectangle(extent = {{-80, 80}, {80, -80}}), Line(origin = {9.84, 0}, points = {{-9.84189, 60}, {10.1581, 0}, {-9.84189, -60}}, thickness = 0.5, smooth = Smooth.Bezier), Line(origin = {0, 70}, points = {{0, 10}, {0, -10}}, thickness = 1), Line(origin = {0.0458716, -69.9541}, points = {{0, 10}, {0, -10}}, thickness = 1), Line(origin = {30, 50}, points = {{-30, 10}, {30, -10}}, pattern = LinePattern.Dot), Line(origin = {30, -40}, points = {{-30, -20}, {30, 0}}, pattern = LinePattern.Dot)}, coordinateSystem(initialScale = 0.1)), - Description(info= -" - - BurstMembrane - - - -

- The module model a perfect one dimentional burst membrane. - Perfect means no pressure loss when opened and no flow when close. One dimensional since the membrane can bursted only when the boundary pressure difference dp ≥ dp_burst. - A negative pressure difference having an absolute value above the threshold dp_burst would not make the menbrane bursted. -

- -

- The membrane is assumed non bursted at the initialisation. When it becomes burst, it is non reversible. -

- -

- In this model of leaks, there is only one equation to model the behavior of the flow resistance. It is rather quadratic to the velocity for an equipment hole and linear to the velocity for the porosities. -

- -

- Therefore, in the module, the relation of the of the pressure loss is function of the kinetic energy exponent leakExponent. -

- - - -

- The leak surface area is defined as a fraction of the wall surface equal to leakSurfaceRatio. -

- - - - -")); - -end BurstMembrane; diff --git a/FluidDynamics/Components/Buildings/HalfWall.mo b/FluidDynamics/Components/Buildings/HalfWall.mo deleted file mode 100644 index 3686a9a..0000000 --- a/FluidDynamics/Components/Buildings/HalfWall.mo +++ /dev/null @@ -1,158 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Buildings; - -model HalfWall - // - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; - import TAeZoSysPro.HeatTransfer.Types.Dynamics; - import TAeZoSysPro.HeatTransfer.Types.MeshGrid; - import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid; - //Media - replaceable package Medium = TAeZoSysPro.Media.MyMedia; - // User defined parameters - parameter MeshGrid mesh = MeshGrid.biotAndGeometricalGrowth "Selection of meshing function" annotation( - Dialog(group = "Meshing properties")); - parameter Real q = 1.2 "Growth rate (if geometricalGrowth chosen)" annotation( - Dialog(group = "Meshing properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 "Decoupled value of the heat transfer (if biot segment chosen)" annotation( - Dialog(group = "Meshing properties")); - parameter Integer N(min = 1) = integer(max(1, 5 * Th / 0.2 * 1e-6 * d * cp / k)) "Number of layers : 1 to 65535" annotation( - Dialog(group = "Meshing properties")); - parameter Modelica.SIunits.Area A = 0 "Wall area " annotation( - Dialog(group = "Geometrical properties")); - parameter Modelica.SIunits.Height Lc = 0 "Wall characteristic length" annotation( - Dialog(group = "Geometrical properties")); - parameter Modelica.SIunits.Length Th = 0 "Wall thickness" annotation( - Dialog(group = "Geometrical properties")); - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance" annotation( - Dialog(group = "Dynamic properties")); - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial" annotation( - Dialog(group = "Dynamic properties")); - parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 "Wall specific heat capacity" annotation( - Dialog(group = "Thermal properties")); - parameter Modelica.SIunits.Density d(displayUnit = "kg/m3") = 0 "Wall density" annotation( - Dialog(group = "Thermal properties")); - parameter Modelica.SIunits.ThermalConductivity k = 0 "Wall conductivity" annotation( - Dialog(group = "Thermal properties")); - parameter Real add_on_conv = 1 "Custom add-on for convection" annotation( - Dialog(group = "Convection properties")); - parameter Real add_on_cond = 1 "Custom add-on for condensation" annotation( - Dialog(group = "Convection properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE "free convection Correlation" annotation( - Dialog(group = "Convection properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Convection properties")); - // - parameter Modelica.SIunits.Emissivity eps = 0 "Wall emissivity " annotation( - Dialog(group = "Radiative properties")); - parameter Real add_on_rad = 1 "Custom add-on" annotation( - Dialog(group = "Radiative properties")); - // Internal variables - Modelica.SIunits.BiotNumber Bi; - // Components inside wall are defined - TAeZoSysPro.HeatTransfer.BasesClasses.PartialWall partialWall(A = A, N = N, T_start = T_start, Th = Th, cp = cp, d = d, energyDynamics = energyDynamics, h = h, k = k, mesh = mesh, q = q, symmetricalMesh = false) if N > 1 annotation( - Placement(visible = true, transformation(origin = {46.5, 18.5}, extent = {{-29.5, -29.5}, {29.5, 29.5}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.FreeConvection convection(redeclare - package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation, h_cv_const = h_cv_const) annotation ( - Placement(visible = true, transformation(origin = {-10, 89}, extent = {{-11, -11}, {11, 11}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A, add_on = add_on_rad, eps = eps) annotation( - Placement(visible = true, transformation(origin = {-16.5, -70.5}, extent = {{-22.5, -22.5}, {22.5, 22.5}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad annotation( - Placement(visible = true, transformation(origin = {-61, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall annotation( - Placement(visible = true, transformation(origin = {-52, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput F_view annotation( - Placement(visible = true, transformation(origin = {-50, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b annotation( - Placement(visible = true, transformation(origin = {99, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface annotation( - Placement(visible = true, transformation(origin = {-50, 60}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-90, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.Condensation condensation(redeclare - package Medium = Medium, A = A) annotation ( - Placement(visible = true, transformation(origin = {-50, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start,cp = cp, energyDynamics = energyDynamics, m = Th * A * d) if N==1 annotation( - Placement(visible = true, transformation(origin = {46, -54}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); -equation - condensation.h_cv = convection.h_cv; - connect(port_surface, partialWall.port_a) annotation( - Line(points = {{-50, 60}, {18, 60}, {18, 18.5}}, color = {191, 0, 0})); - connect(F_view, carrollRadiation.Fview) annotation( - Line(points = {{-50, -30}, {1.5, -30}, {1.5, -52.5}}, color = {0, 0, 127})); - connect(port_a_rad, carrollRadiation.port_b) annotation( - Line(points = {{-61, -70}, {-48, -70}, {-48, -70.5}, {-39, -70.5}}, color = {191, 0, 0})); - connect(carrollRadiation.port_a, partialWall.port_a) annotation( - Line(points = {{6, -70.5}, {18, -70.5}, {18, 18.5}}, color = {191, 0, 0})); - if N > 1 then - Bi = convection.h_cv * (partialWall.x[2] - partialWall.x[1]) / k; - else - Bi = 0.0; - end if; - - A_wall = A; -//output y is set to Awall and it can be connected to FviewCalculator - connect(partialWall.port_b, port_b) annotation( - Line(points = {{75, 18.5}, {88, 18.5}, {88, 0}, {100, 0}}, color = {191, 0, 0})); - connect(condensation.heatPort, partialWall.port_a) annotation( - Line(points = {{-40, 30}, {18, 30}, {18, 18.5}}, color = {191, 0, 0})); - connect(port_a, condensation.flowPort) annotation( - Line(points = {{-90, 90}, {-70, 90}, {-70, 30}, {-60, 30}, {-60, 30}}, color = {0, 85, 255})); - connect(port_a, convection.port_b) annotation( - Line(points = {{-90, 90}, {-20, 90}, {-20, 90}, {-20, 90}}, color = {0, 85, 255})); - connect(convection.port_a, partialWall.port_a) annotation( - Line(points = {{2, 90}, {18, 90}, {18, 18}}, color = {191, 0, 0})); - connect(convection.port_a, heatCapacitor.port) annotation( - Line(points = {{2, 90}, {18, 90}, {18, -44}, {46, -44}}, color = {191, 0, 0})); - connect(port_surface, heatCapacitor.port) annotation( - Line(points = {{-50, 60}, {18, 60}, {18, -44}, {46, -44}}, color = {191, 0, 0})); - connect(condensation.heatPort, heatCapacitor.port) annotation( - Line(points = {{-40, 30}, {18, 30}, {18, -44}, {46, -44}}, color = {191, 0, 0})); - connect(carrollRadiation.port_a, heatCapacitor.port) annotation( - Line(points = {{6, -70}, {18, -70}, {18, -44}, {46, -44}}, color = {191, 0, 0})); - connect(port_b, heatCapacitor.port) annotation( - Line(points = {{100, 0}, {88, 0}, {88, -44}, {46, -44}}, color = {191, 0, 0})); - annotation( - Diagram(graphics = {Rectangle(origin = {43.5, -1}, fillColor = {218, 218, 218}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-42.5, 101}, {36.5, -99}}), Text(origin = {46, 52}, extent = {{-20, 10}, {20, -10}}, textString = "If N > 1"), Text(origin = {46, -32}, extent = {{-20, 10}, {20, -10}}, textString = "If N = 1")}, coordinateSystem(initialScale = 0.1)), - Icon(graphics = {Rectangle(origin = {11, 9}, fillColor = {191, 191, 191}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-51, 91}, {29, -109}}), Line(origin = {-70, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-60, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 88.1389}, points = {{9, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 52.1389}, points = {{9, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-93, 93}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "Fluid"), Text(origin = {-93, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Text(origin = {-73, -25}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view"), Text(origin = {-73, -49}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall"), Line(origin = {-52.1559, -79.8606}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52.5726, -99.7217}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Ellipse(origin = {-44, 88}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {-44, 70}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {-44, 52}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Line(origin = {-61.3433, 71.0195}, points = {{9, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " - - - HalfWall - - - - - - -

- This component models the thermal response of half wall in interface with a rest ambiance where the thermal exchanges are mainly driven by natural convection, radiation and condensation. -

- -

- This component is an assembly of the PartialWall module, the FreeConvection module, the CarrollRadiation module and the Condensation module. The solid wall is dicretises in N along its depth to model the heat propagation. By defaut the value of N is computed from the depth and the thermal diffusivty of the wall.
- When the number of layers N is equal to one, the PartialWall is replaced by a HeatCapacitor. -

- - -

- A port name port_surface is connected to the boundary port of the PartialWall. - It can be usefull for specific applications when another modules is required et can be latter connected to this empty heat port. -

- -

- The HalfWall supplies as output the surface area of the wall, via its A_wall port, to the FviewCalculator module and get from this last the form (or view) factor as input via the F_view port. The connection is performed explicitely via the graphic connectors. -

- -"), - experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-06, Interval = 36)); -end HalfWall; \ No newline at end of file diff --git a/FluidDynamics/Components/Buildings/Wall.mo b/FluidDynamics/Components/Buildings/Wall.mo deleted file mode 100644 index aec7e0d..0000000 --- a/FluidDynamics/Components/Buildings/Wall.mo +++ /dev/null @@ -1,213 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Buildings; - -model Wall - // - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - import TAeZoSysPro.HeatTransfer.Types.MeshGrid ; - import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid ; - - -//Media - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - // User defined parameters - parameter MeshGrid mesh = MeshGrid.biotAndGeometricalGrowth "Selection of meshing function" annotation( - Dialog(group="Meshing properties")); - parameter Real q = 1.2 "Growth rate (if geometricalGrowth chosen)" annotation( - Dialog(group="Meshing properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 "Decoupled value of the heat transfer (if biot segment chosen)" annotation( - Dialog(group="Meshing properties")); - parameter Integer N(min=1) = integer(max(1, 5 * Th / 0.2 * 1e-6 * d * cp / k)) "Number of layers : 1 to 65535" annotation( - Dialog(group="Meshing properties")); - - parameter Modelica.SIunits.Area A = 0 "Wall area " annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Height Lc = 0 "Wall characteristic length" annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Length Th = 0 "Wall thickness" annotation( - Dialog(group="Geometrical properties")); - - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance" annotation( - Dialog(group="Dynamic properties")); - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial" annotation( - Dialog(group="Dynamic properties")); - - parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 "Wall specific heat capacity" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.Density d(displayUnit="kg/m3") = 0 "Wall density" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.ThermalConductivity k = 0 "Wall conductivity" annotation( - Dialog(group="Thermal properties")); - - parameter Real add_on_conv = 1 "Custom add-on for convection" annotation( - Dialog(group = "Convection properties")); - parameter Real add_on_cond = 1 "Custom add-on for condensation" annotation( - Dialog(group = "Convection properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation_a = Correlations.vertical_plate_ASHRAE "free convection Correlation" annotation( - Dialog(group = "Convection properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation_b = if correlation_a == Correlations.ceiling_ASHRAE then Correlations.ground_ASHRAE elseif correlation_a == Correlations.ground_ASHRAE then Correlations.ceiling_ASHRAE else correlation_a "free convection Correlation" annotation( - Dialog(group = "Convection properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const_a = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Convection properties")); - - parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const_b = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Convection properties")); - // - parameter Modelica.SIunits.Emissivity eps_a = 0 "Wall emissivity " annotation( - Dialog(group = "Radiative properties")); - parameter Modelica.SIunits.Emissivity eps_b = 0 "Wall emissivity " annotation( - Dialog(group = "Radiative properties")); - parameter Real add_on_rad = 1 "Custom add-on" annotation( - Dialog(group = "Radiative properties")); - -// Internal variables - Modelica.SIunits.BiotNumber Bi_a, Bi_b ; - -// Components inside wall are defined - TAeZoSysPro.HeatTransfer.BasesClasses.PartialWall partialWall(A = A, N = N, T_start = T_start, Th = Th, cp = cp, d = d, energyDynamics = energyDynamics, h = h, k = k, mesh = mesh, q = q, symmetricalMesh = true) if N > 1 annotation( - Placement(visible = true, transformation(origin = {0.5, 10.5}, extent = {{-29.5, -29.5}, {29.5, 29.5}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.FreeConvection freeConvection_a(redeclare package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation_a, h_cv_const = h_cv_const_a) annotation( - Placement(visible = true, transformation(origin = {-55, 70}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation_a(A = A, add_on = add_on_rad, eps = eps_a) annotation( - Placement(visible = true, transformation(origin = {-59.5, -79.5}, extent = {{-19.5, -19.5}, {19.5, 19.5}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad annotation( - Placement(visible = true, transformation(origin = {-101, -78}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall_a annotation( - Placement(visible = true, transformation(origin = {-90, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput F_view_a annotation( - Placement(visible = true, transformation(origin = {-90, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface_a annotation( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.FreeConvection freeConvection_b(redeclare package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation_b, h_cv_const = h_cv_const_b) annotation( - Placement(visible = true, transformation(origin = {57, 70}, extent = {{18, -18}, {-18, 18}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation_b(A = A, add_on = add_on_rad, eps = eps_b) annotation( - Placement(visible = true, transformation(origin = {59.5, -80.5}, extent = {{20.5, -20.5}, {-20.5, 20.5}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b_rad annotation( - Placement(visible = true, transformation(origin = {101, -80}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall_b annotation( - Placement(visible = true, transformation(origin = {90, -20}, extent = {{10, -10}, {-10, 10}}, rotation = 180), iconTransformation(origin = {93, -53}, extent = {{7, -7}, {-7, 7}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput F_view_b annotation( - Placement(visible = true, transformation(origin = {90, -50}, extent = {{10, -10}, {-10, 10}}, rotation = 0), iconTransformation(origin = {93, -27}, extent = {{7, -7}, {-7, 7}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_surface_b annotation( - Placement(visible = true, transformation(origin = {101, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {-100, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {100, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.Condensation condensation_a(redeclare package Medium = Medium, A = A, add_on = add_on_cond, h_cv = freeConvection_a.h_cv) annotation( - Placement(visible = true, transformation(origin = {-55, 21}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.Condensation condensation_b(redeclare package Medium = Medium, A = A, add_on = add_on_cond, h_cv = freeConvection_b.h_cv) annotation( - Placement(visible = true, transformation(origin = {55, 21}, extent = {{15, -15}, {-15, 15}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start,cp = cp, energyDynamics = energyDynamics, m = Th * A * d) if N==1 annotation( - Placement(visible = true, transformation(origin = {0, -70}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); - -equation - connect(port_a_rad, carrollRadiation_a.port_b) annotation( - Line(points = {{-101, -78}, {-88, -78}, {-88, -79.5}, {-79, -79.5}}, color = {191, 0, 0})); - - if N > 1 then - Bi_a = freeConvection_a.h_cv * (partialWall.x[2] - partialWall.x[1]) / k; - Bi_b = freeConvection_b.h_cv * (partialWall.x[end] - partialWall.x[end-1]) / k; - else - Bi_a = 0.0; - Bi_b = 0.0; - end if; - -A_wall_a = A; -A_wall_b = A; -//output y is set to Awall and it can be connected to FviewCalculator - connect(freeConvection_a.port_a, partialWall.port_a) annotation( - Line(points = {{-36, 70}, {-28, 70}, {-28, 10.5}}, color = {191, 0, 0})); - connect(carrollRadiation_a.port_a, partialWall.port_a) annotation( - Line(points = {{-40, -79.5}, {-28, -79.5}, {-28, 10.5}}, color = {191, 0, 0})); - connect(freeConvection_b.port_a, partialWall.port_b) annotation( - Line(points = {{39, 70}, {28, 70}, {28, 10.5}, {29, 10.5}}, color = {191, 0, 0})); - connect(carrollRadiation_b.port_a, partialWall.port_b) annotation( - Line(points = {{39, -80.5}, {28, -80.5}, {28, 10.5}, {29, 10.5}}, color = {191, 0, 0})); - connect(carrollRadiation_b.port_b, port_b_rad) annotation( - Line(points = {{80, -80.5}, {92, -80.5}, {92, -80}, {101, -80}}, color = {191, 0, 0})); - connect(port_surface_a, partialWall.port_a) annotation( - Line(points = {{-100, 0}, {-28, 0}, {-28, 10.5}}, color = {191, 0, 0})); - connect(port_surface_b, partialWall.port_b) annotation( - Line(points = {{101, 0}, {27.5, 0}, {27.5, 10.5}, {29, 10.5}}, color = {191, 0, 0})); - connect(F_view_a, carrollRadiation_a.Fview) annotation( - Line(points = {{-90, -50}, {-44, -50}, {-44, -64}}, color = {0, 0, 127})); - connect(F_view_b, carrollRadiation_b.Fview) annotation( - Line(points = {{90, -50}, {44, -50}, {44, -64}, {43, -64}}, color = {0, 0, 127})); - connect(condensation_a.heatPort, partialWall.port_a) annotation( - Line(points = {{-41.5, 21}, {-28, 21}, {-28, 10.5}}, color = {191, 0, 0})); - connect(port_a, freeConvection_a.port_b) annotation( - Line(points = {{-100, 70}, {-74, 70}, {-74, 70}, {-72, 70}}, color = {0, 85, 255})); - connect(port_a, condensation_a.flowPort) annotation( - Line(points = {{-100, 70}, {-86, 70}, {-86, 21}, {-69, 21}}, color = {0, 85, 255})); - connect(condensation_b.heatPort, partialWall.port_b) annotation( - Line(points = {{41.5, 21}, {28, 21}, {28, 10.5}, {29, 10.5}}, color = {191, 0, 0})); - connect(freeConvection_b.port_b, port_b) annotation( - Line(points = {{74, 70}, {100, 70}, {100, 70}, {100, 70}}, color = {0, 85, 255})); - connect(condensation_b.flowPort, port_b) annotation( - Line(points = {{69, 21}, {88, 21}, {88, 70}, {100, 70}}, color = {0, 85, 255})); - connect(freeConvection_a.port_a, heatCapacitor.port) annotation( - Line(points = {{-36, 70}, {-28, 70}, {-28, -60}, {0, -60}}, color = {191, 0, 0})); - connect(heatCapacitor.port, condensation_a.heatPort) annotation( - Line(points = {{0, -60}, {-28, -60}, {-28, 21}, {-41.5, 21}}, color = {191, 0, 0})); - connect(port_surface_a, heatCapacitor.port) annotation( - Line(points = {{-100, 0}, {-28, 0}, {-28, -60}, {0, -60}}, color = {191, 0, 0})); - connect(carrollRadiation_a.port_a, heatCapacitor.port) annotation( - Line(points = {{-40, -79.5}, {-28, -79.5}, {-28, -60}, {0, -60}}, color = {191, 0, 0})); - connect(freeConvection_b.port_a, heatCapacitor.port) annotation( - Line(points = {{40, 70}, {28, 70}, {28, -60}, {0, -60}}, color = {191, 0, 0})); - connect(condensation_b.heatPort, heatCapacitor.port) annotation( - Line(points = {{41.5, 21}, {28, 21}, {28, -60}, {0, -60}}, color = {191, 0, 0})); - connect(port_surface_b, heatCapacitor.port) annotation( - Line(points = {{101, 0}, {28, 0}, {28, -60}, {0, -60}}, color = {191, 0, 0})); - connect(carrollRadiation_b.port_a, heatCapacitor.port) annotation( - Line(points = {{39, -80.5}, {28, -80.5}, {28, -60}, {0, -60}}, color = {191, 0, 0})); - annotation( - Diagram(graphics = {Rectangle(origin = {3.5, -1}, fillColor = {218, 218, 218}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-42.5, 101}, {36.5, -99}}), Text(origin = {2, 46}, extent = {{-20, 10}, {20, -10}}, textString = "If N > 1"), Text(origin = {2, -46}, extent = {{-20, 10}, {20, -10}}, textString = "If N = 1")}, coordinateSystem(initialScale = 0.1)), - Icon(graphics = {Rectangle(origin = {11, 9}, fillColor = {191, 191, 191}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-51, 91}, {29, -109}}), Line(origin = {-70, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-58, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 88.1389}, points = {{7, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 54.14}, points = {{7, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-106, 93}, lineThickness = 1, extent = {{-14, 7}, {26, -13}}, textString = "Fluid"), Text(origin = {-93, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Text(origin = {-73, -27}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view_a"), Text(origin = {-73, -49}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall_a"), Line(origin = {-52.1559, -79.8606}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52.5726, -99.7217}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {67, -47}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall_b"), Text(origin = {67, -27}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view_b"), Line(origin = {52.8486, -80.2659}, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {52.4319, -100.127}, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {68.8387, 69.7336}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {59.8387, 53.7336}, rotation = 180, points = {{7, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {59.8387, 87.7336}, rotation = 180, points = {{7, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {56.8387, 69.7336}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {94, 93}, lineThickness = 1, extent = {{-14, 7}, {26, -13}}, textString = "Fluid"), Text(origin = {87, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Ellipse(origin = {-46, 88}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {-46, 70}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {-46, 52}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {46, 88}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {46, 70}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {46, 52}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}})}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " - - - HalfWall - - - - - - -

- This component models the thermal response of wall in interface with a rest ambiances where the thermal exchanges are mainly driven by natural convection, radiation and condensation. -

- -

- The suffix '..._a' refers to side where the ports 'port_a' are. -

- -

- This component is an assembly of the PartialWall module, the FreeConvection modules, the CarrollRadiation modules and the Condensation modules. The solid wall is dicretises in N along its depth to model the heat propagation. By defaut the value of N is computed from the depth and the thermal diffusivty of the wall.
- When the number of layers N is equal to one, the PartialWall is replaced by a HeatCapacitor. -

- -

- Ports name port_surface are connected to boundary ports of the PartialWall. - It can be usefull for specific applications when another modules is required et can be latter connected to this empty heat port. -

- -

- The Wall supplies as output the surface area of the wall, via its A_wall ports, to the FviewCalculator module and get from this last the form (or view) factor as input via the F_view ports. The connection is performed explicitely via the graphic connectors. -

- -"), - experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-06, Interval = 36)); - -end Wall; \ No newline at end of file diff --git a/FluidDynamics/Components/HeatExchangers/AnalyticExchanger.mo b/FluidDynamics/Components/HeatExchangers/AnalyticExchanger.mo deleted file mode 100644 index 5d940a6..0000000 --- a/FluidDynamics/Components/HeatExchangers/AnalyticExchanger.mo +++ /dev/null @@ -1,115 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.HeatExchangers; - -model AnalyticExchanger - // - extends TAeZoSysPro.HeatTransfer.BasesClasses.PartialHeatExchanger; - import TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness ; - import TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff ; - // - import SI = Modelica.SIunits ; - - // Medium declaration - replaceable package MediumA = TAeZoSysPro.Media.MyMedia ; - replaceable package MediumB = TAeZoSysPro.Media.MyMedia ; - - // - replaceable function effectiveness = ExchangerEffectiveness.counterCurrent ; - replaceable function heatTransferCoeff = ExchangerHeatTransferCoeff.user_defined ; - - // User defined parameters - parameter SI.Area CrossSectionA = 1 "Cross section of the pipe for the fluid A" annotation(Dialog(group="Geometrical parameters")) ; - parameter SI.Area CrossSectionB = 1 "Cross section of the pipe for the fluid B" annotation(Dialog(group="Geometrical parameters")); - parameter Real ksi_fixedA = 1.0 annotation(Dialog(group="Flow parameters")); - parameter Real ksi_fixedB = 1.0 annotation(Dialog(group="Flow parameters")); - - // Internal variables - MediumA.ThermodynamicState stateA_in "State of fluid A a inlet" ; - MediumB.ThermodynamicState stateB_in "State of fluid B a inlet" ; - SI.SpecificHeatCapacity cp_A ; - SI.SpecificHeatCapacity cp_B ; - SI.MassFlowRate m_flowA "Mass flow rate of fluid A" ; - SI.MassFlowRate m_flowB "Mass flow rate of fluid B" ; - SI.PressureDifference dp_A "fluid A pressure drop"; - SI.PressureDifference dp_B "fluid B pressure drop"; - - // Imported modules - Modelica.Fluid.Interfaces.FluidPort_a port_A_in(redeclare package Medium = MediumA) annotation ( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_A_out(redeclare package Medium = MediumA) annotation ( - Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_a port_B_in(redeclare package Medium = MediumB) annotation ( - Placement(visible = true, transformation(origin = {-68, 88}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, -84}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_B_out(redeclare package Medium = MediumB) annotation ( - Placement(visible = true, transformation(origin = {66, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 82}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -equation -// - stateA_in = MediumA.setState_phX(port_A_in.p, inStream(port_A_in.h_outflow), inStream(port_A_in.Xi_outflow)); - stateB_in = MediumB.setState_phX(port_B_in.p, inStream(port_B_in.h_outflow), inStream(port_B_in.Xi_outflow)); - - // compute thermodynamical properties - cp_A = MediumA.specificHeatCapacityCp(stateA_in) ; - cp_B = MediumB.specificHeatCapacityCp(stateB_in) ; - - // - Qc_A = m_flowA * cp_A ; - Qc_B = m_flowB * cp_B ; - - // - T_A_in = MediumA.temperature(stateA_in) ; - T_B_in = MediumB.temperature(stateB_in) ; - -//momentum - steady state assumptions - m_flowA = CrossSectionA * TAeZoSysPro.FluidDynamics.Utilities.regRoot2( - x = port_A_in.p - port_A_out.p, - x_small = 10, - k1 = 2 * MediumA.density(stateA_in) / ksi_fixedA, - k2 = 2 * MediumA.density(stateA_in) / ksi_fixedA); - dp_A = port_A_in.p - port_A_out.p; - - m_flowB = CrossSectionB * TAeZoSysPro.FluidDynamics.Utilities.regRoot2( - x = port_B_in.p - port_B_out.p, - x_small = 10, - k1 = 2 * MediumB.density(stateB_in) / ksi_fixedB, - k2 = 2 * MediumB.density(stateB_in) / ksi_fixedB); - dp_B = port_B_in.p - port_B_out.p; - -// heat exchange properties - h_global = heatTransferCoeff() ; - Eff = effectiveness(NTU = NTU, Cr = Cr) ; - -// ports handover - port_A_in.m_flow = m_flowA; - port_A_in.h_outflow = inStream(port_A_in.h_outflow); -// reverse flow not modelled - port_A_in.Xi_outflow = inStream(port_A_in.Xi_outflow); - port_A_out.m_flow + port_A_in.m_flow = 0.0; - m_flowA * (inStream(port_A_in.h_outflow) - port_A_out.h_outflow) = Q_flow; - port_A_out.Xi_outflow = inStream(port_A_out.Xi_outflow); -// - port_B_in.m_flow = m_flowB; - port_B_in.h_outflow = inStream(port_B_in.h_outflow); -// reverse flow not modelled - port_B_in.Xi_outflow = inStream(port_B_in.Xi_outflow); - port_B_out.m_flow + port_B_in.m_flow = 0.0; - m_flowB * (inStream(port_B_in.h_outflow) - port_B_out.h_outflow) = -Q_flow; - port_B_out.Xi_outflow = inStream(port_B_out.Xi_outflow); - -annotation(Documentation(info = " - - - DryExchanger - - - - - -

- This component models a dry heat exchange. It is a duplication of the component HeatExchanger - from the HeatTransfer package adapted to use fluidports. -

- - -")) ; - -end AnalyticExchanger; diff --git a/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow.mo b/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow.mo deleted file mode 100644 index 1a2695d..0000000 --- a/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow.mo +++ /dev/null @@ -1,137 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Machines.BaseClasses.PumpCharacteristics; - -function polynomialFlow - import Modelica.Math.Vectors ; - - extends Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.baseFlow ; - - input Modelica.SIunits.VolumeFlowRate V_flow_nominal[:] - "Volume flow rate for N operating points (single pump)" annotation(Dialog); - input Modelica.SIunits.Position head_nominal[:] "Pump head for N operating points" annotation(Dialog); - input Integer OrderPolyFitting(max = 3) = 3 "Order of the polynom that fits the fan curve"; - - protected - Integer N = size(V_flow_nominal,1) "Number of nominal operating points"; - Real[OrderPolyFitting + 1] coeff "[^0,^1,^2,...,^OrderPolyFitting]"; - Real[N, OrderPolyFitting + 1] A ; - Modelica.SIunits.VolumeFlowRate V_flow_min = min(V_flow_nominal); - Modelica.SIunits.VolumeFlowRate V_flow_max = max(V_flow_nominal); - Modelica.SIunits.Position head_min "Head from the fitting at V_flow_min "; - Modelica.SIunits.Position head_max "Head from the fitting at V_flow_max "; - Real poly ; - -algorithm -// Initialisation - poly := 0.0 ; - -// - //A := {{V_flow_nominal[i]^(j-1) for i in 1:N} for j in 1:OrderPolyFitting + 1}; - for j in 1:OrderPolyFitting + 1 loop - for i in 1:N loop - A[i, j] := V_flow_nominal[i] ^(j - 1); - end for; - end for; - -// Compute the coefficient to fit the curve - -coeff := Modelica.Math.Matrices.leastSquares(A = A, b = head_nominal); - -// Compute the minimal head with the fitting coefficients - poly := coeff[OrderPolyFitting+1] ; - for i in 1:OrderPolyFitting loop - poly := poly * V_flow_min + coeff[OrderPolyFitting+1-i] ; - end for ; - head_min := poly ; - -// Compute the maximal head with the fitting coefficients - poly := coeff[OrderPolyFitting+1] ; - for i in 1:OrderPolyFitting loop - poly := poly * V_flow_max + coeff[OrderPolyFitting+1-i] ; - end for ; - head_max := poly ; - - if V_flow >= V_flow_max then /* Linear extrapolation until zero head */ - // poly is the derivative of the curve at V_flow_max - poly := coeff[OrderPolyFitting+1] * (OrderPolyFitting) ; - for i in 1:OrderPolyFitting-1 loop - poly := poly * V_flow_max + coeff[OrderPolyFitting+1-i] * (OrderPolyFitting-i) ; - end for ; - head := head_max + (V_flow - V_flow_max) * poly ; - if head < 0.0 then // head is threshold at 0.0 ; - head := 0.0 ; - end if ; - - elseif V_flow <= V_flow_min and V_flow > 0.0 then /* Linear extrapolation */ - // poly is the derivative of the curve at V_flow_min - poly := coeff[OrderPolyFitting+1] * (OrderPolyFitting) ; - for i in 1:OrderPolyFitting-1 loop - poly := poly * V_flow_min + coeff[OrderPolyFitting+1-i] * (OrderPolyFitting-i) ; - end for ; - head := head_min + (V_flow - V_flow_min) * poly ; - - elseif V_flow <= 0.0 then - if V_flow_min <= 0.0 then - head := coeff[1] ; - - else - // poly is the derivative of the curve at V_flow_min - poly := coeff[OrderPolyFitting+1] * (OrderPolyFitting) ; - for i in 1:OrderPolyFitting-1 loop - poly := poly * V_flow_min + coeff[OrderPolyFitting+1-i] * (OrderPolyFitting-i) ; - end for ; - head := head_min + (0 - V_flow_min) * poly ; - end if ; - - else - poly := coeff[OrderPolyFitting+1] ; - for i in 1:OrderPolyFitting loop - poly := poly * V_flow + coeff[OrderPolyFitting+1-i] ; - end for ; - - head := poly ; - if head < 0.0 then // head is threshold at 0.0 ; - head := 0.0 ; - end if ; - - end if ; - -annotation( - inverse(V_flow = polynomialFlow_inv(V_flow_nominal=V_flow_nominal, - head_nominal = head_nominal, - head = head, - OrderPolyFitting = OrderPolyFitting)), - Documentation(info = " - - - polynomialFlow - - - - -

- This function computes the head in meter supplied by a pump at a given volume flow rate V_flow from a polynomial fitting of the pump curve. -

- -

- The fitting is carried out from nominal inputs of the volume flow rate and the head (V_flow_nominal and head_nominal) via the least squares method. - The order of the polynom that fits the curve is settable via the input OrderPolyFitting but cannot go over the third order. -

- -

-

  • If the input V_flow is out of the range of the input nominal data V_flow_nominal, a linear extrapolation is performed. -

    - -

    -

  • If V_flow <= 0 the head remains at head = f(V_flow = 0). This condition is prior to the bullet point above. -

    - -

    -

  • If the head computed by the polynom or by the extrapolation combined with the polynom goes bellow 0, the heat is threshold at 0 ( head ⩾ 0). -

    - - -") ) ; - -end polynomialFlow; diff --git a/FluidDynamics/Components/Machines/ControlledVolumeFlowPump.mo b/FluidDynamics/Components/Machines/ControlledVolumeFlowPump.mo deleted file mode 100644 index 0986508..0000000 --- a/FluidDynamics/Components/Machines/ControlledVolumeFlowPump.mo +++ /dev/null @@ -1,151 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Machines; - -model ControlledVolumeFlowPump "Pump with controlled volume flow rate" - - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - - // User defined parameters - parameter Boolean Fan = false "If true fan icon else pump icon" annotation(Evaluate=true, HideResult=true, choices(checkBox=true)) ; - parameter Boolean checkValve = false "= true to prevent reverse flow" annotation( - Dialog(group = "Assumptions"), - Evaluate = true) ; - parameter Boolean use_V_flow_set = false "= true to use input signal V_flow_set instead of V_flow_nominal"; - parameter Modelica.SIunits.VolumeFlowRate V_flow_nominal "Nominal volume flow rate, fixed if not use_V_flow_set"; - parameter Modelica.SIunits.Efficiency eta = 0.8 "Isentropic efficiency" ; - -// Internal variables - Modelica.SIunits.VolumeFlowRate V_flow "Volume flow rate at port_a" ; - Modelica.SIunits.MassFlowRate m_flow "Mass flow rate" ; - Modelica.SIunits.Power P "Power given to the fluid" ; - Modelica.SIunits.Density d "Density at port_a"; - Modelica.SIunits.Position head "Pump head"; - Modelica.SIunits.PressureDifference dp "Pressure difference between port_a and port_b" ; - Medium.ThermodynamicState state "State at inlet" ; - - // Imported modules - Modelica.Blocks.Interfaces.RealInput V_flow_set if use_V_flow_set "Prescribed mass flow rate" annotation ( - Placement(visible = true, transformation(origin = {0, 100}, extent = {{-20, -20}, {20, 20}}, rotation = -90), iconTransformation(extent = {{-20, 80}, {20, 120}}, rotation = -90))); - Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium, m_flow(min = if not checkValve then -Modelica.Constants.inf else 0)) annotation( - Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium, m_flow(max = if not checkValve then +Modelica.Constants.inf else 0)) annotation( - Placement(visible = true, transformation(origin = {100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -protected - Modelica.Blocks.Interfaces.RealInput V_flow_set_internal "Needed to connect to conditional connector" ; - -equation -// Internal connector value when use_m_flow_set = false - if not use_V_flow_set then - V_flow_set_internal = V_flow_nominal; - end if; - connect(V_flow_set, V_flow_set_internal) annotation( - Line); - -// Get the state at inlet - state = Medium.setState_phX(p = port_a.p, h = if checkValve then inStream(port_a.h_outflow) else actualStream(port_a.h_outflow)); - -// - dp = port_a.p - port_b.p ; - V_flow = V_flow_set_internal ; - V_flow = m_flow / d ; - d = Medium.density(state) ; - head = -dp/(d*Modelica.Constants.g_n) ; - P = -dp*V_flow/eta; - -// Ports handover - // port_a - port_a.m_flow = m_flow; - port_a.h_outflow = if checkValve then inStream(port_a.h_outflow) else inStream(port_b.h_outflow) ; - port_a.Xi_outflow = if checkValve then inStream(port_a.Xi_outflow) else inStream(port_b.Xi_outflow) ; - port_a.C_outflow = if checkValve then inStream(port_a.C_outflow) else inStream(port_b.C_outflow) ; - // port_b - port_a.m_flow + port_b.m_flow = 0.0 ; - port_b.h_outflow = noEvent(if abs(m_flow)>10*Modelica.Constants.eps then P/m_flow+inStream(port_a.h_outflow) else inStream(port_a.h_outflow)); - port_b.Xi_outflow = inStream(port_a.Xi_outflow) ; - port_b.C_outflow = inStream(port_a.C_outflow) ; - - annotation( - defaultComponentName="pump", - Documentation(info = -" -

    - This model describes a pump with ideally controlled volume flow rate. -

    -

    - The input connectors V_flow_set can optionally be enabled via use_V_flow_set to provide time varying set points. -

    -

    - Use this model if the pump characteristics is of secondary interest. - The actual characteristics can be configured later on for the appropriate rotational speed N. - Then the model can be replaced with a PrescribedPump. -

    -"), - Icon(graphics = { - Polygon( - lineColor = {0, 0, 255}, - pattern = LinePattern.None, - fillPattern = FillPattern.VerticalCylinder, - points = {{-48, -60}, {-72, -100}, {72, -100}, {48, -60}, {-48, -60}}), - Rectangle( - fillColor = {0, 127, 255}, - fillPattern = FillPattern.HorizontalCylinder, - extent = {{-100, 46}, {100, -46}}), - Ellipse( - visible = Fan, - lineColor = {0, 0, 127}, - fillColor = {255, 255, 255}, - fillPattern = FillPattern.Solid, - lineThickness = 0.5, - extent = {{-80, 80}, {80, -80}}, - endAngle = 360), - Polygon( - visible = Fan, - origin = {0, 39}, - fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, - lineThickness = 0.5, - points = {{0, -39}, {-12, 35}, {0, 39}, {12, 35}, {0, -39}}), - Polygon( - visible = Fan, - origin = {40, -1}, - rotation = -90, - fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, - lineThickness = 0.5, - points = {{0, -39}, {-12, 35}, {0, 39}, {12, 35}, {0, -39}}), - Polygon( - visible = Fan, - origin = {0, -39}, - rotation = 180, - fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, - lineThickness = 0.5, - points = {{0, -39}, {-12, 35}, {0, 39}, {12, 35}, {0, -39}}), - Polygon( - visible = Fan, - origin = {-40, -1}, - rotation = 90, - fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, - lineThickness = 0.5, points = {{0, -39}, {-12, 35}, {0, 39}, {12, 35}, {0, -39}}), - Ellipse( - visible = Fan, - origin = {0, -2}, - fillColor = {182, 182, 182}, - fillPattern = FillPattern.Sphere, - lineThickness = 1, - extent = {{-10, -10}, {10, 10}}, - endAngle = 360), - Ellipse( - visible = not Fan, - extent={{-80,80},{80,-80}}, - fillPattern=FillPattern.Sphere, - fillColor={0,100,199}), - Polygon( - visible = not Fan, - points={{-28,30},{-28,-30},{50,-2},{-28,30}}, - pattern=LinePattern.None, - fillPattern=FillPattern.HorizontalCylinder, - fillColor={255,255,255})})) ; - -end ControlledVolumeFlowPump; diff --git a/FluidDynamics/Components/Machines/PrescribedPump.mo b/FluidDynamics/Components/Machines/PrescribedPump.mo deleted file mode 100644 index 18ea7a5..0000000 --- a/FluidDynamics/Components/Machines/PrescribedPump.mo +++ /dev/null @@ -1,37 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Machines; - -model PrescribedPump "Pump with ideally controlled speed" - - extends BaseClasses.PartialPump ; - -//User defined parameters - parameter Boolean use_N_in = false "Get the rotational speed from the input connector" ; - parameter Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm N_const = N_nominal "Constant rotational speed" annotation(Dialog(enable = not use_N_in)); - -//Imported modules - Modelica.Blocks.Interfaces.RealInput N_in(unit="rev/min") if use_N_in "Prescribed rotational speed" annotation (Placement(transformation( - extent={{-20,-20},{20,20}}, - rotation=-90, - origin={0,100}), iconTransformation( - extent={{-20,-20},{20,20}}, - rotation=-90, - origin={0,100}))); - -protected - Modelica.Blocks.Interfaces.RealInput N_in_internal(unit="rev/min") - "Needed to connect to conditional connector"; - -equation - // Connect statement active only if use_p_in = true - connect(N_in, N_in_internal); - - // Internal connector value when use_p_in = false - if not use_N_in then - N_in_internal = N_const; - end if; - - // Set N with a lower limit to avoid singularities at zero speed - N = max(N_in_internal,1e-3) "Rotational speed"; - - -end PrescribedPump; diff --git a/FluidDynamics/Components/Orifices/OpeningAnalytic.mo b/FluidDynamics/Components/Orifices/OpeningAnalytic.mo deleted file mode 100644 index 9ac5078..0000000 --- a/FluidDynamics/Components/Orifices/OpeningAnalytic.mo +++ /dev/null @@ -1,99 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Orifices; - -model OpeningAnalytic - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - - // User defined parameters - parameter Real Cd = 0.61 "discharge coefficient"; - parameter Modelica.SIunits.CrossSection A = 1 "Opening cross section"; - parameter Modelica.SIunits.Height H = 1 "Opening's Height"; - parameter Modelica.SIunits.Length Alt_a = 1.0 "Altitude of port_a"; - parameter Modelica.SIunits.Length Alt_b = 1.0 "Altitude of port_b"; - parameter Modelica.SIunits.Length Alt_opening = 1.0 "Altitude at the opening center"; - - // Internal variables - Modelica.SIunits.Pressure p_a "Pressure of node connected to port_a"; - Modelica.SIunits.Pressure p_b "Pressure of node connected to port_b"; - Modelica.SIunits.PressureDifference dp; - Modelica.SIunits.Density rho_A,rho_B; - Medium.Density[Medium.nX] rho_up, rho_down "Upstream density in upper and lower part of the opening"; - Medium.MassFraction[Medium.nX] X_up, X_down; - Modelica.SIunits.Height HN "Heigh of the point where flow switches in direction (zero flow)"; - Medium.ThermodynamicState state_a, state_b; - Modelica.SIunits.MassFlowRate m_flow_up, m_flow_down "mass flow rate in upper and lower part of the opening"; - - // Imported modules - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-58, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {38, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -protected - Modelica.SIunits.SpecificEnthalpy h_a "Specific enthalpy from port_a" ; - Modelica.SIunits.SpecificEnthalpy h_b "Specific enthalpy from port_b" ; - parameter Modelica.SIunits.Velocity Vel_small = 0.001 ; - constant Modelica.SIunits.Acceleration g = Modelica.Constants.g_n "Gravitational acceleration"; - -equation -// - state_a = Medium.setState_dTX(d = sum(port_a.d), T = port_a.T, X = port_a.d / sum(port_a.d)); - state_b = Medium.setState_dTX(d = sum(port_b.d), T = port_b.T, X = port_b.d / sum(port_b.d)); - -// pressure reconstruction - p_a = Medium.pressure(state_a) + sum(port_a.d) * g * (Alt_a-Alt_opening); - p_b = Medium.pressure(state_b) + sum(port_b.d) * g * (Alt_b-Alt_opening); - dp = p_a - p_b; - -// specific enthalpy reconstruction - h_a = Medium.specificEnthalpy(state_a); - h_b = Medium.specificEnthalpy(state_b); - -// density - rho_A = sum(port_a.d); - rho_B = sum(port_b.d); - -// upsteam density - rho_up = smooth(1, if dp - (sum(port_a.d) - sum(port_b.d)) * g * (H - HN) > 0 then port_a.d else port_b.d); - rho_down = port_a.d + port_b.d - rho_up; - -// upstream mass fraction - X_up = rho_up / sum(rho_up); - X_down = port_a.d/rho_A + port_b.d/rho_B - X_up; - -// altidude of change in direction of flow (if change happens) - HN = min(max(dp / ((rho_A - rho_B) * g) + H/2, 0), H); - -// m_flow = f(dp, Δρ, ΔH) - m_flow_up = Cd * A/H * sqrt(2 * sum(rho_up)) * ( Modelica.Fluid.Utilities.regRoot(x=dp, delta=1e-3) * (H - HN) - Modelica.Fluid.Utilities.regRoot(x=(rho_A - rho_B) * g, delta=1e-3) * 2/3 * (H-HN)^(3/2) ); - m_flow_down = Cd * A/H * sqrt(2 * sum(rho_down)) * ( Modelica.Fluid.Utilities.regRoot(x=dp, delta=1e-3) * (- HN) - Modelica.Fluid.Utilities.regRoot(x=(rho_A - rho_B) * g, delta=1e-3) * 2/3 * (-HN^(3/2)) ); - -// Port handover - port_a.m_flow = m_flow_up * X_up + m_flow_down * X_down ; - port_a.m_flow + port_b.m_flow = fill(0.0, Medium.nX); - - port_a.H_flow = semiLinear(m_flow_up, h_a + g * (Alt_a - Alt_b), h_b - g * (Alt_a - Alt_b)); - port_a.H_flow + port_b.H_flow = 0; - - annotation( - Icon(graphics = {Line(origin = {0, 69.8886}, points = {{0, 30}, {0, -30}}, thickness = 2), Line(origin = {0, -70}, points = {{0, 30}, {0, -30}}, thickness = 2)}, coordinateSystem(initialScale = 0.1)), - experiment(StartTime = 0, StopTime = 1000, Tolerance = 1e-06, Interval = 1), - Documentation(info = " - - Opening - - - -

    - This components allows to model the mass flow rate through from either static boundary pressure difference or buoyancy effect through a vertical orifice in a wall spliting two ambiances. -

    - -

    - To be considered as an orifice, the depth of the hole in the wall has to remain bellow the hydrodynamic entrance region (Distance between the entrance of the hole and the position where the dynamic boundary layers meet). -

    - -

    - See demonstration. -

    -")); - -end OpeningAnalytic; \ No newline at end of file diff --git a/FluidDynamics/Components/Pipes/DynamicPipe.mo b/FluidDynamics/Components/Pipes/DynamicPipe.mo deleted file mode 100644 index 93576ab..0000000 --- a/FluidDynamics/Components/Pipes/DynamicPipe.mo +++ /dev/null @@ -1,166 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Pipes; - -model DynamicPipe - // Imports - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - -// Medium - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - // User defined parameters - parameter Modelica.SIunits.Area A "Inner cross section area" annotation( - Dialog(group = "Geometry")); - parameter Modelica.SIunits.Length L "Pipe length" annotation( - Dialog(group = "Geometry")); - parameter Integer N = 3 "Number of discrete layers" ; - parameter Real ksi = 1 "dynamic pressure loss" annotation( - Dialog(group = "Flow")); - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance"; - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial"; - parameter Dynamics massDynamics = Dynamics.SteadyStateInitial "Formulation of mass balance"; - parameter Modelica.SIunits.Temperature X_start[:] = Medium.X_default "Start value for mass fractions, if massDynamics = FixedInitial"; - // Internal variables - Modelica.SIunits.Density d_a "Density if flow positive at port_a" ; - Modelica.SIunits.Density d_b "Density if flow positive at port_b" ; - Modelica.SIunits.PressureDifference dp; - Modelica.SIunits.Velocity Vel; - Modelica.SIunits.MassFlowRate m_flow "Aperture flow kg/s"; - // Imported Modules - Modelica.Fluid.Interfaces.FluidPort_a port_a(replaceable package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_b(replaceable package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.PDE.Transport.UpwindFirstOrder transport[2]( - each N=N, - each CoeffSpaceDer=Vel, - each x = linspace(0.0, L, N+1), - each SourceTerm = fill(0.0, N), - N_quantity = {1, Medium.nXi}) annotation( - Placement(visible = true, transformation(origin = {0, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); - -initial equation - - if energyDynamics == Dynamics.SteadyStateInitial then - der(transport[1].u[:,1])= fill(0.0, N); - - elseif energyDynamics == Dynamics.FixedInitial then - for i in 1:N loop - transport[1].u[i,1]= Medium.specificEnthalpy_pTX( - p = port_a.p, - T = T_start, - X = {0.00767631} ); - end for; - - elseif energyDynamics == Dynamics.SteadyState then - assert(false, "SteadyState pipe is not model, use rather static pipe module", level = AssertionLevel.error); - - end if ; - - if massDynamics == Dynamics.SteadyStateInitial then - for index in 1:Medium.nXi loop - der(transport[2].u[1:N,index])= fill(0.0, N); - end for; - - elseif massDynamics == Dynamics.FixedInitial then - transport[2].u[1:N,1:Medium.nXi]=fill(X_start[1:Medium.nXi], N); - - elseif massDynamics == Dynamics.SteadyState then - assert(false, "SteadyState pipe is not modelled, use rather static pipe module", level = AssertionLevel.error); - - end if ; - -equation -// mass balance - d_a = Medium.density_phX(p = port_a.p, h = inStream(port_a.h_outflow), X = cat(1, inStream(port_a.Xi_outflow), {1 - sum(inStream(port_a.Xi_outflow))})); - d_b = Medium.density_phX(p = port_b.p, - h = inStream(port_b.h_outflow), - X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))})) ; -// momentum - dp = port_a.p - port_b.p; - Vel =Modelica.Fluid.Utilities.regRoot2(x = dp, - x_small = 0.01, - k1 = 2.0 / (ksi*d_a), - k2 = 2.0 / (ksi*d_b)) ; - Vel * d_a * A = m_flow ; -// Transports of enthalpy - // boundary equations - transport[1].u_ghost_left[1] = inStream(port_a.h_outflow) "left boundary equation"; - transport[1].u_ghost_right[1] = inStream(port_b.h_outflow) "right boundary equation"; - -// Transports of mass - // boundary equations - transport[2].u_ghost_left[1:Medium.nXi] = inStream(port_a.Xi_outflow) "left boundary equation"; - transport[2].u_ghost_right[1:Medium.nXi] = inStream(port_b.Xi_outflow) "right boundary equation"; - -// Ports handover - port_a.m_flow = m_flow; - port_a.m_flow + port_b.m_flow = 0.0; - port_a.h_outflow = transport[1].u[1,1]; - port_b.h_outflow = transport[1].u[N,1]; - port_a.Xi_outflow = transport[2].u[1,1:Medium.nXi]; - port_b.Xi_outflow = transport[2].u[N,1:Medium.nXi]; - - annotation (defaultComponentName="dynamicPipe", -Documentation(info =" - - - StaticPipe - - - -

    - This components allows to model the mass flow rate through a pipe from a pressure difference at boundaries and the pressure loss coefficient ksi. -

    - -

    - Compared with a static pipe, the following assumptions are performed: -

      -
    1. The mass balance is assumed quasi-static -
    2. Density is assumed constant along the exchanger
    3. -
        -
      • Mass conservation within the control volume is not respected
      • -
      • Change of kinetic energy from contraction or expansion in neglected
      • -
      • Change of temperature from kinetic energy variation is neglected
      • -
      -
    -

    - -

    - ksi expresses how many dynamic pressure is lost. - It is assumed to be constant and therefore independent of the flow regime. -

    - - - -

    - The mass flow rate relation derives: -

    - - - -

    - Where: -

      -
    • dp is the pressure difference between port_a.p and port_b.p
    • -
    • ksi is the pressure loss coefficient
    • -
    • d is the upstream density
    • -
    • Vel is fluid velocity
    • -
    • m_flow is the mass flow rate through the pipe
    • -
    • A is cross section of the pipe
    • -
    -

    - -

    - To avoid infinite derivative at dp=0, The square root is replaced by the function regRoot2 of the MSL that replace the square root by a polynomial expression to insure a finite derivative. The threshold to switch between the polynom and the square root is abs(dp≤0.1) Pa -

    - -"), -Icon(coordinateSystem( - preserveAspectRatio=false, - extent={{-100,-100},{100,100}}), graphics={Rectangle(fillColor = {95, 95, 95}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-100, 40}, {100, -40}}), Rectangle(fillColor = {0, 127, 255}, fillPattern = FillPattern.HorizontalCylinder, extent = {{-100, 44}, {100, -44}}), Line(origin = {-40, 12}, points = {{0, 30}, {0, -54}}, color = {150, 150, 150}, thickness = 2), Line(origin = {40, 12}, points = {{0, 30}, {0, -54}}, color = {150, 150, 150}, thickness = 2), Text(origin = {-66, 0}, lineColor = {255, 255, 255}, extent = {{-20, 40}, {20, -40}}, textString = "1"), Text(origin = {66, 0}, lineColor = {255, 255, 255}, extent = {{-20, 40}, {20, -40}}, textString = "N"), Text(lineColor = {255, 255, 255}, extent = {{-20, 40}, {20, -40}}, textString = "...")}), - experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.002)); - -end DynamicPipe; diff --git a/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/polynomial.mo b/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/polynomial.mo deleted file mode 100644 index 7d3c71c..0000000 --- a/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/polynomial.mo +++ /dev/null @@ -1,20 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses.ValveCharacteristics; - -function polynomial "Polynomial characteristic: rc = c[1] + c[2]*pos + c[3]*pos^2 + ...." - extends baseFunc ; - input Real c[:] "Polynomial coefficients"; - -algorithm - - rc := c[size(c, 1)]; - for i in size(c, 1)-1:-1:1 loop - rc := c[i] + pos*rc; - end for; - - annotation (Documentation(info=" -

    -Evaluate a polynomial using Horner's scheme. -

    -")) ; - -end polynomial; diff --git a/FluidDynamics/Components/Valves/BaseClasses/package.mo b/FluidDynamics/Components/Valves/BaseClasses/package.mo deleted file mode 100644 index 72d7159..0000000 --- a/FluidDynamics/Components/Valves/BaseClasses/package.mo +++ /dev/null @@ -1,5 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Components.Valves; - -package BaseClasses "Base classes used in the Valves package (only of interest to build new component models)" - extends Modelica.Icons.BasesPackage; -end BaseClasses; diff --git a/FluidDynamics/Sources/Atmosphere.mo b/FluidDynamics/Sources/Atmosphere.mo deleted file mode 100644 index a4dc881..0000000 --- a/FluidDynamics/Sources/Atmosphere.mo +++ /dev/null @@ -1,123 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Sources; - -model Atmosphere - // Medium declaration - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - /*Get TAeZoSysPro reference moist air Media*/ - package Medium_MoistAirTAezo=TAeZoSysPro.Media.Air.MoistAir; - -// User defined parameters - parameter Boolean use_p_in = false "Get the pressure from the input connector" annotation( - Evaluate=true, HideResult=true, choices(checkBox=true)); - parameter Boolean use_T_in = false "Get the temperature from the input connector" annotation( - Evaluate=true, HideResult=true, choices(checkBox=true)) ; - parameter Boolean use_RH_in = false "Get the relative humidity from the input connector" annotation( - Evaluate=true, HideResult=true, choices(checkBox=true)) ; - - parameter Modelica.SIunits.Temperature T = 293.15 "Atmosphere temperature" ; - parameter Modelica.SIunits.Pressure p = 101325 "Atmosphere Pressure" ; - parameter Real RH = 0.6 "Atmosphere relative humidity - Only accounted if medium == Moist air" ; - parameter Medium.MassFraction X[Medium.nX] = Medium.X_default "usefull except for Moist Air"; - - parameter Integer nPorts = 0 "Number of fluidport" annotation(Dialog(connectorSizing=true)); - // Internal variables - Medium.ThermodynamicState state ; - -// Imported module - Modelica.Fluid.Interfaces.FluidPort_a[nPorts] Fluidport(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {-30, 26}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b Flowport(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {-26, -46}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b Heatport annotation( - Placement(visible = true, transformation(origin = {-44, -14}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput p_in if use_p_in annotation( - Placement(visible = true, transformation(origin = {-72, 56}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-95, 59}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput T_in if use_T_in annotation( - Placement(visible = true, transformation(origin = {-74, 14}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-95, -1}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput RH_in if use_RH_in annotation( - Placement(visible = true, transformation(origin = {-70, -30}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-95, -61}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); - -protected - /*Using TAeZoSysPro medium function ensure no fail with new OM frontend (function exist whatever medium used*/ - TAeZoSysPro.Media.Air.MoistAir.MassFraction X_moist[TAeZoSysPro.Media.Air.MoistAir.nX] ; - - /*depending on chosen medium, parameter X vector to be adjusted*/ - Medium.MassFraction X_final[Medium.nX] ; - - Modelica.Blocks.Interfaces.RealInput T_internal - "Temperature at ports. Needed to connect to conditional connector"; - Modelica.Blocks.Interfaces.RealInput p_internal - "Pressure at ports. Needed to connect to conditional connector"; - Modelica.Blocks.Interfaces.RealInput RH_internal - "Relative humidity at ports. Needed to connect to conditional connector"; - -equation - connect(T_internal, T_in) ; - connect(p_internal, p_in) ; - connect(RH_internal, RH_in) ; - - if not use_p_in then - p_internal = p; - end if; - - if not use_T_in then - T_internal = T; - end if; - - if not use_RH_in then - RH_internal = RH; - end if; - - X_moist= cat(1, {TAeZoSysPro.Media.Air.MoistAir.massFraction_pTphi(p = p_internal, T = T_internal, phi = RH_internal)}, {1-TAeZoSysPro.Media.Air.MoistAir.massFraction_pTphi(p = p_internal, T = T_internal, phi = RH_internal)}); - X_final= if Medium.mediumName =="Moist air" then X_moist else X; - state = Medium.setState_pTX(p = p_internal, - T = T_internal, - X=X_final) ; - -// Ports handover -// Flowport - Flowport.T = T_internal; - Flowport.d = Medium.density(state) * X_final ; -// Heatport - Heatport.T = T_internal; -// Fluidport - for i in 1:nPorts loop - Fluidport[i].p = p_internal; - Fluidport[i].h_outflow = Medium.specificEnthalpy(state); - Fluidport[i].Xi_outflow = X_final[1:Medium.nXi]; - end for; - annotation( - Icon(coordinateSystem(initialScale = 0.1), graphics = {Ellipse(origin = {-8, 23}, extent = {{-52, 37}, {68, -83}}, endAngle = 360), Text(origin = {-65, 87}, extent = {{-35, 13}, {165, -7}}, textString = "P=%p"), Text(origin = {-37, 33}, extent = {{-63, 47}, {137, 27}}, textString = "T=%T"), Text(origin = {-17, -97}, extent = {{-83, 17}, {117, -3}}, textString = "RH=%RH")}), - Documentation(info = " - - - Atmosphere - - - -

    - This components supplies boundaries with prescribed temperature, pression and composition. -

    - -

    - If use_p_in is false (default option), the p parameter is used as boundary pressure, and the p_in input connector is disabled.
    - if use_p_in is true, then the p parameter is ignored, and the value provided by the input connector is used instead. -

    - -

    - The same thing goes for the temperature and composition. -

    - -

    - Note, that boundary temperature and mass fractions have only an effect if the mass flow is from the boundary into the port. - If mass is flowing from the port into the boundary, the boundary definitions, with exception of boundary pressure, do not have an effect. -

    - -

    - This module has been developped to be used with an Air or Moist air Media. Indeed, specific function are required when modelling moist air.
    - When modelling Moist Air, the atmosphere component can supply an over saturated ambiance (meanning that the ambiance contains liquid water = foggy). -

    - - -")); -end Atmosphere; diff --git a/FluidDynamics/Sources/Boundary_p.mo b/FluidDynamics/Sources/Boundary_p.mo deleted file mode 100644 index c20bc6c..0000000 --- a/FluidDynamics/Sources/Boundary_p.mo +++ /dev/null @@ -1,53 +0,0 @@ -within TAeZoSysPro.FluidDynamics.Sources; - -model Boundary_p "Boundary with prescribed pressure" - replaceable package Medium = Modelica.Media.Water.WaterIF97_ph - "Medium model within the source" annotation (choicesAllMatching=true); - parameter Integer nPorts=0 "Number of ports" annotation(Dialog(connectorSizing=true)); - parameter Boolean use_p_in = false - "Get the pressure from the input connector" - annotation(Evaluate=true, HideResult=true, choices(checkBox=true)); - parameter Medium.AbsolutePressure p = Medium.p_default - "Fixed value of pressure" - annotation (Dialog(enable = not use_p_in)); - Modelica.Blocks.Interfaces.RealInput p_in if use_p_in - "Prescribed boundary pressure" annotation ( - Placement(visible = true, transformation(extent = {{-140, 60}, {-100, 100}}, rotation = 0), iconTransformation(extent = {{-140, -18}, {-100, 22}}, rotation = 0))); - - Modelica.Fluid.Interfaces.FluidPorts_b ports[nPorts]( - redeclare each package Medium = Medium) annotation( - Placement(transformation(extent={{90,40},{110,-40}}))); - -protected - Modelica.Blocks.Interfaces.RealInput p_in_internal - "Needed to connect to conditional connector"; - -equation - connect(p_in, p_in_internal); - if not use_p_in then - p_in_internal = p; - end if; - for i in 1:nPorts loop - ports[i].p = p_in_internal; - ports[i].m_flow = 0.0; - ports[i].h_outflow = inStream(ports[i].h_outflow); - ports[i].Xi_outflow = inStream(ports[i].Xi_outflow); - ports[i].C_outflow = inStream(ports[i].C_outflow); - end for; - - annotation (defaultComponentName="boundary_p", - Documentation(info=" -

    -Component to set the pressure at ports. The m_flow is set to zero. The 'outflow' properties are set to 'inStream' properties. -

    -

    -This component is mainly used to set the pressure of a liquid node -

    - -"), - Icon(coordinateSystem( - preserveAspectRatio=true, - extent={{-100,-100},{100,100}}), graphics={Ellipse(fillColor = {0, 127, 255}, fillPattern = FillPattern.Sphere, extent = {{-100, 100}, {100, -100}}, endAngle = 360), - Text(lineColor = {0, 0, 255}, extent = {{-150, 120}, {150, 160}}, textString = "%name"), - Text(origin = {-4, -72},extent = {{-152, 134}, {-68, 94}}, textString = "p")})); -end Boundary_p; diff --git a/HeatTransfer/Components/FanVentilation.mo b/HeatTransfer/Components/FanVentilation.mo deleted file mode 100644 index 53edb37..0000000 --- a/HeatTransfer/Components/FanVentilation.mo +++ /dev/null @@ -1,127 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Components; -model FanVentilation - replaceable package Medium = TAeZoSysPro.Media.MyMedia "Medium in the component"; - - // User defined parameters - parameter Boolean Use_External_MassFlow = false; - parameter Modelica.SIunits.Power Q_flow_aero_nominal = 0 "Fan power given to fluid at nominal conditions"; - parameter Modelica.SIunits.VolumeFlowRate V_flow_nominal = 0 "Volume flow rate at nominal conditions"; - - // Internal variables - Modelica.SIunits.Power Q_flow_aero "Fan power given to fluid"; - Modelica.SIunits.SpecificHeatCapacity cp "Mean specific heat capacity"; - Modelica.SIunits.Density d; - Modelica.SIunits.MassFlowRate m_flow; - Modelica.SIunits.Energy E "Energy passed throught the component"; - // - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b annotation ( - Placement(visible = true, transformation(origin = {0, 98}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a annotation ( - Placement(visible = true, transformation(origin = {-1, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-101, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput m_flow_in if Use_External_MassFlow annotation ( - Placement(visible = true, transformation(origin = {-106, 78}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, 84}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput V_flow_in if not Use_External_MassFlow annotation ( - Placement(visible = true, transformation(origin = {-106, -40}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, -86}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -protected - Modelica.Blocks.Interfaces.RealInput m_flow_in_internal - "Needed to connect to conditional connector"; - Modelica.Blocks.Interfaces.RealInput V_flow_in_internal - "Needed to connect to conditional connector"; - -initial equation - E = 0.0; - -equation - connect(m_flow_in, m_flow_in_internal); - connect(V_flow_in, V_flow_in_internal); - - cp = Medium.specificHeatCapacityCp(Medium.setState_pTX(p = Medium.reference_p, T = (port_a.T + port_b.T)/2)); - - d = Medium.density_pTX(p = Medium.reference_p, T = port_a.T, X = Medium.reference_X); - - if Use_External_MassFlow then - m_flow = m_flow_in_internal; - V_flow_in_internal = m_flow_in_internal / d; - else - m_flow = V_flow_in_internal * d; - m_flow_in_internal = V_flow_in_internal * d; - end if; - -// Fan power - Q_flow_aero = Q_flow_aero_nominal * ((m_flow / d) / V_flow_nominal)^2; - -// Energy balance - port_b.Q_flow = m_flow * cp * (port_b.T - port_a.T) - Q_flow_aero; - der(E) = port_b.Q_flow; - -// ports handover - port_a.Q_flow = 0; - - annotation ( - Diagram(coordinateSystem(grid = {2, 2}, initialScale = 0.1)), - Icon(graphics={ Ellipse(lineThickness = 1, extent = {{-100, -100}, {100, 100}}, endAngle = 360), Ellipse(lineColor = {182, 182, 182}, - lineThickness = 2, extent = {{-98, -98}, {98, 98}}, endAngle = 360), Polygon(origin = {44.28, 19.95}, fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), Polygon(origin = {-43.72, -20.05}, rotation = 180, fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), Polygon(origin = {-19.72, 43.95}, rotation = 90, fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), Polygon(origin = {20.28, -44.05}, rotation = -90, fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), Ellipse(fillColor = {182, 182, 182}, - fillPattern = FillPattern.Sphere, - lineThickness = 1, extent = {{-10, -10}, {10, 10}}, endAngle = 360), Text(origin = {-82, 85}, extent = {{-10, 7}, {24, -7}}, textString = "[kg / s]", fontSize = 6), Text(origin = {-82, -81}, extent = {{-10, 5}, {26, -13}}, textString = "[m3 / s]", fontSize = 6)}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " - - - Ventilation - - - - -

    - This components computes the heat flow balance between the heat flow from the supply ventilation where fan in present between inlet conditions and the blowing in the control volume and the exhaust assuming steady pressure balance thus steady mass flow balance. -

    - -

    - Beacause of the thermal mode only, it assumes that the inlet mass flow rate is always equal to the outlet (the dynamic mass balance is reached generally much faster that the thermal balance). - The exhaust temperature is the temperature at port_b and the supply at port_a. -

    - -

    - It is assumed that the fan curve pressure vs volume flow rate is linear to the volume flow rate. - The aeraulic power is the product of the pressure difference at the boundary of the fan and the volume flow rate a suction. -

    - - - -

    - The enthalpy flow balance to the volume that receive mass derives: -

    - - - -

    - Where : -

      -
    • ∆p_fan is pressure difference at fan boundaries
    • -
    • a a is the proportionality coefficient between the pressure difference and the flow
    • -
    • V_flow is the volume flow rate at fan suction
    • -
    • H_flow is the enthalpy flow rate
    • -
    • m_flow is the mass flow rate
    • -
    • h is the specific enthalpy
    • -
    • cp is the specific heat capacity
    • -
    • T is the temperature
    • -
    -

    - -

    - It is supposed that the specific heat capacity varies linearly with the temperature therefore the mean specific capacity is the specific capacity at the mean temperature. -

    - - - - ")); -end FanVentilation; diff --git a/HeatTransfer/Components/HalfWall.mo b/HeatTransfer/Components/HalfWall.mo deleted file mode 100644 index 52e6b01..0000000 --- a/HeatTransfer/Components/HalfWall.mo +++ /dev/null @@ -1,155 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Components; - -model HalfWall - // - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - import TAeZoSysPro.HeatTransfer.Types.MeshGrid ; - import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid ; - - -//Media - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - // User defined parameters - parameter MeshGrid mesh = MeshGrid.biotAndGeometricalGrowth "Selection of meshing function" annotation( - Dialog(group="Meshing properties")); - parameter Real q = 1.2 "Growth rate (if geometricalGrowth chosen)" annotation( - Dialog(group="Meshing properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 "Decoupled value of the heat transfer (if biot segment chosen)" annotation( - Dialog(group="Meshing properties")); - parameter Integer N(min=1) = integer(max(1, 5 * Th / 0.2 * 1e-6 * d * cp / k)) "Number of layers : 1 to 65535" annotation( - Dialog(group="Meshing properties")); - - parameter Modelica.SIunits.Area A = 0 "Wall area " annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Height Lc = 0 "Wall characteristic length" annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Length Th = 0 "Wall thickness" annotation( - Dialog(group="Geometrical properties")); - - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance" annotation( - Dialog(group="Dynamic properties")); - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial" annotation( - Dialog(group="Dynamic properties")); - - parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 "Wall specific heat capacity" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.Density d(displayUnit="kg/m3") = 0 "Wall density" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.ThermalConductivity k = 0 "Wall conductivity" annotation( - Dialog(group="Thermal properties")); - - parameter Real add_on_conv = 1 "Custom add-on" annotation( - Dialog(group = "Convection properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE "free convection Correlation" annotation( - Dialog(group = "Convection properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Convection properties")); - // - parameter Modelica.SIunits.Emissivity eps = 0 "Wall emissivity " annotation( - Dialog(group = "Radiative properties")); - parameter Real add_on_rad = 1 "Custom add-on" annotation( - Dialog(group = "Radiative properties")); - -// Internal variables - Modelica.SIunits.BiotNumber Bi ; - -// Components inside wall are defined - TAeZoSysPro.HeatTransfer.BasesClasses.PartialWall partialWall(A = A, N = N, T_start = T_start, Th = Th, cp = cp, d = d, energyDynamics = energyDynamics, h = h, k = k, mesh = mesh, q = q, symmetricalMesh = false) if N>1 annotation( - Placement(visible = true, transformation(origin = {4.5, 22.5}, extent = {{-29.5, -29.5}, {29.5, 29.5}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection convection(redeclare - package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation, h_cv_const = h_cv_const) annotation ( - Placement(visible = true, transformation(origin = {-47, 70}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A, add_on = add_on_rad, eps = eps) annotation( - Placement(visible = true, transformation(origin = {-56.5, -70.5}, extent = {{-22.5, -22.5}, {22.5, 22.5}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_conv annotation( - Placement(visible = true, transformation(origin = {-101, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad annotation( - Placement(visible = true, transformation(origin = {-101, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall annotation( - Placement(visible = true, transformation(origin = {-92, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput F_view annotation( - Placement(visible = true, transformation(origin = {-90, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b annotation( - Placement(visible = true, transformation(origin = {99, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface annotation( - Placement(visible = true, transformation(origin = {-100, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start,cp = cp, energyDynamics = energyDynamics, m = Th * A * d) if N==1 annotation( - Placement(visible = true, transformation(origin = {4, -50}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); -equation - connect(port_surface, partialWall.port_a) annotation( - Line(points = {{-100, 30}, {-24, 30}, {-24, 22.5}}, color = {191, 0, 0})); - connect(port_a_conv, convection.port_b) annotation( - Line(points = {{-101, 70}, {-65, 70}}, color = {191, 0, 0})); - connect(convection.port_a, partialWall.port_a) annotation( - Line(points = {{-29, 70}, {-24, 70}, {-24, 22.5}}, color = {191, 0, 0})); - connect(F_view, carrollRadiation.Fview) annotation( - Line(points = {{-90, -30}, {-38.5, -30}, {-38.5, -52.5}}, color = {0, 0, 127})); - connect(port_a_rad, carrollRadiation.port_b) annotation( - Line(points = {{-101, -70}, {-88, -70}, {-88, -70.5}, {-79, -70.5}}, color = {191, 0, 0})); - connect(carrollRadiation.port_a, partialWall.port_a) annotation( - Line(points = {{-34, -70.5}, {-24, -70.5}, {-24, 22.5}}, color = {191, 0, 0})); - connect(partialWall.port_b, port_b) annotation( - Line(points = {{33, 22.5}, {68, 22.5}, {68, 0}, {100, 0}}, color = {191, 0, 0})); - - if N > 1 then - Bi = convection.h_cv*(partialWall.x[2]-partialWall.x[1]) / k ; - else - Bi = 0.0; - end if; - - -A_wall = A; - connect(convection.port_a, heatCapacitor.port) annotation( - Line(points = {{-28, 70}, {-24, 70}, {-24, -40}, {4, -40}}, color = {191, 0, 0})); - connect(port_surface, heatCapacitor.port) annotation( - Line(points = {{-100, 30}, {-24, 30}, {-24, -40}, {4, -40}}, color = {191, 0, 0})); - connect(carrollRadiation.port_a, heatCapacitor.port) annotation( - Line(points = {{-34, -70}, {-24, -70}, {-24, -40}, {4, -40}}, color = {191, 0, 0})); - connect(port_b, heatCapacitor.port) annotation( - Line(points = {{100, 0}, {68, 0}, {68, -40}, {4, -40}}, color = {191, 0, 0})); //output y is set to Awall and it can be connected to FviewCalculator - annotation( - Diagram(graphics = {Rectangle(origin = {3.5, -1}, fillColor = {218, 218, 218}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-42.5, 101}, {36.5, -99}}), Text(origin = {4, 58}, extent = {{-20, 10}, {20, -10}}, textString = "If N > 1"), Text(origin = {4, -28}, extent = {{-20, 10}, {20, -10}}, textString = "If N = 1")}, coordinateSystem(initialScale = 0.1)), - Icon(graphics = {Rectangle(origin = {11, 9}, fillColor = {191, 191, 191}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-51, 91}, {29, -109}}), Line(origin = {-70, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 88.1389}, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 54.1389}, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-93, 93}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "Fluid"), Text(origin = {-93, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Text(origin = {-73, -25}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view"), Text(origin = {-73, -49}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall"), Line(origin = {-52.1559, -79.8606}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52.5726, -99.7217}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " - - - HalfWall - - - - - - -

    - This component models the thermal response of half wall in interface with a rest ambiance where the thermal exchanges are mainly driven by natural convection and radiation. -

    - -

    - This component is an assembly of the PartialWall module, the FreeConvection module and a CarrollRadiation module. The solid wall is dicretises in N along its depth to model the heat propagation. By defaut the value of N is computed from the depth and the thermal diffusivty of the wall.
    - When the number of layers N is equal to one, the PartialWall is replaced by a HeatCapacitor. -

    - -

    - A port name port_surface is connected to the boundary port of the PartialWall. - It can be usefull for specific applications when another modules is required et can be latter connected to this empty heat port. -

    - -

    - The HalfWall supplies as output the surface area of the wall, via its A_wall port, to the FviewCalculator module and get from this last the form (or view) factor as input via the F_view port. The connection is performed explicitely via the graphic connectors. -

    - -"), - experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-06, Interval = 36)); - -end HalfWall; \ No newline at end of file diff --git a/HeatTransfer/Components/Ventilation.mo b/HeatTransfer/Components/Ventilation.mo deleted file mode 100644 index 90c87a2..0000000 --- a/HeatTransfer/Components/Ventilation.mo +++ /dev/null @@ -1,106 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Components; -model Ventilation - replaceable package Medium = TAeZoSysPro.Media.MyMedia "Medium in the component"; - // User defined parameters - parameter Boolean Use_External_MassFlow = false; - // Internal variables - Modelica.SIunits.SpecificHeatCapacity cp "Mean specific heat capacity"; - Modelica.SIunits.Density d; - Modelica.SIunits.MassFlowRate m_flow; - Modelica.SIunits.Energy E "Energy passed throught the component"; - // - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b annotation ( - Placement(visible = true, transformation(origin = {0, 98}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a annotation ( - Placement(visible = true, transformation(origin = {-1, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-101, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput m_flow_in if Use_External_MassFlow annotation ( - Placement(visible = true, transformation(origin = {-106, 78}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, 84}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput V_flow_in if not Use_External_MassFlow annotation ( - Placement(visible = true, transformation(origin = {-106, -40}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, -86}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -protected - Modelica.Blocks.Interfaces.RealInput m_flow_in_internal - "Needed to connect to conditional connector"; - Modelica.Blocks.Interfaces.RealInput V_flow_in_internal - "Needed to connect to conditional connector"; - -initial equation - E = 0.0; - -equation - connect(m_flow_in, m_flow_in_internal); - connect(V_flow_in, V_flow_in_internal); - - cp = Medium.specificHeatCapacityCp(Medium.setState_pTX(p = Medium.reference_p, T = (port_a.T + port_b.T)/2)); - - d = Medium.density_pTX(p = Medium.reference_p, T = port_a.T, X = Medium.reference_X); - - if Use_External_MassFlow then - m_flow = m_flow_in_internal; - V_flow_in_internal = m_flow_in_internal / d; - else - m_flow = V_flow_in_internal * d; - m_flow_in_internal = V_flow_in_internal * d; - end if; - - port_b.Q_flow = m_flow * cp * (port_b.T - port_a.T); - der(E) = port_b.Q_flow; - - // ports handover - port_a.Q_flow = 0; - - annotation ( - Diagram(coordinateSystem(grid = {2, 2}, initialScale = 0.1)), - Icon(graphics={ Ellipse(lineThickness = 1, extent = {{-100, -100}, {100, 100}}, endAngle = 360), Ellipse(lineColor = {182, 182, 182}, - lineThickness = 2, extent = {{-98, -98}, {98, 98}}, endAngle = 360), Polygon(origin = {44.28, 19.95}, fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), Polygon(origin = {-43.72, -20.05}, rotation = 180, fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), Polygon(origin = {-19.72, 43.95}, rotation = 90, fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), Polygon(origin = {20.28, -44.05}, rotation = -90, fillColor = {182, 182, 182}, - fillPattern = FillPattern.Solid, points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), Ellipse(fillColor = {182, 182, 182}, - fillPattern = FillPattern.Sphere, - lineThickness = 1, extent = {{-10, -10}, {10, 10}}, endAngle = 360), Text(origin = {-82, 85}, extent = {{-10, 7}, {24, -7}}, textString = "[kg / s]", fontSize = 6), Text(origin = {-82, -81}, extent = {{-10, 5}, {26, -13}}, textString = "[m3 / s]", fontSize = 6)}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " - - - Ventilation - - - - -

    - This components computes the heat flow balance between the heat flow from the supply ventilation and the exhaust assuming steady pressure balance thus steady mass flow balance. -

    - -

    - Beacause of the thermal mode only, it assumes that the inlet mass flow rate is always equal to the outlet (the dynamic mass balance is reached generally much faster that the thermal balance). - The exhaust temperature is the temperature at port_b and the supply at port_a. -

    - -

    - The enthalpy flow balance to the volume that receive mass derives: -

    - - - -

    - Where : -

      -
    • H_flow is the enthalpy flow rate
    • -
    • m_flow is the mass flow rate
    • -
    • h is the specific enthalpy
    • -
    • cp is the specific heat capacity
    • -
    • T is the temperature
    • -
    -

    - -

    - It is supposed that the specific heat capacity varies linearly with the temperature therefore the mean specific capacity is the specific capacity at the mean temperature. -

    - - - - ")); -end Ventilation; diff --git a/HeatTransfer/Components/VerticalOpening.mo b/HeatTransfer/Components/VerticalOpening.mo deleted file mode 100644 index ae3a783..0000000 --- a/HeatTransfer/Components/VerticalOpening.mo +++ /dev/null @@ -1,82 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Components; - -model VerticalOpening - replaceable package Medium = TAeZoSysPro.Media.MyMedia; - // - constant Modelica.SIunits.Acceleration g_n = Modelica.Constants.g_n; - constant Modelica.SIunits.Pressure p = Medium.reference_p "fluid pressure"; - parameter Boolean mass_conservation = true "If true, mass flow profile is assumed symmetrical from either side of the middle of the opening"; - parameter Real Cd = 0.61 "discharge coefficient"; - parameter Modelica.SIunits.CrossSection A = 1 "Opening's section"; - parameter Modelica.SIunits.Length H = 1 "Opening's Height"; - - // Internal variable - Medium.ThermodynamicState state_A; - Medium.ThermodynamicState state_B; - Modelica.SIunits.TemperatureDifference dT "port_a.T - port_b.T"; - Modelica.SIunits.Density rho_A,rho_B; - Modelica.SIunits.Density rho_up, rho_down "Upstream density in upper and lower part of the opening"; - Medium.SpecificEnthalpy h_A, h_B; - Modelica.SIunits.MassFlowRate m_flow_up, m_flow_down "mass flow rate in upper and lower part of the opening"; - Modelica.SIunits.Height HN "Heigh of the point where flow switches in direction (zero flow)"; - - // Imported components - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a annotation( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b annotation( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -equation -// - state_A = Medium.setState_pTX(p = p, T = port_a.T); - state_B = Medium.setState_pTX(p = p, T = port_b.T); -// state_Mean = Medium.setState_pTX(p = p, T = (Heatport_a.T+Heatport_b.T)/2); - dT = port_a.T - port_b.T; - rho_A = Medium.density(state_A); - rho_B = Medium.density(state_B); - rho_up = smooth(1, if port_a.T >= port_b.T then rho_A else rho_B); - rho_down = rho_A + rho_B - rho_up; - h_A = Medium.specificEnthalpy(state_A); - h_B = Medium.specificEnthalpy(state_B); - -// quasi static flow assumption. Analytic integration over the height of m_flow(z) = f(dp(z)) - m_flow_up = Cd * A/H * Modelica.Fluid.Utilities.regRoot( - x = 2 * rho_up * g_n * (rho_B - rho_A), - delta = 1e-3) * 2/3 * (H-HN)^(3/2); - m_flow_down = Cd * A/H * Modelica.Fluid.Utilities.regRoot( - x = 2 * rho_down * g_n * (rho_B - rho_A), - delta = 1e-3) * 2/3 * (-HN^(3/2)); - -// if mass_conservation then the heigh of the 0 flow is compute to insure that m_flow_up = m_flow_down in absolute value - HN = if mass_conservation then H / ( (rho_down/rho_up)^(1/3) + 1 ) else H/2; - -// port handover - port_a.Q_flow = smooth(0, if sign(port_a.T - port_b.T) > 0 then m_flow_down * (h_B - h_A) else m_flow_up * (h_B - h_A)); - port_b.Q_flow = smooth(0, if sign(port_a.T - port_b.T) > 0 then -m_flow_up * (h_A - h_B) else -m_flow_down * (h_A - h_B)); - - - annotation( - Icon(graphics = {Line(origin = {0, 69.8886}, points = {{0, 30}, {0, -30}}, thickness = 2), Line(origin = {0, -70}, points = {{0, 30}, {0, -30}}, thickness = 2)}, coordinateSystem(initialScale = 0.1)), - experiment(StartTime = 0, StopTime = 1000, Tolerance = 1e-06, Interval = 1), - Documentation(info = -" - - Vertical Opening - - - -

    - This module allows to model the net heat flow induces by air movement only from bouyancy through an opening that links two ambiances. -

    - -

    - See demonstration. -

    - -

    - When mass conservation is set to true, the height HN where the flow changes in direction is computed to insure that m_flow_up and m_flow_down are equal is absolute value. If not HN is equal to H/2 -

    - -")); - -end VerticalOpening; \ No newline at end of file diff --git a/HeatTransfer/Components/Wall.mo b/HeatTransfer/Components/Wall.mo deleted file mode 100644 index d93ba7b..0000000 --- a/HeatTransfer/Components/Wall.mo +++ /dev/null @@ -1,194 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Components; - -model Wall - // - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - import TAeZoSysPro.HeatTransfer.Types.MeshGrid ; - import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid ; - - -//Media - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - // User defined parameters - parameter MeshGrid mesh = MeshGrid.biotAndGeometricalGrowth "Selection of meshing function" annotation( - Dialog(group="Meshing properties")); - parameter Real q = 1.2 "Growth rate (if geometricalGrowth chosen)" annotation( - Dialog(group="Meshing properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 "Decoupled value of the heat transfer (if biot segment chosen)" annotation( - Dialog(group="Meshing properties")); - parameter Integer N(min=1) = integer(max(1, 5 * Th / 0.2 * 1e-6 * d * cp / k)) "Number of layers : 1 to 65535" annotation( - Dialog(group="Meshing properties")); - - parameter Modelica.SIunits.Area A = 0 "Wall area " annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Height Lc = 0 "Wall characteristic length" annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Length Th = 0 "Wall thickness" annotation( - Dialog(group="Geometrical properties")); - - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance" annotation( - Dialog(group="Dynamic properties")); - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial" annotation( - Dialog(group="Dynamic properties")); - - parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 "Wall specific heat capacity" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.Density d(displayUnit="kg/m3") = 0 "Wall density" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.ThermalConductivity k = 0 "Wall conductivity" annotation( - Dialog(group="Thermal properties")); - - parameter Real add_on_conv = 1 "Custom add-on" annotation( - Dialog(group = "Convection properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation_a = Correlations.vertical_plate_ASHRAE "free convection Correlation" annotation( - Dialog(group = "Convection properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation_b = if correlation_a == Correlations.ceiling_ASHRAE then Correlations.ground_ASHRAE elseif correlation_a == Correlations.ground_ASHRAE then Correlations.ceiling_ASHRAE else correlation_a "free convection Correlation" annotation( - Dialog(group = "Convection properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const_a = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Convection properties")); - - parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const_b = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Convection properties")); - // - parameter Modelica.SIunits.Emissivity eps_a = 0 "Wall emissivity " annotation( - Dialog(group = "Radiative properties")); - parameter Modelica.SIunits.Emissivity eps_b = 0 "Wall emissivity " annotation( - Dialog(group = "Radiative properties")); - parameter Real add_on_rad = 1 "Custom add-on" annotation( - Dialog(group = "Radiative properties")); - -// Internal variables - Modelica.SIunits.BiotNumber Bi_a, Bi_b ; - -// Components inside wall are defined - TAeZoSysPro.HeatTransfer.BasesClasses.PartialWall partialWall(A = A, N = N, T_start = T_start, Th = Th, cp = cp, d = d, energyDynamics = energyDynamics, h = h, k = k, mesh = mesh, q = q, symmetricalMesh = true) if N>1 annotation( - Placement(visible = true, transformation(origin = {0.5, 26.5}, extent = {{-29.5, -29.5}, {29.5, 29.5}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection freeConvection_a(redeclare package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation_a, h_cv_const = h_cv_const_a) annotation( - Placement(visible = true, transformation(origin = {-55, 70}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation_a(A = A, add_on = add_on_rad, eps = eps_a) annotation( - Placement(visible = true, transformation(origin = {-58.5, -70.5}, extent = {{-22.5, -22.5}, {22.5, 22.5}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_conv annotation( - Placement(visible = true, transformation(origin = {-101, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad annotation( - Placement(visible = true, transformation(origin = {-101, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall_a annotation( - Placement(visible = true, transformation(origin = {-92, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput F_view_a annotation( - Placement(visible = true, transformation(origin = {-90, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b_conv annotation( - Placement(visible = true, transformation(origin = {101, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface_a annotation( - Placement(visible = true, transformation(origin = {-100, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection freeConvection_b(redeclare package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation_b, h_cv_const = h_cv_const_b) annotation( - Placement(visible = true, transformation(origin = {57, 70}, extent = {{18, -18}, {-18, 18}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation_b(A = A, add_on = add_on_rad, eps = eps_b) annotation( - Placement(visible = true, transformation(origin = {59.5, -70.5}, extent = {{22.5, -22.5}, {-22.5, 22.5}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b_rad annotation( - Placement(visible = true, transformation(origin = {101, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall_b annotation( - Placement(visible = true, transformation(origin = {90, -2}, extent = {{10, -10}, {-10, 10}}, rotation = 180), iconTransformation(origin = {93, -53}, extent = {{7, -7}, {-7, 7}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput F_view_b annotation( - Placement(visible = true, transformation(origin = {92, -30}, extent = {{10, -10}, {-10, 10}}, rotation = 0), iconTransformation(origin = {93, -27}, extent = {{7, -7}, {-7, 7}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_surface_b annotation( - Placement(visible = true, transformation(origin = {99, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start,cp = cp, energyDynamics = energyDynamics, m = Th * A * d) if N==1 annotation( - Placement(visible = true, transformation(origin = {0, -46}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); -equation - connect(port_a_conv, freeConvection_a.port_b) annotation( - Line(points = {{-101, 70}, {-73, 70}}, color = {191, 0, 0})); - connect(port_a_rad, carrollRadiation_a.port_b) annotation( - Line(points = {{-101, -70}, {-88, -70}, {-88, -70.5}, {-81, -70.5}}, color = {191, 0, 0})); - if N > 1 then - Bi_a = freeConvection_a.h_cv * (partialWall.x[2] - partialWall.x[1]) / k; - Bi_b = freeConvection_b.h_cv * (partialWall.x[end] - partialWall.x[end-1]) / k; - else - Bi_a = 0.0; - Bi_b = 0.0; - end if; - - -A_wall_a = A; -A_wall_b = A; -//output y is set to Awall and it can be connected to FviewCalculator - connect(freeConvection_a.port_a, partialWall.port_a) annotation( - Line(points = {{-36, 70}, {-28, 70}, {-28, 26.5}}, color = {191, 0, 0})); - connect(carrollRadiation_a.port_a, partialWall.port_a) annotation( - Line(points = {{-36, -70.5}, {-28, -70.5}, {-28, 26.5}}, color = {191, 0, 0})); - connect(freeConvection_b.port_a, partialWall.port_b) annotation( - Line(points = {{39, 70}, {28, 70}, {28, 26.5}, {29, 26.5}}, color = {191, 0, 0})); - connect(carrollRadiation_b.port_a, partialWall.port_b) annotation( - Line(points = {{38, -70}, {28, -70}, {28, 26.5}, {29, 26.5}}, color = {191, 0, 0})); - connect(freeConvection_b.port_b, port_b_conv) annotation( - Line(points = {{75, 70}, {102, 70}}, color = {191, 0, 0})); - connect(carrollRadiation_b.port_b, port_b_rad) annotation( - Line(points = {{82, -70}, {100, -70}, {100, -70}, {102, -70}}, color = {191, 0, 0})); - connect(port_surface_a, partialWall.port_a) annotation( - Line(points = {{-100, 30}, {-28, 30}, {-28, 26.5}}, color = {191, 0, 0})); - connect(port_surface_b, partialWall.port_b) annotation( - Line(points = {{100, 30}, {28, 30}, {28, 26.5}, {29, 26.5}}, color = {191, 0, 0})); - connect(F_view_a, carrollRadiation_a.Fview) annotation( - Line(points = {{-90, -30}, {-42, -30}, {-42, -52}, {-40, -52}}, color = {0, 0, 127})); - connect(F_view_b, carrollRadiation_b.Fview) annotation( - Line(points = {{92, -30}, {44, -30}, {44, -52}, {42, -52}}, color = {0, 0, 127})); - connect(freeConvection_a.port_a, heatCapacitor.port) annotation( - Line(points = {{-36, 70}, {-28, 70}, {-28, -36}, {0, -36}}, color = {191, 0, 0})); - connect(port_surface_a, heatCapacitor.port) annotation( - Line(points = {{-100, 30}, {-28, 30}, {-28, -36}, {0, -36}}, color = {191, 0, 0})); - connect(carrollRadiation_a.port_a, heatCapacitor.port) annotation( - Line(points = {{-36, -70}, {-28, -70}, {-28, -36}, {0, -36}}, color = {191, 0, 0})); - connect(freeConvection_b.port_a, heatCapacitor.port) annotation( - Line(points = {{40, 70}, {28, 70}, {28, -36}, {0, -36}}, color = {191, 0, 0})); - connect(port_surface_b, heatCapacitor.port) annotation( - Line(points = {{100, 30}, {28, 30}, {28, -36}, {0, -36}}, color = {191, 0, 0})); - connect(carrollRadiation_b.port_a, heatCapacitor.port) annotation( - Line(points = {{38, -70}, {28, -70}, {28, -36}, {0, -36}}, color = {191, 0, 0})); - annotation( - Diagram(graphics = {Rectangle(origin = {3.5, -1}, fillColor = {218, 218, 218}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-42.5, 101}, {36.5, -99}}), Text(origin = {2, 60}, extent = {{-20, 10}, {20, -10}}, textString = "If N > 1"), Text(origin = {2, -26}, extent = {{-20, 10}, {20, -10}}, textString = "If N = 1")}, coordinateSystem(initialScale = 0.1)), - Icon(graphics = {Rectangle(origin = {11, 9}, fillColor = {191, 191, 191}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-51, 91}, {29, -109}}), Line(origin = {-70, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 88.1389}, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 54.1389}, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-93, 93}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "Fluid"), Text(origin = {-93, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Text(origin = {-73, -27}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view_a"), Text(origin = {-73, -49}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall_a"), Line(origin = {-52.1559, -79.8606}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52.5726, -99.7217}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {67, -47}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall_b"), Text(origin = {67, -27}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view_b"), Line(origin = {52.8486, -80.2659}, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {52.4319, -100.127}, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {68.8387, 69.7336}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {59.8387, 53.7336}, rotation = 180, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {59.8387, 87.7336}, rotation = 180, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {50.8387, 69.7336}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {87, 93}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "Fluid"), Text(origin = {87, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT")}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " - - - Wall - - - - - - -

    - This component models the thermal response of wall in interface with a rest ambiances where the thermal exchanges are mainly driven by natural convection and radiation. -

    - -

    - The suffix '..._a' refers to side where the ports 'port_a' are. -

    - -

    - This component is an assembly of the PartialWall module, the FreeConvection modules and a CarrollRadiation modules. The solid wall is dicretises in N along its depth to model the heat propagation. By defaut the value of N is computed from the depth and the thermal diffusivty of the wall.
    - When the number of layers N is equal to one, the PartialWall is replaced by a HeatCapacitor. -

    - -

    - Ports name port_surface are connected to boundary ports of the PartialWall. - It can be usefull for specific applications when another modules is required et can be latter connected to this empty heat port. -

    - -

    - The Wall supplies as output the surface area of the wall, via its A_wall ports, to the FviewCalculator module and get from this last the form (or view) factor as input via the F_view ports. The connection is performed explicitely via the graphic connectors. -

    - -"), - experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-06, Interval = 36)); - -end Wall; \ No newline at end of file diff --git a/HeatTransfer/Components/package.mo b/HeatTransfer/Components/package.mo deleted file mode 100644 index b525d77..0000000 --- a/HeatTransfer/Components/package.mo +++ /dev/null @@ -1,86 +0,0 @@ -within TAeZoSysPro.HeatTransfer; - -package Components - - extends Modelica.Icons.Package; - -annotation (Icon(coordinateSystem(preserveAspectRatio = true, extent = {{-100,-100},{100,100}}), graphics={ - Rectangle( - origin = {12,40}, - fillColor = {192,192,192}, - fillPattern = FillPattern.Backward, - extent = {{-100,-100},{-70,18}}), - Line( - origin = {12,40}, - points = {{-44,16},{-44,-100}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{-4,16},{-4,-100}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{30,18},{30,-100}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{66,18},{66,-100}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{66,-100},{76,-80}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{66,-100},{56,-80}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{30,-100},{40,-80}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{30,-100},{20,-80}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{-4,-100},{6,-80}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{-4,-100},{-14,-80}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{-44,-100},{-34,-80}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{-44,-100},{-54,-80}}, - color = {0,127,255}), - Line( - origin = {12,40}, - points = {{-70,-60},{66,-60}}, - color = {191,0,0}), - Line( - origin = {12,40}, - points = {{46,-70},{66,-60}}, - color = {191,0,0}), - Line( - origin = {12,40}, - points = {{46,-50},{66,-60}}, - color = {191,0,0}), - Line( - origin = {12,40}, - points = {{46,-30},{66,-20}}, - color = {191,0,0}), - Line( - origin = {12,40}, - points = {{46,-10},{66,-20}}, - color = {191,0,0}), - Line( - origin = {12,40}, - points = {{-70,-20},{66,-20}}, - color = {191,0,0})})) ; - -end Components; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_coCurrent.mo b/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_coCurrent.mo deleted file mode 100644 index 490f5b4..0000000 --- a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_coCurrent.mo +++ /dev/null @@ -1,17 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.Tests; - -model test_coCurrent - - parameter Real NTU = 10 "Number of transfer unit" ; - Real Cr "Ratio of thermal condutance" ; - Modelica.SIunits.Efficiency Eff "Exchanger effectiveness" ; - Modelica.Blocks.Sources.Ramp ramp1(duration = 1, height = 1) annotation( - Placement(visible = true, transformation(origin = {-10, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); -equation - Cr = ramp1.y ; - Eff = TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.coCurrent(NTU = NTU, Cr = Cr) ; - -annotation( - experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.01)); - -end test_coCurrent; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_counterCurrent.mo b/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_counterCurrent.mo deleted file mode 100644 index 4d8ba60..0000000 --- a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_counterCurrent.mo +++ /dev/null @@ -1,15 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.Tests; - -model test_counterCurrent - - parameter Real NTU = 10 "Number of transfer unit" ; - Real Cr "Ratio of thermal condutance" ; - Modelica.SIunits.Efficiency Eff "Exchanger effectiveness" ; - Modelica.Blocks.Sources.Ramp ramp1(duration = 1, height = 1) annotation( - Placement(visible = true, transformation(origin = {-10, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); -equation - Cr = ramp1.y ; - Eff = TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.counterCurrent(NTU = NTU, Cr = Cr) ; - -annotation( - experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.01));end test_counterCurrent; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/baseFunc.mo b/HeatTransfer/Functions/ExchangerEffectiveness/baseFunc.mo deleted file mode 100644 index d0fd961..0000000 --- a/HeatTransfer/Functions/ExchangerEffectiveness/baseFunc.mo +++ /dev/null @@ -1,11 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness; - -function baseFunc - - extends Modelica.Icons.Function ; - // - input Real NTU "Number of transfer unit" ; - input Real Cr "Ratio of thermal condutance" ; - output Modelica.SIunits.Efficiency Eff "Exchanger effectiveness" ; - -end baseFunc; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/package.mo b/HeatTransfer/Functions/ExchangerEffectiveness/package.mo deleted file mode 100644 index 81333f2..0000000 --- a/HeatTransfer/Functions/ExchangerEffectiveness/package.mo +++ /dev/null @@ -1,7 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions; - -package ExchangerEffectiveness "Package of functions to compute the effectiveness of an exchanger" - - extends Modelica.Icons.FunctionsPackage ; - -end ExchangerEffectiveness; diff --git a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/test_from_correlations.mo b/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/test_from_correlations.mo deleted file mode 100644 index 8294c06..0000000 --- a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/test_from_correlations.mo +++ /dev/null @@ -1,31 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff.Tests; - -model test_from_correlations - - parameter Modelica.SIunits.ReynoldsNumber Re_A = 1e5 "Reynolds number for flow A" ; - parameter Modelica.SIunits.PrandtlNumber Pr_A = 7 "Prandtl number for fluid A" ; - parameter Modelica.SIunits.Length Lc_A = 0.2 "Charactereistic length for flow A" ; - parameter Modelica.SIunits.ThermalConductivity k_A = 0.06 "Thermal conductivity for fluid A" ; - parameter Modelica.SIunits.ReynoldsNumber Re_B = 1e6 "Reynolds number for flow A" ; - parameter Modelica.SIunits.PrandtlNumber Pr_B = 1 "Prandtl number for fluid A" ; - parameter Modelica.SIunits.Length Lc_B = 1 "Charactereistic length for flow A" ; - parameter Modelica.SIunits.ThermalConductivity k_B = 0.03 "Thermal conductivity for fluid A" ; - Modelica.SIunits.CoefficientOfHeatTransfer h, h_A, h_B "Heat transfer Coefficient" ; - -equation - - h = TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff.from_correlations( - Re_A = Re_A, - Pr_A = Pr_A, - Lc_A = Lc_A, - k_A = k_A, - Re_B = Re_B, - Pr_B = Pr_B, - Lc_B = Lc_B, - k_B = k_B); - - h_A = TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.internal_pipe_ASHRAE(Re = Re_A, Pr = Pr_A, dT = 0.0) * k_A / Lc_A ; - - h_B = TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.flat_plate_ASHRAE(Re = Re_B, Pr=Pr_B)* k_B / Lc_B ; - -end test_from_correlations; diff --git a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/baseFun.mo b/HeatTransfer/Functions/ExchangerHeatTransferCoeff/baseFun.mo deleted file mode 100644 index 31926b5..0000000 --- a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/baseFun.mo +++ /dev/null @@ -1,9 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; - -partial function baseFun "Base class for heat transfer coefficient calculation in heat exchanger" - - extends Modelica.Icons.Function ; - // - output Modelica.SIunits.CoefficientOfHeatTransfer h "Heat transfer Coefficient" ; - -end baseFun; diff --git a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/from_correlations.mo b/HeatTransfer/Functions/ExchangerHeatTransferCoeff/from_correlations.mo deleted file mode 100644 index bc96e97..0000000 --- a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/from_correlations.mo +++ /dev/null @@ -1,26 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; - -function from_correlations - - extends baseFun ; - input Modelica.SIunits.ReynoldsNumber Re_A "Reynolds number for flow A" ; - input Modelica.SIunits.PrandtlNumber Pr_A "Prandtl number for fluid A" ; - input Modelica.SIunits.Length Lc_A "Charactereistic length for flow A" ; - input Modelica.SIunits.ThermalConductivity k_A "Thermal conductivity for fluid A" ; - input Modelica.SIunits.ReynoldsNumber Re_B "Reynolds number for flow A" ; - input Modelica.SIunits.PrandtlNumber Pr_B "Prandtl number for fluid A" ; - input Modelica.SIunits.Length Lc_B "Charactereistic length for flow A" ; - input Modelica.SIunits.ThermalConductivity k_B "Thermal conductivity for fluid A" ; - -protected - Modelica.SIunits.NusseltNumber Nu_A ; - Modelica.SIunits.NusseltNumber Nu_B ; - -algorithm - - Nu_A := TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.internal_pipe_ASHRAE(Re = Re_A, Pr = Pr_A, dT = 0.0) ; - Nu_B := TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.flat_plate_ASHRAE(Re = Re_B, Pr=Pr_B) ; - - h := ( Lc_A/(Nu_A*k_A) + Lc_B/(Nu_B*k_B) )^(-1) ; - -end from_correlations; diff --git a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.mo b/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.mo deleted file mode 100644 index 76e79b4..0000000 --- a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.mo +++ /dev/null @@ -1,7 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions; - -package ExchangerHeatTransferCoeff "Package of functions to compute the heat transfer coefficient between the two fluids of an exchanger" - - extends Modelica.Icons.FunctionsPackage ; - -end ExchangerHeatTransferCoeff; diff --git a/HeatTransfer/Functions/FreeConvection/Tests/ground_ASHRAE.mo b/HeatTransfer/Functions/FreeConvection/Tests/ground_ASHRAE.mo deleted file mode 100644 index 1fd4781..0000000 --- a/HeatTransfer/Functions/FreeConvection/Tests/ground_ASHRAE.mo +++ /dev/null @@ -1,18 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.FreeConvection.Tests; - -model ground_ASHRAE - - Modelica.SIunits.NusseltNumber Nu ; - Modelica.SIunits.RayleighNumber Ra ; - Modelica.SIunits.TemperatureDifference dT "Difference of Temperature plate - fluid"; - -equation - Ra = min(10^time, 10^11); - dT = 20 ; - - Nu = Functions.FreeConvection.ground_ASHRAE(Ra = Ra, dT = dT) ; - -annotation( - experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-6, Interval = 0.1)); - -end ground_ASHRAE; diff --git a/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_Recknagel.mo b/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_Recknagel.mo deleted file mode 100644 index 571d4aa..0000000 --- a/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_Recknagel.mo +++ /dev/null @@ -1,18 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.FreeConvection.Tests; - -model vertical_plate_Recknagel - parameter Modelica.SIunits.Temperature T_ref = 283.15 "Reference temperature"; - Modelica.SIunits.Temperature T_mean "Mean temperature between plate and fluid"; - Modelica.SIunits.TemperatureDifference dT "Difference temperature between plate and fluid"; - Modelica.SIunits.CoefficientOfHeatTransfer h_cv "Convective heat transfer coefficient"; - -equation - - dT = time; - T_mean = T_ref + dT / 2; - h_cv = Functions.FreeConvection.vertical_plate_Recknagel(dT = dT, T_mean = T_mean); - - annotation( - experiment(StartTime = 0, StopTime = 20, Tolerance = 1e-06, Interval = 0.2)); - -end vertical_plate_Recknagel; diff --git a/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndGeometricalGrowthGrid.mo b/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndGeometricalGrowthGrid.mo deleted file mode 100644 index b36387f..0000000 --- a/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndGeometricalGrowthGrid.mo +++ /dev/null @@ -1,24 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.MeshGrid.Tests; - -model test_biotAndGeometricalGrowthGrid - - parameter Modelica.SIunits.Length L = 1 "Length of the domain to mesh" ; - parameter Integer N = 8 "number of segments" ; - parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 ; - parameter Modelica.SIunits.ThermalConductivity k = 1 ; - parameter Modelica.SIunits.Position x[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.biotAndGeometricalGrowthGrid(L = L, - N = N, - q = 1.2, - h = h, - k = k, - symmetricalMesh = false); - parameter Modelica.SIunits.Position x2[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.biotAndGeometricalGrowthGrid(L = L, - N = N, - q = 2, - h = h, - k = k, - symmetricalMesh = true); - -equation - -end test_biotAndGeometricalGrowthGrid; diff --git a/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndUniformGrid.mo b/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndUniformGrid.mo deleted file mode 100644 index 71e9cdf..0000000 --- a/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndUniformGrid.mo +++ /dev/null @@ -1,22 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.MeshGrid.Tests; - -model test_biotAndUniformGrid - - parameter Modelica.SIunits.Length L = 1 "Length of the domain to mesh" ; - parameter Integer N = 5 "number of segments" ; - parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 ; - parameter Modelica.SIunits.ThermalConductivity k = 1 ; - parameter Modelica.SIunits.Position x[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.biotAndUniformGrid(L = L, - N = N, - h = h, - k = k, - symmetricalMesh = false); - parameter Modelica.SIunits.Position x2[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.biotAndUniformGrid(L = L, - N = N, - h = h, - k = k, - symmetricalMesh = true); - -equation - -end test_biotAndUniformGrid; diff --git a/HeatTransfer/Functions/MeshGrid/Tests/test_geometricalGrowthGrid.mo b/HeatTransfer/Functions/MeshGrid/Tests/test_geometricalGrowthGrid.mo deleted file mode 100644 index ddf4b57..0000000 --- a/HeatTransfer/Functions/MeshGrid/Tests/test_geometricalGrowthGrid.mo +++ /dev/null @@ -1,25 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.MeshGrid.Tests; - -model test_geometricalGrowthGrid - - parameter Modelica.SIunits.Length L = 1 "Length of the domain to mesh" ; - parameter Integer N_odd = 5 "Odd number of segments" ; - parameter Integer N_even = 6 "Even number of segments" ; - parameter Modelica.SIunits.Position x[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.geometricalGrowthGrid(L = L, - N = N_odd, - q = 1.2, - symmetricalMesh = false); - parameter Modelica.SIunits.Position x_sym_odd[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.geometricalGrowthGrid(L = L, - N = N_odd, - q = 1.2, - symmetricalMesh = true); - - parameter Modelica.SIunits.Position x_sym_even[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.geometricalGrowthGrid(L = L, - N = N_even, - q = 1.2, - symmetricalMesh = true); - -equation - - -end test_geometricalGrowthGrid ; diff --git a/HeatTransfer/Functions/MeshGrid/package.mo b/HeatTransfer/Functions/MeshGrid/package.mo deleted file mode 100644 index 722dcd0..0000000 --- a/HeatTransfer/Functions/MeshGrid/package.mo +++ /dev/null @@ -1,7 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions; - -package MeshGrid "Package of functions to set the shape and the size of a mesh" - - extends Modelica.Icons.FunctionsPackage ; - -end MeshGrid; diff --git a/HeatTransfer/Functions/Radiation/Tests/h_rad.mo b/HeatTransfer/Functions/Radiation/Tests/h_rad.mo deleted file mode 100644 index 957fda8..0000000 --- a/HeatTransfer/Functions/Radiation/Tests/h_rad.mo +++ /dev/null @@ -1,18 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Functions.Radiation.Tests; - -model h_rad - - parameter Modelica.SIunits.Temperature T_A = 303.15 ; - parameter Modelica.SIunits.Temperature T_B = 283.15 ; - constant Modelica.SIunits.Emissivity eps = 1 ; - Modelica.SIunits.CoefficientOfHeatTransfer h_rad, h_rad_check ; - -equation - - h_rad = Radiation.h_rad(T_A = T_A, T_B = T_B, R_th = 1/eps) ; - h_rad_check = eps * Modelica.Constants.sigma * (T_A^4 - T_B^4) / (T_A - T_B) ; - -annotation( - experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.002)); - -end h_rad; diff --git a/HeatTransfer/Interfaces/HeatPort.mo b/HeatTransfer/Interfaces/HeatPort.mo deleted file mode 100644 index 1b717fc..0000000 --- a/HeatTransfer/Interfaces/HeatPort.mo +++ /dev/null @@ -1,10 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Interfaces; - -partial connector HeatPort "Thermal port for 1-dim. heat transfer" - Modelica.SIunits.Temperature T "Port temperature"; - flow Modelica.SIunits.HeatFlowRate Q_flow - "Heat flow rate (positive if flowing from outside into the component)"; - annotation (Documentation(info=" - -")); -end HeatPort ; diff --git a/HeatTransfer/Interfaces/HeatPort_a.mo b/HeatTransfer/Interfaces/HeatPort_a.mo deleted file mode 100644 index 111b041..0000000 --- a/HeatTransfer/Interfaces/HeatPort_a.mo +++ /dev/null @@ -1,37 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Interfaces; - -connector HeatPort_a - "Thermal port for 1-dim. heat transfer (filled rectangular icon)" - - extends HeatPort; - - annotation(defaultComponentName = "port_a", - Documentation(info=" -

    This connector is used for 1-dimensional heat flow between components. -The variables in the connector are:

    -
    -T       Temperature in [Kelvin].
    -Q_flow  Heat flow rate in [Watt].
    -
    -

    According to the Modelica sign convention, a positive heat flow -rate Q_flow is considered to flow into a component. This -convention has to be used whenever this connector is used in a model -class.

    -

    Note, that the two connector classes HeatPort_a and -HeatPort_b are identical with the only exception of the different -icon layout.

    "), Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ - 100,100}}), graphics={Rectangle( - extent={{-100,100},{100,-100}}, - lineColor={191,0,0}, - fillColor={191,0,0}, - fillPattern=FillPattern.Solid)}), - Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100}, - {100,100}}), graphics={Rectangle( - extent={{-50,50},{50,-50}}, - lineColor={191,0,0}, - fillColor={191,0,0}, - fillPattern=FillPattern.Solid), Text( - extent={{-120,120},{100,60}}, - lineColor={191,0,0}, - textString="%name")})); -end HeatPort_a; diff --git a/HeatTransfer/Interfaces/HeatPort_b.mo b/HeatTransfer/Interfaces/HeatPort_b.mo deleted file mode 100644 index a7215af..0000000 --- a/HeatTransfer/Interfaces/HeatPort_b.mo +++ /dev/null @@ -1,37 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Interfaces; - -connector HeatPort_b - "Thermal port for 1-dim. heat transfer (unfilled rectangular icon)" - - extends HeatPort; - - annotation(defaultComponentName = "port_b", - Documentation(info=" -

    This connector is used for 1-dimensional heat flow between components. -The variables in the connector are:

    -
    -T       Temperature in [Kelvin].
    -Q_flow  Heat flow rate in [Watt].
    -
    -

    According to the Modelica sign convention, a positive heat flow -rate Q_flow is considered to flow into a component. This -convention has to be used whenever this connector is used in a model -class.

    -

    Note, that the two connector classes HeatPort_a and -HeatPort_b are identical with the only exception of the different -icon layout.

    "), Diagram(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100}, - {100,100}}), graphics={Rectangle( - extent={{-50,50},{50,-50}}, - lineColor={191,0,0}, - fillColor={255,255,255}, - fillPattern=FillPattern.Solid), Text( - extent={{-100,120},{120,60}}, - lineColor={191,0,0}, - textString="%name")}), - Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{ - 100,100}}), graphics={Rectangle( - extent={{-100,100},{100,-100}}, - lineColor={191,0,0}, - fillColor={255,255,255}, - fillPattern=FillPattern.Solid)})); -end HeatPort_b; diff --git a/HeatTransfer/Sensors/Density.mo b/HeatTransfer/Sensors/Density.mo deleted file mode 100644 index d6fb246..0000000 --- a/HeatTransfer/Sensors/Density.mo +++ /dev/null @@ -1,29 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Sensors; - -model Density "Ideal one port density sensor" - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - extends Modelica.Icons.RotationalSensor; - Modelica.Blocks.Interfaces.RealOutput d(final quantity="Density", - final unit="kg/m3", - min=0) "Density in port medium" - annotation (Placement(transformation(extent={{100,-10},{120,10}}))); - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port annotation( - Placement(visible = true, transformation(origin = {0, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput p(final quantity="Absolute pressure", - final unit="Pa", - min=0) "Absolute pressure in port medium" annotation( - Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); -equation - d = Medium.density_pTX(p = p, T = port.T, X = Medium.X_default); - port.Q_flow = 0.0 ; -annotation ( - Icon(coordinateSystem(initialScale = 0.1), graphics = {Line(points = {{0, -70}, {0, -100}}, color = {0, 0, 127}), Text(lineColor = {0, 0, 255}, extent = {{-150, 80}, {150, 120}}, textString = "%name"), Text(origin = {4, 2},extent = {{156, -23}, {56, -61}}, textString = "d"), Line(points = {{70, 0}, {100, 0}}, color = {0, 0, 127}), Text(origin = {-216, 82}, extent = {{156, -23}, {56, -61}}, textString = "p")}), - Documentation(info=" - -

    - This model outputs the density of the fluid from the port tempeature and the input of pressure. - The sensor is ideal, i.e. it does not influence the fluid. -

    -"), - Diagram(coordinateSystem(initialScale = 0.1))); -end Density; diff --git a/HeatTransfer/Types/CrossFlow_arrangement.mo b/HeatTransfer/Types/CrossFlow_arrangement.mo deleted file mode 100644 index 3ba1814..0000000 --- a/HeatTransfer/Types/CrossFlow_arrangement.mo +++ /dev/null @@ -1,6 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Types; - -type CrossFlow_arrangement = enumeration( -both_unmixed "Both fluids are unmixed", -fluidA_mixed_fluidB_unmixed "Fluid A in mixed and B unmixed", -fluidB_mixed_fluidA_unmixed "Fluid A in mixed and B unmixed") "Enumeration defining the configuration of a cross flows exchanger"; diff --git a/HeatTransfer/Types/ForcedConvectionCorrelation.mo b/HeatTransfer/Types/ForcedConvectionCorrelation.mo deleted file mode 100644 index 9f82e58..0000000 --- a/HeatTransfer/Types/ForcedConvectionCorrelation.mo +++ /dev/null @@ -1,8 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Types; - - -type ForcedConvectionCorrelation = enumeration( -internal_pipe_ASHRAE "Dittus and Boelter correlation for the internal flow inside a cylinder", -crossFlow_cylinder_ASHRAE "Churchill and Bernstein correlation for the external flow for cross flow over cylinder", -flat_plate_ASHRAE "ASHRAE correlation for the external flow over a flat plate", -Constant "Constant convection heat transfer ") "Enumeration defining the correlation of table"; diff --git a/HeatTransfer/Types/FreeConvectionCorrelation.mo b/HeatTransfer/Types/FreeConvectionCorrelation.mo deleted file mode 100644 index 9e1ccd0..0000000 --- a/HeatTransfer/Types/FreeConvectionCorrelation.mo +++ /dev/null @@ -1,9 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Types; - -type FreeConvectionCorrelation = enumeration( -vertical_plate_ASHRAE "Churchill & Chu correlation for a flat vertical plate", -vertical_plate_Recknagel "Recknagel correlation for a flat vertical plate", -ground_ASHRAE "Lloyd and Moran correlation for a horizontal ground plate", -ceiling_ASHRAE "Lloyd and Moran correlation for a horizontal ceiling plate", -horizontal_cylinder_ASHRAE "Churchill & Chu correlation for the external flow around an horizontal cylinder", -Constant "Constant convective heat transfer coefficient") "Enumeration defining the correlation of table"; diff --git a/HeatTransfer/Types/MeshGrid.mo b/HeatTransfer/Types/MeshGrid.mo deleted file mode 100644 index 6e185dd..0000000 --- a/HeatTransfer/Types/MeshGrid.mo +++ /dev/null @@ -1,10 +0,0 @@ -within TAeZoSysPro.HeatTransfer.Types; - -type MeshGrid = enumeration( - uniform - "Uniform grid with equal spacing between vertices", - biotAndUniform "Uniform grid with equal spacing between vertices execpted for boundary segments with a specing from biot number", - geometricalGrowth "Grid with geometrical growth spacing between vertices", - biotAndGeometricalGrowth - "Grid with geometrical growth spacing between vertices execpted for boundary segments with a specing from biot number") - "Enumeration to define the function used to mesh the domain" ; diff --git a/Media/Air/MoistAir.mo b/Media/Air/MoistAir.mo deleted file mode 100644 index 93fae50..0000000 --- a/Media/Air/MoistAir.mo +++ /dev/null @@ -1,1319 +0,0 @@ -within TAeZoSysPro.Media.Air; - -package MoistAir - - extends Modelica.Media.Interfaces.PartialMedium(redeclare replaceable record FluidConstants = Modelica.Media.Interfaces.Types.IdealGas.FluidConstants, mediumName = "Moist air", substanceNames = {"water", "air"}, final reducedX = true, final singleState = false, reference_X = {0.01, 0.99}, reference_T = 293.15, Temperature(min = 190, max = 647), ThermoStates = Modelica.Media.Interfaces.Choices.IndependentVariables.dTX); - import Modelica.Media.Interfaces.Types.ExtraProperty; - constant Integer Water = 1 "Index of water (in substanceNames, massFractions X, etc.)"; - constant Integer Air = 2 "Index of air (in substanceNames, massFractions X, etc.)"; - constant Real k_mair = steam.MM / dryair.MM "Ratio of molar weights"; - - record dryair - constant SI.SpecificHeatCapacity R = Modelica.Media.IdealGases.Common.SingleGasesData.Air.R; - constant SI.MolarMass MM = Modelica.Media.IdealGases.Common.SingleGasesData.Air.MM; - constant SI.SpecificHeatCapacityAtConstantPressure cp = 1006.4 "Specific heat capacity of dry air at 293.15K (20°C)"; - end dryair; - - record steam - constant SI.SpecificHeatCapacity R = Modelica.Media.IdealGases.Common.SingleGasesData.H2O.R; - constant SI.MolarMass MM = Modelica.Media.IdealGases.Common.SingleGasesData.H2O.MM; - constant SI.SpecificEnergy h_lv = 2453.55e3 "Enthalpy of vaporization of water at 293.15K (20°C)"; - constant SI.SpecificHeatCapacityAtConstantPressure cp = 1886.0 "Specific heat capacity of steam at 293.15K (20°C)"; - end steam; - - record water - constant SI.SpecificHeatCapacityAtConstantPressure cp = 4181 "Specific heat capacity of liquid water at 293.15K (20°C)"; - end water; - - record ice - constant SI.SpecificHeatCapacityAtConstantPressure cp = 2060 "Specific heat capacity of solid water at 273.15K (0°C)"; - constant SI.SpecificEnergy h_sl = 333e3 "Enthalpy of fusion of water at 273.15K (0°C)"; - end ice; - - constant SI.MolarMass[2] MMX = {steam.MM, dryair.MM} "Molar masses of components"; - constant FluidConstants[nS] fluidConstants = {Modelica.Media.IdealGases.Common.FluidData.H2O, Modelica.Media.IdealGases.Common.FluidData.N2} "Constant data for the fluid"; - import SI = Modelica.SIunits; - import Modelica.SIunits; - - redeclare record extends ThermodynamicState "Thermodynamic state variables of moist air" - Density d "density of medium"; - Temperature T "Temperature of medium"; - MassFraction[nX] X(start = reference_X) "Mass fractions (= (component mass)/total mass m_i/m)"; - end ThermodynamicState; - - redeclare replaceable model extends BaseProperties(T(stateSelect = if preferredMediumStates then StateSelect.prefer else StateSelect.default), d(stateSelect = if preferredMediumStates then StateSelect.prefer else StateSelect.default), Xi(each stateSelect = if preferredMediumStates then StateSelect.prefer else StateSelect.default), final standardOrderComponents = true) "Moist air base properties record" - /* d, T, X = X[Water] are used as preferred states, since only then all - other quantities can be computed in a recursive sequence. - If other variables are selected as states, static state selection - is no longer possible and non-linear algebraic equations occur. - */ - Real phi "Relative humidity"; - MassFraction X_liquid "Mass fraction of liquid or solid water"; - MassFraction X_steam "Mass fraction of steam water"; - MassFraction X_air "Mass fraction of air"; - Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - - equation - assert(T >= 190 and T <= 647, " -Temperature T is not in the allowed range -190.0 K <= (T =" + String(T) + " K) <= 647.0 K -required from medium model \"" + mediumName + "\"."); - MM = 1 / (Xi[Water] / MMX[Water] + (1.0 - Xi[Water]) / MMX[Air]); - d_sat = saturationDensity(T); - X_liquid = max(d * X[Water] - d_sat, 0) / d; - X_steam = Xi[Water] - X_liquid; - X_air = 1 - Xi[Water]; - h = h_dTX(d, T, Xi); -// R = dryair.R * (X_air / (1 - X_liquid)) + steam.R * X_steam / (1 - X_liquid); - R = r_dTX(d, T, Xi); -// - u = h - R * T; -// u = X_air*720*(T-reference_T) + X_steam*(1000*(T-reference_T)+steam.h_lv) + X_liquid*4185*(T-reference_T); -// u = h - p/d; - p = d * (1 - X_liquid) * R * T; -/* Note, is computed under the assumption that the volume of the liquid - water is negligible with respect to the volume of air and of steam - */ - state.d = d; - state.T = T; - state.X = X; - phi = min(d * X[Water], d_sat) / d_sat; - annotation( - Documentation(info = " -

    - This model computes thermodynamic properties of moist air from three independent (thermodynamic or/and numerical) state variables. - Preferred numerical states are temperature T, density d and the reduced composition vector Xi, which contains the water mass fraction only. - As an EOS the ideal gas law is used and associated restrictions apply. - The model can also be used in the fog region, when moisture is present in its liquid state. - However, it is assumed that the liquid water volume is negligible compared to that of the gas phase. - Computation of thermal properties is based on property data of dry air and water (source: VDI-Wärmeatlas), respectively. - Besides the standard thermodynamic variables absolute and relative humidity, x_water and phi, respectively, are given by the model. - Upper case X denotes absolute humidity with respect to mass of moist air while absolute humidity with respect to mass of dry air only is denoted by a lower case x throughout the model. - See package description for further information. -

    -")); - end BaseProperties; - - redeclare function extends setState_pTX - protected - SI.MassFraction X_sat "Absolute humidity per unit mass of moist air at saturation"; - MassFraction X_liquid "Mass fraction of liquid or solid water"; - MassFraction X_air; - SI.Pressure p_sat "water saturation pressure"; - SI.SpecificHeatCapacity R "Mixture gas constant"; - SI.Density d_sat; - SI.Density d_air_sat; - SI.Pressure p_air_sat; - - - algorithm - assert(if size(X, 1) == nX then X[Air] > 1e-4 else 1 - X[Water] > 1e-4, "Too little dry air in the mixture to compute the density", AssertionLevel.error); - X_air:=1.0-X[Water]; - p_sat := saturationPressure(T); - d_sat := p_sat / (steam.R * T); - p_air_sat := max(p - p_sat,0); /*Manage the case with high gas temperature where psat > p */ - d_air_sat := p_air_sat/(dryair.R*T); - - X_sat := min(d_sat/(d_sat+d_air_sat),0.99); /*Manage the case with high gas temperature where psat > p */ - - /* X_sat +X_air/(1-X_l)=1 : balance for gas part */ - X_liquid := max(-X_air/(1-X_sat)+1.0, 0.0); - R := dryair.R * (1 - X[Water]) / (1 - X_liquid) + steam.R * (X[Water] - X_liquid) / (1 - X_liquid); - state := if size(X, 1) == nX then ThermodynamicState(d = p / ((1 - X_liquid) * R * T), T = T, X = X) else ThermodynamicState(d = p / ((1 - X_liquid) * R * T), T = T, X = cat(1, X, {1 - sum(X)})); - annotation( - smoothOrder = 2, - Documentation(info = " - The thermodynamic state record is computed from pressure p, temperature T and composition X.
    - If X[Air]<1e-4, the density cannot be computed in case of diphasique water since p and T remain contant. - - - ")); - end setState_pTX; - - redeclare function extends setState_phX - protected - SI.MassFraction X_sat "Absolute humidity per unit mass of moist air at saturation"; - SI.MassFraction X_steam "Mass fraction of gaseous water (kg gas water / kg moist air)"; - SI.Temperature T "Temperature"; - - algorithm - state := if size(X, 1) == nX then ThermodynamicState(d = d_phX(p = p, h = h, X = X), T = T_phX(p = p, h = h, X = X), X = X) else ThermodynamicState(d = d_phX(p = p, h = h, X = X), T = T_phX(p = p, h = h, X = X), X = cat(1, X, {1 - sum(X)})); - annotation( - smoothOrder = 2, - Documentation(info = " - The thermodynamic state record is computed from pressure p, specific enthalpy h and composition X. - ")); - end setState_phX; - - redeclare function extends setState_dTX - algorithm - state := if size(X, 1) == nX then ThermodynamicState(d = d, T = T, X = X) else ThermodynamicState(d = d, T = T, X = cat(1, X, {1 - sum(X)})); - annotation( - smoothOrder = 2, - Documentation(info = " - The thermodynamic state record is computed from density d, temperature T and composition X. - ")); - end setState_dTX; - - redeclare function extends setSmoothState "Return thermodynamic state so that it smoothly approximates: if x > 0 then state_a else state_b" - algorithm - state := ThermodynamicState(d = Modelica.Media.Common.smoothStep(x, state_a.d, state_b.d, x_small), T = Modelica.Media.Common.smoothStep(x, state_a.T, state_b.T, x_small), X = Modelica.Media.Common.smoothStep(x, state_a.X, state_b.X, x_small)); - end setSmoothState; - - function Xsaturation "Return absolute humidity per unit mass of moist air at saturation as a function of the thermodynamic state record" - extends Modelica.Icons.Function; - input ThermodynamicState state "Thermodynamic state record"; - output MassFraction X_sat "Steam mass fraction of sat. boundary"; - algorithm - X_sat := saturationDensity(state.T) / (saturationDensity(state.T) + state.d * state.X[Air]); - annotation( - smoothOrder = 2, - Documentation(info = " - Absolute humidity per unit mass of moist air at saturation is computed from density and temperature in the state record. Note, that this mass fraction refers to mass of moist air at saturation. - ")); - end Xsaturation; - - function xsaturation "Return absolute humidity per unit mass of dry air at saturation as a function of the thermodynamic state record" - extends Modelica.Icons.Function; - input ThermodynamicState state "Thermodynamic state record"; - output MassFraction x_sat "Absolute humidity per unit mass of dry air"; - algorithm - x_sat := saturationDensity(state.T) / (state.d * state.X[Air]); - annotation( - smoothOrder = 2, - Documentation(info = " - Absolute humidity per unit mass of dry air at saturation is computed from density and temperature in the thermodynamic state record. - ")); - end xsaturation; - - function xsaturation_pT "Return absolute humidity per unit mass of dry air at saturation as a function of pressure p and temperature T" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SI.Temperature T "Temperature"; - output MassFraction x_sat "Absolute humidity per unit mass of dry air"; - algorithm - assert(p - saturationPressure(T) >= 1e-4, "p_sat(T) is too close to p", AssertionLevel.error); - x_sat := k_mair * saturationPressure(T) / max(100 * Modelica.Constants.eps, p - saturationPressure(T)); - annotation( - smoothOrder = 2, - Documentation(info = " - Absolute humidity per unit mass of dry air at saturation is computed from pressure and temperature. The function is valid for p-p_sat(T)≥ 1e-4 - ")); - end xsaturation_pT; - - function massFraction_pTphi "Return steam mass fraction as a function of relative humidity phi and temperature T" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input Temperature T "Temperature"; - input Real phi "Relative humidity (0 ... 1.0)"; - output MassFraction X_steam "Absolute humidity, steam mass fraction"; - protected - AbsolutePressure psat = saturationPressure(T) "Saturation pressure"; - algorithm - X_steam := phi * k_mair / (k_mair * phi + p / psat - phi); - annotation( - smoothOrder = 2, - Documentation(info = " - Absolute humidity per unit mass of moist air is computed from temperature, pressure and relative humidity. - ")); - end massFraction_pTphi; - - function relativeHumidity_pTX "Return relative humidity as a function of pressure p, temperature T and composition X" - extends Modelica.Icons.Function; - input SI.Pressure p "Pressure"; - input SI.Temperature T "Temperature"; - input SI.MassFraction[:] X "Composition"; - output Real phi "Relative humidity"; - protected - SI.Pressure p_steam_sat "Saturation pressure"; - SI.MassFraction X_air "Dry air mass fraction"; - algorithm - p_steam_sat := min(saturationPressure(T), 0.999 * p); - X_air := 1 - X[Water]; - phi := max(0.0, min(1.0, p / p_steam_sat * X[Water] / (X[Water] + k_mair * X_air))); - annotation( - smoothOrder = 2, - Documentation(info = " - Relative humidity is computed from pressure, temperature and composition with 1.0 as the upper limit at saturation. Water mass fraction is the first entry in the composition vector. - ")); - end relativeHumidity_pTX; - - function relativeHumidity "Return relative humidity as a function of the thermodynamic state record" - extends Modelica.Icons.Function; - input ThermodynamicState state "Thermodynamic state"; - output Real phi "Relative humidity"; - protected - SI.Density d_sat "Saturation density of water in mosit air"; - algorithm - d_sat := saturationDensity(state.T); - phi := min(state.d * state.X[Water] - d_sat) / d_sat; - annotation( - smoothOrder = 2, - Documentation(info = " - Relative humidity is computed from the thermodynamic state record with 1.0 as the upper limit at saturation. - ")); - end relativeHumidity; - - function gasConstant "Return ideal gas constant as a function from thermodynamic state, remains valid with liquid water in the mixture" - extends Modelica.Icons.Function; - input ThermodynamicState state "Thermodynamic state"; - output SI.SpecificHeatCapacity R "Mixture gas constant"; - protected - MassFraction X_liquid "Mass fraction of liquid or solid water"; - Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - algorithm - d_sat := saturationDensity(state.T); - X_liquid := max(state.d * state.X[Water] - d_sat, 0) / state.d; - R := dryair.R * (1 - state.X[Water]) / (1 - X_liquid) + steam.R * (state.X[Water] - X_liquid) / (1 - X_liquid); - annotation( - smoothOrder = 2, - Documentation(info = " - The ideal gas constant for moist air is computed from thermodynamic state where the mass fractions of dry air and steam are corrected of the mass fraction of liquid that does not count for the gas contant calculation. -")); - end gasConstant; - - function r_dTX "Return ideal gas constant as a function from thermodynamic d, T and X, remains valid with liquid water in the mixture" - input SI.Density d "Density"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - output SI.SpecificHeatCapacity R "Mixture gas constant"; - protected - MassFraction X_liquid "Mass fraction of liquid or solid water"; - Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - algorithm - d_sat := saturationDensity(T); - X_liquid := max(d * X[Water] - d_sat, 0) / d; - R := dryair.R * (1 - X[Water]) / (1 - X_liquid) + steam.R * (X[Water] - X_liquid) / (1 - X_liquid); - annotation( - derivative = r_dTX_der, - Documentation(info = " - The ideal gas constant for moist air is computed from the density d, temperature T and composition X where the mass fractions of dry air and steam are corrected of the mass fraction of liquid that does not count for the gas contant calculation. -")); - end r_dTX; - - function r_dTX_der "Return ideal gas constant derivative as a function from thermodynamic d, T and X, remains valid with liquid water in the mixture" - input SI.Density d "Density"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - input Real dd(unit = "kg/(m3.s)") "Density derivative"; - input Real dT(unit = "K/s") "Temperature derivative"; - input Real dX[:](each unit = "1/s") "Composition derivative"; - output Real R_der(unit = "J/(kg.s.K)") "Time derivative of specific enthalpy"; - protected - SI.MassFraction X_liquid "Mass fraction of liquid or solid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - Real dX_steam(unit = "1/s") "Time derivative of steam mass fraction"; - Real dX_air(unit = "1/s") "Time derivative of dry air mass fraction"; - Real dX_liq(unit = "1/s") "Time derivative of liquid/solid water mass fraction"; - Real dd_sat(unit = "kg/(m3.s)") "Time derivative of saturation density"; - - algorithm - d_sat := saturationDensity(T); - X_liquid := Utilities.smoothMax(X[Water] - d_sat / d, 0.0, 1e-5); - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; - - dd_sat := saturationDensity_der(T, dT); - dX_liq := Utilities.smoothMax_der( - X[Water] - d_sat / d, 0.0, 1e-5, - dX[Water] - dd_sat/d + d_sat * dd / d^2, 0, 0); - dX_steam := dX[Water] - dX_liq; - dX_air := -dX[Water]; - - R_der := (dryair.R * dX_air + steam.R * dX_steam) / (1 - X_liquid) + dX_liq / (1 - X_liquid)^2 * (dryair.R * X_air + steam.R * X_steam) - - annotation( - Documentation(info = " - The ideal gas constant derivative for moist air is computed from the density d, temperature T and composition X where the mass fractions of dry air and steam are corrected of the mass fraction of liquid that does not count for the gas contant calculation. -")); - end r_dTX_der; - - function gasConstant_X "Return ideal gas constant as a function from composition X (only valid for phi<1)" - extends Modelica.Icons.Function; - input SI.MassFraction X[:] "Gas phase composition"; - output SI.SpecificHeatCapacity R "Ideal gas constant"; - algorithm - R := dryair.R * (1 - X[Water]) + steam.R * X[Water]; - annotation( - smoothOrder = 2, - Documentation(info = " - The ideal gas constant for moist air is computed from the gas phase composition. - The first entry in composition vector X is the steam mass fraction of the gas phase. - This function assumed a fully gas mixture thus remains valid for a relative humidity bellow or equal to 1. - ")); - end gasConstant_X; - - function moleToMassFractions "Return mass fractions X from mole fractions" - extends Modelica.Icons.Function; - input SI.MoleFraction moleFractions[:] "Mole fractions of mixture"; - input MolarMass[:] MMX "Molar masses of components"; - output SI.MassFraction X[size(moleFractions, 1)] "Mass fractions of gas mixture"; - protected - MolarMass Mmix = moleFractions * MMX "Molar mass of mixture"; - algorithm - for i in 1:size(moleFractions, 1) loop - X[i] := moleFractions[i] * MMX[i] / Mmix; - end for; - annotation( - smoothOrder = 5); - end moleToMassFractions; - - function massToMoleFractions "Return mole fractions from mass fractions X" - extends Modelica.Icons.Function; - input SI.MassFraction X[:] "Mass fractions of mixture"; - input SI.MolarMass[:] MMX "Molar masses of components"; - output SI.MoleFraction moleFractions[size(X, 1)] "Mole fractions of gas mixture"; - protected - Real invMMX[size(X, 1)] "Inverses of molar weights"; - SI.MolarMass Mmix "Molar mass of mixture"; - algorithm - for i in 1:size(X, 1) loop - invMMX[i] := 1 / MMX[i]; - end for; - Mmix := 1 / (X * invMMX); - for i in 1:size(X, 1) loop - moleFractions[i] := Mmix * X[i] / MMX[i]; - end for; - annotation( - smoothOrder = 5); - end massToMoleFractions; - - replaceable function saturationDensity "Return saturation density of steam as a function of temperature T" - extends Modelica.Icons.Function; - input Temperature T "Saturation temperature"; - output Density dsat "Saturation density"; - algorithm - dsat := saturationPressure(T) / (steam.R * T); - annotation( - derivative = saturationDensity_der, - Inline = true, - Documentation(info = " - Saturation density of steam is computed as function of the Temperature using the saturation pressure function psat and the perfect gas law. -")); - end saturationDensity; - - replaceable function saturationDensity_der "Derivative function for 'saturationDensity'" - extends Modelica.Icons.Function; - input Temperature T "Saturation temperature"; - input Real dTsat(unit = "K/s") "Time derivative of saturation temperature"; - output Real dsat_der(unit = "kg/(m3.s)") "Saturation pressure"; - algorithm -// dsat_der := 1 / steam.R * saturationPressure_der(T, dTsat) * (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T) / T - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T) / T ^ 2) * dTsat; - dsat_der := 1 / steam.R * (saturationPressure_der(T, dTsat) / T - saturationPressure(T) / T^2 * dTsat) - annotation( - Inline = false, - smoothOrder = 5, - Documentation(info = " - Derivative function of saturationDensity - ")); - end saturationDensity_der; - - replaceable function saturationPressure "Return saturation pressure of water as a function of temperature T between 190 and 647.096 K" - extends Modelica.Icons.Function; - input Temperature Tsat "Saturation temperature"; - output AbsolutePressure psat "Saturation pressure"; - algorithm - psat := Utilities.spliceFunction(saturationPressureLiquid(Tsat), sublimationPressureIce(Tsat), Tsat - 273.16, 1.0); - annotation( - Inline = false, - smoothOrder = 5, - derivative = saturationPressure_der, - Documentation(info = " -Saturation pressure of water in the liquid and the solid region is computed using correlations. Functions for the -solid and the liquid region, respectively, are combined using the first derivative continuous spliceFunction. This functions range of validity is from 190 to 647.096 K. For more information on the type of correlation used, see the documentation of the linked functions. -")); - end saturationPressure; - - replaceable function saturationPressure_der "Derivative function for 'saturationPressure'" - extends Modelica.Icons.Function; - input Temperature Tsat "Saturation temperature"; - input Real dTsat(unit = "K/s") "Time derivative of saturation temperature"; - output Real psat_der(unit = "Pa/s") "Saturation pressure"; - algorithm -/*psat := Utilities.spliceFunction(saturationPressureLiquid(Tsat),sublimationPressureIce(Tsat),Tsat-273.16,1.0);*/ - psat_der := Utilities.spliceFunction_der(saturationPressureLiquid(Tsat), sublimationPressureIce(Tsat), Tsat - 273.16, 1.0, saturationPressureLiquid_der(Tsat = Tsat, dTsat = dTsat), sublimationPressureIce_der(Tsat = Tsat, dTsat = dTsat), dTsat, 0); - annotation( - Inline = false, - smoothOrder = 5, - Documentation(info = " - Derivative function of saturationPressure - ")); - end saturationPressure_der; - - replaceable function saturationPressureLiquid "Return saturation pressure of water as a function of temperature T in the range of 273.15K to 647.096K (region 4 from the IF97 definition)" - extends Modelica.Icons.Function; - input SI.Temperature Tsat "Saturation temperature"; - output SI.AbsolutePressure psat "Saturation pressure"; - protected -// SI.Temperature Tcritical = 647.096 "Critical temperature"; -// SI.AbsolutePressure pcritical = 22.064e6 "Critical pressure"; -// Real r1 = 1 - Tsat / Tcritical "Common subexpression"; -// Real a[:] = {-7.85951783, 1.84408259, -11.7866497, 22.6807411, -15.9618719, 1.80122502} "Coefficients a[:]"; -// Real n[:] = {1.0, 1.5, 3.0, 3.5, 4.0, 7.5} "Coefficients n[:]"; - constant SI.Temperature T_limit_low = 273.16; - constant SI.Temperature T_limit_high = 679.096; - SI.Temperature T "Temperature in definition range"; - algorithm -// psat := exp(((a[1]*r1^n[1] + a[2]*r1^n[2] + a[3]*r1^n[3] + a[4]*r1^n[4] -// + a[5]*r1^n[5] + a[6]*r1^n[6])*Tcritical)/Tsat)*pcritical; - T := max(Tsat, T_limit_low); - psat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T); - annotation( - derivative = saturationPressureLiquid_der, - Inline = false, - smoothOrder = 5, - Documentation(info = " -

    Saturation pressure of water above the triple point temperature is computed from temperature.

    -

    Source: A Saul, W Wagner: "International equations for the saturation properties of ordinary water substance", equation 2.1

    - ")); - end saturationPressureLiquid; - - replaceable function saturationPressureLiquid_der "Derivative function for 'saturationPressureLiquid'" - extends Modelica.Icons.Function; - input SI.Temperature Tsat "Saturation temperature"; - input Real dTsat(unit = "K/s") "Saturation temperature derivative"; - output Real psat_der(unit = "Pa/s") "Saturation pressure derivative"; - protected - SI.Temperature Tcritical = 647.096 "Critical temperature"; - SI.AbsolutePressure pcritical = 22.064e6 "Critical pressure"; - Real r1 = 1 - Tsat / Tcritical "Common subexpression 1"; - Real r1_der = -1 / Tcritical * dTsat "Derivative of common subexpression 1"; - Real a[:] = {-7.85951783, 1.84408259, -11.7866497, 22.6807411, -15.9618719, 1.80122502} "Coefficients a[:]"; - Real n[:] = {1.0, 1.5, 3.0, 3.5, 4.0, 7.5} "Coefficients n[:]"; - Real r2 = a[1] * r1 ^ n[1] + a[2] * r1 ^ n[2] + a[3] * r1 ^ n[3] + a[4] * r1 ^ n[4] + a[5] * r1 ^ n[5] + a[6] * r1 ^ n[6] "Common subexpression 2"; - algorithm -// Approach used here is based on Baehr: "Thermodynamik", 12th edition p.204ff, "Method of Wagner" -//psat := exp(((a[1]*r1^n[1] + a[2]*r1^n[2] + a[3]*r1^n[3] + a[4]*r1^n[4] + a[5]*r1^n[5] + a[6]*r1^n[6])*Tcritical)/Tsat) * pcritical; - psat_der := exp(r2 * Tcritical / Tsat) * pcritical * ((a[1] * (r1 ^ (n[1] - 1) * n[1] * r1_der) + a[2] * (r1 ^ (n[2] - 1) * n[2] * r1_der) + a[3] * (r1 ^ (n[3] - 1) * n[3] * r1_der) + a[4] * (r1 ^ (n[4] - 1) * n[4] * r1_der) + a[5] * (r1 ^ (n[5] - 1) * n[5] * r1_der) + a[6] * (r1 ^ (n[6] - 1) * n[6] * r1_der)) * Tcritical / Tsat - r2 * Tcritical * dTsat / Tsat ^ 2); - annotation( - Inline = false, - smoothOrder = 5, - Documentation(info = " -

    Saturation pressure of water above the triple point temperature is computed from temperature.

    -

    Source: A Saul, W Wagner: "International equations for the saturation properties of ordinary water substance", equation 2.1

    - ")); - end saturationPressureLiquid_der; - - replaceable function sublimationPressureIce "Return sublimation pressure of water as a function of temperature T between 190 and 273.16 K" - extends Modelica.Icons.Function; - input SI.Temperature Tsat "Sublimation temperature"; - output SI.AbsolutePressure psat "Sublimation pressure"; - protected - SI.Temperature Ttriple = 273.16 "Triple point temperature"; - SI.AbsolutePressure ptriple = 611.657 "Triple point pressure"; - Real r1 = Tsat / Ttriple "Common subexpression"; - Real a[:] = {-13.9281690, 34.7078238} "Coefficients a[:]"; - Real n[:] = {-1.5, -1.25} "Coefficients n[:]"; - algorithm - psat := exp(a[1] - a[1] * r1 ^ n[1] + a[2] - a[2] * r1 ^ n[2]) * ptriple; - annotation( - Inline = false, - smoothOrder = 5, - derivative = sublimationPressureIce_der, - Documentation(info = " -

    Sublimation pressure of water below the triple point temperature is computed from temperature.

    -

    Source: W Wagner, A Saul, A Pruss: "International equations for the pressure along the melting and along the sublimation curve of ordinary water substance", equation 3.5

    - ")); - end sublimationPressureIce; - - replaceable function sublimationPressureIce_der "Derivative function for 'sublimationPressureIce'" - extends Modelica.Icons.Function; - input SI.Temperature Tsat "Sublimation temperature"; - input Real dTsat(unit = "K/s") "Sublimation temperature derivative"; - output Real psat_der(unit = "Pa/s") "Sublimation pressure derivative"; - protected - SI.Temperature Ttriple = 273.16 "Triple point temperature"; - SI.AbsolutePressure ptriple = 611.657 "Triple point pressure"; - Real r1 = Tsat / Ttriple "Common subexpression 1"; - Real r1_der = dTsat / Ttriple "Derivative of common subexpression 1"; - Real a[:] = {-13.9281690, 34.7078238} "Coefficients a[:]"; - Real n[:] = {-1.5, -1.25} "Coefficients n[:]"; - algorithm -//psat := exp(a[1] - a[1]*r1^n[1] + a[2] - a[2]*r1^n[2]) * ptriple; - psat_der := exp(a[1] - a[1] * r1 ^ n[1] + a[2] - a[2] * r1 ^ n[2]) * ptriple * ((-a[1] * (r1 ^ (n[1] - 1) * n[1] * r1_der)) - a[2] * (r1 ^ (n[2] - 1) * n[2] * r1_der)); - annotation( - Inline = false, - smoothOrder = 5, - Documentation(info = " -

    Sublimation pressure of water below the triple point temperature is computed from temperature.

    -

    Source: W Wagner, A Saul, A Pruss: "International equations for the pressure along the melting and along the sublimation curve of ordinary water substance", equation 3.5

    - ")); - end sublimationPressureIce_der; - - replaceable function enthalpyOfVaporization "Return vaporization enthalpy of condensing fluid" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - output SpecificEnthalpy r0 "Vaporization enthalpy"; - algorithm - r0 := water.cp * (reference_T - T) + steam.h_lv + steam.cp * (T - reference_T); - annotation( - Inline = true, - smoothOrder = 5, - Documentation(info = " -

    Enthalpy of vaporization of water is computed from temperature.

    -

    As the enthalpy is a state function, it does not depend on the transformation path. - Therefore, the enthalpy of vaporisation at a given temperature is computed from the enthalpy of vaporisation at 2°C corrected by the sensible enthalpy diffence between the temperature T and 0°C

    - ")); - end enthalpyOfVaporization; - - replaceable function enthalpyOfLiquid "Return enthalpy of liquid water as a function of temperature T(use enthalpyOfWater instead)" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - output SpecificEnthalpy h "Liquid enthalpy"; - algorithm - h := water.cp * (T - reference_T); - annotation( - Inline = true, - smoothOrder = 5, - Documentation(info = " -

    Specific enthalpy of water is computed from temperature and constant specific heat capacity.

    - ")); - end enthalpyOfLiquid; - - replaceable function enthalpyOfGas "Return specific enthalpy of gas (air and steam) as a function of temperature T and composition X (only valide for phi<1)" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - input MassFraction[:] X "Vector of mass fractions"; - output SpecificEnthalpy h "Specific enthalpy"; - algorithm - h := (steam.cp * (T - reference_T) + steam.h_lv) * X[Water] + dryair.cp * (T - reference_T) * (1.0 - X[Water]); - annotation( - Inline = true, - smoothOrder = 5, - Documentation(info = " - Specific enthalpy of moist air is computed from temperature and constant specific heat capacity, provided all water is in the gaseous state. The first entry in the composition vector X must be the mass fraction of steam. For a function that also covers the fog region please refer to h_dTX. -")); - end enthalpyOfGas; - - replaceable function enthalpyOfCondensingGas "Return specific enthalpy of steam as a function of temperature T" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - output SpecificEnthalpy h "Specific enthalpy"; - algorithm - h := steam.cp * (T - reference_T) + steam.h_lv; - annotation( - Inline = true, - smoothOrder = 5, - Documentation(info = " - Specific enthalpy of steam is computed from temperature and constant specific heat capacity. -")); - end enthalpyOfCondensingGas; - - replaceable function enthalpyOfNonCondensingGas "Return specific enthalpy of dry air as a function of temperature T" - extends Modelica.Icons.Function; - input Temperature T "Temperature"; - output SpecificEnthalpy h "Specific enthalpy"; - algorithm - h := dryair.cp * (T - reference_T); - annotation( - Inline = true, - smoothOrder = 5, - Documentation(info = " - Specific enthalpy of dry air is computed from temperature and constant specific heat capacity. -")); - end enthalpyOfNonCondensingGas; - - function enthalpyOfWater "Computes specific enthalpy of water (solid/liquid) near atmospheric pressure from temperature T" - extends Modelica.Icons.Function; - input SIunits.Temperature T "Temperature"; - output SIunits.SpecificEnthalpy h "Specific enthalpy of water"; - - algorithm -/*simple model assuming constant properties: - heat capacity of solid water: 2050 J/kg - enthalpy of fusion (liquid=>solid): 333000 J/kg*/ - h := Utilities.spliceFunction(water.cp * (T - reference_T), ice.cp * (T - reference_T) - ice.h_sl, T - 273.16, 0.1); - annotation( - derivative = enthalpyOfWater_der, - Documentation(info = " - Specific enthalpy of water (liquid and solid) is computed from temperature using constant properties as follows:
    -
      -
    • heat capacity of liquid water:water(record).cp J/kg
    • -
    • heat capacity of solid water: 2050 J/kg
    • -
    • enthalpy of fusion (liquid=>solid): 333000 J/kg
    • -
    - Pressure is assumed to be around 1 bar. This function is usually used to determine the specific enthalpy of the liquid or solid fraction of moist air. - ")); - end enthalpyOfWater; - - function enthalpyOfWater_der "Derivative function of enthalpyOfWater" - extends Modelica.Icons.Function; - input SIunits.Temperature T "Temperature"; - input Real dT(unit = "K/s") "Time derivative of temperature"; - output Real dh(unit = "J/(kg.s)") "Time derivative of specific enthalpy"; - - algorithm -/*simple model assuming constant properties: - heat capacity of solid water: 2050 J/kg - enthalpy of fusion (liquid=>solid): 333000 J/kg*/ -//h:=Utilities.spliceFunction(water.cp*(T-273.15),2050*(T-273.15)-333000,T-273.16,0.1); - dh := Utilities.spliceFunction_der(water.cp * (T - reference_T), ice.cp * (T - reference_T) - ice.h_sl, T - 273.16, 0.1, water.cp * dT, ice.cp * dT, dT, 0); - annotation( - Documentation(info = " - Derivative function for enthalpyOfWater. - - ")); - end enthalpyOfWater_der; - - redeclare function extends pressure "Returns pressure of ideal gas as a function of the thermodynamic state record" - protected - SI.MassFraction X_liquid "Mass fraction of liquid or solid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - - algorithm - d_sat := saturationDensity(state.T); - X_liquid := max(state.d * state.X[Water] - d_sat, 0) / state.d; - X_steam := state.X[Water] - X_liquid; - X_air := 1 - state.X[Water]; - p := state.d * (dryair.R * X_air + steam.R * X_steam) * state.T; - annotation( - smoothOrder = 5, - Documentation(info = " -

    Pressure is returned from the thermodynamic state record input from the density and the temparture applying the ideal gas law.

    - ")); - end pressure; - - redeclare function extends temperature "Return temperature of ideal gas as a function of the thermodynamic state record" - algorithm - T := state.T; - annotation( - smoothOrder = 2, - Documentation(info = " - Temperature is returned from the thermodynamic state record input as a simple assignment. - ")); - end temperature; - - function T_phX "Return temperature as a function of pressure p, specific enthalpy h and composition X" - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input MassFraction[:] X "Mass fractions of composition"; - output Temperature T "Temperature"; - - protected - SI.MoleFraction Y[2] "Mole fraction of species in the medium"; - SI.MassFraction X_liq "Mass fraction of liquid"; - SI.Temperature T_sat "Steam saturation temperature at given steam pressure"; - SI.MassFraction X_steam "Mass fraction of steam in medium"; - Integer i; - - algorithm - i := 0; - /* specific enthalpy formula is assumed to be - h = X_air*dryair.cp*(T_sat-T_ref)+X_steam*(steam.cp*(T_sat-T_ref)+h_lv)+(1-X_air-X_steam)*water.cp*(T_sat-T_ref) */ - T := (h - X[Water] * steam.h_lv) / (X[Air] * dryair.cp + X[Water] * steam.cp) + reference_T; - Y := massToMoleFractions(X = X, MMX = MMX); - T_sat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p * Y[Water]); - if T < T_sat then - while abs((T - T_sat) / T_sat) > 1e-5 loop - T := T_sat; - X_steam := ( h - (T - reference_T) * (X[Water] * water.cp + X[Air] * dryair.cp) ) / ( steam.h_lv + (steam.cp - water.cp) * (T - reference_T) ); - X_liq := X[Water] - X_steam; - Y := massToMoleFractions(X = {X_steam/(1 - X_liq), 1-X_steam/(1 - X_liq) }, MMX = MMX); - T_sat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p * Y[Water]); - i := i + 1; - end while; - T := T_sat; - else - X_steam := X[Water]; - X_liq := 0.0; - end if; - - //The region of solid water is not allowed - assert(T > 273.16, "The solid region for water in the T_phX function is not allowed", level = AssertionLevel.error) ; - //Modelica.Utilities.Streams.print("i = "+String(i)) ; - annotation( - Documentation(info = " -

    - Temperature is computed from pressure, specific enthalpy and composition. - Loop over the saturation temperature is performed for the fog region and for dry mixture, - the temperature is computed from analytic inversion of the enthalpy relation with respect to the temperature. -

    - - ")); - end T_phX; - - redeclare function extends density "Returns density as a function of the thermodynamic state record" - algorithm - d := state.d; - annotation( - smoothOrder = 2, - Documentation(info = " - Density is returned from the thermodynamic state record input as a simple assignment. - ")); - end density; - - function d_phX "Returns density as a function of pressure p, enthalpy h and composition X" - extends Modelica.Icons.Function; - input AbsolutePressure p "Pressure"; - input SpecificEnthalpy h "Specific enthalpy"; - input MassFraction X[:] = reference_X "Mass fractions"; - output Density d "Density"; - protected - SI.Temperature T; - SI.MassFraction X_steam "Steam mass fraction in the medium"; - SI.MassFraction X_liquid "Liquid water mass fraction in the medium"; - SI.MolarMass MMmix "Molar mass of gas mixture"; - algorithm - T := T_phX(p = p, h = h, X = X); - X_steam := (h - (X[Air] * (dryair.cp - water.cp) + water.cp) * (T - reference_T)) / ((steam.cp - water.cp) * (T - reference_T) + steam.h_lv); - X_steam := min(X_steam, X[Water]); - X_liquid := max(X[Water] - X_steam, 0.0); - MMmix := (X_steam / (1 - X_liquid) / steam.MM + X[Air] / (1 - X_liquid) / dryair.MM) ^ (-1); - d := p / (Modelica.Constants.R / MMmix * T); - annotation( - smoothOrder = 2, - Documentation(info = " - Density is returned from the pressure p, specific enthalpy h and composition X. - ")); - end d_phX; - - redeclare function extends specificEnthalpy "Return specific enthalpy of moist air as a function of the thermodynamic state record" - algorithm - h := h_dTX(state.d, state.T, state.X); - annotation( - smoothOrder = 2, - Documentation(info = " - Specific enthalpy of moist air is computed from the thermodynamic state record. The fog region is included for both, ice and liquid fog. - ")); - end specificEnthalpy; - - function h_dTX "Return specific enthalpy of moist air as a function of density d, temperature T and composition X" - extends Modelica.Icons.Function; - input SI.Density d "Density"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - output SI.SpecificEnthalpy h "Specific enthalpy at p, T, X"; - protected - SI.MassFraction X_liquid "Mass fraction of liquid or solid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - algorithm - d_sat := saturationDensity(T); - X_liquid := max(d * X[Water] - d_sat, 0) / d; - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; -//h := X_air*dryair.cp*(T-273.15) + X_steam*(steam.cp*(T-273.15)+steam.h_lv) + enthalpyOfWater(T)*X_liquid; - h := X_air * dryair.cp * (T - reference_T) + X_steam * (steam.cp * (T - reference_T) + steam.h_lv) + X_liquid * water.cp * (T - reference_T); - - annotation( - Inline = false, - derivative=h_dTX_der, - Documentation(info = " - Specific enthalpy of moist air is computed from density, temperature and composition with X[1] as the total water mass fraction. The fog region is included for both, ice and liquid fog. - ")); - end h_dTX; - - function h_dTX_der "Derivative function of h_dTX" - extends Modelica.Icons.Function; - input SI.Density d "Density"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - input Real dd(unit = "kg/(m3.s)") "Density derivative"; - input Real dT(unit = "K/s") "Temperature derivative"; - input Real dX[:](each unit = "1/s") "Composition derivative"; - output Real h_der(unit = "J/(kg.s)") "Time derivative of specific enthalpy"; - - protected - SI.MassFraction X_liquid "Mass fraction of liquid or solid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - Real dX_steam(unit = "1/s") "Time derivative of steam mass fraction"; - Real dX_air(unit = "1/s") "Time derivative of dry air mass fraction"; - Real dX_liq(unit = "1/s") "Time derivative of liquid/solid water mass fraction"; - Real dd_sat(unit = "kg/(m3.s)") "Time derivative of saturation density"; - - algorithm - d_sat := saturationDensity(T); - X_liquid := Utilities.smoothMax(X[Water] - d_sat/d, 0.0, 1e-6); - //X_liquid := max(X[Water] - d_sat/d, 0); - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; - dX_air := -dX[Water]; - dd_sat := saturationDensity_der(T, dT); - dX_liq := Utilities.smoothMax_der(X[Water] - d_sat/d, 0.0, 1e-5, (d * dX[Water] + dd * X[Water] - dd_sat) / d - (d * X[Water] - d_sat) / (d * d) * dd, 0, 0); - //dX_liq := if X_liquid > 0.0 then dX[Water] - dd_sat / d + dd*d_sat / (d*d) else 0.0; - dX_steam := dX[Water] - dX_liq; - h_der := X_air * dryair.cp * dT + dX_air * dryair.cp * (T - reference_T) + X_steam * steam.cp * dT + dX_steam * (steam.h_lv + steam.cp * (T - reference_T)) + X_liquid * water.cp * dT + dX_liq * water.cp * (T - reference_T); - annotation( - Inline = false, - smoothOrder = 1, - Documentation(info = " - Derivative function for h_dTX. - ")); - end h_dTX_der; - - function h_pTX "Return specific enthalpy of moist air as a function of pressure p, temperature T and composition X" - extends Modelica.Icons.Function; - input SI.Pressure p "Pressure"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - output SI.SpecificEnthalpy h "Specific enthalpy at p, T, X"; - protected - SI.AbsolutePressure p_steam_sat "partial saturation pressure of steam"; - SI.MassFraction X_sat "Absolute humidity per unit mass of moist air"; - SI.MassFraction X_liquid "Mass fraction of liquid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - algorithm - p_steam_sat := saturationPressure(T); - X_sat := min(p_steam_sat * k_mair / max(100 * Modelica.Constants.eps, p - p_steam_sat) * (1 - X[Water]), 1.0); - X_liquid := max(X[Water] - X_sat, 0.0); - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; - h := (X_steam * steam.cp + X_air * dryair.cp) * (T - reference_T) + X_steam * steam.h_lv + enthalpyOfWater(T) * X_liquid; - annotation( - derivative = h_pTX_der, - Inline = false, - Documentation(info = " -

    - Specific enthalpy of moist air is computed from pressure, temperature and composition with X[1] as the total water mass fraction. - The fog region is included for both, ice and liquid fog. -

    -

    - This function is only valid for a mass fraction of air X[Air] > 1e-4. - Otherwise, when the mixture is fully composed of water, the ratio between steam and liquid water cannot be determine since the pressure p and the temperature T remains constant whatever the ratio. -

    - ")); - end h_pTX; - - function h_pTX_der "Derivative function of h_pTX" - extends Modelica.Icons.Function; - input SI.Pressure p "Pressure"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - input Real dp(unit = "Pa/s") "Pressure derivative"; - input Real dT(unit = "K/s") "Temperature derivative"; - input Real dX[:](each unit = "1/s") "Composition derivative"; - output Real h_der(unit = "J/(kg.s)") "Time derivative of specific enthalpy"; - protected - SI.AbsolutePressure p_steam_sat "partial saturation pressure of steam"; - SI.MassFraction X_sat "Absolute humidity per unit mass of moist air"; - SI.MassFraction X_liquid "Mass fraction of liquid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.MassFraction x_sat "Absolute humidity per unit mass of dry air at saturation"; - Real dX_steam(unit = "1/s") "Time derivative of steam mass fraction"; - Real dX_air(unit = "1/s") "Time derivative of dry air mass fraction"; - Real dX_liq(unit = "1/s") "Time derivative of liquid/solid water mass fraction"; - Real dps(unit = "Pa/s") "Time derivative of saturation pressure"; - Real dx_sat(unit = "1/s") "Time derivative of absolute humidity per unit mass of dry air"; - algorithm - p_steam_sat := saturationPressure(T); - x_sat := p_steam_sat * k_mair / max(100 * Modelica.Constants.eps, p - p_steam_sat); - X_sat := min(x_sat * (1 - X[Water]), 1.0); - X_liquid := Utilities.smoothMax(X[Water] - X_sat, 0.0, 1e-5); - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; - dX_air := -dX[Water]; - dps := saturationPressure_der(Tsat = T, dTsat = dT); - dx_sat := k_mair * (dps * (p - p_steam_sat) - p_steam_sat * (dp - dps)) / (p - p_steam_sat) / (p - p_steam_sat); - dX_liq := Utilities.smoothMax_der(X[Water] - X_sat, 0.0, 1e-5, (1 + x_sat) * dX[Water] - (1 - X[Water]) * dx_sat, 0, 0); - dX_steam := dX[Water] - dX_liq; - h_der := X_air * dryair.cp * dT + dX_air * dryair.cp * (T - reference_T) + X_steam * steam.cp * dT + dX_steam * (steam.h_lv + steam.cp * (T - reference_T)) + X_liquid * enthalpyOfWater_der(T = T, dT = dT) + dX_liq * enthalpyOfWater(T); - annotation( - Inline = false, - smoothOrder = 1, - Documentation(info = " - Derivative function for h_pTX. - ")); - end h_pTX_der; - - redeclare function extends isentropicExponent "Return isentropic exponent (only for gas fraction!)" - algorithm - gamma := specificHeatCapacityCp(state) / specificHeatCapacityCv(state); - end isentropicExponent; - - function isentropicEnthalpyApproximation "Approximate calculation of h_is from upstream properties, downstream pressure, gas part only" - extends Modelica.Icons.Function; - input AbsolutePressure p2 "Downstream pressure"; - input ThermodynamicState state "Thermodynamic state at upstream location"; - output SpecificEnthalpy h_is "Isentropic enthalpy"; - protected - SpecificEnthalpy h "Specific enthalpy at upstream location"; - IsentropicExponent gamma = isentropicExponent(state) "Isentropic exponent"; - protected - AbsolutePressure p1 "Upstream pressure"; - algorithm - h := {steam.cp * (state.T - reference_T), dryair.cp * (state.T - reference_T)} * state.X; - p1 := state.d * (state.X[Water] * steam.R + (1 - state.X[Water]) * dryair.R) * state.T; - h_is := h + gamma / (gamma - 1.0) * (state.T * gasConstant_X(state.X)) * ((p2 / p1) ^ ((gamma - 1) / gamma) - 1.0); - end isentropicEnthalpyApproximation; - - redeclare function extends specificInternalEnergy "Return specific internal energy of moist air as a function of the thermodynamic state record" - extends Modelica.Icons.Function; - - algorithm - u := specificInternalEnergy_dTX(state.d, state.T, state.X); - annotation( - smoothOrder = 2, - Documentation(info = " - Specific internal energy is determined from the thermodynamic state record, assuming that the liquid or solid water volume is negligible. - ")); - end specificInternalEnergy; - - function specificInternalEnergy_dTX "Return specific internal energy of moist air as a function of density d, temperature T and composition X" - extends Modelica.Icons.Function; - input SI.Density d "Density"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - output SI.SpecificInternalEnergy u "Specific internal energy"; - protected - SI.MassFraction X_liquid "Mass fraction of liquid or solid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.MassFraction d_sat "Steam water density of saturation boundary in kg_water/m3"; - Real R_gas "Ideal gas constant"; - algorithm - d_sat := saturationDensity(T); - X_liquid := max(d * X[Water] - d_sat, 0) / d; - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; - R_gas := dryair.R * X_air / (1 - X_liquid) + steam.R * X_steam / (1 - X_liquid); - u := X_steam * steam.cp * (T - reference_T) + X_air * dryair.cp * (T - reference_T) + enthalpyOfWater(T) * X_liquid - R_gas * T; - annotation( - derivative = specificInternalEnergy_dTX_der, - Documentation(info = " - Specific internal energy is determined from density d, temperature T and composition X, assuming that the liquid or solid water volume is negligible. - ")); - end specificInternalEnergy_dTX; - - function specificInternalEnergy_dTX_der "Derivative function for specificInternalEnergy_dTX" - extends Modelica.Icons.Function; - input SI.Density d "Density"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - input Real dd(unit = "kg/(m3.s)") "Density derivative"; - input Real dT(unit = "K/s") "Temperature derivative"; - input Real dX[:](each unit = "1/s") "Mass fraction derivatives"; - output Real u_der(unit = "J/(kg.s)") "Specific internal energy derivative"; - protected - SI.MassFraction X_liquid "Mass fraction of liquid or solid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - SI.SpecificHeatCapacity R_gas "Ideal gas constant"; - Real dX_steam(unit = "1/s") "Time derivative of steam mass fraction"; - Real dX_air(unit = "1/s") "Time derivative of dry air mass fraction"; - Real dX_liq(unit = "1/s") "Time derivative of liquid/solid water mass fraction"; - Real dd_sat(unit = "kg/(m3.s)") "Time derivative of saturation density"; - Real dR_gas(unit = "J/(kg.K.s)") "Time derivative of ideal gas constant"; - algorithm - d_sat := saturationDensity(T); - X_liquid := Utilities.spliceFunction(max(d * X[Water] - d_sat, 0) / d, 0.0, max(d * X[Water] - d_sat, 0) / d, 1e-6); - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; - R_gas := steam.R * X_steam / (1 - X_liquid) + dryair.R * X_air / (1 - X_liquid); - dd_sat := saturationDensity_der(T, dT); - dX_liq := Utilities.spliceFunction_der((d * X[Water] - d_sat) / d, 0.0, (d * X[Water] - d_sat) / d, 1e-6, (d * dX[Water] + dd * X[Water] - dd_sat) / d - (d * X[Water] - d_sat) / (d * d) * dd, 0.0, (d * dX[Water] + dd * X[Water] - dd_sat) / d - (d * X[Water] - d_sat) / (d * d) * dd, 0.0); - dX_air := -dX[Water]; - dX_steam := dX[Water] - dX_liq; - dR_gas := (steam.R * (dX_steam * (1 - X_liquid) + dX_liq * X_steam) + dryair.R * (dX_air * (1 - X_liquid) + dX_liq * X_air)) / (1 - X_liquid) / (1 - X_liquid); - u_der := h_dTX_der(d, T, X, dd, dT, dX) - R_gas * dT - dR_gas * T annotation( - Documentation(info = " - Derivative function for specificInternalEnergy_dTX. - ")); - end specificInternalEnergy_dTX_der; - - redeclare function extends specificEntropy "Return specific entropy from thermodynamic state record" - algorithm - s := s_dTX(state.d, state.T, state.X); - annotation( - Inline = false, - smoothOrder = 2, - Documentation(info = " - Specific entropy is calculated from the thermodynamic state record, assuming ideal gas behavior and including entropy of mixing. Liquid but not solid water is taken into account. - ")); - end specificEntropy; - - function s_dTX "Return specific entropy of moist air as a function of density d, temperature T and composition X" - extends Modelica.Icons.Function; - input SI.Density d "Density"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - output SI.SpecificEntropy s "Specific entropy at p, T, X"; - protected - SI.Pressure p[2] "Vector of partial pressure of water and dry air"; - SI.MassFraction X_liquid "Mass fraction of liquid or solid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.MassFraction d_sat "Steam water density of saturation boundary in kg_water/m3"; - algorithm - d_sat := saturationDensity(T); - X_liquid := max(d * X[Water] - d_sat, 0) / d; - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; - p[Water] := d * X_steam * steam.R * T; - p[Air] := d * X_air * dryair.R * T; - s := X_air * dryair.cp * Modelica.Math.log(T / reference_T) + X_steam * steam.cp * Modelica.Math.log(T / reference_T) - Modelica.Constants.R * (Utilities.smoothMax(X_steam / MMX[Water], 0.0, 1e-9) * Modelica.Math.log(max(p[Water], Modelica.Constants.eps) / reference_p) + Utilities.smoothMax(X_air / MMX[Air], 0.0, 1e-9) * Modelica.Math.log(max(p[Air], Modelica.Constants.eps) / reference_p)) + X_liquid * water.cp * Modelica.Math.log(T / reference_T) + X_liquid * enthalpyOfVaporization(T) / T; - annotation( - derivative = s_dTX_der, - Inline = false, - Documentation(info = " - Specific entropy of moist air is computed from density, temperature and composition with X[1] as the total water mass fraction. - ")); - end s_dTX; - - function s_dTX_der "Derivative function of h_dTX" - extends Modelica.Icons.UnderConstruction; - input SI.Density d "Density"; - input SI.Temperature T "Temperature"; - input SI.MassFraction X[:] "Mass fractions of moist air"; - input Real dd(unit = "kg/(m3.s)") "Derivative of density"; - input Real dT(unit = "K/s") "Derivative of temperature"; - input Real dX[nX](each unit = "1/s") "Derivative of mass fractions"; - output Real ds(unit = "J/(kg.K.s)") "Specific entropy at p, T, X"; - protected - SI.Pressure p[2] "Vector of partial pressure of water and dry air"; - SI.MassFraction X_liquid "Mass fraction of liquid or solid water"; - SI.MassFraction X_steam "Mass fraction of steam water"; - SI.MassFraction X_air "Mass fraction of air"; - SI.MassFraction d_sat "Steam water density of saturation boundary in kg_water/m3"; - Real dp[2](unit = "Pa/s") "Time derivative of vector of partial pressure of water and dry air"; - Real dX_steam(unit = "1/s") "Time derivative of steam mass fraction"; - Real dX_air(unit = "1/s") "Time derivative of dry air mass fraction"; - Real dX_liq(unit = "1/s") "Time derivative of liquid/solid water mass fraction"; - Real dd_sat(unit = "kg/(m3.s)") "Time derivative of saturation density"; - algorithm - d_sat := saturationDensity(T); - X_liquid := Utilities.smoothMax(max(d * X[Water] - d_sat, 0) / d, 0.0, 1e-5); - X_steam := X[Water] - X_liquid; - X_air := 1 - X[Water]; - p[Water] := d * X_steam * steam.R * T; - p[Air] := d * X_air * dryair.R * T; - dX_air := -dX[Water]; -//dd_sat = dd_sat/dp*dp/dT*dT - dd_sat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhov_dp(Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T)) * Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat_der(T, dT); - dX_liq := Utilities.smoothMax_der(max(d * X[Water] - d_sat, 0) / d, 0.0, 1e-5, d * dX[Water] + dd * X[Water] - dd_sat, 0, 0); - dX_steam := dX[Water] - dX_liq; - dp[Water] := dd * X_steam * steam.R * T + d * (dX_steam * steam.R * T + X_steam * steam.R * dT); - dp[Air] := dd * X_air * dryair.R * T + d * (dX_air * dryair.R * T + X_air * dryair.R * dT); - ds := (1 - X[Water]) * dryair.cp * dT / T + dX_air * dryair.cp * Modelica.Math.log(T / reference_T) + X[Water] * steam.cp * dT / T + dX[Water] * Modelica.Math.log(T / reference_T) - Modelica.Constants.R * (1 / MMX[Water] * (Utilities.smoothMax_der(X[Water], 0.0, 1e-9, dX[Water], 0.0, 0.0) * Modelica.Math.log(max(dp[Water], Modelica.Constants.eps) / reference_p) + dp[Water] / p[Water] * Utilities.smoothMax(X[Water], 0.0, 1e-9)) + 1 / MMX[Air] * (Utilities.smoothMax_der(X[Air], 0.0, 1e-9, dX[Air], 0.0, 0.0) * Modelica.Math.log(max(p[Air], Modelica.Constants.eps) / reference_p) + dp[Air] / p[Air] * Utilities.smoothMax(X[Air], 0.0, 1e-9))) + dX_liq * water.cp * Modelica.Math.log(T / reference_T) + X_liquid * water.cp * dT / T; - annotation( - Inline = false, - smoothOrder = 1, - Documentation(info = " - Specific entropy of moist air is computed from density, temperature and composition with X[1] as the total water mass fraction. - ")); - end s_dTX_der; - - redeclare function extends specificGibbsEnergy "Return specific Gibbs energy as a function of the thermodynamic state record, only valid for phi<1" - extends Modelica.Icons.Function; - - algorithm - g := h_dTX(state.d, state.T, state.X) - state.T * specificEntropy(state); - annotation( - smoothOrder = 2, - Documentation(info = " - The Gibbs Energy is computed from the thermodynamic state record for moist air with a water content below saturation. - ")); - end specificGibbsEnergy; - - redeclare function extends specificHelmholtzEnergy "Return specific Helmholtz energy as a function of the thermodynamic state record, only valid for phi<1" - extends Modelica.Icons.Function; - - algorithm - f := h_dTX(state.d, state.T, state.X) - gasConstant(state) * state.T - state.T * specificEntropy(state); - annotation( - smoothOrder = 2, - Documentation(info = " - The Specific Helmholtz Energy is computed from the thermodynamic state record for moist air with a water content below saturation. - ")); - end specificHelmholtzEnergy; - - redeclare function extends specificHeatCapacityCp "Return specific heat capacity at constant pressure as a function of the thermodynamic state record" - protected - SI.Density d_sat "Steam water density of saturation boundary in kg_water/m3"; - SI.MassFraction X_liquid; - SI.MassFraction X_steam; - SI.MassFraction X_air; - - algorithm - d_sat := saturationDensity(state.T); - X_liquid := max(state.d * state.X[Water] - d_sat, 0) / state.d; - X_steam := state.X[Water] - X_liquid; - X_air := 1 - state.X[Water]; - cp := steam.cp * X_steam + dryair.cp * X_air + water.cp * X_liquid; -// cp := steam.cp*state.X[Water] + dryair.cp*(1-state.X[Water]); - annotation( - Inline = false, - smoothOrder = 2, - Documentation(info = " - The specific heat capacity at constant pressure cp is computed from temperature and composition for a mixture of steam (X[1]) and dry air. Solid water region is excluded. - ")); - end specificHeatCapacityCp; - - redeclare function extends specificHeatCapacityCv "Return specific heat capacity at constant volume as a function of the thermodynamic state record, only valide for phi<1" - algorithm - cv := (steam.cp - steam.R) * state.X[Water] + (dryair.cp - dryair.R) * (1 - state.X[Water]); - annotation( - Inline = true, - smoothOrder = 2, - Documentation(info = " - The specific heat capacity at constant density cv is computed from temperature and composition for a mixture of steam (X[1]) and dry air. All water is assumed to be in the vapor state. - ")); - end specificHeatCapacityCv; - - redeclare function extends dynamicViscosity "Return dynamic viscosity as a function of the thermodynamic state record, valid from 123.15 K to 1273.15 K" - import Modelica.Media.Incompressible.TableBased.Polynomials_Temp; - - algorithm - eta := 1.81063e-5; - annotation( - smoothOrder = 5, - Documentation(info = " -

    Dynamic viscosity is constant and the value is computed from the NIST at the reference temperature and pressure and for dry air

    - ")); - end dynamicViscosity; - - redeclare function extends thermalConductivity "Return thermal conductivity as a function of the thermodynamic state record, valid from 123.15 K to 1273.15 K" - import Modelica.Media.Incompressible.TableBased.Polynomials_Temp; - import Cv = Modelica.SIunits.Conversions; - - algorithm - lambda := 0.0258738; - annotation( - smoothOrder = 2, - Documentation(info = " -

    Thermal conductivity is constant and the value is computed from the NIST at the reference temperature and pressure and for dry air

    - ")); - end thermalConductivity; - - redeclare function extends velocityOfSound - algorithm - a := sqrt(isentropicExponent(state) * gasConstant(state) * temperature(state)); - annotation( - Documentation(revisions = " -

    2012-01-12 Stefan Wischhusen: Initial Release.

    - ")); - end velocityOfSound; - - redeclare function extends isobaricExpansionCoefficient - algorithm - beta := 1 / temperature(state); - annotation( - Documentation(revisions = " -

    2012-01-12 Stefan Wischhusen: Initial Release.

    - ")); - end isobaricExpansionCoefficient; - - redeclare function extends isothermalCompressibility - algorithm - kappa := 1 / pressure(state); - annotation( - Documentation(revisions = " -

    2012-01-12 Stefan Wischhusen: Initial Release.

    - ")); - end isothermalCompressibility; - - redeclare function extends isentropicEnthalpy "Isentropic enthalpy (only valid for phi<1)" - extends Modelica.Icons.Function; - - algorithm - h_is := isentropicEnthalpyApproximation(p2 = p_downstream, state = refState); - annotation(); - end isentropicEnthalpy; - - package Utilities "Utility functions" - extends Modelica.Icons.UtilitiesPackage; - - function spliceFunction "Spline interpolation of two functions" - extends Modelica.Icons.Function; - input Real pos "Returned value for x-deltax >= 0"; - input Real neg "Returned value for x+deltax <= 0"; - input Real x "Function argument"; - input Real deltax = 1 "Region around x with spline interpolation"; - output Real out; - protected - Real scaledX; - Real scaledX1; - Real y; - algorithm - scaledX1 := x / deltax; - scaledX := scaledX1 * Modelica.Math.asin(1); - if scaledX1 <= (-0.999999999) then - y := 0; - elseif scaledX1 >= 0.999999999 then - y := 1; - else - y := (Modelica.Math.tanh(Modelica.Math.tan(scaledX)) + 1) / 2; - end if; - out := pos * y + (1 - y) * neg; - annotation( - derivative = spliceFunction_der); - end spliceFunction; - - function spliceFunction_der "Derivative of spliceFunction" - extends Modelica.Icons.Function; - input Real pos; - input Real neg; - input Real x; - input Real deltax = 1; - input Real dpos; - input Real dneg; - input Real dx; - input Real ddeltax = 0; - output Real out; - protected - Real scaledX; - Real scaledX1; - Real dscaledX1; - Real y; - algorithm - scaledX1 := x / deltax; - scaledX := scaledX1 * Modelica.Math.asin(1); - dscaledX1 := (dx - scaledX1 * ddeltax) / deltax; - if scaledX1 <= (-0.99999999999) then - y := 0; - elseif scaledX1 >= 0.9999999999 then - y := 1; - else - y := (Modelica.Math.tanh(Modelica.Math.tan(scaledX)) + 1) / 2; - end if; - out := dpos * y + (1 - y) * dneg; - if abs(scaledX1) < 1 then - out := out + (pos - neg) * dscaledX1 * Modelica.Math.asin(1) / 2 / (Modelica.Math.cosh(Modelica.Math.tan(scaledX)) * Modelica.Math.cos(scaledX)) ^ 2; - end if; - end spliceFunction_der; - - function smoothMax - extends Modelica.Icons.Function; - import Modelica.Math; - input Real x1 "First argument of smooth max operator"; - input Real x2 "Second argument of smooth max operator"; - input Real dx "Approximate difference between x1 and x2, below which regularization starts"; - output Real y "Result of smooth max operator"; - algorithm - y := max(x1, x2) + Math.log(exp(4 / dx * (x1 - max(x1, x2))) + exp(4 / dx * (x2 - max(x1, x2)))) / (4 / dx); - annotation( - smoothOrder = 2, - Documentation(info = " -

    An implementation of Kreisselmeier Steinhauser smooth maximum

    - ")); - end smoothMax; - - function smoothMax_der - extends Modelica.Icons.Function; - import Modelica.Math.exp; - import Modelica.Math.log; - input Real x1 "First argument of smooth max operator"; - input Real x2 "Second argument of smooth max operator"; - input Real dx "Approximate difference between x1 and x2, below which regularization starts"; - input Real dx1; - input Real dx2; - input Real ddx; - output Real dy "Derivative of smooth max operator"; - algorithm - dy := (if x1 > x2 then dx1 else dx2) + 0.25 * (((4 * (dx1 - (if x1 > x2 then dx1 else dx2)) / dx - 4 * (x1 - max(x1, x2)) * ddx / dx ^ 2) * exp(4 * (x1 - max(x1, x2)) / dx) + (4 * (dx2 - (if x1 > x2 then dx1 else dx2)) / dx - 4 * (x2 - max(x1, x2)) * ddx / dx ^ 2) * exp(4 * (x2 - max(x1, x2)) / dx)) * dx / (exp(4 * (x1 - max(x1, x2)) / dx) + exp(4 * (x2 - max(x1, x2)) / dx)) + log(exp(4 * (x1 - max(x1, x2)) / dx) + exp(4 * (x2 - max(x1, x2)) / dx)) * ddx); - annotation( - Documentation(info = " -

    An implementation of Kreisselmeier Steinhauser smooth maximum

    - ")); - end smoothMax_der; - end Utilities; -end MoistAir; \ No newline at end of file diff --git a/Media/MyMedia/package.mo b/Media/MyMedia/package.mo deleted file mode 100644 index 4a0a7f0..0000000 --- a/Media/MyMedia/package.mo +++ /dev/null @@ -1,60 +0,0 @@ -within TAeZoSysPro.Media; - -package MyMedia - extends Modelica.Icons.Package; - -// inherite extend the package of the media to propagate it to all components using MyMedia as default media -//extends Modelica.Media.Air.ReferenceAir.Air_pT ; -extends Modelica.Media.Air.SimpleAir ; -//extends TAeZoSysPro.Media.Air.MoistAir ; -//extends Modelica.Media.Air.MoistAir ; - - annotation( - Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100,100}}), - graphics={ - Line( - points = {{-76,-80},{-62,-30},{-32,40},{4,66},{48,66},{73,45},{62,-8},{48,-50},{38,-80}}, - color={64,64,64}, - smooth=Smooth.Bezier), - Line( - points={{-40,20},{68,20}}, - color={175,175,175}), - Line( - points={{-40,20},{-44,88},{-44,88}}, - color={175,175,175}), - Line( - points={{68,20},{86,-58}}, - color={175,175,175}), - Line( - points={{-60,-28},{56,-28}}, - color={175,175,175}), - Line( - points={{-60,-28},{-74,84},{-74,84}}, - color={175,175,175}), - Line( - points={{56,-28},{70,-80}}, - color={175,175,175}), - Line( - points={{-76,-80},{38,-80}}, - color={175,175,175}), - Line( - points={{-76,-80},{-94,-16},{-94,-16}}, - color={175,175,175})}), - Documentation(info = -" - - MyMedia - - - -

    - The objective of this class is to be used as the default Medium in each module required the definition of a Medium . - This class is inherited of a Media (ReferenceAir, MoistAir, Air_H2 or any Media from the Modelica Standard Library or from TAeZoSysPro. -

    -

    - If the user want to change the media used, it can just change the inherited media and it is propagated to all components. -

    - - -")); -end MyMedia; diff --git a/PDE/Examples/BoundaryStepDiffusion.mo b/PDE/Examples/BoundaryStepDiffusion.mo deleted file mode 100644 index 76833b7..0000000 --- a/PDE/Examples/BoundaryStepDiffusion.mo +++ /dev/null @@ -1,56 +0,0 @@ -within TAeZoSysPro.PDE.Examples; - -model BoundaryStepDiffusion - import pi = Modelica.Constants.pi ; - - extends Modelica.Icons.Example ; - - constant Real std_dev = 0.05 ; - constant Real u_init = 0 ; - constant Real u_left = 20 ; - - parameter Integer N(quantity ="number of discrete layer", min=11) = 11 "Number of layer" ; - parameter Modelica.SIunits.Length L = 1 "length of the domain"; - parameter Real dx = L / N ; - parameter Real x[N+2] = cat(1, {0.0}, linspace(dx/2,L-dx/2,N), {L} ) ; - parameter Real xbis[N+2] = cat(1, {0.0}, linspace(dx/2,L-dx/2,N), {L} ) ; - parameter Modelica.SIunits.DiffusionCoefficient Dth = 0.001 ; - Real[N+2] u_1order ; - Real[N+2] u_analytic ; - - TAeZoSysPro.PDE.ThermalDiffusion.CentralSecondOrder centralSecondOrder( - N = N, - x = linspace(0,L,N+1), - CoeffTimeDer = 1, - CoeffSpaceDer = -Dth, - SourceTerm = zeros(N)) annotation ( - Placement(visible = true, transformation(origin = {0, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -initial equation -// for i in 2:N+2-1 loop -// u_1order[i] = exp(-( (x[i] - L/2) / (2*std_dev) ) ^2) "Initial Condition" ; -// end for ; - - centralSecondOrder.u[2:end-1] = fill(u_init,N) "Initial Condition" ; - - -equation -// Analytical solution -for compt in 1:N+2 loop - u_analytic[compt] = u_left*(1-x[compt]/L) - 2*u_left/pi * sum( 1/i*exp(-(i*Dth^0.5*pi/L)^2*time) * sin(i * pi / L * x[compt]) for i in 1:30 ) ; -end for ; - - - // Boundary conditions - centralSecondOrder.u[1] = if initial() then u_init else u_left "Left boundary condition"; - centralSecondOrder.u[end] = u_init "Right boundary condition"; - - // PDE domain - //centralSecondOrder.SourceTerm = zeros(N); - u_1order = centralSecondOrder.u - - -annotation( - experiment(StartTime = 0, StopTime = 300, Tolerance = 1e-06, Interval = 0.3)); - -end BoundaryStepDiffusion; diff --git a/PDE/Examples/DiffusionGaussian.mo b/PDE/Examples/DiffusionGaussian.mo deleted file mode 100644 index a46deb8..0000000 --- a/PDE/Examples/DiffusionGaussian.mo +++ /dev/null @@ -1,48 +0,0 @@ -within TAeZoSysPro.PDE.Examples; - -model DiffusionGaussian - import pi = Modelica.Constants.pi ; - - extends Modelica.Icons.Example ; - - parameter Integer N(quantity ="number of discrete layer", min=11) = 22 "Number of layer" ; - parameter Modelica.SIunits.Length L = 2 "length of the domain"; - parameter Real dx = L / N ; - parameter Real x[N+2] = cat(1, {0.0}, linspace(dx/2,L-dx/2,N), {L} ) ; - parameter Real xbis[N+2] = cat(1, {0.0}, linspace(dx/2,L-dx/2,N), {L} ) ; - parameter Modelica.SIunits.DiffusionCoefficient Dth = 1 ; - parameter Modelica.SIunits.Time t_0 = 1e-3 " Initial time to avoid divisions by zero"; - Real[N+2] u_1order ; - Real[N+2] u_analytic ; - - TAeZoSysPro.PDE.ThermalDiffusion.CentralSecondOrder centralSecondOrder( - N = N, - x = linspace(0,L,N+1), - CoeffTimeDer = 1, - CoeffSpaceDer = -Dth, - SourceTerm = zeros(N)) annotation ( - Placement(visible = true, transformation(origin = {0, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - -initial equation - for i in 2:N+1 loop - centralSecondOrder.u[i] = 1 / sqrt(4 * Modelica.Constants.pi * Dth * t_0) * exp(- (x[i] - L/2)^2 / (4*Dth*t_0)) "Initial Condition" ; - end for ; - -equation -// Analytical solution -for compt in 1:N+2 loop - u_analytic[compt] = 1 / sqrt(4 * Modelica.Constants.pi * Dth * time) * exp(-(x[compt]-L/2)^2/(4*Dth*time)); -end for ; - - - // Boundary conditions - centralSecondOrder.u[1] = 1 / sqrt(4 * Modelica.Constants.pi * Dth * time) * exp(-(-L/2)^2/(4*Dth*time)) "Left boundary condition"; - centralSecondOrder.u[end] = 1 / sqrt(4 * Modelica.Constants.pi * Dth * time) * exp(-(L/2)^2/(4*Dth*time)) "Right boundary condition"; - - // PDE domain - //centralSecondOrder.SourceTerm = zeros(N); - u_1order = centralSecondOrder.u -annotation ( - experiment(StartTime = 1e-3, StopTime = 1, Tolerance = 1e-6, Interval = 0.0001)); - -end DiffusionGaussian; diff --git a/Contact.mo b/src/TAeZoSysPro/Contact.mo similarity index 91% rename from Contact.mo rename to src/TAeZoSysPro/Contact.mo index 10dcc50..0885c66 100644 --- a/Contact.mo +++ b/src/TAeZoSysPro/Contact.mo @@ -3,9 +3,11 @@ within TAeZoSysPro; class Contact extends Modelica.Icons.Contact; - annotation( - preferredView = "info", - Documentation(info = " + + annotation ( + preferredView = "info", + Documentation( + info = " @@ -65,7 +67,6 @@ class Contact "), - Diagram(coordinateSystem(grid = {1, 2}))); - + Diagram(coordinateSystem(grid = {1, 2}))); -end Contact; \ No newline at end of file +end Contact; diff --git a/FluidDynamics/BasesClasses/Condensation.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/Condensation.mo similarity index 78% rename from FluidDynamics/BasesClasses/Condensation.mo rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/Condensation.mo index b9adab0..bc926bb 100644 --- a/FluidDynamics/BasesClasses/Condensation.mo +++ b/src/TAeZoSysPro/FluidDynamics/BasesClasses/Condensation.mo @@ -1,55 +1,69 @@ within TAeZoSysPro.FluidDynamics.BasesClasses; model Condensation + // medium declaration replaceable package Medium = TAeZoSysPro.Media.MyMedia; - Medium.ThermodynamicState state "State of fluid at infinite conditions"; - + Medium.ThermodynamicState state + "State of fluid at infinite conditions"; + // User defined parameters - parameter Modelica.SIunits.Area A = 1 "Wall surface area"; - parameter Real add_on = 1 "add on mass transfer coefficient"; - + parameter Modelica.SIunits.Area A = 1 + "Wall surface area"; + parameter Real add_on = 1 + "add on mass transfer coefficient"; + // Internal variables - Modelica.SIunits.MassFlowRate m_flow "Mass flow rate >0 if condensation"; - Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp "Specific Heat Capacity"; - Modelica.SIunits.Density d_sat "Saturation density of the condensable species"; - Real betaV(unit = "m/s") "mass transfer coefficient"; + Modelica.SIunits.MassFlowRate m_flow + "Mass flow rate >0 if condensation"; + Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp + "Specific Heat Capacity"; + Modelica.SIunits.Density d_sat + "Saturation density of the condensable species"; + Real betaV(unit = "m/s") + "mass transfer coefficient"; // Imported Modules - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b heatPort annotation( - Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput m_flow_cond(unit = "kg/s") annotation( - Placement(visible = true, transformation(origin = {0, -50}, extent = {{10, -10}, {-10, 10}}, rotation = 90), iconTransformation(origin = {-30, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 270))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-92, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput h_cv(unit = "W/(m2.K)") "Convective heat exchange coefficient" annotation( - Placement(visible = true, transformation(origin = {-80, 60}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-80, 60}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b heatPort + annotation ( + Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput m_flow_cond(unit = "kg/s") + annotation ( + Placement(visible = true, transformation(origin = {0, -50}, extent = {{10, -10}, {-10, 10}}, rotation = 90), iconTransformation(origin = {-30, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 270))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-92, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput h_cv(unit = "W/(m2.K)") + "Convective heat exchange coefficient" + annotation ( + Placement(visible = true, transformation(origin = {-80, 60}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-80, 60}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); equation -// Calculation of properties + // Calculation of properties state = Medium.setState_dTX(d = sum(flowPort.d), T = flowPort.T, X = flowPort.d / sum(flowPort.d)); cp = Medium.specificHeatCapacityCp(state); - d_sat = Medium.saturationPressure(heatPort.T) / (heatPort.T*Modelica.Constants.R/Medium.MMX[Medium.Water]) ; + d_sat = Medium.saturationPressure(heatPort.T) / (heatPort.T * Modelica.Constants.R / Medium.MMX[Medium.Water]); -// Calculation of the condensation flow rate + // Calculation of the condensation flow rate betaV = add_on * h_cv / (sum(flowPort.d) * cp); - m_flow = betaV * max((flowPort.d[Medium.Water] - d_sat), 0.0) * A ; + m_flow = betaV * max((flowPort.d[Medium.Water] - d_sat), 0.0) * A; -// Ports handover + // Ports handover flowPort.m_flow[Medium.Water] = m_flow; flowPort.m_flow[Medium.Air] = 0; flowPort.H_flow = m_flow * Medium.enthalpyOfCondensingGas(heatPort.T); - heatPort.Q_flow = -m_flow * Medium.enthalpyOfVaporization(heatPort.T) ; + heatPort.Q_flow = -m_flow * Medium.enthalpyOfVaporization(heatPort.T); + + //Output condensation data + m_flow_cond = m_flow; -//Output condensation data - m_flow_cond = m_flow ; - - annotation( + annotation ( Diagram, Icon(graphics = {Rectangle(origin = {-10, -1}, fillColor = {136, 136, 136}, fillPattern = FillPattern.Cross, extent = {{-10, 101}, {30, -99}}), Ellipse(origin = {-23, 46}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Line(origin = {44.67, 60}, points = {{-15, 0}, {15, 0}}, color = {255, 0, 0}, thickness = 1.25, arrow = {Arrow.Filled, Arrow.Filled}, arrowSize = 5), Line(origin = {44.67, -40}, points = {{-15, 0}, {15, 0}}, color = {255, 0, 0}, thickness = 1.25, arrow = {Arrow.Filled, Arrow.Filled}, arrowSize = 5), Line(origin = {44.67, 40}, points = {{-15, 0}, {15, 0}}, color = {255, 0, 0}, thickness = 1.25, arrow = {Arrow.Filled, Arrow.Filled}, arrowSize = 5), Line(origin = {44.28, -60}, points = {{-15, 0}, {15, 0}}, color = {255, 0, 0}, thickness = 1.25, arrow = {Arrow.Filled, Arrow.Filled}, arrowSize = 5), Ellipse(origin = {-23, 30}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Ellipse(origin = {-23, 14}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Ellipse(origin = {-23, -2}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Ellipse(origin = {-23, -18}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Ellipse(origin = {-23, -34}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Ellipse(origin = {-23, -50}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Ellipse(origin = {-23, -66}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Ellipse(origin = {-23, -82}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360), Ellipse(origin = {-23, -98}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-11, 34}, {3, 20}}, endAngle = 360)}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " + Documentation( + info = " Condensation diff --git a/FluidDynamics/BasesClasses/FreeAeraulicConvection.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/FreeAeraulicConvection.mo similarity index 53% rename from FluidDynamics/BasesClasses/FreeAeraulicConvection.mo rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/FreeAeraulicConvection.mo index 578ce17..5916854 100644 --- a/FluidDynamics/BasesClasses/FreeAeraulicConvection.mo +++ b/src/TAeZoSysPro/FluidDynamics/BasesClasses/FreeAeraulicConvection.mo @@ -2,78 +2,111 @@ within TAeZoSysPro.FluidDynamics.BasesClasses; model FreeAeraulicConvection - import TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import TAeZoSysPro.HeatTransfer.Functions.FreeConvection ; - import SI = Modelica.SIunits ; + import TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import TAeZoSysPro.HeatTransfer.Functions.FreeConvection; + import SI = Modelica.SIunits; // - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; + replaceable package Medium = TAeZoSysPro.Media.MyMedia; // User defined parameters - parameter Real add_on = 1 "Custom add-on"; - parameter SI.Area A = 0 "Wall Area " annotation( - Dialog(group="Geometrical properties")); - parameter SI.Length Lc = 0 "characteritic dimension for correlation" annotation( - Dialog(group="Geometrical properties")); - parameter FreeConvectionCorrelation correlation = FreeConvectionCorrelation.vertical_plate_ASHRAE "Free convection Correlation" annotation( - Dialog(group="Flow properties")); - parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 "heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group="Flow properties")); + parameter Real add_on = 1 + "Custom add-on"; + parameter SI.Area A = 0 + "Wall Area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter SI.Length Lc = 0 + "characteritic dimension for correlation" + annotation ( + Dialog(group = "Geometrical properties")); + parameter FreeConvectionCorrelation correlation = FreeConvectionCorrelation.vertical_plate_ASHRAE + "Free convection Correlation" + annotation ( + Dialog(group = "Flow properties")); + parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 + "heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Flow properties")); -// Internal variables - Medium.Temperature T_mean "Mean temperature between fluid and wall"; - SI.TemperatureDifference dT "Wall Temperature - fluid Temperature "; - SI.CoefficientOfHeatTransfer h_cv "Heat transfert coefficient"; - SI.Density d "Density of fluid at T_mean"; - SI.Pressure p "pressure at flowport_Inlet" ; - SI.SpecificEnthalpy h "pressure at flowport_Inlet" ; - SI.SpecificHeatCapacity cp "Specific heat capacity of fluid at T_mean"; - SI.DynamicViscosity mu "Dynamic viscosity of fluid at T_mean"; - SI.ThermalConductivity k "Thermal Conductivity of fluid at T_mean"; - SI.PrandtlNumber Pr "Prandtl Number"; - SI.GrashofNumber Gr "Grashof Number"; - SI.RayleighNumber Ra "Rayleigh Number"; - SI.NusseltNumber Nu "Nusselt Number"; - SI.Energy E "Energy passed throught the component" ; - SI.MassFraction[Medium.nX] X_Inlet "Mass fraction at inlet"; - SI.HeatFlowRate Q_flow ; - SI.MassFlowRate m_flow "Mass flow rate induced by convection"; + // Internal variables + Medium.Temperature T_mean + "Mean temperature between fluid and wall"; + SI.TemperatureDifference dT + "Wall Temperature - fluid Temperature "; + SI.CoefficientOfHeatTransfer h_cv + "Heat transfert coefficient"; + SI.Density d + "Density of fluid at T_mean"; + SI.Pressure p + "pressure at flowport_Inlet"; + SI.SpecificEnthalpy h + "pressure at flowport_Inlet"; + SI.SpecificHeatCapacity cp + "Specific heat capacity of fluid at T_mean"; + SI.DynamicViscosity mu + "Dynamic viscosity of fluid at T_mean"; + SI.ThermalConductivity k + "Thermal Conductivity of fluid at T_mean"; + SI.PrandtlNumber Pr + "Prandtl Number"; + SI.GrashofNumber Gr + "Grashof Number"; + SI.RayleighNumber Ra + "Rayleigh Number"; + SI.NusseltNumber Nu + "Nusselt Number"; + SI.Energy E + "Energy passed throught the component"; + SI.MassFraction[Medium.nX] X_Inlet + "Mass fraction at inlet"; + SI.HeatFlowRate Q_flow; + SI.MassFlowRate m_flow + "Mass flow rate induced by convection"; // Imported Modules - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b flowPort_up(redeclare package - Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {0, 100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-10, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b flowPort_down(redeclare - package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {0, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-10, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort_inlet(redeclare - package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort_a annotation( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b flowPort_up( + redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {0, 100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-10, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b flowPort_down( + redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {0, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-10, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort_inlet( + redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort_a + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + protected + Medium.ThermodynamicState state; initial equation - E = 0.0 ; + + E = 0.0; equation -// Temporary equation + + // Temporary equation p = Medium.reference_p; -// State Calculation + // State Calculation T_mean = (heatPort_a.T + flowPort_inlet.T) / 2; -// + // dT = heatPort_a.T - flowPort_inlet.T; X_Inlet = 1 / sum(flowPort_inlet.d) * flowPort_inlet.d; state = Medium.setState_dTX(d = sum(flowPort_inlet.d), T = T_mean); -// Thermodynamic properties calculation + // Thermodynamic properties calculation d = Medium.density(state); - h = Medium.specificEnthalpy(state) ; + h = Medium.specificEnthalpy(state); mu = Medium.dynamicViscosity(state); cp = Medium.specificHeatCapacityCp(state); k = Medium.thermalConductivity(state); -// Calculation of characteristic numbers for convection + // Calculation of characteristic numbers for convection Pr = mu * cp / k; Gr = 9.81 * 1 / flowPort_inlet.T * d ^ 2 * abs(dT) * Lc ^ 3 / mu ^ 2; - Ra = Gr * Pr ; -// Selection of the correlation + Ra = Gr * Pr; + // Selection of the correlation if correlation == FreeConvectionCorrelation.vertical_plate_ASHRAE then Nu = FreeConvection.vertical_plate_ASHRAE(Pr = Pr, Ra = Ra); elseif correlation == FreeConvectionCorrelation.vertical_plate_Recknagel then @@ -90,26 +123,27 @@ equation Nu = 0; assert(false, "The correlation selected is not yet implemented of not applicable", AssertionLevel.error); end if; -//Convective heat transfer calculation + //Convective heat transfer calculation h_cv = Nu * k / Lc; -// Heat flux calculation + // Heat flux calculation Q_flow = add_on * A * h_cv * dT; - der(E) = Q_flow ; -// Mass flow rate induced by buoyancy + der(E) = Q_flow; + // Mass flow rate induced by buoyancy m_flow = h_cv * A / cp; -// port handover -// Mass balance + // port handover + // Mass balance flowPort_inlet.m_flow = m_flow * X_Inlet; flowPort_up.m_flow = -max(sign(dT) * m_flow, 0.0) * X_Inlet; flowPort_inlet.m_flow + flowPort_up.m_flow + flowPort_down.m_flow = fill(0.0, Medium.nX); -// Energy balance + // Energy balance heatPort_a.Q_flow = Q_flow; flowPort_inlet.H_flow = m_flow * h; - flowPort_up.H_flow = -max(m_flow * h * sign(dT), 0.0) - max(Q_flow, 0.0) ; + flowPort_up.H_flow = -max(m_flow * h * sign(dT), 0.0) - max(Q_flow, 0.0); flowPort_inlet.H_flow + flowPort_up.H_flow + flowPort_down.H_flow + Q_flow = 0; - - annotation( - Documentation(info =" + + annotation ( + Documentation( + info = " FreeConvection @@ -171,8 +205,8 @@ equation "), - Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(origin = {-54, 0}, fillColor = {140, 138, 145}, fillPattern = FillPattern.Cross, extent = {{-26, 100}, {14, -100}}), Line(origin = {35, 40}, points = {{-67, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {35, -40}, points = {{-65, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-92, 35}, rotation = 180, extent = {{-12, 15}, {28, -5}}, textString = "Wall"), Text(origin = {108, 35}, extent = {{-28, 5}, {12, -15}}, textString = "Fluid"), Line(origin = {-10, 39}, points = {{0, -39}, {0, 39}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-9.97, -40.69}, rotation = 180, points = {{0, -39}, {0, 39}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {30.471, -40.6561}, rotation = 180, points = {{0, -39}, {0, 39}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {30.441, 39.0339}, points = {{0, -39}, {0, 39}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {70.441, 39.0339}, points = {{0, -39}, {0, 39}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {70.471, -40.6561}, rotation = 180, points = {{0, -39}, {0, 39}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Text(origin = {26, 4}, extent = {{-28, 24}, {28, -24}}, textString = "hcv"), Line(origin = {25, 0}, points = {{-27, -22}, {27, 22}}, thickness = 1.75, arrow = {Arrow.None, Arrow.Filled})}), + Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(origin = {-54, 0}, fillColor = {140, 138, 145}, fillPattern = FillPattern.Cross, extent = {{-26, 100}, {14, -100}}), Line(origin = {35, 40}, points = {{-67, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {35, -40}, points = {{-65, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-92, 35}, rotation = 180, extent = {{-12, 15}, {28, -5}}, textString = "Wall"), Text(origin = {108, 35}, extent = {{-28, 5}, {12, -15}}, textString = "Fluid"), Line(origin = {-10, 39}, points = {{0, -39}, {0, 39}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-9.97, -40.69}, rotation = 180, points = {{0, -39}, {0, 39}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {30.471, -40.6561}, rotation = 180, points = {{0, -39}, {0, 39}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {30.441, 39.0339}, points = {{0, -39}, {0, 39}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {70.441, 39.0339}, points = {{0, -39}, {0, 39}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {70.471, -40.6561}, rotation = 180, points = {{0, -39}, {0, 39}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Text(origin = {26, 4}, extent = {{-28, 24}, {28, -24}}, textString = "hcv"), Line(origin = {25, 0}, points = {{-27, -22}, {27, 22}}, thickness = 1.75, arrow = {Arrow.None, Arrow.Filled})}), Diagram(graphics = {Rectangle(origin = {-56, -3}, fillColor = {172, 172, 172}, fillPattern = FillPattern.Cross, extent = {{-22, 85}, {22, -85}}), Line(origin = {-1, 42}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-1, 0}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {1, -44}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), - __OpenModelica_commandLineOptions = ""); + __OpenModelica_commandLineOptions = ""); end FreeAeraulicConvection; diff --git a/FluidDynamics/BasesClasses/FreeConvection.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/FreeConvection.mo similarity index 54% rename from FluidDynamics/BasesClasses/FreeConvection.mo rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/FreeConvection.mo index f423242..b4f87f3 100644 --- a/FluidDynamics/BasesClasses/FreeConvection.mo +++ b/src/TAeZoSysPro/FluidDynamics/BasesClasses/FreeConvection.mo @@ -2,66 +2,94 @@ within TAeZoSysPro.FluidDynamics.BasesClasses; model FreeConvection - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import Functions = TAeZoSysPro.HeatTransfer.Functions.FreeConvection ; - import SI = Modelica.SIunits ; + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import Functions = TAeZoSysPro.HeatTransfer.Functions.FreeConvection; + import SI = Modelica.SIunits; // replaceable package Medium = TAeZoSysPro.Media.MyMedia; // User defined parameters - parameter Real add_on = 1 "Custom add-on"; - parameter SI.Area A = 0 "Wall surface Area" annotation( - Dialog(group="Geometrical properties")); - parameter SI.Length Lc = 1 "characteritic dimension for correlation" annotation( - Dialog(group="Geometrical properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE "Free convection Correlation" annotation( - Dialog(group="Flow properties")); - parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group="Flow properties")); - -// Internal variables - SI.TemperatureDifference dT "Wall- fluid Temperatures"; - Medium.Temperature T_mean "Mean temperature between fluid and wall"; - SI.CoefficientOfHeatTransfer h_cv "Heat transfert coefficient"; - SI.Density d "Density of fluid at T_mean"; - SI.SpecificHeatCapacity cp "Specific heat capacity of fluid at T_mean"; - SI.DynamicViscosity mu "Dynamic viscosity of fluid at T_mean"; - SI.ThermalConductivity k "Thermal Conductivity of fluid at T_mean"; - SI.PrandtlNumber Pr "Prandtl Number"; - SI.GrashofNumber Gr "Grashof Number"; - SI.RayleighNumber Ra "Rayleigh Number"; - SI.NusseltNumber Nu "Nusselt Number"; - SI.HeatFlowRate Q_flow "Heat flow rate from wall to fluid"; - SI.Energy E "Energy passed throught the component" ; - HeatTransfer.Interfaces.HeatPort_a port_a annotation( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {96, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + parameter Real add_on = 1 + "Custom add-on"; + parameter SI.Area A = 0 + "Wall surface Area" + annotation ( + Dialog(group = "Geometrical properties")); + parameter SI.Length Lc = 1 + "characteritic dimension for correlation" + annotation ( + Dialog(group = "Geometrical properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE + "Free convection Correlation" + annotation ( + Dialog(group = "Flow properties")); + parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Flow properties")); + + // Internal variables + SI.TemperatureDifference dT + "Wall- fluid Temperatures"; + Medium.Temperature T_mean + "Mean temperature between fluid and wall"; + SI.CoefficientOfHeatTransfer h_cv + "Heat transfert coefficient"; + SI.Density d + "Density of fluid at T_mean"; + SI.SpecificHeatCapacity cp + "Specific heat capacity of fluid at T_mean"; + SI.DynamicViscosity mu + "Dynamic viscosity of fluid at T_mean"; + SI.ThermalConductivity k + "Thermal Conductivity of fluid at T_mean"; + SI.PrandtlNumber Pr + "Prandtl Number"; + SI.GrashofNumber Gr + "Grashof Number"; + SI.RayleighNumber Ra + "Rayleigh Number"; + SI.NusseltNumber Nu + "Nusselt Number"; + SI.HeatFlowRate Q_flow + "Heat flow rate from wall to fluid"; + SI.Energy E + "Energy passed throught the component"; + HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {96, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + protected + Medium.ThermodynamicState state; - + initial equation - E = 0.0 ; - + + E = 0.0; + equation - T_mean = (port_a.T + port_b.T) / 2 "port_a and port_b are defined in Element1D"; + T_mean = (port_a.T + port_b.T) / 2 + "port_a and port_b are defined in Element1D"; state = Medium.setState_dTX( - d = sum(port_b.d), - T = T_mean, - X=port_b.d/sum(port_b.d)); - -// Thermodynamic properties calculation + d = sum(port_b.d), + T = T_mean, + X = port_b.d / sum(port_b.d)); + + // Thermodynamic properties calculation d = Medium.density(state); mu = Medium.dynamicViscosity(state); cp = Medium.specificHeatCapacityCp(state); k = Medium.thermalConductivity(state); - -// Calculation of characteristic numbers for convection + + // Calculation of characteristic numbers for convection Pr = mu * cp / k; - Gr = 9.81 * 1/port_b.T * d^2 * abs(dT) * Lc^3 / mu^2 ; - Ra = Gr * Pr ; - -// Selection of the correlation + Gr = 9.81 * 1 / port_b.T * d ^ 2 * abs(dT) * Lc ^ 3 / mu ^ 2; + Ra = Gr * Pr; + + // Selection of the correlation if correlation == Correlations.vertical_plate_ASHRAE then Nu = Functions.vertical_plate_ASHRAE(Pr = Pr, Ra = Ra); elseif correlation == Correlations.vertical_plate_Recknagel then @@ -78,24 +106,23 @@ equation Nu = 0; assert(false, "The correlation selected is not yet implemented of not applicable", AssertionLevel.error); end if; - -// Convective heat transfer calculation + + // Convective heat transfer calculation h_cv = Nu * k / Lc; - -// Heat flux calculation + + // Heat flux calculation dT = port_a.T - port_b.T; Q_flow = add_on * h_cv * A * dT; - der(E) = Q_flow ; + der(E) = Q_flow; -// Port handovers - port_a.Q_flow = Q_flow ; + // Port handovers + port_a.Q_flow = Q_flow; port_b.m_flow = fill(0.0, Medium.nX); - port_b.H_flow + port_a.Q_flow = 0.0; + port_b.H_flow + port_a.Q_flow = 0.0; - - annotation( - Documentation(info = - " + annotation ( + Documentation( + info = " FreeConvection @@ -141,8 +168,8 @@ equation "), - Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(origin = {-54, 0}, fillColor = {140, 138, 145}, fillPattern = FillPattern.Cross, extent = {{-26, 100}, {14, -100}}), Line(origin = {-10, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {30, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {70, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {25, 40}, points = {{-55, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {25, -40}, points = {{-55, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {26, 4}, extent = {{-28, 24}, {28, -24}}, textString = "hcv"), Line(origin = {25, 0}, points = {{-27, -22}, {27, 22}}, thickness = 1.75, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-88, 23}, rotation = 180, extent = {{-4, 11}, {28, -5}}, textString = "Wall", fontSize = 8), Text(origin = {114, 23}, extent = {{-28, 5}, {0, -9}}, textString = "Fluid", fontSize = 8)}), + Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(origin = {-54, 0}, fillColor = {140, 138, 145}, fillPattern = FillPattern.Cross, extent = {{-26, 100}, {14, -100}}), Line(origin = {-10, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {30, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {70, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {25, 40}, points = {{-55, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {25, -40}, points = {{-55, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {26, 4}, extent = {{-28, 24}, {28, -24}}, textString = "hcv"), Line(origin = {25, 0}, points = {{-27, -22}, {27, 22}}, thickness = 1.75, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-88, 23}, rotation = 180, extent = {{-4, 11}, {28, -5}}, textString = "Wall", fontSize = 8), Text(origin = {114, 23}, extent = {{-28, 5}, {0, -9}}, textString = "Fluid", fontSize = 8)}), Diagram(graphics = {Rectangle(origin = {-56, -3}, fillColor = {172, 172, 172}, fillPattern = FillPattern.Cross, extent = {{-22, 85}, {22, -85}}), Line(origin = {-1, 42}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-1, 0}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {1, -44}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), - __OpenModelica_commandLineOptions = ""); + __OpenModelica_commandLineOptions = ""); end FreeConvection; diff --git a/FluidDynamics/BasesClasses/GasNode.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/GasNode.mo similarity index 51% rename from FluidDynamics/BasesClasses/GasNode.mo rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/GasNode.mo index 1b63e40..1b2a7ae 100644 --- a/FluidDynamics/BasesClasses/GasNode.mo +++ b/src/TAeZoSysPro/FluidDynamics/BasesClasses/GasNode.mo @@ -1,167 +1,205 @@ within TAeZoSysPro.FluidDynamics.BasesClasses; model GasNode + // additionnal package - import Modelica.Fluid.Types; - import Modelica.Fluid.Types.Dynamics; - import SI = Modelica.SIunits ; -// Medium declaration - replaceable package Medium = TAeZoSysPro.Media.MyMedia; - Medium.BaseProperties medium(preferredMediumStates = (if energyDynamics == Dynamics.SteadyState and massDynamics == Dynamics.SteadyState then false else true)); - /*Get TAeZoSysPro reference moist air Media*/ - package Medium_MoistAirTAezo=TAeZoSysPro.Media.Air.MoistAir; - // User defined parameters + import Modelica.Fluid.Types; + import Modelica.Fluid.Types.Dynamics; + import SI = Modelica.SIunits; + // Medium declaration + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + Medium.BaseProperties medium(preferredMediumStates = (if energyDynamics == Dynamics.SteadyState and massDynamics == Dynamics.SteadyState then false else true)); + /*Get TAeZoSysPro reference moist air Media*/ + package Medium_MoistAirTAezo = TAeZoSysPro.Media.Air.MoistAir; + // User defined parameters // Assumptions - parameter Types.Dynamics energyDynamics = Dynamics.FixedInitial "Formulation of energy balance" annotation( - Dialog(tab = "Assumptions", group="Dynamics")); - parameter Types.Dynamics massDynamics = Dynamics.FixedInitial "Formulation of mass balance" annotation( - Dialog(tab = "Assumptions", group="Dynamics")); - final parameter Types.Dynamics substanceDynamics = massDynamics "Formulation of substance balance" annotation( - Dialog(tab = "Assumptions", group="Dynamics")); - final parameter Types.Dynamics traceDynamics = massDynamics "Formulation of trace substance balance" annotation( - Dialog(tab = "Assumptions", group="Dynamics")); - // Fixed start value - parameter SI.AbsolutePressure p_start = 101325 "Initial absolute static pressure" annotation( - Dialog(tab = "Initialization")); - parameter SI.Temperature T_start = 293.15 "Initial temperature" annotation( - Dialog(tab = "Initialization")); - parameter Real RH_start(min = 0, max = 1) = 0.6 "Initial relative humidity (pmoisture/psat) <= 1" annotation( - Dialog(enable = Medium.mediumName == "Moist air", tab = "Initialization")) ; - // - parameter Integer nPorts = 0 "Number of fluidport" annotation ( - Dialog(connectorSizing = true)); - parameter SI.Volume V = 1 "Geometric Volume of the gas node" ; + parameter Types.Dynamics energyDynamics = Dynamics.FixedInitial + "Formulation of energy balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + parameter Types.Dynamics massDynamics = Dynamics.FixedInitial + "Formulation of mass balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + final parameter Types.Dynamics substanceDynamics = massDynamics + "Formulation of substance balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + final parameter Types.Dynamics traceDynamics = massDynamics + "Formulation of trace substance balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + // Fixed start value + parameter SI.AbsolutePressure p_start = 101325 + "Initial absolute static pressure" + annotation ( + Dialog(tab = "Initialization")); + parameter SI.Temperature T_start = 293.15 + "Initial temperature" + annotation ( + Dialog(tab = "Initialization")); + parameter Real RH_start(min = 0, max = 1) = 0.6 + "Initial relative humidity (pmoisture/psat) <= 1" + annotation ( + Dialog(enable = Medium.mediumName == "Moist air", tab = "Initialization")); + // + parameter Integer nPorts = 0 + "Number of fluidport" + annotation ( + Dialog(connectorSizing = true)); + parameter SI.Volume V = 1 + "Geometric Volume of the gas node"; // Internal variables // Potential variables - SI.Mass m "Mass of mixture"; - SI.Mass mXi[Medium.nXi] "Masses of independent components in the fluid" ; - SI.Mass[Medium.nC] mC "Masses of trace substances in the fluid"; - // C need to be added here because unlike for Xi, which has medium.Xi,there is no variable medium.C - Medium.ExtraProperty C[Medium.nC] "Trace substance mixture content"; - SI.InternalEnergy U "Internal energy of mixing" ; - // Flow variables - SI.MassFlowRate mb_flow "Mass flows across boundaries" ; - SI.MassFlowRate[Medium.nXi] mbXi_flow "Substance mass flows across boundaries" ; - Medium.MassFlowRate ports_mXi_flow[nPorts,Medium.nXi]; - Medium.ExtraPropertyFlowRate[Medium.nC] mbC_flow "Trace substance mass flows across boundaries" ; - SI.EnthalpyFlowRate Hb_flow "Enthalpy flow across boundaries or energy source/sink" ; - SI.HeatFlowRate Qb_flow "Heat flow across boundaries or energy source/sink" ; - // Imported modules - Modelica.Fluid.Interfaces.FluidPort_a fluidPort[nPorts](redeclare each package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {0, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort annotation( - Placement(visible = true, transformation(origin = {0, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + SI.Mass m + "Mass of mixture"; + SI.Mass mXi[Medium.nXi] + "Masses of independent components in the fluid"; + SI.Mass[Medium.nC] mC + "Masses of trace substances in the fluid"; + // C need to be added here because unlike for Xi, which has medium.Xi,there is no variable medium.C + Medium.ExtraProperty C[Medium.nC] + "Trace substance mixture content"; + SI.InternalEnergy U + "Internal energy of mixing"; + // Flow variables + SI.MassFlowRate mb_flow + "Mass flows across boundaries"; + SI.MassFlowRate[Medium.nXi] mbXi_flow + "Substance mass flows across boundaries"; + Medium.MassFlowRate ports_mXi_flow[nPorts, Medium.nXi]; + Medium.ExtraPropertyFlowRate[Medium.nC] mbC_flow + "Trace substance mass flows across boundaries"; + SI.EnthalpyFlowRate Hb_flow + "Enthalpy flow across boundaries or energy source/sink"; + SI.HeatFlowRate Qb_flow + "Heat flow across boundaries or energy source/sink"; + // Imported modules + Modelica.Fluid.Interfaces.FluidPort_a fluidPort[nPorts](redeclare each package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {0, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort + annotation ( + Placement(visible = true, transformation(origin = {0, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected - Real[Medium.nC] mC_scaled(min=fill(Modelica.Constants.eps, Medium.nC)) "Scaled masses of trace substances in the fluid"; - parameter Medium.ExtraProperty C_start[Medium.nC](quantity=Medium.extraPropertiesNames) = Medium.C_default; - - parameter Medium_MoistAirTAezo.MassFraction X_start_moist[Medium_MoistAirTAezo.nX]= cat(1, {Medium_MoistAirTAezo.massFraction_pTphi(p = p_start, T = T_start, phi = RH_start)}, {1-Medium_MoistAirTAezo.massFraction_pTphi(p = p_start, T = T_start, phi = RH_start)}); - - parameter Medium.MassFraction X_start[Medium.nX] = if Medium.mediumName == "Moist air" then - X_start_moist - else - Medium.X_default ; -protected + Real[Medium.nC] mC_scaled(min = fill(Modelica.Constants.eps, Medium.nC)) + "Scaled masses of trace substances in the fluid"; + parameter Medium.ExtraProperty C_start[Medium.nC](quantity = Medium.extraPropertiesNames) = Medium.C_default; + + parameter Medium_MoistAirTAezo.MassFraction X_start_moist[Medium_MoistAirTAezo.nX] = cat(1, {Medium_MoistAirTAezo.massFraction_pTphi(p = p_start, T = T_start, phi = RH_start)}, {1 - Medium_MoistAirTAezo.massFraction_pTphi(p = p_start, T = T_start, phi = RH_start)}); + + parameter Medium.MassFraction X_start[Medium.nX] = + if Medium.mediumName == "Moist air" then + X_start_moist + else + Medium.X_default; + +protected initial equation -// initialization of balances -//Energy + + // initialization of balances + //Energy if energyDynamics == Dynamics.FixedInitial then medium.T = T_start; elseif energyDynamics == Dynamics.SteadyStateInitial then der(medium.T) = 0; end if; -//Mass + //Mass if massDynamics == Dynamics.FixedInitial then medium.p = p_start; elseif massDynamics == Dynamics.SteadyStateInitial then der(medium.p) = 0; end if; -//Substances + //Substances if substanceDynamics == Dynamics.FixedInitial then - medium.Xi = X_start[1:Medium.nXi]; + medium.Xi = X_start[1 : Medium.nXi]; elseif substanceDynamics == Dynamics.SteadyStateInitial then der(medium.Xi) = zeros(Medium.nXi); end if; -//Traces + //Traces if traceDynamics == Dynamics.FixedInitial then - mC_scaled = m * C_start[1:Medium.nC] ./ Medium.C_nominal; + mC_scaled = m * C_start[1 : Medium.nC] ./ Medium.C_nominal; elseif traceDynamics == Dynamics.SteadyStateInitial then der(mC_scaled) = zeros(Medium.nC); end if; + equation - - assert(not(energyDynamics<>Dynamics.SteadyState and massDynamics==Dynamics.SteadyState) or Medium.singleState, "Bad combination of dynamics options and Medium not conserving mass because V is fixed."); - -// Total quantities + + assert(not (energyDynamics <> Dynamics.SteadyState and massDynamics == Dynamics.SteadyState) or Medium.singleState, "Bad combination of dynamics options and Medium not conserving mass because V is fixed."); + + // Total quantities m = V * medium.d; - mXi = m*medium.Xi ; - U = m*medium.u ; - mC = m*C ; - -// Boundary flow quantities - for i in 1:nPorts loop + mXi = m * medium.Xi; + U = m * medium.u; + mC = m * C; + + // Boundary flow quantities + for i in 1 : nPorts loop ports_mXi_flow[i, :] = fluidPort[i].m_flow * actualStream(fluidPort[i].Xi_outflow); end for; - - for j in 1:Medium.nXi loop - mbXi_flow[j] = sum(ports_mXi_flow[:,j]) + flowPort.m_flow[j] ; + + for j in 1 : Medium.nXi loop + mbXi_flow[j] = sum(ports_mXi_flow[:, j]) + flowPort.m_flow[j]; end for; - - mb_flow = sum(fluidPort.m_flow) + sum(flowPort.m_flow) ; - Qb_flow = heatPort.Q_flow ; - Hb_flow = sum(fluidPort.m_flow .* actualStream(fluidPort.h_outflow)) + flowPort.H_flow ; - -// Balance equations + + mb_flow = sum(fluidPort.m_flow) + sum(flowPort.m_flow); + Qb_flow = heatPort.Q_flow; + Hb_flow = sum(fluidPort.m_flow .* actualStream(fluidPort.h_outflow)) + flowPort.H_flow; + + // Balance equations // Energy if energyDynamics == Dynamics.SteadyState then 0 = Hb_flow + Qb_flow; else der(U) = Hb_flow + Qb_flow; end if; - + // Mass if massDynamics == Dynamics.SteadyState then 0 = mb_flow; else der(m) = mb_flow; end if; - + // Independant masses if substanceDynamics == Dynamics.SteadyState then zeros(Medium.nXi) = mbXi_flow; else der(mXi) = mbXi_flow; end if; - + // Trace masses if traceDynamics == Dynamics.SteadyState then zeros(Medium.nC) = mbC_flow; else der(mC_scaled) = mbC_flow ./ Medium.C_nominal; end if; - mC = mC_scaled.*Medium.C_nominal; - -// port handovers + mC = mC_scaled .* Medium.C_nominal; + + // port handovers // fluidPorts - for i in 1:nPorts loop + for i in 1 : nPorts loop fluidPort[i].p = medium.p; fluidPort[i].h_outflow = medium.h; fluidPort[i].Xi_outflow = medium.Xi; end for; - + // flowPort flowPort.d = cat(1, mXi, {m - sum(mXi)}) / V; flowPort.T = medium.T; - + // heatPort - heatPort.T = medium.T; - -annotation(Documentation(info = " + heatPort.T = medium.T; + + annotation ( + Documentation( + info = " GasNode diff --git a/FluidDynamics/BasesClasses/GasNode_two_phases.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/GasNode_two_phases.mo similarity index 68% rename from FluidDynamics/BasesClasses/GasNode_two_phases.mo rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/GasNode_two_phases.mo index 0fb45aa..18e5ef9 100644 --- a/FluidDynamics/BasesClasses/GasNode_two_phases.mo +++ b/src/TAeZoSysPro/FluidDynamics/BasesClasses/GasNode_two_phases.mo @@ -1,18 +1,32 @@ -within TAeZoSysPro.FluidDynamics.BasesClasses; +within TAeZoSysPro.FluidDynamics.BasesClasses; model GasNode_two_phases + model FogModel - Modelica.SIunits.Density d_condensable "Density of the condensable species"; - Modelica.SIunits.Density d_sat "Saturation density of the condensable species"; - Modelica.SIunits.Pressure p_sat "Saturation pressure of the condensable species"; - Modelica.SIunits.Diameter d_drop "Diameter of equivalent droplet"; - Modelica.SIunits.Velocity Vel "Velocity of droplet"; - parameter Modelica.SIunits.Area A "Surface area through which fog drains"; - Modelica.SIunits.MassFlowRate m_flow_fog "Mass flow rate of droplet leaving the control volume"; - Modelica.SIunits.ReynoldsNumber Re "Reynolds number"; + + Modelica.SIunits.Density d_condensable + "Density of the condensable species"; + Modelica.SIunits.Density d_sat + "Saturation density of the condensable species"; + Modelica.SIunits.Pressure p_sat + "Saturation pressure of the condensable species"; + Modelica.SIunits.Diameter d_drop + "Diameter of equivalent droplet"; + Modelica.SIunits.Velocity Vel + "Velocity of droplet"; + parameter Modelica.SIunits.Area A + "Surface area through which fog drains"; + Modelica.SIunits.MassFlowRate m_flow_fog + "Mass flow rate of droplet leaving the control volume"; + Modelica.SIunits.ReynoldsNumber Re + "Reynolds number"; input Medium.ThermodynamicState state; - constant Modelica.SIunits.Density d_liquidPhase = 1000 "Density of the liquid phase of the condensation species"; - parameter Modelica.SIunits.NumberDensityOfMolecules n_drops = 150 * 1e6 "Number density of droplets in fog"; + constant Modelica.SIunits.Density d_liquidPhase = 1000 + "Density of the liquid phase of the condensation species"; + parameter Modelica.SIunits.NumberDensityOfMolecules n_drops = 150 * 1e6 + "Number density of droplets in fog"; + equation + // Temporary equations d_condensable = Medium.density(state) * state.X[Medium.Water]; @@ -24,14 +38,15 @@ model GasNode_two_phases d_drop / 2 = (max(d_condensable - d_sat, 0) / (d_liquidPhase * n_drops * 4 / 3 * Modelica.Constants.pi)) ^ (1 / 3); // quasi static flow: viscous friction force( Stocke's law) + bouyancy force + weight = 0 - Vel = d_liquidPhase * d_drop^2 * Modelica.Constants.g_n / (18 * Medium.dynamicViscosity(state)); + Vel = d_liquidPhase * d_drop ^ 2 * Modelica.Constants.g_n / (18 * Medium.dynamicViscosity(state)); Re = Medium.density(state) * Vel * d_drop / Medium.dynamicViscosity(state); // mass flow rate = velocity * wet surface * amount of droplets peer wet surface * density of droplet m_flow_fog = Vel * A * (n_drops * Modelica.Constants.pi / 6 * d_drop ^ 3) * d_liquidPhase; - - annotation( - Documentation(info = " + + annotation ( + Documentation( + info = " FogModel @@ -123,6 +138,7 @@ model GasNode_two_phases /> ")); + end FogModel; // additionnal package @@ -134,93 +150,132 @@ model GasNode_two_phases Medium.BaseProperties medium(preferredMediumStates = if energyDynamics == Dynamics.SteadyState and massDynamics == Dynamics.SteadyState then false else true); // User defined parameters // Assumptions - parameter Types.Dynamics energyDynamics = Dynamics.FixedInitial "Formulation of energy balance" annotation ( - Dialog(tab = "Assumptions", group = "Dynamics")); - parameter Types.Dynamics massDynamics = Dynamics.FixedInitial "Formulation of mass balance" annotation ( - Dialog(tab = "Assumptions", group = "Dynamics")); - final parameter Types.Dynamics substanceDynamics = massDynamics "Formulation of substance balance" annotation ( - Dialog(tab = "Assumptions", group = "Dynamics")); - final parameter Types.Dynamics traceDynamics = massDynamics "Formulation of trace substance balance" annotation ( - Dialog(tab = "Assumptions", group = "Dynamics")); + parameter Types.Dynamics energyDynamics = Dynamics.FixedInitial + "Formulation of energy balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + parameter Types.Dynamics massDynamics = Dynamics.FixedInitial + "Formulation of mass balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + final parameter Types.Dynamics substanceDynamics = massDynamics + "Formulation of substance balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + final parameter Types.Dynamics traceDynamics = massDynamics + "Formulation of trace substance balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); // Fixed start value - parameter SI.AbsolutePressure p_start = 101325 "Initial absolute static pressure" annotation ( - Dialog(tab = "Initialization")); - parameter SI.Temperature T_start = 293.15 "Initial temperature" annotation ( - Dialog(tab = "Initialization")); - parameter Real RH_start(min = 0, max = 1) = 0.6 "Initial relative humidity (pmoisture/psat) <= 1" annotation ( - Dialog(enable = Medium.mediumName == "Moist air", tab = "Initialization")); + parameter SI.AbsolutePressure p_start = 101325 + "Initial absolute static pressure" + annotation ( + Dialog(tab = "Initialization")); + parameter SI.Temperature T_start = 293.15 + "Initial temperature" + annotation ( + Dialog(tab = "Initialization")); + parameter Real RH_start(min = 0, max = 1) = 0.6 + "Initial relative humidity (pmoisture/psat) <= 1" + annotation ( + Dialog(enable = Medium.mediumName == "Moist air", tab = "Initialization")); // - parameter Integer nPorts = 0 "Number of fluidport" annotation ( - Dialog(connectorSizing = true)); - parameter SI.Volume V = 1 "Geometric Volume of the gas node"; - parameter Modelica.SIunits.Area A = V ^ (2 / 3) "Surface area through which fog drains"; + parameter Integer nPorts = 0 + "Number of fluidport" + annotation ( + Dialog(connectorSizing = true)); + parameter SI.Volume V = 1 + "Geometric Volume of the gas node"; + parameter Modelica.SIunits.Area A = V ^ (2 / 3) + "Surface area through which fog drains"; // Internal variables // Potential variables - SI.Mass m "Mass of mixture"; - SI.Mass mXi[Medium.nXi] "Masses of independent components in the fluid"; - SI.Mass[Medium.nC] mC "Masses of trace substances in the fluid"; + SI.Mass m + "Mass of mixture"; + SI.Mass mXi[Medium.nXi] + "Masses of independent components in the fluid"; + SI.Mass[Medium.nC] mC + "Masses of trace substances in the fluid"; // C need to be added here because unlike for Xi, which has medium.Xi,there is no variable medium.C - Medium.ExtraProperty C[Medium.nC] "Trace substance mixture content"; - SI.InternalEnergy U "Internal energy of mixing"; + Medium.ExtraProperty C[Medium.nC] + "Trace substance mixture content"; + SI.InternalEnergy U + "Internal energy of mixing"; // Flow variables - SI.MassFlowRate mb_flow "Mass flows across boundaries"; - SI.MassFlowRate[Medium.nXi] mbXi_flow "Substance mass flows across boundaries"; + SI.MassFlowRate mb_flow + "Mass flows across boundaries"; + SI.MassFlowRate[Medium.nXi] mbXi_flow + "Substance mass flows across boundaries"; Medium.MassFlowRate ports_mXi_flow[nPorts, Medium.nXi]; - Medium.ExtraPropertyFlowRate[Medium.nC] mbC_flow "Trace substance mass flows across boundaries"; - SI.EnthalpyFlowRate Hb_flow "Enthalpy flow across boundaries or energy source/sink"; - SI.HeatFlowRate Qb_flow "Heat flow across boundaries or energy source/sink"; + Medium.ExtraPropertyFlowRate[Medium.nC] mbC_flow + "Trace substance mass flows across boundaries"; + SI.EnthalpyFlowRate Hb_flow + "Enthalpy flow across boundaries or energy source/sink"; + SI.HeatFlowRate Qb_flow + "Heat flow across boundaries or energy source/sink"; // Imported modules - Modelica.Fluid.Interfaces.FluidPort_a fluidPort[nPorts](redeclare each - package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {0, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort annotation ( - Placement(visible = true, transformation(origin = {0, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a fluidPort[nPorts]( + redeclare each package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {0, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort + annotation ( + Placement(visible = true, transformation(origin = {0, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-18, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); FogModel fogModel(state = medium.state, A = A); + protected - Real[Medium.nC] mC_scaled(min = fill(Modelica.Constants.eps, Medium.nC)) "Scaled masses of trace substances in the fluid"; + + Real[Medium.nC] mC_scaled(min = fill(Modelica.Constants.eps, Medium.nC)) + "Scaled masses of trace substances in the fluid"; parameter Medium.ExtraProperty C_start[Medium.nC](quantity = Medium.extraPropertiesNames) = Medium.C_default; parameter Medium.MassFraction X_start[Medium.nX] = if Medium.mediumName == "Moist air" then cat(1, {Medium.massFraction_pTphi(p = p_start, T = T_start, phi = RH_start)}, {1 - Medium.massFraction_pTphi(p = p_start, T = T_start, phi = RH_start)}) else Medium.X_default; + public + initial equation -// initialization of balances -//Energy + + // initialization of balances + //Energy if energyDynamics == Dynamics.FixedInitial then medium.T = T_start; elseif energyDynamics == Dynamics.SteadyStateInitial then der(medium.T) = 0; end if; -//Mass + //Mass if massDynamics == Dynamics.FixedInitial then medium.p = p_start; elseif massDynamics == Dynamics.SteadyStateInitial then der(medium.p) = 0; end if; -//Substances + //Substances if substanceDynamics == Dynamics.FixedInitial then - medium.Xi = X_start[1:Medium.nXi]; + medium.Xi = X_start[1 : Medium.nXi]; elseif substanceDynamics == Dynamics.SteadyStateInitial then der(medium.Xi) = zeros(Medium.nXi); end if; -//Traces + //Traces if traceDynamics == Dynamics.FixedInitial then - mC_scaled = m * C_start[1:Medium.nC] ./ Medium.C_nominal; + mC_scaled = m * C_start[1 : Medium.nC] ./ Medium.C_nominal; elseif traceDynamics == Dynamics.SteadyStateInitial then der(mC_scaled) = zeros(Medium.nC); end if; + equation + assert(not (energyDynamics <> Dynamics.SteadyState and massDynamics == Dynamics.SteadyState) or Medium.singleState, "Bad combination of dynamics options and Medium not conserving mass because V is fixed."); -// Total quantities + // Total quantities m = V * medium.d; mXi = m * medium.Xi; U = m * medium.u; mC = m * C; -// Boundary flow quantities - for i in 1:nPorts loop + // Boundary flow quantities + for i in 1 : nPorts loop ports_mXi_flow[i, :] = fluidPort[i].m_flow * actualStream(fluidPort[i].Xi_outflow); end for; - for j in 1:Medium.nXi loop + for j in 1 : Medium.nXi loop if j == Medium.Water then mbXi_flow[j] = sum(ports_mXi_flow[:, j]) + flowPort.m_flow[j] - fogModel.m_flow_fog; else @@ -230,46 +285,48 @@ equation mb_flow = sum(fluidPort.m_flow) + sum(flowPort.m_flow) - fogModel.m_flow_fog; Qb_flow = heatPort.Q_flow; Hb_flow = sum(fluidPort.m_flow .* actualStream(fluidPort.h_outflow)) - fogModel.m_flow_fog * Medium.enthalpyOfWater(medium.T) + flowPort.H_flow; -// Balance equations -// Energy + // Balance equations + // Energy if energyDynamics == Dynamics.SteadyState then 0 = Hb_flow + Qb_flow; else der(U) = Hb_flow + Qb_flow; end if; -// Mass + // Mass if massDynamics == Dynamics.SteadyState then 0 = mb_flow; else der(m) = mb_flow; end if; -// Independant masses + // Independant masses if substanceDynamics == Dynamics.SteadyState then zeros(Medium.nXi) = mbXi_flow; else der(mXi) = mbXi_flow; end if; -// Trace masses + // Trace masses if traceDynamics == Dynamics.SteadyState then zeros(Medium.nC) = mbC_flow; else der(mC_scaled) = mbC_flow ./ Medium.C_nominal; end if; mC = mC_scaled .* Medium.C_nominal; -// port handovers -// fluidPorts - for i in 1:nPorts loop + // port handovers + // fluidPorts + for i in 1 : nPorts loop fluidPort[i].p = medium.p; fluidPort[i].h_outflow = medium.h; fluidPort[i].Xi_outflow = medium.Xi; end for; -// flowPort + // flowPort flowPort.d = cat(1, mXi, {m - sum(mXi)}) / V; flowPort.T = medium.T; -// heatPort + // heatPort heatPort.T = medium.T; + annotation ( - Documentation(info = " + Documentation( + info = " GasNode @@ -331,11 +388,30 @@ equation

    "), - Icon(graphics={ Rectangle(origin = {-7, -6}, lineColor = {0, 0, 127}, fillColor = {154, 231, 231}, - fillPattern = FillPattern.Sphere, - lineThickness = 0.5, extent = {{-73, 66}, {47, -54}}), Polygon(origin = {0, 80}, lineColor = {0, 0, 127}, fillColor = {154, 231, 231}, - fillPattern = FillPattern.Sphere, - lineThickness = 0.5, points = {{40, -20}, {-80, -20}, {-40, 20}, {80, 20}, {40, -20}}), Polygon(origin = {60, 21}, lineColor = {0, 0, 127}, fillColor = {154, 231, 231}, - fillPattern = FillPattern.HorizontalCylinder, - lineThickness = 0.5, points = {{-20, -81}, {-20, 39}, {20, 79}, {20, -41}, {-20, -81}}), Text(origin = {0, -81}, extent = {{-100, 11}, {100, -11}}, textString = "V = %V")}, coordinateSystem(initialScale = 0.1))); + Icon( + graphics = { + Rectangle( + origin = {-7, -6}, + lineColor = {0, 0, 127}, + fillColor = {154, 231, 231}, + fillPattern = FillPattern.Sphere, + lineThickness = 0.5, + extent = {{-73, 66}, {47, -54}}), + Polygon( + origin = {0, 80}, + lineColor = {0, 0, 127}, + fillColor = {154, 231, 231}, + fillPattern = FillPattern.Sphere, + lineThickness = 0.5, + points = {{40, -20}, {-80, -20}, {-40, 20}, {80, 20}, {40, -20}}), + Polygon( + origin = {60, 21}, + lineColor = {0, 0, 127}, + fillColor = {154, 231, 231}, + fillPattern = FillPattern.HorizontalCylinder, + lineThickness = 0.5, + points = {{-20, -81}, {-20, 39}, {20, 79}, {20, -41}, {-20, -81}}), + Text(origin = {0, -81}, extent = {{-100, 11}, {100, -11}}, textString = "V = %V")}, + coordinateSystem(initialScale = 0.1))); + end GasNode_two_phases; diff --git a/FluidDynamics/BasesClasses/Interface_liq_gas.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/Interface_liq_gas.mo similarity index 69% rename from FluidDynamics/BasesClasses/Interface_liq_gas.mo rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/Interface_liq_gas.mo index 3617a43..04252c2 100644 --- a/FluidDynamics/BasesClasses/Interface_liq_gas.mo +++ b/src/TAeZoSysPro/FluidDynamics/BasesClasses/Interface_liq_gas.mo @@ -1,148 +1,202 @@ within TAeZoSysPro.FluidDynamics.BasesClasses; model Interface_liq_gas + import SI = Modelica.SIunits; -// + // replaceable package Medium = TAeZoSysPro.Media.MyMedia; - replaceable package MediumLiquid = Modelica.Media.Water.WaterIF97_ph; -// User defined parameters - parameter SI.Area A = 0 "Interface surface Area" annotation( - Dialog(group = "Geometrical properties")); - parameter SI.Length Lc = 4 * A ^ 0.5 "Perimeter of the surface Area" annotation( - Dialog(group = "Geometrical properties")); - parameter SI.Emissivity eps = 0.96 "Emissivity of liquid interface" annotation( - Dialog(group = "Geometrical properties")); - parameter Modelica.SIunits.NumberDensityOfMolecules n_bubbles = 150 * 1e6 "Number density of bubble in node" ; - constant Modelica.SIunits.CoefficientOfFriction Cx = 0.47 "drag coefficient for a sphere" ; - -// Internal variables + replaceable package MediumLiquid = Modelica.Media.Water.WaterIF97_ph; + // User defined parameters + parameter SI.Area A = 0 + "Interface surface Area" + annotation ( + Dialog(group = "Geometrical properties")); + parameter SI.Length Lc = 4 * A ^ 0.5 + "Perimeter of the surface Area" + annotation ( + Dialog(group = "Geometrical properties")); + parameter SI.Emissivity eps = 0.96 + "Emissivity of liquid interface" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.NumberDensityOfMolecules n_bubbles = 150 * 1e6 + "Number density of bubble in node"; + constant Modelica.SIunits.CoefficientOfFriction Cx = 0.47 + "drag coefficient for a sphere"; + + // Internal variables //for convection - Medium.Temperature T_mean "Mean temperature between fluid and wall"; - SI.TemperatureDifference dT "Temperature difference Interface - gas"; - SI.Pressure p "Pressure of the atmosphere"; - SI.CoefficientOfHeatTransfer h_cv "Heat transfert coefficient"; - SI.Density d "Density of fluid at T_mean"; - SI.SpecificHeatCapacity cp "Specific heat capacity of fluid at T_mean"; - SI.DynamicViscosity mu "Dynamic viscosity of fluid at T_mean"; - SI.ThermalConductivity k "Thermal Conductivity of fluid at T_mean"; - SI.PrandtlNumber Pr "Prandtl Number"; - SI.GrashofNumber Gr "Grashof Number"; - SI.RayleighNumber Ra "Rayleigh Number"; - SI.NusseltNumber Nu "Nusselt Number"; - Real betaV(unit = "m/s") "Mass transfer coefficient"; - SI.HeatFlowRate Q_flow_conv "Heat flow rate from convection"; + Medium.Temperature T_mean + "Mean temperature between fluid and wall"; + SI.TemperatureDifference dT + "Temperature difference Interface - gas"; + SI.Pressure p + "Pressure of the atmosphere"; + SI.CoefficientOfHeatTransfer h_cv + "Heat transfert coefficient"; + SI.Density d + "Density of fluid at T_mean"; + SI.SpecificHeatCapacity cp + "Specific heat capacity of fluid at T_mean"; + SI.DynamicViscosity mu + "Dynamic viscosity of fluid at T_mean"; + SI.ThermalConductivity k + "Thermal Conductivity of fluid at T_mean"; + SI.PrandtlNumber Pr + "Prandtl Number"; + SI.GrashofNumber Gr + "Grashof Number"; + SI.RayleighNumber Ra + "Rayleigh Number"; + SI.NusseltNumber Nu + "Nusselt Number"; + Real betaV(unit = "m/s") + "Mass transfer coefficient"; + SI.HeatFlowRate Q_flow_conv + "Heat flow rate from convection"; //for evapo-condensation - SI.HeatFlowRate Q_flow_evap "Heat flow rate from evaporation"; - SI.EnthalpyFlowRate H_flow_evap ; - SI.MassFlowRate m_flow_evap "Mass flow rate from evaporation"; - SI.Density d_sat "Saturation density of the condensable species"; + SI.HeatFlowRate Q_flow_evap + "Heat flow rate from evaporation"; + SI.EnthalpyFlowRate H_flow_evap; + SI.MassFlowRate m_flow_evap + "Mass flow rate from evaporation"; + SI.Density d_sat + "Saturation density of the condensable species"; //for boiling - SI.SpecificEnthalpy h_dew "Specific dew enthalpy of liquid medium"; - SI.SpecificEnthalpy h_bubble "Specific bubble enthalpy of liquid medium"; - SI.SpecificEnthalpy h "Specific enthalpy of liquid medium"; - SI.Density d_liq "Density in the liquid medium"; - SI.Diameter d_bubble "Diameter of bubble in liquid medium"; - SI.Velocity Vel "Ascending velocity of bubble in the liquid medium"; - SI.MassFlowRate m_flow_bubble "Mass flow rate from boiling"; - Real Xg "Mass fraction of gas in the liquid medium"; - SI.ReynoldsNumber Re "Reynold number of a bubble"; + SI.SpecificEnthalpy h_dew + "Specific dew enthalpy of liquid medium"; + SI.SpecificEnthalpy h_bubble + "Specific bubble enthalpy of liquid medium"; + SI.SpecificEnthalpy h + "Specific enthalpy of liquid medium"; + SI.Density d_liq + "Density in the liquid medium"; + SI.Diameter d_bubble + "Diameter of bubble in liquid medium"; + SI.Velocity Vel + "Ascending velocity of bubble in the liquid medium"; + SI.MassFlowRate m_flow_bubble + "Mass flow rate from boiling"; + Real Xg + "Mass fraction of gas in the liquid medium"; + SI.ReynoldsNumber Re + "Reynold number of a bubble"; // - SI.Energy E "Energy passed throught the component"; - + SI.Energy E + "Energy passed throught the component"; + // Imported modules - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a heatPort_a annotation( - Placement(visible = true, transformation(origin = {-60, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-60, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature prescribedTemperature annotation( - Placement(visible = true, transformation(origin = {-90, 18}, extent = {{10, -10}, {-10, 10}}, rotation = -90))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b flowPort_b(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {50, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_b port_rad annotation( - Placement(visible = true, transformation(origin = {-90, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A, eps = 0.8) annotation( - Placement(visible = true, transformation(origin = {-60, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 90))); - Modelica.Blocks.Interfaces.RealInput F_view annotation( - Placement(visible = true, transformation(origin = {-7, 85}, extent = {{-15, -15}, {15, 15}}, rotation = -90), iconTransformation(origin = {-10, 90}, extent = {{-10, -10}, {10, 10}}, rotation = -90))); - Modelica.Blocks.Interfaces.RealOutput A_wall annotation( - Placement(visible = true, transformation(origin = {-36, 84}, extent = {{-10, -10}, {10, 10}}, rotation = 90), iconTransformation(origin = {-40, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 90))); - Modelica.Fluid.Interfaces.FluidPort_a fluidPort_a(redeclare package Medium = MediumLiquid) annotation( - Placement(visible = true, transformation(origin = {54, -88}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {60, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a heatPort_a + annotation ( + Placement(visible = true, transformation(origin = {-60, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-60, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature prescribedTemperature + annotation ( + Placement(visible = true, transformation(origin = {-90, 18}, extent = {{10, -10}, {-10, 10}}, rotation = -90))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b flowPort_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {50, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_b port_rad + annotation ( + Placement(visible = true, transformation(origin = {-90, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A, eps = 0.8) + annotation ( + Placement(visible = true, transformation(origin = {-60, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 90))); + Modelica.Blocks.Interfaces.RealInput F_view + annotation ( + Placement(visible = true, transformation(origin = {-7, 85}, extent = {{-15, -15}, {15, 15}}, rotation = -90), iconTransformation(origin = {-10, 90}, extent = {{-10, -10}, {10, 10}}, rotation = -90))); + Modelica.Blocks.Interfaces.RealOutput A_wall + annotation ( + Placement(visible = true, transformation(origin = {-36, 84}, extent = {{-10, -10}, {10, 10}}, rotation = 90), iconTransformation(origin = {-40, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 90))); + Modelica.Fluid.Interfaces.FluidPort_a fluidPort_a(redeclare package Medium = MediumLiquid) + annotation ( + Placement(visible = true, transformation(origin = {54, -88}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {60, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + protected + Medium.ThermodynamicState state; - MediumLiquid.SaturationProperties sat "Saturation property record at the interface"; + MediumLiquid.SaturationProperties sat + "Saturation property record at the interface"; initial equation + E = 0.0; - + equation - T_mean = (heatPort_a.T + flowPort_b.T) / 2 "port_a and port_b are defined in Element1D"; + + T_mean = (heatPort_a.T + flowPort_b.T) / 2 + "port_a and port_b are defined in Element1D"; dT = heatPort_a.T - flowPort_b.T; prescribedTemperature.T = heatPort_a.T; - p = Medium.pressure(Medium.setState_dTX(d = sum(flowPort_b.d), T = flowPort_b.T, X=flowPort_b.d/sum(flowPort_b.d))); - state = Medium.setState_dTX(d = sum(flowPort_b.d), T = T_mean, X=flowPort_b.d/sum(flowPort_b.d)); - sat = MediumLiquid.setSat_p(p = p) ; - -// Thermodynamic properties calculation + p = Medium.pressure(Medium.setState_dTX(d = sum(flowPort_b.d), T = flowPort_b.T, X = flowPort_b.d / sum(flowPort_b.d))); + state = Medium.setState_dTX(d = sum(flowPort_b.d), T = T_mean, X = flowPort_b.d / sum(flowPort_b.d)); + sat = MediumLiquid.setSat_p(p = p); + + // Thermodynamic properties calculation d = Medium.density(state); mu = Medium.dynamicViscosity(state); cp = Medium.specificHeatCapacityCp(state); k = Medium.thermalConductivity(state); - -// Calculation of characteristic numbers for convection + + // Calculation of characteristic numbers for convection Pr = mu * cp / k; Gr = 9.81 * 1 / flowPort_b.T * d ^ 2 * abs(dT) * Lc ^ 3 / mu ^ 2; Ra = Gr * Pr; Nu = TAeZoSysPro.HeatTransfer.Functions.FreeConvection.ground_ASHRAE(dT = dT, Ra = Ra); - -// Convective heat transfer calculation + + // Convective heat transfer calculation h_cv = Nu * k / Lc; - -// Convective Heat flow rate calculation + + // Convective Heat flow rate calculation Q_flow_conv = h_cv * A * dT; - -// Evapocondensation heat flow rate calculation + + // Evapocondensation heat flow rate calculation d_sat = Medium.saturationPressure(heatPort_a.T) / (heatPort_a.T * Modelica.Constants.R / Medium.MMX[Medium.Water]); //d_sat = MediumLiquid.dewDensity(sat) ; betaV = h_cv / (sum(flowPort_b.d) * cp); m_flow_evap = betaV * (d_sat - flowPort_b.d[Medium.Water]) * A; Q_flow_evap = m_flow_evap * Medium.enthalpyOfVaporization(heatPort_a.T); - H_flow_evap = m_flow_evap * Medium.enthalpyOfCondensingGas(heatPort_a.T); + H_flow_evap = m_flow_evap * Medium.enthalpyOfCondensingGas(heatPort_a.T); -// Boiling - h_dew = MediumLiquid.dewEnthalpy(sat) ; - h_bubble = MediumLiquid.bubbleEnthalpy(sat) ; - h = inStream(fluidPort_a.h_outflow) ; + // Boiling + h_dew = MediumLiquid.dewEnthalpy(sat); + h_bubble = MediumLiquid.bubbleEnthalpy(sat); + h = inStream(fluidPort_a.h_outflow); h_dew * Xg + (1 - Xg) * h_bubble = h; - d_liq = MediumLiquid.density_ph(p = fluidPort_a.p, h = inStream(fluidPort_a.h_outflow)) ; + d_liq = MediumLiquid.density_ph(p = fluidPort_a.p, h = inStream(fluidPort_a.h_outflow)); // - Modelica.Constants.pi * (d_bubble^3)/6 = max(Xg, 0.0) * d_liq / d_sat / n_bubbles ; + Modelica.Constants.pi * (d_bubble ^ 3) / 6 = max(Xg, 0.0) * d_liq / d_sat / n_bubbles; // quasi static flow: friction force + bouyancy force = 0 - Vel = sqrt(4/3*Modelica.Constants.g_n * d_bubble / Cx) ; + Vel = sqrt(4 / 3 * Modelica.Constants.g_n * d_bubble / Cx); m_flow_bubble = Vel * A * (n_bubbles * Modelica.Constants.pi / 6 * d_bubble ^ 3) * d_sat; - Re = MediumLiquid.bubbleDensity(sat) * Vel * d_bubble / MediumLiquid.dynamicViscosity(MediumLiquid.setBubbleState(sat)) ; -// + Re = MediumLiquid.bubbleDensity(sat) * Vel * d_bubble / MediumLiquid.dynamicViscosity(MediumLiquid.setBubbleState(sat)); + // der(E) = heatPort_a.Q_flow; - A_wall = A ; - -// Ports handovers - heatPort_a.Q_flow = carrollRadiation.Q_flow + Q_flow_conv + Q_flow_evap + m_flow_bubble * (h_dew - h_bubble) ; + A_wall = A; + + // Ports handovers + heatPort_a.Q_flow = carrollRadiation.Q_flow + Q_flow_conv + Q_flow_evap + m_flow_bubble * (h_dew - h_bubble); flowPort_b.H_flow = -Q_flow_conv - H_flow_evap - m_flow_bubble * Medium.enthalpyOfCondensingGas(heatPort_a.T); - flowPort_b.m_flow[Medium.Water] = -m_flow_evap - m_flow_bubble ; + flowPort_b.m_flow[Medium.Water] = -m_flow_evap - m_flow_bubble; flowPort_b.m_flow[Medium.Air] = 0.0; fluidPort_a.p = p; - fluidPort_a.m_flow = m_flow_evap + m_flow_bubble ; + fluidPort_a.m_flow = m_flow_evap + m_flow_bubble; fluidPort_a.h_outflow = inStream(fluidPort_a.h_outflow); fluidPort_a.Xi_outflow = inStream(fluidPort_a.Xi_outflow); fluidPort_a.C_outflow = inStream(fluidPort_a.C_outflow); - - connect(port_rad, carrollRadiation.port_b) annotation( - Line(points = {{-90, 90}, {-90, 75}, {-60, 75}, {-60, 60}}, color = {191, 0, 0})); - connect(prescribedTemperature.port, carrollRadiation.port_a) annotation( - Line(points = {{-90, 28}, {-90, 28}, {-90, 32}, {-60, 32}, {-60, 40}, {-60, 40}}, color = {191, 0, 0})); - connect(F_view, carrollRadiation.Fview) annotation( - Line(points = {{-6, 86}, {-8, 86}, {-8, 42}, {-52, 42}, {-52, 42}}, color = {0, 0, 127})); - - annotation( - Documentation(info = " + + connect(port_rad, carrollRadiation.port_b) + annotation ( + Line(points = {{-90, 90}, {-90, 75}, {-60, 75}, {-60, 60}}, color = {191, 0, 0})); + connect(prescribedTemperature.port, carrollRadiation.port_a) + annotation ( + Line(points = {{-90, 28}, {-90, 28}, {-90, 32}, {-60, 32}, {-60, 40}, {-60, 40}}, color = {191, 0, 0})); + connect(F_view, carrollRadiation.Fview) + annotation ( + Line(points = {{-6, 86}, {-8, 86}, {-8, 42}, {-52, 42}, {-52, 42}}, color = {0, 0, 127})); + + annotation ( + Documentation( + info = " Interface_liq_gas diff --git a/FluidDynamics/BasesClasses/LiquidNode.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/LiquidNode.mo similarity index 75% rename from FluidDynamics/BasesClasses/LiquidNode.mo rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/LiquidNode.mo index 4554afc..877152d 100644 --- a/FluidDynamics/BasesClasses/LiquidNode.mo +++ b/src/TAeZoSysPro/FluidDynamics/BasesClasses/LiquidNode.mo @@ -1,6 +1,7 @@ within TAeZoSysPro.FluidDynamics.BasesClasses; model LiquidNode + // additionnal package import Modelica.Fluid.Types; import Modelica.Fluid.Types.Dynamics; @@ -11,130 +12,162 @@ model LiquidNode Medium.BaseProperties medium(preferredMediumStates = if energyDynamics == Dynamics.SteadyState and massDynamics == Dynamics.SteadyState then false else true); //User defined parameters // Assumptions - parameter Types.Dynamics energyDynamics = Dynamics.FixedInitial "Formulation of energy balance" annotation( - Dialog(tab = "Assumptions", group = "Dynamics")); - parameter Types.Dynamics massDynamics = Dynamics.FixedInitial "Formulation of mass balance" annotation( - Dialog(tab = "Assumptions", group = "Dynamics")); - final parameter Types.Dynamics substanceDynamics = massDynamics "Formulation of substance balance" annotation( - Dialog(tab = "Assumptions", group = "Dynamics")); - final parameter Types.Dynamics traceDynamics = massDynamics "Formulation of trace substance balance" annotation( - Dialog(tab = "Assumptions", group = "Dynamics")); + parameter Types.Dynamics energyDynamics = Dynamics.FixedInitial + "Formulation of energy balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + parameter Types.Dynamics massDynamics = Dynamics.FixedInitial + "Formulation of mass balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + final parameter Types.Dynamics substanceDynamics = massDynamics + "Formulation of substance balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); + final parameter Types.Dynamics traceDynamics = massDynamics + "Formulation of trace substance balance" + annotation ( + Dialog(tab = "Assumptions", group = "Dynamics")); // Fixed start value - parameter SI.Temperature T_start = 293.15 "Initial temperature" annotation( - Dialog(tab = "Initialization")); - parameter Medium.MassFraction X_start[Medium.nX] = Medium.X_default ; - parameter SI.Volume V_start = 0 "Initial volume" annotation( - Dialog(group = "Geometrical properties")); + parameter SI.Temperature T_start = 293.15 + "Initial temperature" + annotation ( + Dialog(tab = "Initialization")); + parameter Medium.MassFraction X_start[Medium.nX] = Medium.X_default; + parameter SI.Volume V_start = 0 + "Initial volume" + annotation ( + Dialog(group = "Geometrical properties")); + // + parameter Integer nPorts = 1 + "Number of fluidport" + annotation ( + Dialog(connectorSizing = true)); + + // Internal variables + SI.Enthalpy H + "Medium enthalpy"; // - parameter Integer nPorts = 1 "Number of fluidport" annotation( - Dialog(connectorSizing = true)); - -// Internal variables - SI.Enthalpy H "Medium enthalpy"; -// - SI.Mass m "Medium mass"; - SI.Mass mXi[Medium.nXi] "Masses of independent components in the fluid"; - SI.Mass[Medium.nC] mC "Masses of trace substances in the fluid"; - SI.Volume V; -// C need to be added here because unlike for Xi, which has medium.Xi,there is no variable medium.C - Medium.ExtraProperty C[Medium.nC] "Trace substance mixture content"; + SI.Mass m + "Medium mass"; + SI.Mass mXi[Medium.nXi] + "Masses of independent components in the fluid"; + SI.Mass[Medium.nC] mC + "Masses of trace substances in the fluid"; + SI.Volume V; + // C need to be added here because unlike for Xi, which has medium.Xi,there is no variable medium.C + Medium.ExtraProperty C[Medium.nC] + "Trace substance mixture content"; // - SI.MassFlowRate mb_flow "Mass flows across boundaries"; - SI.MassFlowRate[Medium.nXi] mbXi_flow "Substance mass flows across boundaries"; + SI.MassFlowRate mb_flow + "Mass flows across boundaries"; + SI.MassFlowRate[Medium.nXi] mbXi_flow + "Substance mass flows across boundaries"; Medium.MassFlowRate ports_mXi_flow[nPorts, Medium.nXi]; - Medium.ExtraPropertyFlowRate[Medium.nC] mbC_flow "Trace substance mass flows across boundaries"; - SI.EnthalpyFlowRate Hb_flow "Enthalpy flow across boundaries or energy source/sink"; - SI.HeatFlowRate Qb_flow "Heat flow across boundaries or energy source/sink"; + Medium.ExtraPropertyFlowRate[Medium.nC] mbC_flow + "Trace substance mass flows across boundaries"; + SI.EnthalpyFlowRate Hb_flow + "Enthalpy flow across boundaries or energy source/sink"; + SI.HeatFlowRate Qb_flow + "Heat flow across boundaries or energy source/sink"; // // Imported modules - Modelica.Fluid.Interfaces.FluidPorts_a fluidPort[nPorts](redeclare each package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -40}, {10, 40}}, rotation = 0), iconTransformation(origin = {50, 90}, extent = {{-10, -40}, {10, 40}}, rotation = -90))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort(T(start = 500.0, nominal = 500.0)) annotation( - Placement(visible = true, transformation(origin = {0, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-50, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPorts_a fluidPort[nPorts](redeclare each package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -40}, {10, 40}}, rotation = 0), iconTransformation(origin = {50, 90}, extent = {{-10, -40}, {10, 40}}, rotation = -90))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort(T(start = 500.0, nominal = 500.0)) + annotation ( + Placement(visible = true, transformation(origin = {0, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-50, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + protected - Real[Medium.nC] mC_scaled(min = fill(Modelica.Constants.eps, Medium.nC)) "Scaled masses of trace substances in the fluid"; - parameter Medium.ExtraProperty C_start[Medium.nC](quantity=Medium.extraPropertiesNames) = Medium.C_default; + + Real[Medium.nC] mC_scaled(min = fill(Modelica.Constants.eps, Medium.nC)) + "Scaled masses of trace substances in the fluid"; + parameter Medium.ExtraProperty C_start[Medium.nC](quantity = Medium.extraPropertiesNames) = Medium.C_default; initial equation -// initialization of balances -//Energy + + // initialization of balances + //Energy if energyDynamics == Dynamics.FixedInitial then medium.T = T_start; elseif energyDynamics == Dynamics.SteadyStateInitial then der(medium.T) = 0; end if; - m = V_start * medium.d ; -//Substances + m = V_start * medium.d; + //Substances if substanceDynamics == Dynamics.FixedInitial then - medium.Xi = X_start[1:Medium.nXi]; + medium.Xi = X_start[1 : Medium.nXi]; elseif substanceDynamics == Dynamics.SteadyStateInitial then der(medium.Xi) = zeros(Medium.nXi); end if; -//Traces + //Traces if traceDynamics == Dynamics.FixedInitial then - mC_scaled = m * C_start[1:Medium.nC] ./ Medium.C_nominal; + mC_scaled = m * C_start[1 : Medium.nC] ./ Medium.C_nominal; elseif traceDynamics == Dynamics.SteadyStateInitial then der(mC_scaled) = zeros(Medium.nC); end if; equation - -// Total quantities + + // Total quantities m = V * medium.d; mXi = m * medium.Xi; H = m * medium.h; mC = m * C; - -// Boundary flow quantities - for i in 1:nPorts loop + + // Boundary flow quantities + for i in 1 : nPorts loop ports_mXi_flow[i, :] = fluidPort[i].m_flow * actualStream(fluidPort[i].Xi_outflow); end for; - - for j in 1:Medium.nXi loop + + for j in 1 : Medium.nXi loop mbXi_flow[j] = sum(ports_mXi_flow[:, j]); end for; - - mb_flow = sum(fluidPort.m_flow) ; + + mb_flow = sum(fluidPort.m_flow); Qb_flow = heatPort.Q_flow; - Hb_flow = sum(fluidPort.m_flow .* actualStream(fluidPort.h_outflow)) ; -// Balance equations -// Energy + Hb_flow = sum(fluidPort.m_flow .* actualStream(fluidPort.h_outflow)); + // Balance equations + // Energy if energyDynamics == Dynamics.SteadyState then 0 = Hb_flow + Qb_flow; else der(H) = Hb_flow + Qb_flow; end if; -// Mass + // Mass if massDynamics == Dynamics.SteadyState then 0 = mb_flow; else der(m) = mb_flow; end if; -// Independant masses + // Independant masses if substanceDynamics == Dynamics.SteadyState then zeros(Medium.nXi) = mbXi_flow; else der(mXi) = mbXi_flow; end if; -// Trace masses + // Trace masses if traceDynamics == Dynamics.SteadyState then zeros(Medium.nC) = mbC_flow; else der(mC_scaled) = mbC_flow ./ Medium.C_nominal; end if; mC = mC_scaled .* Medium.C_nominal; -// port handovers -// fluidPorts - for i in 1:nPorts loop + // port handovers + // fluidPorts + for i in 1 : nPorts loop fluidPort[i].p = medium.p; fluidPort[i].h_outflow = medium.h; fluidPort[i].Xi_outflow = medium.Xi; end for; -// heatPort + // heatPort heatPort.T = medium.T; - annotation( - Documentation(info = " + + annotation ( + Documentation( + info = " The Modelica License 2 @@ -203,4 +236,5 @@ end if
    "), Icon(graphics = {Rectangle(origin = {-96, 55}, fillPattern = FillPattern.Solid, extent = {{-4, 33}, {4, -35}}), Rectangle(origin = {96, 55}, fillPattern = FillPattern.Solid, extent = {{-4, 33}, {4, -35}}), Ellipse(origin = {13, 25}, fillColor = {0, 85, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-5, 5}, {3, -3}}, endAngle = 360), Rectangle(origin = {-30, -22}, lineColor = {0, 85, 255}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-70, 42}, {130, -78}}), Ellipse(origin = {-75, 5}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-75, -13}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-75, -31}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-47, -31}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-47, -13}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-47, 5}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-47, -49}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-75, -49}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-47, -67}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-75, -67}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-47, -85}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-19, -49}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-19, -67}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-75, -85}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-19, -31}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-19, -13}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-19, 5}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Ellipse(origin = {-19, -85}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-3, 3}, {3, -3}}, endAngle = 360), Polygon(origin = {9.09, 29.85}, fillColor = {0, 85, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{-1.09366, -1.85355}, {6.90634, -1.85355}, {2.90634, 6.14645}, {-1.09366, -1.85355}}), Polygon(origin = {41.09, 29.85}, fillColor = {0, 85, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{-1.09366, -1.85355}, {6.90634, -1.85355}, {2.90634, 6.14645}, {-1.09366, -1.85355}}), Ellipse(origin = {45, 25}, fillColor = {0, 85, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-5, 5}, {3, -3}}, endAngle = 360), Ellipse(origin = {75, 25}, fillColor = {0, 85, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-5, 5}, {3, -3}}, endAngle = 360), Polygon(origin = {71.09, 29.85}, fillColor = {0, 85, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{-1.09366, -1.85355}, {6.90634, -1.85355}, {2.90634, 6.14645}, {-1.09366, -1.85355}})}, coordinateSystem(initialScale = 0.1))); + end LiquidNode; diff --git a/src/TAeZoSysPro/FluidDynamics/BasesClasses/MolecularDiffusion.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/MolecularDiffusion.mo new file mode 100644 index 0000000..28630ed --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/BasesClasses/MolecularDiffusion.mo @@ -0,0 +1,779 @@ +within TAeZoSysPro.FluidDynamics.BasesClasses; +model MolecularDiffusion + + //Media delcaration + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + + // User defined parameters + parameter Modelica.SIunits.Thickness Th = 1 + "Thickness between concentration potential difference"; + parameter Modelica.SIunits.CrossSection A = 0; + parameter Modelica.SIunits.DiffusionCoefficient D = 25 * 1e-6; + + // Internal variables + Real grad_X[Medium.nX](each quantity = "spatial gradient", each unit = "m-1") + "gradient of mass fraction"; + Modelica.SIunits.MassFlowRate[Medium.nX] m_flow; + Modelica.SIunits.Density d_mean; + Modelica.SIunits.Temperature T_mean; + Modelica.SIunits.SpecificEnthalpy[Medium.nX] h; + Real J[Medium.nX](each quantity = "mass flux rate", each unit = "kg.m-2.s-1") + "Gradient of mass fraction"; + Modelica.SIunits.MassFraction[Medium.nX] X_a; + Modelica.SIunits.MassFraction[Medium.nX] X_b; + + // Imported modules + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b flowPort_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +equation + + X_a = flowPort_a.d / sum(flowPort_a.d); + X_b = flowPort_b.d / sum(flowPort_b.d); + d_mean = 1 / 2 * (sum(flowPort_a.d) + sum(flowPort_b.d)); + T_mean = 1 / 2 * (flowPort_a.T + flowPort_b.T); + h[1] = Medium.enthalpyOfCondensingGas(T_mean); + h[2] = Medium.enthalpyOfNonCondensingGas(T_mean); + + // + + // for a binary gas mixture + grad_X = 1 / Th * (X_b - X_a); + J[1] = -d_mean * D * grad_X[1]; + J[2] = -J[1]; + m_flow = J * A; + + // Port handovers + flowPort_a.m_flow = m_flow; + flowPort_a.H_flow = m_flow * h; + flowPort_a.m_flow = -flowPort_b.m_flow; + flowPort_a.H_flow + flowPort_b.H_flow = 0.0; + + annotation ( + Documentation( + info = " + + + MolecularDiffusion + + + + +

    + This components allows to model the mass flow rate induced by the gradient of concentration of species within a binary gas mixture. + The mass flow rate of species derives from the Fick's equation. +

    + +

    + The physical model under this module uses the following assumptions: +

      +
    • the total concentration of the mixture is approximately constant
    • +
    +

    + + + +

    + Where: +

      +
    • m_flow j is the mass flow rate of the species 'j' [kg.m-2.s-1]
    • +
    • ρ is the density of the mixture [kg.m-3]
    • +
    • Dij binary coefficient of diffusion from 'i' to 'j' [m2.s-1]
    • +
    • cj mass fraction of the species 'j' [-]
    • +
    +

    + +

    + The quantities contained in the equation are such that Dij = Dji (symmetry of the interaction between particles i and j) and ci + cj = 1 (by definition of the mass fraction). + It is deduce that diffusion does not globally transport mass, it only distributes it differently: +

    + + + +

    + Therefore an to avoid mass transport, the global density used in the equations above are computed at the middle of the diffusion length. +

    + + +"), + Icon( + graphics = { + Ellipse( + origin = {-52, 80}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, 68}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, 56}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, 20}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, 44}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, 32}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, -40}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, -28}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, -52}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, -16}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, -4}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, 8}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, -76}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-52, -64}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-40, 62}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-30, 74}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-30, 50}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, 64}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-40, 38}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-30, 26}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-40, 14}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-30, 2}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-40, -10}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-30, -22}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-40, -34}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-30, -46}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-40, -58}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-30, -70}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, 40}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, 16}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, -8}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, -32}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, -56}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, -78}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, 86}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-40, 86}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-40, -80}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Rectangle(fillColor = {0, 170, 255}, extent = {{-56, 88}, {62, -84}}), + Ellipse( + origin = {54, 80}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, 8}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, -4}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, -16}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, 32}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, 44}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, 20}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, 56}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, 68}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, -28}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, -40}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, -52}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, -64}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {54, -76}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {42, 86}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {42, 62}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {42, 38}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {42, 14}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {42, -10}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {42, -34}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {42, -58}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {42, -80}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {30, 74}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {30, 50}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {30, 26}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {30, 2}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {30, -22}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {30, -46}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {30, -70}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, 86}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, 64}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, 40}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, 16}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, -8}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, -32}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, -56}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, -78}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {24, 64}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {24, 42}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {24, 18}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {24, -6}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {24, -30}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {24, -54}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, 76}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, 54}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, 30}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, 6}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, -18}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, -42}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {10, -66}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {24, -76}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {46, 74}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {46, 26}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {46, -22}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {46, -70}, + fillColor = {0, 85, 255}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, 76}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, 54}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, 30}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, 6}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, -18}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, -42}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-12, -66}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-24, 64}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-24, 40}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-24, 16}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-24, -8}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-24, -32}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-24, -56}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-24, -80}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-24, 86}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-44, 74}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-44, 26}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-44, -22}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Ellipse( + origin = {-44, -70}, + fillColor = {255, 0, 0}, + fillPattern = FillPattern.Solid, + extent = {{-2, 2}, {4, -4}}, + endAngle = 360), + Line(origin = {0, 2}, points = {{0, 86}, {0, -86}}, pattern = LinePattern.Dot)}, + coordinateSystem(initialScale = 0.1))); + +end MolecularDiffusion; diff --git a/FluidDynamics/BasesClasses/package.mo b/src/TAeZoSysPro/FluidDynamics/BasesClasses/package.mo similarity index 100% rename from FluidDynamics/BasesClasses/package.mo rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/package.mo diff --git a/FluidDynamics/BasesClasses/package.order b/src/TAeZoSysPro/FluidDynamics/BasesClasses/package.order similarity index 100% rename from FluidDynamics/BasesClasses/package.order rename to src/TAeZoSysPro/FluidDynamics/BasesClasses/package.order diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Buildings/BurstMembrane.mo b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/BurstMembrane.mo new file mode 100644 index 0000000..3eb5f2b --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/BurstMembrane.mo @@ -0,0 +1,103 @@ +within TAeZoSysPro.FluidDynamics.Components.Buildings; + +model BurstMembrane + + replaceable package Medium = TAeZoSysPro.Media.MyMedia + "Medium in the component" + annotation (choicesAllMatching = true); + + // User defined parameters + parameter Modelica.SIunits.PressureDifference dp_burst = 7000 + "Pressure difference to which the disk burst"; + + // Internal variables + Boolean bursted + "Bursted membrane"; + Modelica.SIunits.PressureDifference dp; + Medium.MassFlowRate m_flow; + + // Imported modules + Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0), iconTransformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(extent = {{110, -10}, {90, 10}}, rotation = 0), iconTransformation(extent = {{110, -10}, {90, 10}}, rotation = 0))); + +initial equation + + bursted = false; + +equation + + dp = port_a.p - port_b.p; + + if pre(bursted) then + dp = 0.0; + else + m_flow = 0.0; + end if; + + when dp >= dp_burst then + bursted = true; + end when; + + // Port handover + // Mass balance (no storage) + port_a.m_flow = m_flow; + port_a.m_flow + port_b.m_flow = 0; + + // Transport of substances + port_a.Xi_outflow = inStream(port_b.Xi_outflow); + port_b.Xi_outflow = inStream(port_a.Xi_outflow); + + port_a.C_outflow = inStream(port_b.C_outflow); + port_b.C_outflow = inStream(port_a.C_outflow); + + // Isenthalpic state transformation (no storage and no loss of energy) + port_a.h_outflow = inStream(port_b.h_outflow); + port_b.h_outflow = inStream(port_a.h_outflow); + + annotation ( + Icon(graphics = {Rectangle(extent = {{-80, 80}, {80, -80}}), Line(origin = {9.84, 0}, points = {{-9.84189, 60}, {10.1581, 0}, {-9.84189, -60}}, thickness = 0.5, smooth = Smooth.Bezier), Line(origin = {0, 70}, points = {{0, 10}, {0, -10}}, thickness = 1), Line(origin = {0.0458716, -69.9541}, points = {{0, 10}, {0, -10}}, thickness = 1), Line(origin = {30, 50}, points = {{-30, 10}, {30, -10}}, pattern = LinePattern.Dot), Line(origin = {30, -40}, points = {{-30, -20}, {30, 0}}, pattern = LinePattern.Dot)}, coordinateSystem(initialScale = 0.1)), + Description( + info = " + + BurstMembrane + + + +

    + The module model a perfect one dimentional burst membrane. + Perfect means no pressure loss when opened and no flow when close. One dimensional since the membrane can bursted only when the boundary pressure difference dp ≥ dp_burst. + A negative pressure difference having an absolute value above the threshold dp_burst would not make the menbrane bursted. +

    + +

    + The membrane is assumed non bursted at the initialisation. When it becomes burst, it is non reversible. +

    + +

    + In this model of leaks, there is only one equation to model the behavior of the flow resistance. It is rather quadratic to the velocity for an equipment hole and linear to the velocity for the porosities. +

    + +

    + Therefore, in the module, the relation of the of the pressure loss is function of the kinetic energy exponent leakExponent. +

    + + + +

    + The leak surface area is defined as a fraction of the wall surface equal to leakSurfaceRatio. +

    + + + + +")); + +end BurstMembrane; diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Buildings/HalfWall.mo b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/HalfWall.mo new file mode 100644 index 0000000..717db28 --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/HalfWall.mo @@ -0,0 +1,231 @@ +within TAeZoSysPro.FluidDynamics.Components.Buildings; + +model HalfWall + + // + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + import TAeZoSysPro.HeatTransfer.Types.MeshGrid; + import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid; + //Media + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters + parameter MeshGrid mesh = MeshGrid.biotAndGeometricalGrowth + "Selection of meshing function" + annotation ( + Dialog(group = "Meshing properties")); + parameter Real q = 1.2 + "Growth rate (if geometricalGrowth chosen)" + annotation ( + Dialog(group = "Meshing properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 + "Decoupled value of the heat transfer (if biot segment chosen)" + annotation ( + Dialog(group = "Meshing properties")); + parameter Integer N(min = 1) = integer(max(1, 5 * Th / 0.2 * 1e-6 * d * cp / k)) + "Number of layers : 1 to 65535" + annotation ( + Dialog(group = "Meshing properties")); + parameter Modelica.SIunits.Area A = 0 + "Wall area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Height Lc = 0 + "Wall characteristic length" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Length Th = 0 + "Wall thickness" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 + "Wall specific heat capacity" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.Density d(displayUnit = "kg/m3") = 0 + "Wall density" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.ThermalConductivity k = 0 + "Wall conductivity" + annotation ( + Dialog(group = "Thermal properties")); + parameter Real add_on_conv = 1 + "Custom add-on for convection" + annotation ( + Dialog(group = "Convection properties")); + parameter Real add_on_cond = 1 + "Custom add-on for condensation" + annotation ( + Dialog(group = "Convection properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE + "free convection Correlation" + annotation ( + Dialog(group = "Convection properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Convection properties")); + // + parameter Modelica.SIunits.Emissivity eps = 0 + "Wall emissivity " + annotation ( + Dialog(group = "Radiative properties")); + parameter Real add_on_rad = 1 + "Custom add-on" + annotation ( + Dialog(group = "Radiative properties")); + // Internal variables + Modelica.SIunits.BiotNumber Bi; + // Components inside wall are defined + TAeZoSysPro.HeatTransfer.BasesClasses.PartialWall partialWall(A = A, N = N, T_start = T_start, Th = Th, cp = cp, d = d, energyDynamics = energyDynamics, h = h, k = k, mesh = mesh, q = q, symmetricalMesh = false) if N > 1 + annotation ( + Placement(visible = true, transformation(origin = {46.5, 18.5}, extent = {{-29.5, -29.5}, {29.5, 29.5}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.FreeConvection convection( + redeclare package Medium = Medium, + A = A, + Lc = Lc, + add_on = add_on_conv, + correlation = correlation, + h_cv_const = h_cv_const) + annotation ( + Placement(visible = true, transformation(origin = {-10, 89}, extent = {{-11, -11}, {11, 11}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A, add_on = add_on_rad, eps = eps) + annotation ( + Placement(visible = true, transformation(origin = {-16.5, -70.5}, extent = {{-22.5, -22.5}, {22.5, 22.5}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad + annotation ( + Placement(visible = true, transformation(origin = {-61, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall + annotation ( + Placement(visible = true, transformation(origin = {-52, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput F_view + annotation ( + Placement(visible = true, transformation(origin = {-50, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b + annotation ( + Placement(visible = true, transformation(origin = {99, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface + annotation ( + Placement(visible = true, transformation(origin = {-50, 60}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-90, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.Condensation condensation( + redeclare package Medium = Medium, + A = A) + annotation ( + Placement(visible = true, transformation(origin = {-50, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start, cp = cp, energyDynamics = energyDynamics, m = Th * A * d) if N == 1 + annotation ( + Placement(visible = true, transformation(origin = {46, -54}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); + +equation + + condensation.h_cv = convection.h_cv; + connect(port_surface, partialWall.port_a) + annotation ( + Line(points = {{-50, 60}, {18, 60}, {18, 18.5}}, color = {191, 0, 0})); + connect(F_view, carrollRadiation.Fview) + annotation ( + Line(points = {{-50, -30}, {1.5, -30}, {1.5, -52.5}}, color = {0, 0, 127})); + connect(port_a_rad, carrollRadiation.port_b) + annotation ( + Line(points = {{-61, -70}, {-48, -70}, {-48, -70.5}, {-39, -70.5}}, color = {191, 0, 0})); + connect(carrollRadiation.port_a, partialWall.port_a) + annotation ( + Line(points = {{6, -70.5}, {18, -70.5}, {18, 18.5}}, color = {191, 0, 0})); + if N > 1 then + Bi = convection.h_cv * (partialWall.x[2] - partialWall.x[1]) / k; + else + Bi = 0.0; + end if; + + A_wall = A; + //output y is set to Awall and it can be connected to FviewCalculator + connect(partialWall.port_b, port_b) + annotation ( + Line(points = {{75, 18.5}, {88, 18.5}, {88, 0}, {100, 0}}, color = {191, 0, 0})); + connect(condensation.heatPort, partialWall.port_a) + annotation ( + Line(points = {{-40, 30}, {18, 30}, {18, 18.5}}, color = {191, 0, 0})); + connect(port_a, condensation.flowPort) + annotation ( + Line(points = {{-90, 90}, {-70, 90}, {-70, 30}, {-60, 30}, {-60, 30}}, color = {0, 85, 255})); + connect(port_a, convection.port_b) + annotation ( + Line(points = {{-90, 90}, {-20, 90}, {-20, 90}, {-20, 90}}, color = {0, 85, 255})); + connect(convection.port_a, partialWall.port_a) + annotation ( + Line(points = {{2, 90}, {18, 90}, {18, 18}}, color = {191, 0, 0})); + connect(convection.port_a, heatCapacitor.port) + annotation ( + Line(points = {{2, 90}, {18, 90}, {18, -44}, {46, -44}}, color = {191, 0, 0})); + connect(port_surface, heatCapacitor.port) + annotation ( + Line(points = {{-50, 60}, {18, 60}, {18, -44}, {46, -44}}, color = {191, 0, 0})); + connect(condensation.heatPort, heatCapacitor.port) + annotation ( + Line(points = {{-40, 30}, {18, 30}, {18, -44}, {46, -44}}, color = {191, 0, 0})); + connect(carrollRadiation.port_a, heatCapacitor.port) + annotation ( + Line(points = {{6, -70}, {18, -70}, {18, -44}, {46, -44}}, color = {191, 0, 0})); + connect(port_b, heatCapacitor.port) + annotation ( + Line(points = {{100, 0}, {88, 0}, {88, -44}, {46, -44}}, color = {191, 0, 0})); + + annotation ( + Diagram(graphics = {Rectangle(origin = {43.5, -1}, fillColor = {218, 218, 218}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-42.5, 101}, {36.5, -99}}), Text(origin = {46, 52}, extent = {{-20, 10}, {20, -10}}, textString = "If N > 1"), Text(origin = {46, -32}, extent = {{-20, 10}, {20, -10}}, textString = "If N = 1")}, coordinateSystem(initialScale = 0.1)), + Icon(graphics = {Rectangle(origin = {11, 9}, fillColor = {191, 191, 191}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-51, 91}, {29, -109}}), Line(origin = {-70, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-60, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 88.1389}, points = {{9, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 52.1389}, points = {{9, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-93, 93}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "Fluid"), Text(origin = {-93, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Text(origin = {-73, -25}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view"), Text(origin = {-73, -49}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall"), Line(origin = {-52.1559, -79.8606}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52.5726, -99.7217}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Ellipse(origin = {-44, 88}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {-44, 70}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {-44, 52}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Line(origin = {-61.3433, 71.0195}, points = {{9, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), + Documentation( + info = " + + + HalfWall + + + + + + +

    + This component models the thermal response of half wall in interface with a rest ambiance where the thermal exchanges are mainly driven by natural convection, radiation and condensation. +

    + +

    + This component is an assembly of the PartialWall module, the FreeConvection module, the CarrollRadiation module and the Condensation module. The solid wall is dicretises in N along its depth to model the heat propagation. By defaut the value of N is computed from the depth and the thermal diffusivty of the wall.
    + When the number of layers N is equal to one, the PartialWall is replaced by a HeatCapacitor. +

    + + +

    + A port name port_surface is connected to the boundary port of the PartialWall. + It can be usefull for specific applications when another modules is required et can be latter connected to this empty heat port. +

    + +

    + The HalfWall supplies as output the surface area of the wall, via its A_wall port, to the FviewCalculator module and get from this last the form (or view) factor as input via the F_view port. The connection is performed explicitely via the graphic connectors. +

    + +"), + experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-06, Interval = 36)); + +end HalfWall; diff --git a/FluidDynamics/Components/Buildings/InertMass.mo b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/InertMass.mo similarity index 56% rename from FluidDynamics/Components/Buildings/InertMass.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Buildings/InertMass.mo index 03065a8..b56d87c 100644 --- a/FluidDynamics/Components/Buildings/InertMass.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/InertMass.mo @@ -1,88 +1,142 @@ within TAeZoSysPro.FluidDynamics.Components.Buildings; model InertMass + // - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import TAeZoSysPro.HeatTransfer.Types.Dynamics; -//Media - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; + //Media + replaceable package Medium = TAeZoSysPro.Media.MyMedia; // User defined parameters - parameter Modelica.SIunits.Area A_conv = 0 "Convective surface area " annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Area A_rad = A_conv "Radiative surface area " annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Length Lc = 1 "characteritic dimension for correlation" annotation( - Dialog(group="Geometrical properties")); - - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance" annotation( - Dialog(group="Dynamic properties")); - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial" annotation( - Dialog(group="Dynamic properties")); - - parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 "Specific heat capacity" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.Mass m= 0 "Mass of the component" annotation( - Dialog(group="Thermal properties")); - - parameter Real add_on_conv = 1 "Custom add-on for convection" annotation( - Dialog(group = "Convection properties")); - parameter Real add_on_cond = 1 "Custom add-on for condensation" annotation( - Dialog(group = "Convection properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE "free convection Correlation" annotation( - Dialog(group = "Convection properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Convection properties")); + parameter Modelica.SIunits.Area A_conv = 0 + "Convective surface area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Area A_rad = A_conv + "Radiative surface area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Length Lc = 1 + "characteritic dimension for correlation" + annotation ( + Dialog(group = "Geometrical properties")); + + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial" + annotation ( + Dialog(group = "Dynamic properties")); + + parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 + "Specific heat capacity" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.Mass m = 0 + "Mass of the component" + annotation ( + Dialog(group = "Thermal properties")); + + parameter Real add_on_conv = 1 + "Custom add-on for convection" + annotation ( + Dialog(group = "Convection properties")); + parameter Real add_on_cond = 1 + "Custom add-on for condensation" + annotation ( + Dialog(group = "Convection properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE + "free convection Correlation" + annotation ( + Dialog(group = "Convection properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Convection properties")); // - parameter Modelica.SIunits.Emissivity eps = 0 "Wall emissivity " annotation( - Dialog(group = "Radiative properties")); - parameter Real add_on_rad = 1 "Custom add-on" annotation( - Dialog(group = "Radiative properties")); + parameter Modelica.SIunits.Emissivity eps = 0 + "Wall emissivity " + annotation ( + Dialog(group = "Radiative properties")); + parameter Real add_on_rad = 1 + "Custom add-on" + annotation ( + Dialog(group = "Radiative properties")); + + // imported module + TAeZoSysPro.FluidDynamics.BasesClasses.FreeConvection convection( + redeclare package Medium = Medium, + A = A_conv, + Lc = Lc, + add_on = add_on_conv, + correlation = correlation, + h_cv_const = h_cv_const) + annotation ( + Placement(visible = true, transformation(origin = {-41, 80}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A_rad, add_on = add_on_rad, eps = eps) + annotation ( + Placement(visible = true, transformation(origin = {-59.5, -79.5}, extent = {{-19.5, -19.5}, {19.5, 19.5}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad + annotation ( + Placement(visible = true, transformation(origin = {-101, -78}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall + annotation ( + Placement(visible = true, transformation(origin = {-90, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput F_view + annotation ( + Placement(visible = true, transformation(origin = {-90, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start, cp = cp, energyDynamics = energyDynamics, m = m) + annotation ( + Placement(visible = true, transformation(origin = {0, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.Condensation condensation( + redeclare package Medium = Medium, + A = A_conv, + add_on = add_on_cond, + h_cv = convection.h_cv) + annotation ( + Placement(visible = true, transformation(origin = {-35, 39}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, 60}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 48}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); -// imported module - TAeZoSysPro.FluidDynamics.BasesClasses.FreeConvection convection(redeclare - package Medium = Medium, A = A_conv, Lc = Lc, add_on = add_on_conv, correlation = correlation, h_cv_const = h_cv_const) annotation ( - Placement(visible = true, transformation(origin = {-41, 80}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A_rad, add_on = add_on_rad, eps = eps) annotation( - Placement(visible = true, transformation(origin = {-59.5, -79.5}, extent = {{-19.5, -19.5}, {19.5, 19.5}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad annotation( - Placement(visible = true, transformation(origin = {-101, -78}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall annotation( - Placement(visible = true, transformation(origin = {-90, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput F_view annotation( - Placement(visible = true, transformation(origin = {-90, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface annotation( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start, cp = cp, energyDynamics = energyDynamics, m = m) annotation( - Placement(visible = true, transformation(origin = {0, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.Condensation condensation(redeclare - package Medium = Medium, A = A_conv, add_on = add_on_cond, h_cv = convection.h_cv) annotation ( - Placement(visible = true, transformation(origin = {-35, 39}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-100, 60}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 48}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); equation - connect(F_view, carrollRadiation.Fview) annotation( - Line(points = {{-90, -50}, {-44, -50}, {-44, -64}}, color = {0, 0, 127})); - connect(port_a_rad, carrollRadiation.port_b) annotation( - Line(points = {{-101, -78}, {-88, -78}, {-88, -79.5}, {-79, -79.5}}, color = {191, 0, 0})); + + connect(F_view, carrollRadiation.Fview) + annotation ( + Line(points = {{-90, -50}, {-44, -50}, {-44, -64}}, color = {0, 0, 127})); + connect(port_a_rad, carrollRadiation.port_b) + annotation ( + Line(points = {{-101, -78}, {-88, -78}, {-88, -79.5}, {-79, -79.5}}, color = {191, 0, 0})); A_wall = A_rad; - connect(convection.port_a, heatCapacitor.port) annotation( - Line(points = {{-23, 80}, {-20, 80}, {-20, 0}, {0, 0}}, color = {191, 0, 0})); - connect(carrollRadiation.port_a, heatCapacitor.port) annotation( - Line(points = {{-40, -79.5}, {-20, -79.5}, {-20, 0}, {0, 0}}, color = {191, 0, 0})); - connect(port_surface, heatCapacitor.port) annotation( - Line(points = {{-100, 0}, {0, 0}}, color = {191, 0, 0})); - connect(condensation.heatPort, heatCapacitor.port) annotation( - Line(points = {{-22, 39}, {-20, 39}, {-20, 0}, {0, 0}}, color = {191, 0, 0})); - connect(port_a, convection.port_b) annotation( - Line(points = {{-100, 60}, {-80, 60}, {-80, 80}, {-58, 80}, {-58, 80}}, color = {0, 85, 255})); - connect(port_a, condensation.flowPort) annotation( - Line(points = {{-100, 60}, {-80, 60}, {-80, 38}, {-48, 38}, {-48, 40}}, color = {0, 85, 255})); + connect(convection.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-23, 80}, {-20, 80}, {-20, 0}, {0, 0}}, color = {191, 0, 0})); + connect(carrollRadiation.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-40, -79.5}, {-20, -79.5}, {-20, 0}, {0, 0}}, color = {191, 0, 0})); + connect(port_surface, heatCapacitor.port) + annotation ( + Line(points = {{-100, 0}, {0, 0}}, color = {191, 0, 0})); + connect(condensation.heatPort, heatCapacitor.port) + annotation ( + Line(points = {{-22, 39}, {-20, 39}, {-20, 0}, {0, 0}}, color = {191, 0, 0})); + connect(port_a, convection.port_b) + annotation ( + Line(points = {{-100, 60}, {-80, 60}, {-80, 80}, {-58, 80}, {-58, 80}}, color = {0, 85, 255})); + connect(port_a, condensation.flowPort) + annotation ( + Line(points = {{-100, 60}, {-80, 60}, {-80, 38}, {-48, 38}, {-48, 40}}, color = {0, 85, 255})); - annotation( - defaultComponentName = "inertMass", - Documentation(info = " + annotation ( + defaultComponentName = "inertMass", + Documentation( + info = " InertMass diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Buildings/Wall.mo b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/Wall.mo new file mode 100644 index 0000000..9bf05ea --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/Wall.mo @@ -0,0 +1,300 @@ +within TAeZoSysPro.FluidDynamics.Components.Buildings; + +model Wall + + // + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + import TAeZoSysPro.HeatTransfer.Types.MeshGrid; + import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid; + + //Media + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters + parameter MeshGrid mesh = MeshGrid.biotAndGeometricalGrowth + "Selection of meshing function" + annotation ( + Dialog(group = "Meshing properties")); + parameter Real q = 1.2 + "Growth rate (if geometricalGrowth chosen)" + annotation ( + Dialog(group = "Meshing properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 + "Decoupled value of the heat transfer (if biot segment chosen)" + annotation ( + Dialog(group = "Meshing properties")); + parameter Integer N(min = 1) = integer(max(1, 5 * Th / 0.2 * 1e-6 * d * cp / k)) + "Number of layers : 1 to 65535" + annotation ( + Dialog(group = "Meshing properties")); + + parameter Modelica.SIunits.Area A = 0 + "Wall area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Height Lc = 0 + "Wall characteristic length" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Length Th = 0 + "Wall thickness" + annotation ( + Dialog(group = "Geometrical properties")); + + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial" + annotation ( + Dialog(group = "Dynamic properties")); + + parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 + "Wall specific heat capacity" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.Density d(displayUnit = "kg/m3") = 0 + "Wall density" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.ThermalConductivity k = 0 + "Wall conductivity" + annotation ( + Dialog(group = "Thermal properties")); + + parameter Real add_on_conv = 1 + "Custom add-on for convection" + annotation ( + Dialog(group = "Convection properties")); + parameter Real add_on_cond = 1 + "Custom add-on for condensation" + annotation ( + Dialog(group = "Convection properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation_a = Correlations.vertical_plate_ASHRAE + "free convection Correlation" + annotation ( + Dialog(group = "Convection properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation_b = if correlation_a == Correlations.ceiling_ASHRAE then Correlations.ground_ASHRAE elseif correlation_a == Correlations.ground_ASHRAE then Correlations.ceiling_ASHRAE else correlation_a + "free convection Correlation" + annotation ( + Dialog(group = "Convection properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const_a = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Convection properties")); + + parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const_b = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Convection properties")); + // + parameter Modelica.SIunits.Emissivity eps_a = 0 + "Wall emissivity " + annotation ( + Dialog(group = "Radiative properties")); + parameter Modelica.SIunits.Emissivity eps_b = 0 + "Wall emissivity " + annotation ( + Dialog(group = "Radiative properties")); + parameter Real add_on_rad = 1 + "Custom add-on" + annotation ( + Dialog(group = "Radiative properties")); + + // Internal variables + Modelica.SIunits.BiotNumber Bi_a, Bi_b; + + // Components inside wall are defined + TAeZoSysPro.HeatTransfer.BasesClasses.PartialWall partialWall(A = A, N = N, T_start = T_start, Th = Th, cp = cp, d = d, energyDynamics = energyDynamics, h = h, k = k, mesh = mesh, q = q, symmetricalMesh = true) if N > 1 + annotation ( + Placement(visible = true, transformation(origin = {0.5, 10.5}, extent = {{-29.5, -29.5}, {29.5, 29.5}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.FreeConvection freeConvection_a(redeclare package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation_a, h_cv_const = h_cv_const_a) + annotation ( + Placement(visible = true, transformation(origin = {-55, 70}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation_a(A = A, add_on = add_on_rad, eps = eps_a) + annotation ( + Placement(visible = true, transformation(origin = {-59.5, -79.5}, extent = {{-19.5, -19.5}, {19.5, 19.5}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad + annotation ( + Placement(visible = true, transformation(origin = {-101, -78}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall_a + annotation ( + Placement(visible = true, transformation(origin = {-90, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput F_view_a + annotation ( + Placement(visible = true, transformation(origin = {-90, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface_a + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.FreeConvection freeConvection_b(redeclare package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation_b, h_cv_const = h_cv_const_b) + annotation ( + Placement(visible = true, transformation(origin = {57, 70}, extent = {{18, -18}, {-18, 18}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation_b(A = A, add_on = add_on_rad, eps = eps_b) + annotation ( + Placement(visible = true, transformation(origin = {59.5, -80.5}, extent = {{20.5, -20.5}, {-20.5, 20.5}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b_rad + annotation ( + Placement(visible = true, transformation(origin = {101, -80}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall_b + annotation ( + Placement(visible = true, transformation(origin = {90, -20}, extent = {{10, -10}, {-10, 10}}, rotation = 180), iconTransformation(origin = {93, -53}, extent = {{7, -7}, {-7, 7}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput F_view_b + annotation ( + Placement(visible = true, transformation(origin = {90, -50}, extent = {{10, -10}, {-10, 10}}, rotation = 0), iconTransformation(origin = {93, -27}, extent = {{7, -7}, {-7, 7}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_surface_b + annotation ( + Placement(visible = true, transformation(origin = {101, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {100, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.Condensation condensation_a(redeclare package Medium = Medium, A = A, add_on = add_on_cond, h_cv = freeConvection_a.h_cv) + annotation ( + Placement(visible = true, transformation(origin = {-55, 21}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.Condensation condensation_b(redeclare package Medium = Medium, A = A, add_on = add_on_cond, h_cv = freeConvection_b.h_cv) + annotation ( + Placement(visible = true, transformation(origin = {55, 21}, extent = {{15, -15}, {-15, 15}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start, cp = cp, energyDynamics = energyDynamics, m = Th * A * d) if N == 1 + annotation ( + Placement(visible = true, transformation(origin = {0, -70}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); + +equation + + connect(port_a_rad, carrollRadiation_a.port_b) + annotation ( + Line(points = {{-101, -78}, {-88, -78}, {-88, -79.5}, {-79, -79.5}}, color = {191, 0, 0})); + + if N > 1 then + Bi_a = freeConvection_a.h_cv * (partialWall.x[2] - partialWall.x[1]) / k; + Bi_b = freeConvection_b.h_cv * (partialWall.x[end] - partialWall.x[end - 1]) / k; + else + Bi_a = 0.0; + Bi_b = 0.0; + end if; + + A_wall_a = A; + A_wall_b = A; + //output y is set to Awall and it can be connected to FviewCalculator + connect(freeConvection_a.port_a, partialWall.port_a) + annotation ( + Line(points = {{-36, 70}, {-28, 70}, {-28, 10.5}}, color = {191, 0, 0})); + connect(carrollRadiation_a.port_a, partialWall.port_a) + annotation ( + Line(points = {{-40, -79.5}, {-28, -79.5}, {-28, 10.5}}, color = {191, 0, 0})); + connect(freeConvection_b.port_a, partialWall.port_b) + annotation ( + Line(points = {{39, 70}, {28, 70}, {28, 10.5}, {29, 10.5}}, color = {191, 0, 0})); + connect(carrollRadiation_b.port_a, partialWall.port_b) + annotation ( + Line(points = {{39, -80.5}, {28, -80.5}, {28, 10.5}, {29, 10.5}}, color = {191, 0, 0})); + connect(carrollRadiation_b.port_b, port_b_rad) + annotation ( + Line(points = {{80, -80.5}, {92, -80.5}, {92, -80}, {101, -80}}, color = {191, 0, 0})); + connect(port_surface_a, partialWall.port_a) + annotation ( + Line(points = {{-100, 0}, {-28, 0}, {-28, 10.5}}, color = {191, 0, 0})); + connect(port_surface_b, partialWall.port_b) + annotation ( + Line(points = {{101, 0}, {27.5, 0}, {27.5, 10.5}, {29, 10.5}}, color = {191, 0, 0})); + connect(F_view_a, carrollRadiation_a.Fview) + annotation ( + Line(points = {{-90, -50}, {-44, -50}, {-44, -64}}, color = {0, 0, 127})); + connect(F_view_b, carrollRadiation_b.Fview) + annotation ( + Line(points = {{90, -50}, {44, -50}, {44, -64}, {43, -64}}, color = {0, 0, 127})); + connect(condensation_a.heatPort, partialWall.port_a) + annotation ( + Line(points = {{-41.5, 21}, {-28, 21}, {-28, 10.5}}, color = {191, 0, 0})); + connect(port_a, freeConvection_a.port_b) + annotation ( + Line(points = {{-100, 70}, {-74, 70}, {-74, 70}, {-72, 70}}, color = {0, 85, 255})); + connect(port_a, condensation_a.flowPort) + annotation ( + Line(points = {{-100, 70}, {-86, 70}, {-86, 21}, {-69, 21}}, color = {0, 85, 255})); + connect(condensation_b.heatPort, partialWall.port_b) + annotation ( + Line(points = {{41.5, 21}, {28, 21}, {28, 10.5}, {29, 10.5}}, color = {191, 0, 0})); + connect(freeConvection_b.port_b, port_b) + annotation ( + Line(points = {{74, 70}, {100, 70}, {100, 70}, {100, 70}}, color = {0, 85, 255})); + connect(condensation_b.flowPort, port_b) + annotation ( + Line(points = {{69, 21}, {88, 21}, {88, 70}, {100, 70}}, color = {0, 85, 255})); + connect(freeConvection_a.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-36, 70}, {-28, 70}, {-28, -60}, {0, -60}}, color = {191, 0, 0})); + connect(heatCapacitor.port, condensation_a.heatPort) + annotation ( + Line(points = {{0, -60}, {-28, -60}, {-28, 21}, {-41.5, 21}}, color = {191, 0, 0})); + connect(port_surface_a, heatCapacitor.port) + annotation ( + Line(points = {{-100, 0}, {-28, 0}, {-28, -60}, {0, -60}}, color = {191, 0, 0})); + connect(carrollRadiation_a.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-40, -79.5}, {-28, -79.5}, {-28, -60}, {0, -60}}, color = {191, 0, 0})); + connect(freeConvection_b.port_a, heatCapacitor.port) + annotation ( + Line(points = {{40, 70}, {28, 70}, {28, -60}, {0, -60}}, color = {191, 0, 0})); + connect(condensation_b.heatPort, heatCapacitor.port) + annotation ( + Line(points = {{41.5, 21}, {28, 21}, {28, -60}, {0, -60}}, color = {191, 0, 0})); + connect(port_surface_b, heatCapacitor.port) + annotation ( + Line(points = {{101, 0}, {28, 0}, {28, -60}, {0, -60}}, color = {191, 0, 0})); + connect(carrollRadiation_b.port_a, heatCapacitor.port) + annotation ( + Line(points = {{39, -80.5}, {28, -80.5}, {28, -60}, {0, -60}}, color = {191, 0, 0})); + + annotation ( + Diagram(graphics = {Rectangle(origin = {3.5, -1}, fillColor = {218, 218, 218}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-42.5, 101}, {36.5, -99}}), Text(origin = {2, 46}, extent = {{-20, 10}, {20, -10}}, textString = "If N > 1"), Text(origin = {2, -46}, extent = {{-20, 10}, {20, -10}}, textString = "If N = 1")}, coordinateSystem(initialScale = 0.1)), + Icon(graphics = {Rectangle(origin = {11, 9}, fillColor = {191, 191, 191}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-51, 91}, {29, -109}}), Line(origin = {-70, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-58, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 88.1389}, points = {{7, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 54.14}, points = {{7, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-106, 93}, lineThickness = 1, extent = {{-14, 7}, {26, -13}}, textString = "Fluid"), Text(origin = {-93, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Text(origin = {-73, -27}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view_a"), Text(origin = {-73, -49}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall_a"), Line(origin = {-52.1559, -79.8606}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52.5726, -99.7217}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {67, -47}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall_b"), Text(origin = {67, -27}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view_b"), Line(origin = {52.8486, -80.2659}, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {52.4319, -100.127}, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {68.8387, 69.7336}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {59.8387, 53.7336}, rotation = 180, points = {{7, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {59.8387, 87.7336}, rotation = 180, points = {{7, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {56.8387, 69.7336}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {94, 93}, lineThickness = 1, extent = {{-14, 7}, {26, -13}}, textString = "Fluid"), Text(origin = {87, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Ellipse(origin = {-46, 88}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {-46, 70}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {-46, 52}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {46, 88}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {46, 70}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}}), Ellipse(origin = {46, 52}, fillColor = {0, 85, 255}, fillPattern = FillPattern.Solid, extent = {{-4, 4}, {4, -4}})}, coordinateSystem(initialScale = 0.1)), + Documentation( + info = " + + + HalfWall + + + + + + +

    + This component models the thermal response of wall in interface with a rest ambiances where the thermal exchanges are mainly driven by natural convection, radiation and condensation. +

    + +

    + The suffix '..._a' refers to side where the ports 'port_a' are. +

    + +

    + This component is an assembly of the PartialWall module, the FreeConvection modules, the CarrollRadiation modules and the Condensation modules. The solid wall is dicretises in N along its depth to model the heat propagation. By defaut the value of N is computed from the depth and the thermal diffusivty of the wall.
    + When the number of layers N is equal to one, the PartialWall is replaced by a HeatCapacitor. +

    + +

    + Ports name port_surface are connected to boundary ports of the PartialWall. + It can be usefull for specific applications when another modules is required et can be latter connected to this empty heat port. +

    + +

    + The Wall supplies as output the surface area of the wall, via its A_wall ports, to the FviewCalculator module and get from this last the form (or view) factor as input via the F_view ports. The connection is performed explicitely via the graphic connectors. +

    + +"), + experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-06, Interval = 36)); + +end Wall; diff --git a/FluidDynamics/Components/Buildings/WallLeaks.mo b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/WallLeaks.mo similarity index 68% rename from FluidDynamics/Components/Buildings/WallLeaks.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Buildings/WallLeaks.mo index 5838936..a050ab7 100644 --- a/FluidDynamics/Components/Buildings/WallLeaks.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/WallLeaks.mo @@ -1,50 +1,66 @@ within TAeZoSysPro.FluidDynamics.Components.Buildings; model WallLeaks + replaceable package Medium = TAeZoSysPro.Media.MyMedia; // - parameter Modelica.SIunits.Area A "Wall surface area" annotation( - Dialog(group = "Geometry")); - parameter Real leakSurfaceRatio(min=0.0, max=1.0) = 1e-4 "ratio of leak surface m²leak / m²wall" annotation( - Dialog(group = "Geometry")); + parameter Modelica.SIunits.Area A + "Wall surface area" + annotation ( + Dialog(group = "Geometry")); + parameter Real leakSurfaceRatio(min = 0.0, max = 1.0) = 1e-4 + "ratio of leak surface m²leak / m²wall" + annotation ( + Dialog(group = "Geometry")); // - parameter Real ksi(min=1.0) = 1.0 "dynamic pressure loss" annotation( - Dialog(group = "Flow")); - parameter Real leakExponent = 1.35 "Exponent for Behavior model of the leak" annotation( - Dialog(group = "Flow")); + parameter Real ksi(min = 1.0) = 1.0 + "dynamic pressure loss" + annotation ( + Dialog(group = "Flow")); + parameter Real leakExponent = 1.35 + "Exponent for Behavior model of the leak" + annotation ( + Dialog(group = "Flow")); // Modelica.SIunits.PressureDifference dp; - Modelica.SIunits.MassFlowRate m_flow "Mass flow rate through the leak(s)"; + Modelica.SIunits.MassFlowRate m_flow + "Mass flow rate through the leak(s)"; Modelica.SIunits.Density d, d_a, d_b; // - Modelica.Fluid.Interfaces.FluidPort_a port_a(replaceable package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {-100, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_b(replaceable package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {100, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_a(replaceable package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_b(replaceable package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {100, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +protected -protected parameter Modelica.SIunits.PressureDifference dp_small = 0.01; equation -// - d_a = Medium.density_phX(p = port_a.p, - h = inStream(port_a.h_outflow), - X = cat(1, inStream(port_a.Xi_outflow), {1 - sum(inStream(port_a.Xi_outflow))})) ; - - d_b = Medium.density_phX(p = port_b.p, - h = inStream(port_b.h_outflow), - X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))})) ; -// momentum balance + // + d_a = Medium.density_phX( + p = port_a.p, + h = inStream(port_a.h_outflow), + X = cat(1, inStream(port_a.Xi_outflow), {1 - sum(inStream(port_a.Xi_outflow))})); + + d_b = Medium.density_phX( + p = port_b.p, + h = inStream(port_b.h_outflow), + X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))})); + + // momentum balance dp = port_a.p - port_b.p; d = TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = dp, - x_small = dp_small, - y1 = d_a, + x = dp, + x_small = dp_small, + y1 = d_a, y2 = d_b); - m_flow = A * leakSurfaceRatio * d * (2/(ksi*d))^(1/leakExponent) * Modelica.Fluid.Utilities.regPow(x = dp, delta = dp_small, a = leakExponent); + m_flow = A * leakSurfaceRatio * d * (2 / (ksi * d)) ^ (1 / leakExponent) * Modelica.Fluid.Utilities.regPow(x = dp, delta = dp_small, a = leakExponent); -// port handover + // port handover port_a.m_flow = m_flow; port_a.m_flow + port_b.m_flow = 0.0; port_a.h_outflow = inStream(port_b.h_outflow); @@ -53,10 +69,10 @@ equation port_b.Xi_outflow = inStream(port_a.Xi_outflow); port_a.C_outflow = inStream(port_b.C_outflow); port_b.C_outflow = inStream(port_a.C_outflow); - - annotation( - Documentation(info= -" + + annotation ( + Documentation( + info = " WallLeaks diff --git a/FluidDynamics/Components/Buildings/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/package.mo similarity index 98% rename from FluidDynamics/Components/Buildings/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Buildings/package.mo index 68d0914..033549d 100644 --- a/FluidDynamics/Components/Buildings/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components; package Buildings + extends Modelica.Icons.VariantsPackage; + end Buildings; diff --git a/FluidDynamics/Components/Buildings/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Buildings/package.order similarity index 100% rename from FluidDynamics/Components/Buildings/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Buildings/package.order diff --git a/FluidDynamics/Components/Filters/Filter.mo b/src/TAeZoSysPro/FluidDynamics/Components/Filters/Filter.mo similarity index 69% rename from FluidDynamics/Components/Filters/Filter.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Filters/Filter.mo index 4fc8315..b095e53 100644 --- a/FluidDynamics/Components/Filters/Filter.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Filters/Filter.mo @@ -1,52 +1,67 @@ within TAeZoSysPro.FluidDynamics.Components.Filters; model Filter + // - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters - parameter Real K(unit = "m3/(s.Pa)") = V_flow_nominal / dp_nominal "linear pressure loss coefficient" annotation ( - Dialog(group = "Flow")); - parameter Modelica.SIunits.Pressure dp_nominal "Nominal pressure drop" annotation( - Dialog(group="Nominal operating point")); - parameter Modelica.SIunits.VolumeFlowRate V_flow_nominal "Nominal volume flowrate" annotation( - Dialog(group="Nominal operating point")); - + parameter Real K(unit = "m3/(s.Pa)") = V_flow_nominal / dp_nominal + "linear pressure loss coefficient" + annotation ( + Dialog(group = "Flow")); + parameter Modelica.SIunits.Pressure dp_nominal + "Nominal pressure drop" + annotation ( + Dialog(group = "Nominal operating point")); + parameter Modelica.SIunits.VolumeFlowRate V_flow_nominal + "Nominal volume flowrate" + annotation ( + Dialog(group = "Nominal operating point")); + // Internal variables Modelica.SIunits.PressureDifference dp; - Modelica.SIunits.MassFlowRate m_flow "Aperture flow kg/s"; + Modelica.SIunits.MassFlowRate m_flow + "Aperture flow kg/s"; Modelica.SIunits.Density d; - + // Imported modules - Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected equation + // - d = smooth(0, noEvent( - if dp<0 then - Medium.density(Medium.setState_phX(port_a.p, port_a.h_outflow, port_a.Xi_outflow)) - else - Medium.density(Medium.setState_phX(port_b.p, port_b.h_outflow, port_b.Xi_outflow)) ) ) ; + d = smooth( + 0, + noEvent( + if dp < 0 then + Medium.density(Medium.setState_phX(port_a.p, port_a.h_outflow, port_a.Xi_outflow)) + else + Medium.density(Medium.setState_phX(port_b.p, port_b.h_outflow, port_b.Xi_outflow)))); -// momentum balance + // momentum balance dp = port_a.p - port_b.p; - m_flow = d * K * dp ; + m_flow = d * K * dp; -// port handover + // port handover port_a.m_flow = m_flow; port_a.m_flow + port_b.m_flow = 0.0; port_a.h_outflow = inStream(port_b.h_outflow); port_b.h_outflow = inStream(port_a.h_outflow); port_a.Xi_outflow = inStream(port_b.Xi_outflow); port_b.Xi_outflow = inStream(port_a.Xi_outflow); - - annotation(defaultComponentName="filter", -Documentation(info =" + + annotation ( + defaultComponentName = "filter", + Documentation( + info = " Filter diff --git a/FluidDynamics/Components/Filters/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Filters/package.mo similarity index 98% rename from FluidDynamics/Components/Filters/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Filters/package.mo index a32eadf..4dc1221 100644 --- a/FluidDynamics/Components/Filters/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Filters/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components; package Filters + extends Modelica.Icons.VariantsPackage; + end Filters; diff --git a/FluidDynamics/Components/Filters/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Filters/package.order similarity index 100% rename from FluidDynamics/Components/Filters/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Filters/package.order diff --git a/src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/AnalyticExchanger.mo b/src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/AnalyticExchanger.mo new file mode 100644 index 0000000..833215f --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/AnalyticExchanger.mo @@ -0,0 +1,135 @@ +within TAeZoSysPro.FluidDynamics.Components.HeatExchangers; + +model AnalyticExchanger + + // + extends TAeZoSysPro.HeatTransfer.BasesClasses.PartialHeatExchanger; + import TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness; + import TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; + // + import SI = Modelica.SIunits; + + // Medium declaration + replaceable package MediumA = TAeZoSysPro.Media.MyMedia; + replaceable package MediumB = TAeZoSysPro.Media.MyMedia; + + // + replaceable function effectiveness = ExchangerEffectiveness.counterCurrent; + replaceable function heatTransferCoeff = ExchangerHeatTransferCoeff.user_defined; + + // User defined parameters + parameter SI.Area CrossSectionA = 1 + "Cross section of the pipe for the fluid A" + annotation (Dialog(group = "Geometrical parameters")); + parameter SI.Area CrossSectionB = 1 + "Cross section of the pipe for the fluid B" + annotation (Dialog(group = "Geometrical parameters")); + parameter Real ksi_fixedA = 1.0 + annotation (Dialog(group = "Flow parameters")); + parameter Real ksi_fixedB = 1.0 + annotation (Dialog(group = "Flow parameters")); + + // Internal variables + MediumA.ThermodynamicState stateA_in + "State of fluid A a inlet"; + MediumB.ThermodynamicState stateB_in + "State of fluid B a inlet"; + SI.SpecificHeatCapacity cp_A; + SI.SpecificHeatCapacity cp_B; + SI.MassFlowRate m_flowA + "Mass flow rate of fluid A"; + SI.MassFlowRate m_flowB + "Mass flow rate of fluid B"; + SI.PressureDifference dp_A + "fluid A pressure drop"; + SI.PressureDifference dp_B + "fluid B pressure drop"; + + // Imported modules + Modelica.Fluid.Interfaces.FluidPort_a port_A_in(redeclare package Medium = MediumA) + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_A_out(redeclare package Medium = MediumA) + annotation ( + Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_B_in(redeclare package Medium = MediumB) + annotation ( + Placement(visible = true, transformation(origin = {-68, 88}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, -84}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_B_out(redeclare package Medium = MediumB) + annotation ( + Placement(visible = true, transformation(origin = {66, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 82}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +equation + + // + stateA_in = MediumA.setState_phX(port_A_in.p, inStream(port_A_in.h_outflow), inStream(port_A_in.Xi_outflow)); + stateB_in = MediumB.setState_phX(port_B_in.p, inStream(port_B_in.h_outflow), inStream(port_B_in.Xi_outflow)); + + // compute thermodynamical properties + cp_A = MediumA.specificHeatCapacityCp(stateA_in); + cp_B = MediumB.specificHeatCapacityCp(stateB_in); + + // + Qc_A = m_flowA * cp_A; + Qc_B = m_flowB * cp_B; + + // + T_A_in = MediumA.temperature(stateA_in); + T_B_in = MediumB.temperature(stateB_in); + + //momentum - steady state assumptions + m_flowA = CrossSectionA * TAeZoSysPro.FluidDynamics.Utilities.regRoot2( + x = port_A_in.p - port_A_out.p, + x_small = 10, + k1 = 2 * MediumA.density(stateA_in) / ksi_fixedA, + k2 = 2 * MediumA.density(stateA_in) / ksi_fixedA); + dp_A = port_A_in.p - port_A_out.p; + + m_flowB = CrossSectionB * TAeZoSysPro.FluidDynamics.Utilities.regRoot2( + x = port_B_in.p - port_B_out.p, + x_small = 10, + k1 = 2 * MediumB.density(stateB_in) / ksi_fixedB, + k2 = 2 * MediumB.density(stateB_in) / ksi_fixedB); + dp_B = port_B_in.p - port_B_out.p; + + // heat exchange properties + h_global = heatTransferCoeff(); + Eff = effectiveness(NTU = NTU, Cr = Cr); + + // ports handover + port_A_in.m_flow = m_flowA; + port_A_in.h_outflow = inStream(port_A_in.h_outflow); + // reverse flow not modelled + port_A_in.Xi_outflow = inStream(port_A_in.Xi_outflow); + port_A_out.m_flow + port_A_in.m_flow = 0.0; + m_flowA * (inStream(port_A_in.h_outflow) - port_A_out.h_outflow) = Q_flow; + port_A_out.Xi_outflow = inStream(port_A_out.Xi_outflow); + // + port_B_in.m_flow = m_flowB; + port_B_in.h_outflow = inStream(port_B_in.h_outflow); + // reverse flow not modelled + port_B_in.Xi_outflow = inStream(port_B_in.Xi_outflow); + port_B_out.m_flow + port_B_in.m_flow = 0.0; + m_flowB * (inStream(port_B_in.h_outflow) - port_B_out.h_outflow) = -Q_flow; + port_B_out.Xi_outflow = inStream(port_B_out.Xi_outflow); + + annotation ( + Documentation( + info = " + + + DryExchanger + + + + + +

    + This component models a dry heat exchange. It is a duplication of the component HeatExchanger + from the HeatTransfer package adapted to use fluidports. +

    + + +")); + +end AnalyticExchanger; diff --git a/FluidDynamics/Components/HeatExchangers/DiscreteExchanger.mo b/src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/DiscreteExchanger.mo similarity index 55% rename from FluidDynamics/Components/HeatExchangers/DiscreteExchanger.mo rename to src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/DiscreteExchanger.mo index 3be8be7..885b2cc 100644 --- a/FluidDynamics/Components/HeatExchangers/DiscreteExchanger.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/DiscreteExchanger.mo @@ -1,153 +1,191 @@ within TAeZoSysPro.FluidDynamics.Components.HeatExchangers; model DiscreteExchanger + + // + encapsulated type FlowConfiguration = enumeration(CoCurrent, CounterCurrent); // - encapsulated type FlowConfiguration = enumeration(CoCurrent, CounterCurrent) ; + import TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness; + import TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; // - import TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness ; - import TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff ; -// - import SI = Modelica.SIunits ; + import SI = Modelica.SIunits; // Medium declaration - replaceable package MediumA = TAeZoSysPro.Media.MyMedia ; - replaceable package MediumB = TAeZoSysPro.Media.MyMedia ; + replaceable package MediumA = TAeZoSysPro.Media.MyMedia; + replaceable package MediumB = TAeZoSysPro.Media.MyMedia; // - replaceable function effectiveness = ExchangerEffectiveness.counterCurrent ; - replaceable function heatTransferCoeff = ExchangerHeatTransferCoeff.user_defined ; + replaceable function effectiveness = ExchangerEffectiveness.counterCurrent; + replaceable function heatTransferCoeff = ExchangerHeatTransferCoeff.user_defined; // User defined parameters - parameter Modelica.SIunits.Area A = 1.0 "equivalent exchange surface area" annotation(Dialog(group="Geometrical parameters")); - parameter Modelica.SIunits.Length L_A = 1.0 "Length of the side A of the exchanger" annotation(Dialog(group="Geometrical parameters")); - parameter Modelica.SIunits.Length L_B = 1.0 "Length of the side B of the exchanger" annotation(Dialog(group="Geometrical parameters")); - parameter SI.Area CrossSectionA = 1 "Cross section of the pipe for the fluid A" annotation(Dialog(group="Geometrical parameters")) ; - parameter SI.Area CrossSectionB = 1 "Cross section of the pipe for the fluid B" annotation(Dialog(group="Geometrical parameters")); - parameter Real ksi_fixedA = 1.0 annotation(Dialog(group="Flow parameters")); - parameter Real ksi_fixedB = 1.0 annotation(Dialog(group="Flow parameters")); - parameter Integer N = 3 "Number of discrete layers" ; - parameter FlowConfiguration flowConfiguration = FlowConfiguration.CounterCurrent ; + parameter Modelica.SIunits.Area A = 1.0 + "equivalent exchange surface area" + annotation (Dialog(group = "Geometrical parameters")); + parameter Modelica.SIunits.Length L_A = 1.0 + "Length of the side A of the exchanger" + annotation (Dialog(group = "Geometrical parameters")); + parameter Modelica.SIunits.Length L_B = 1.0 + "Length of the side B of the exchanger" + annotation (Dialog(group = "Geometrical parameters")); + parameter SI.Area CrossSectionA = 1 + "Cross section of the pipe for the fluid A" + annotation (Dialog(group = "Geometrical parameters")); + parameter SI.Area CrossSectionB = 1 + "Cross section of the pipe for the fluid B" + annotation (Dialog(group = "Geometrical parameters")); + parameter Real ksi_fixedA = 1.0 + annotation (Dialog(group = "Flow parameters")); + parameter Real ksi_fixedB = 1.0 + annotation (Dialog(group = "Flow parameters")); + parameter Integer N = 3 + "Number of discrete layers"; + parameter FlowConfiguration flowConfiguration = FlowConfiguration.CounterCurrent; // Internal variables - Modelica.SIunits.ThermalConductance Qc_A(min=0) "Thermal flow rate unit of fluid A"; - Modelica.SIunits.ThermalConductance Qc_B(min=0) "Thermal flow rate unit of fluid B"; + Modelica.SIunits.ThermalConductance Qc_A(min = 0) + "Thermal flow rate unit of fluid A"; + Modelica.SIunits.ThermalConductance Qc_B(min = 0) + "Thermal flow rate unit of fluid B"; Modelica.SIunits.Temperature T_A_in, T_A_out, T_B_in, T_B_out; - Modelica.SIunits.CoefficientOfHeatTransfer h_global "Heat transfer coeffcient between fluid A and B" ; - Modelica.SIunits.HeatFlowRate Q_flow "Heat flow exchanged"; - Modelica.SIunits.Energy E "Energy passed throught the component" ; - MediumA.ThermodynamicState stateA_in "State of fluid A a inlet" ; - MediumB.ThermodynamicState stateB_in "State of fluid B a inlet" ; - SI.SpecificHeatCapacity cp_A ; - SI.SpecificHeatCapacity cp_B ; - SI.MassFlowRate m_flowA "Mass flow rate of fluid A" ; - SI.MassFlowRate m_flowB "Mass flow rate of fluid B" ; - SI.PressureDifference dp_A "fluid A pressure drop"; - SI.PressureDifference dp_B "fluid B pressure drop"; + Modelica.SIunits.CoefficientOfHeatTransfer h_global + "Heat transfer coeffcient between fluid A and B"; + Modelica.SIunits.HeatFlowRate Q_flow + "Heat flow exchanged"; + Modelica.SIunits.Energy E + "Energy passed throught the component"; + MediumA.ThermodynamicState stateA_in + "State of fluid A a inlet"; + MediumB.ThermodynamicState stateB_in + "State of fluid B a inlet"; + SI.SpecificHeatCapacity cp_A; + SI.SpecificHeatCapacity cp_B; + SI.MassFlowRate m_flowA + "Mass flow rate of fluid A"; + SI.MassFlowRate m_flowB + "Mass flow rate of fluid B"; + SI.PressureDifference dp_A + "fluid A pressure drop"; + SI.PressureDifference dp_B + "fluid B pressure drop"; // Imported modules - Modelica.Fluid.Interfaces.FluidPort_a port_A_in(redeclare package Medium = MediumA) annotation ( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_A_out(redeclare package Medium = MediumA) annotation ( - Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_a port_B_in(redeclare package Medium = MediumB) annotation ( - Placement(visible = true, transformation(origin = {-68, 88}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, -84}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_B_out(redeclare package Medium = MediumB) annotation ( - Placement(visible = true, transformation(origin = {66, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 82}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_A_in(redeclare package Medium = MediumA) + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_A_out(redeclare package Medium = MediumA) + annotation ( + Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_B_in(redeclare package Medium = MediumB) + annotation ( + Placement(visible = true, transformation(origin = {-68, 88}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, -84}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_B_out(redeclare package Medium = MediumB) + annotation ( + Placement(visible = true, transformation(origin = {66, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 82}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); TAeZoSysPro.PDE.Transport.UpwindFirstOrder transport_A( - N = N, - x = linspace(0, L_A, N+1), + N = N, + x = linspace(0, L_A, N + 1), CoeffTimeDer = MediumA.density(stateA_in) * CrossSectionA * cp_A, - CoeffSpaceDer = m_flowA * cp_A) annotation ( - Placement(visible = true, transformation(origin = {4, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + CoeffSpaceDer = m_flowA * cp_A) + annotation ( + Placement(visible = true, transformation(origin = {4, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); TAeZoSysPro.PDE.Transport.UpwindFirstOrder transport_B( - N = N, - x = linspace(0, L_B, N+1), + N = N, + x = linspace(0, L_B, N + 1), CoeffTimeDer = MediumB.density(stateB_in) * CrossSectionB * cp_B, - CoeffSpaceDer = m_flowB * cp_B) annotation ( - Placement(visible = true, transformation(origin = {-12, -32}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + CoeffSpaceDer = m_flowB * cp_B) + annotation ( + Placement(visible = true, transformation(origin = {-12, -32}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +initial equation -initial equation E = 0.0; -// der(transport_A.u[2:end]) = fill(0.0, N) ; -// der(transport_B.u[2:end]) = fill(0.0, N) ; - transport_A.u[:,1] = fill(293.15, N) ; - transport_B.u[:,1] = fill(293.15, N) ; - + // der(transport_A.u[2:end]) = fill(0.0, N) ; + // der(transport_B.u[2:end]) = fill(0.0, N) ; + transport_A.u[:, 1] = fill(293.15, N); + transport_B.u[:, 1] = fill(293.15, N); + equation -// + + // stateA_in = MediumA.setState_phX( - port_A_in.p, - inStream(port_A_in.h_outflow), + port_A_in.p, + inStream(port_A_in.h_outflow), inStream(port_A_in.Xi_outflow)); stateB_in = MediumB.setState_phX( - port_B_in.p, - inStream(port_B_in.h_outflow), + port_B_in.p, + inStream(port_B_in.h_outflow), inStream(port_B_in.Xi_outflow)); - -// compute thermodynamical properties + + // compute thermodynamical properties cp_A = MediumA.specificHeatCapacityCp(stateA_in); - cp_B = MediumB.specificHeatCapacityCp(stateB_in) ; - -// + cp_B = MediumB.specificHeatCapacityCp(stateB_in); + + // Qc_A = m_flowA * cp_A; - Qc_B = m_flowB * cp_B ; - -// + Qc_B = m_flowB * cp_B; + + // T_A_in = MediumA.temperature(stateA_in); - T_B_in = MediumB.temperature(stateB_in) ; - -//momentum - steady state assumptions + T_B_in = MediumB.temperature(stateB_in); + + //momentum - steady state assumptions m_flowA = CrossSectionA * TAeZoSysPro.FluidDynamics.Utilities.regRoot2(x = port_A_in.p - port_A_out.p, x_small = 10, k1 = 2 * MediumA.density(stateA_in) / ksi_fixedA, k2 = 2 * MediumA.density(stateA_in) / ksi_fixedA); - dp_A = port_A_in.p - port_A_out.p; - + dp_A = port_A_in.p - port_A_out.p; + m_flowB = CrossSectionB * TAeZoSysPro.FluidDynamics.Utilities.regRoot2( - x = port_B_in.p - port_B_out.p, - x_small = 10, - k1 = 2 * MediumB.density(stateB_in) / ksi_fixedB, + x = port_B_in.p - port_B_out.p, + x_small = 10, + k1 = 2 * MediumB.density(stateB_in) / ksi_fixedB, k2 = 2 * MediumB.density(stateB_in) / ksi_fixedB); - dp_B = port_B_in.p - port_B_out.p; - -// transport + dp_B = port_B_in.p - port_B_out.p; + + // transport // boundary equations - transport_A.u_ghost_left[1] = T_A_in "left BC"; - transport_B.u_ghost_left[1] = T_B_in "left BC"; - transport_A.u_ghost_right[1] = T_A_in "right BC"; - transport_B.u_ghost_right[1] = T_B_in "right BC"; + transport_A.u_ghost_left[1] = T_A_in + "left BC"; + transport_B.u_ghost_left[1] = T_B_in + "left BC"; + transport_A.u_ghost_right[1] = T_A_in + "right BC"; + transport_B.u_ghost_right[1] = T_B_in + "right BC"; - if flowConfiguration == FlowConfiguration.CounterCurrent then - for i in 1:N loop - transport_A.SourceTerm[i] = h_global * A/L_A * (transport_B.u[N+1-i,1]-transport_A.u[i,1]); - transport_B.SourceTerm[i] = h_global * A/L_B * (transport_A.u[N+1-i,1]-transport_B.u[i,1]); + for i in 1 : N loop + transport_A.SourceTerm[i] = h_global * A / L_A * (transport_B.u[N + 1 - i, 1] - transport_A.u[i, 1]); + transport_B.SourceTerm[i] = h_global * A / L_B * (transport_A.u[N + 1 - i, 1] - transport_B.u[i, 1]); end for; - + else - for i in 1:N loop - transport_A.SourceTerm[i] = h_global * A/L_A * (transport_B.u[i,1]-transport_A.u[i,1]); - transport_B.SourceTerm[i] = h_global * A/L_B * (transport_A.u[i,1]-transport_B.u[i,1]); + for i in 1 : N loop + transport_A.SourceTerm[i] = h_global * A / L_A * (transport_B.u[i, 1] - transport_A.u[i, 1]); + transport_B.SourceTerm[i] = h_global * A / L_B * (transport_A.u[i, 1] - transport_B.u[i, 1]); end for; - end if ; + end if; - T_A_out = transport_A.u[end,1] ; - T_B_out = transport_B.u[end,1] ; -// heat exchange properties + T_A_out = transport_A.u[end, 1]; + T_B_out = transport_B.u[end, 1]; + // heat exchange properties h_global = heatTransferCoeff(); - Q_flow = sum(transport_A.SourceTerm) * L_A/N ; - der(E) = Q_flow ; -// ports handover + Q_flow = sum(transport_A.SourceTerm) * L_A / N; + der(E) = Q_flow; + // ports handover port_A_in.m_flow = m_flowA; port_A_in.h_outflow = inStream(port_A_in.h_outflow); -// reverse flow not modelled + // reverse flow not modelled port_A_in.Xi_outflow = inStream(port_A_in.Xi_outflow); port_A_out.m_flow + port_A_in.m_flow = 0.0; m_flowA * (inStream(port_A_in.h_outflow) - port_A_out.h_outflow) = Q_flow; port_A_out.Xi_outflow = inStream(port_A_out.Xi_outflow); -// + // port_B_in.m_flow = m_flowB; port_B_in.h_outflow = inStream(port_B_in.h_outflow); -// reverse flow not modelled + // reverse flow not modelled port_B_in.Xi_outflow = inStream(port_B_in.Xi_outflow); port_B_out.m_flow + port_B_in.m_flow = 0.0; m_flowB * (inStream(port_B_in.h_outflow) - port_B_out.h_outflow) = -Q_flow; - port_B_out.Xi_outflow = inStream(port_B_out.Xi_outflow); + port_B_out.Xi_outflow = inStream(port_B_out.Xi_outflow); -annotation(Documentation(info = " + annotation ( + Documentation( + info = " DiscreteExchanger diff --git a/FluidDynamics/Components/HeatExchangers/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/package.mo similarity index 98% rename from FluidDynamics/Components/HeatExchangers/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/package.mo index 3afe9d4..9da8269 100644 --- a/FluidDynamics/Components/HeatExchangers/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components; package HeatExchangers + extends Modelica.Icons.VariantsPackage; + end HeatExchangers; diff --git a/FluidDynamics/Components/HeatExchangers/package.order b/src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/package.order similarity index 100% rename from FluidDynamics/Components/HeatExchangers/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/HeatExchangers/package.order diff --git a/FluidDynamics/Components/Machines/BaseClasses/PartialPump.mo b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PartialPump.mo similarity index 56% rename from FluidDynamics/Components/Machines/BaseClasses/PartialPump.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PartialPump.mo index c880fff..a97d44a 100644 --- a/FluidDynamics/Components/Machines/BaseClasses/PartialPump.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PartialPump.mo @@ -1,93 +1,121 @@ within TAeZoSysPro.FluidDynamics.Components.Machines.BaseClasses; -partial model PartialPump "Base model for pumps" +partial model PartialPump + "Base model for pumps" + // Import of libraries import Modelica.Constants; - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + + // User defined parameter + parameter Boolean checkValve = false + "= true to prevent reverse flow" + annotation ( + Dialog(group = "Assumptions"), + Evaluate = true); + parameter Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm N_nominal + "Nominal rotational speed for flow characteristic" + annotation ( + Dialog(group = "Characteristics")); + parameter Medium.Density d_nominal = Medium.density_pTX(Medium.p_default, Medium.T_default, Medium.X_default) + "Nominal fluid density for characteristic" + annotation ( + Dialog(group = "Characteristics")); + parameter Boolean use_powerCharacteristic = false + "Use powerCharacteristic (vs. efficiencyCharacteristic)" + annotation ( + Evaluate = true, + Dialog(group = "Characteristics")); + + // Characteristic curves + replaceable function flowCharacteristic = Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.baseFlow + "Head vs. V_flow characteristic at nominal speed and density" + annotation (Dialog(group = "Characteristics"), choicesAllMatching = true); + + replaceable function powerCharacteristic = Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.quadraticPower( + V_flow_nominal = {0, 0, 0}, + W_nominal = {0, 0, 0}) + "Power consumption vs. V_flow at nominal speed and density" + annotation ( + Dialog(group = "Characteristics", enable = use_powerCharacteristic), + choicesAllMatching = true); + + replaceable function efficiencyCharacteristic = Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.constantEfficiency(eta_nominal = 0.8) + constrainedby Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.baseEfficiency + "Efficiency vs. V_flow at nominal speed and density" + annotation ( + Dialog(group = "Characteristics", enable = not use_powerCharacteristic), + choicesAllMatching = true); + + // Internal variables + Modelica.SIunits.VolumeFlowRate V_flow + "Volume flow rate at port_a"; + Modelica.SIunits.MassFlowRate m_flow + "Mass flow rate"; + Modelica.SIunits.Power P + "Power given to the fluid"; + Modelica.SIunits.Density d + "Density at port_a"; + Modelica.SIunits.Position head + "Pump head"; + Modelica.SIunits.PressureDifference dp + "Pressure difference between port_a and port_b"; + Modelica.SIunits.Efficiency eta + "Isentropic efficiency"; + Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm N + "Shaft rotational speed"; + Medium.ThermodynamicState state + "State at inlet"; + // Imported components + Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium, m_flow(min = if not checkValve then -Constants.inf else 0)) + annotation ( + Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium, m_flow(max = if not checkValve then +Constants.inf else 0)) + annotation ( + Placement(visible = true, transformation(origin = {100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); -// User defined parameter - parameter Boolean checkValve = false "= true to prevent reverse flow" annotation( - Dialog(group = "Assumptions"), - Evaluate = true) ; - parameter Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm N_nominal "Nominal rotational speed for flow characteristic" annotation( - Dialog(group="Characteristics")); - parameter Medium.Density d_nominal = Medium.density_pTX(Medium.p_default, Medium.T_default, Medium.X_default) "Nominal fluid density for characteristic" annotation( - Dialog(group="Characteristics")); - parameter Boolean use_powerCharacteristic = false "Use powerCharacteristic (vs. efficiencyCharacteristic)" annotation( - Evaluate=true,Dialog(group="Characteristics")); + constant Modelica.SIunits.Acceleration g = Constants.g_n; +equation -// Characteristic curves - replaceable function flowCharacteristic = Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.baseFlow "Head vs. V_flow characteristic at nominal speed and density" annotation(Dialog(group="Characteristics"), choicesAllMatching=true); - - replaceable function powerCharacteristic = Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.quadraticPower ( - V_flow_nominal={0,0,0},W_nominal={0,0,0}) - "Power consumption vs. V_flow at nominal speed and density" - annotation(Dialog(group="Characteristics", enable = use_powerCharacteristic), - choicesAllMatching=true); - - replaceable function efficiencyCharacteristic = - Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.constantEfficiency(eta_nominal = 0.8) constrainedby - Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.baseEfficiency - "Efficiency vs. V_flow at nominal speed and density" - annotation(Dialog(group="Characteristics",enable = not use_powerCharacteristic), - choicesAllMatching=true); - -// Internal variables - Modelica.SIunits.VolumeFlowRate V_flow "Volume flow rate at port_a" ; - Modelica.SIunits.MassFlowRate m_flow "Mass flow rate" ; - Modelica.SIunits.Power P "Power given to the fluid" ; - Modelica.SIunits.Density d "Density at port_a"; - Modelica.SIunits.Position head "Pump head"; - Modelica.SIunits.PressureDifference dp "Pressure difference between port_a and port_b" ; - Modelica.SIunits.Efficiency eta "Isentropic efficiency" ; - Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm N "Shaft rotational speed"; - Medium.ThermodynamicState state "State at inlet" ; - // Imported components - Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium, m_flow(min = if not checkValve then -Constants.inf else 0)) annotation( - Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium, m_flow(max = if not checkValve then +Constants.inf else 0)) annotation( - Placement(visible = true, transformation(origin = {100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + // Temporary variables - constant Modelica.SIunits.Acceleration g = Constants.g_n ; -equation -// Temporary variables - -// Get the state at inlet + // Get the state at inlet state = Medium.setState_phX(p = port_a.p, h = if checkValve then inStream(port_a.h_outflow) else actualStream(port_a.h_outflow)); -// - dp = port_a.p - port_b.p ; - V_flow = m_flow / d ; - d = Medium.density(state) ; - head = -dp/(d*g) ; - head = (N/N_nominal)^2*flowCharacteristic(V_flow*N_nominal/N) ; + // + dp = port_a.p - port_b.p; + V_flow = m_flow / d; + d = Medium.density(state); + head = -dp / (d * g); + head = (N / N_nominal) ^ 2 * flowCharacteristic(V_flow * N_nominal / N); //V_flow = flowCharacteristic(head) ; -// Power consumption + // Power consumption if use_powerCharacteristic then - P = (N/N_nominal)^2*(d/d_nominal)*powerCharacteristic(V_flow*(N_nominal/N)); - eta = -dp*V_flow/P; + P = (N / N_nominal) ^ 2 * (d / d_nominal) * powerCharacteristic(V_flow * (N_nominal / N)); + eta = -dp * V_flow / P; else - eta = efficiencyCharacteristic(V_flow*(N_nominal/N)) ; - P = -dp*V_flow/eta ; + eta = efficiencyCharacteristic(V_flow * (N_nominal / N)); + P = -dp * V_flow / eta; end if; -// Ports handover + // Ports handover // port_a port_a.m_flow = m_flow; - port_a.h_outflow = if checkValve then inStream(port_a.h_outflow) else inStream(port_b.h_outflow) ; - port_a.Xi_outflow = if checkValve then inStream(port_a.Xi_outflow) else inStream(port_b.Xi_outflow) ; - port_a.C_outflow = if checkValve then inStream(port_a.C_outflow) else inStream(port_b.C_outflow) ; + port_a.h_outflow = if checkValve then inStream(port_a.h_outflow) else inStream(port_b.h_outflow); + port_a.Xi_outflow = if checkValve then inStream(port_a.Xi_outflow) else inStream(port_b.Xi_outflow); + port_a.C_outflow = if checkValve then inStream(port_a.C_outflow) else inStream(port_b.C_outflow); // port_b - port_a.m_flow + port_b.m_flow = 0.0 ; - P = m_flow * (port_b.h_outflow - inStream(port_a.h_outflow)) ; - port_b.Xi_outflow = inStream(port_a.Xi_outflow) ; - port_b.C_outflow = inStream(port_a.C_outflow) ; + port_a.m_flow + port_b.m_flow = 0.0; + P = m_flow * (port_b.h_outflow - inStream(port_a.h_outflow)); + port_b.Xi_outflow = inStream(port_a.Xi_outflow); + port_b.C_outflow = inStream(port_a.C_outflow); - annotation( + annotation ( Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(fillColor = {0, 127, 255}, fillPattern = FillPattern.HorizontalCylinder, extent = {{-100, 46}, {100, -46}}), Polygon(lineColor = {0, 0, 255}, pattern = LinePattern.None, fillPattern = FillPattern.VerticalCylinder, points = {{-48, -60}, {-72, -100}, {72, -100}, {48, -60}, {-48, -60}}), Ellipse(fillColor = {0, 100, 199}, fillPattern = FillPattern.Sphere, extent = {{-80, 80}, {80, -80}}, endAngle = 360), Polygon(fillColor = {255, 255, 255}, pattern = LinePattern.None, fillPattern = FillPattern.HorizontalCylinder, points = {{-28, 30}, {-28, -30}, {50, -2}, {-28, 30}})}), - Documentation(info = " + Documentation( + info = "

    This is the base model for pumps strongly inspired from the PartialPump of Modelica Standard Library (MSL). @@ -149,7 +177,8 @@ equation in order to compute the Net Positive Suction Head available and check for cavitation, provided a two-phase medium model is used (see Advanced tab).

    -", revisions = " +", + revisions = "
    • 8 Jan 2013 by Rüdiger Franke:
      diff --git a/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/package.mo similarity index 100% rename from FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/package.mo diff --git a/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/package.order similarity index 100% rename from FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/package.order diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow.mo b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow.mo new file mode 100644 index 0000000..31a49a6 --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow.mo @@ -0,0 +1,151 @@ +within TAeZoSysPro.FluidDynamics.Components.Machines.BaseClasses.PumpCharacteristics; + +function polynomialFlow + + import Modelica.Math.Vectors; + + extends Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.baseFlow; + + input Modelica.SIunits.VolumeFlowRate V_flow_nominal[:] + "Volume flow rate for N operating points (single pump)" + annotation (Dialog); + input Modelica.SIunits.Position head_nominal[:] + "Pump head for N operating points" + annotation (Dialog); + input Integer OrderPolyFitting(max = 3) = 3 + "Order of the polynom that fits the fan curve"; + +protected + + Integer N = size(V_flow_nominal, 1) + "Number of nominal operating points"; + Real[OrderPolyFitting + 1] coeff + "[^0,^1,^2,...,^OrderPolyFitting]"; + Real[N, OrderPolyFitting + 1] A; + Modelica.SIunits.VolumeFlowRate V_flow_min = min(V_flow_nominal); + Modelica.SIunits.VolumeFlowRate V_flow_max = max(V_flow_nominal); + Modelica.SIunits.Position head_min + "Head from the fitting at V_flow_min "; + Modelica.SIunits.Position head_max + "Head from the fitting at V_flow_max "; + Real poly; + +algorithm + + // Initialisation + poly := 0.0; + + // + //A := {{V_flow_nominal[i]^(j-1) for i in 1:N} for j in 1:OrderPolyFitting + 1}; + for j in 1 : OrderPolyFitting + 1 loop + for i in 1 : N loop + A[i, j] := V_flow_nominal[i] ^ (j - 1); + end for; + end for; + + // Compute the coefficient to fit the curve + + coeff := Modelica.Math.Matrices.leastSquares(A = A, b = head_nominal); + + // Compute the minimal head with the fitting coefficients + poly := coeff[OrderPolyFitting + 1]; + for i in 1 : OrderPolyFitting loop + poly := poly * V_flow_min + coeff[OrderPolyFitting + 1 - i]; + end for; + head_min := poly; + + // Compute the maximal head with the fitting coefficients + poly := coeff[OrderPolyFitting + 1]; + for i in 1 : OrderPolyFitting loop + poly := poly * V_flow_max + coeff[OrderPolyFitting + 1 - i]; + end for; + head_max := poly; + + if V_flow >= V_flow_max then /* Linear extrapolation until zero head */ + // poly is the derivative of the curve at V_flow_max + poly := coeff[OrderPolyFitting + 1] * (OrderPolyFitting); + for i in 1 : OrderPolyFitting - 1 loop + poly := poly * V_flow_max + coeff[OrderPolyFitting + 1 - i] * (OrderPolyFitting - i); + end for; + head := head_max + (V_flow - V_flow_max) * poly; + if head < 0.0 then // head is threshold at 0.0 ; + head := 0.0; + end if; + + elseif V_flow <= V_flow_min and V_flow > 0.0 then /* Linear extrapolation */ + // poly is the derivative of the curve at V_flow_min + poly := coeff[OrderPolyFitting + 1] * (OrderPolyFitting); + for i in 1 : OrderPolyFitting - 1 loop + poly := poly * V_flow_min + coeff[OrderPolyFitting + 1 - i] * (OrderPolyFitting - i); + end for; + head := head_min + (V_flow - V_flow_min) * poly; + + elseif V_flow <= 0.0 then + if V_flow_min <= 0.0 then + head := coeff[1]; + + else + // poly is the derivative of the curve at V_flow_min + poly := coeff[OrderPolyFitting + 1] * (OrderPolyFitting); + for i in 1 : OrderPolyFitting - 1 loop + poly := poly * V_flow_min + coeff[OrderPolyFitting + 1 - i] * (OrderPolyFitting - i); + end for; + head := head_min + (0 - V_flow_min) * poly; + end if; + + else + poly := coeff[OrderPolyFitting + 1]; + for i in 1 : OrderPolyFitting loop + poly := poly * V_flow + coeff[OrderPolyFitting + 1 - i]; + end for; + + head := poly; + if head < 0.0 then // head is threshold at 0.0 ; + head := 0.0; + end if; + + end if; + + annotation ( + inverse( + V_flow = polynomialFlow_inv( + V_flow_nominal = V_flow_nominal, + head_nominal = head_nominal, + head = head, + OrderPolyFitting = OrderPolyFitting)), + Documentation( + info = " + + + polynomialFlow + + + + +

      + This function computes the head in meter supplied by a pump at a given volume flow rate V_flow from a polynomial fitting of the pump curve. +

      + +

      + The fitting is carried out from nominal inputs of the volume flow rate and the head (V_flow_nominal and head_nominal) via the least squares method. + The order of the polynom that fits the curve is settable via the input OrderPolyFitting but cannot go over the third order. +

      + +

      +

    • If the input V_flow is out of the range of the input nominal data V_flow_nominal, a linear extrapolation is performed. +

      + +

      +

    • If V_flow <= 0 the head remains at head = f(V_flow = 0). This condition is prior to the bullet point above. +

      + +

      +

    • If the head computed by the polynom or by the extrapolation combined with the polynom goes bellow 0, the heat is threshold at 0 ( head ⩾ 0). +

      + + +")); + +end polynomialFlow; diff --git a/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow_inv.mo b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow_inv.mo similarity index 52% rename from FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow_inv.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow_inv.mo index b4111d6..4464534 100644 --- a/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow_inv.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/PumpCharacteristics/polynomialFlow_inv.mo @@ -1,51 +1,73 @@ within TAeZoSysPro.FluidDynamics.Components.Machines.BaseClasses.PumpCharacteristics; function polynomialFlow_inv - import Modelica.Math.Vectors ; - extends Modelica.Icons.Function ; - input Modelica.SIunits.Position head "Pump head"; + import Modelica.Math.Vectors; + extends Modelica.Icons.Function; + + input Modelica.SIunits.Position head + "Pump head"; input Modelica.SIunits.VolumeFlowRate V_flow_nominal[:] - "Volume flow rate for N operating points (single pump)" annotation(Dialog); - input Modelica.SIunits.Position head_nominal[:] "Pump head for N operating points" annotation(Dialog); - input Integer OrderPolyFitting(min = 1) = 3 "Order of the polynom that fits the fan curve"; - output Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; - - protected - Integer N = size(V_flow_nominal,1) "Number of nominal operating points"; - Real[OrderPolyFitting + 1] coeff "[^0,^1,^2,...,^OrderPolyFitting]"; - Real[N, OrderPolyFitting + 1] A ; - Real roots[3] "Roots of the polynomial relation between head and the volume flow rate" ; - + "Volume flow rate for N operating points (single pump)" + annotation (Dialog); + input Modelica.SIunits.Position head_nominal[:] + "Pump head for N operating points" + annotation (Dialog); + input Integer OrderPolyFitting(min = 1) = 3 + "Order of the polynom that fits the fan curve"; + output Modelica.SIunits.VolumeFlowRate V_flow + "Volumetric flow rate"; + +protected + + Integer N = size(V_flow_nominal, 1) + "Number of nominal operating points"; + Real[OrderPolyFitting + 1] coeff + "[^0,^1,^2,...,^OrderPolyFitting]"; + Real[N, OrderPolyFitting + 1] A; + Real roots[3] + "Roots of the polynomial relation between head and the volume flow rate"; + algorithm -// - for j in 1:OrderPolyFitting + 1 loop - for i in 1:N loop - A[i, j] := V_flow_nominal[i] ^(j - 1); + + // + for j in 1 : OrderPolyFitting + 1 loop + for i in 1 : N loop + A[i, j] := V_flow_nominal[i] ^ (j - 1); end for; end for; -// Compute the coefficient to fit the curve + // Compute the coefficient to fit the curve coeff := Modelica.Math.Matrices.leastSquares(A = A, b = head_nominal); roots := TAeZoSysPro.FluidDynamics.Functions.rootsPolyOrder3( - a = if OrderPolyFitting == 3 then coeff[end] - else 0.0, - b = if OrderPolyFitting == 3 then coeff[end-1] - elseif OrderPolyFitting == 2 then coeff[end] - else 0.0, + a = + if OrderPolyFitting == 3 then + coeff[end] + else + 0.0, + b = + if OrderPolyFitting == 3 then + coeff[end - 1] + elseif OrderPolyFitting == 2 then + coeff[end] + else + 0.0, c = coeff[2], - d = coeff[1]-head) ; + d = coeff[1] - head); - V_flow := max(roots[1:OrderPolyFitting]) ; - -annotation( - Inline = true, - inverse(head = polynomialFlow(V_flow_nominal=V_flow_nominal, - head_nominal = head_nominal, - V_flow = V_flow, - OrderPolyFitting = OrderPolyFitting)), - Documentation(info = " + V_flow := max(roots[1 : OrderPolyFitting]); + + annotation ( + Inline = true, + inverse( + head = polynomialFlow( + V_flow_nominal = V_flow_nominal, + head_nominal = head_nominal, + V_flow = V_flow, + OrderPolyFitting = OrderPolyFitting)), + Documentation( + info = " polynomialFlow_inv @@ -72,6 +94,6 @@ annotation(

      -") ) ; - +")); + end polynomialFlow_inv; diff --git a/FluidDynamics/Components/Machines/BaseClasses/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/package.mo similarity index 98% rename from FluidDynamics/Components/Machines/BaseClasses/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/package.mo index 0f3c8cb..944afd6 100644 --- a/FluidDynamics/Components/Machines/BaseClasses/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components.Machines; package BaseClasses + extends Modelica.Icons.BasesPackage; + end BaseClasses; diff --git a/FluidDynamics/Components/Machines/BaseClasses/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/package.order similarity index 100% rename from FluidDynamics/Components/Machines/BaseClasses/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Machines/BaseClasses/package.order diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Machines/ControlledVolumeFlowPump.mo b/src/TAeZoSysPro/FluidDynamics/Components/Machines/ControlledVolumeFlowPump.mo new file mode 100644 index 0000000..226d674 --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Machines/ControlledVolumeFlowPump.mo @@ -0,0 +1,176 @@ +within TAeZoSysPro.FluidDynamics.Components.Machines; + +model ControlledVolumeFlowPump + "Pump with controlled volume flow rate" + + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + + // User defined parameters + parameter Boolean Fan = false + "If true fan icon else pump icon" + annotation (Evaluate = true, HideResult = true, choices(checkBox = true)); + parameter Boolean checkValve = false + "= true to prevent reverse flow" + annotation ( + Dialog(group = "Assumptions"), + Evaluate = true); + parameter Boolean use_V_flow_set = false + "= true to use input signal V_flow_set instead of V_flow_nominal"; + parameter Modelica.SIunits.VolumeFlowRate V_flow_nominal + "Nominal volume flow rate, fixed if not use_V_flow_set"; + parameter Modelica.SIunits.Efficiency eta = 0.8 + "Isentropic efficiency"; + + // Internal variables + Modelica.SIunits.VolumeFlowRate V_flow + "Volume flow rate at port_a"; + Modelica.SIunits.MassFlowRate m_flow + "Mass flow rate"; + Modelica.SIunits.Power P + "Power given to the fluid"; + Modelica.SIunits.Density d + "Density at port_a"; + Modelica.SIunits.Position head + "Pump head"; + Modelica.SIunits.PressureDifference dp + "Pressure difference between port_a and port_b"; + Medium.ThermodynamicState state + "State at inlet"; + + // Imported modules + Modelica.Blocks.Interfaces.RealInput V_flow_set if use_V_flow_set + "Prescribed mass flow rate" + annotation ( + Placement(visible = true, transformation(origin = {0, 100}, extent = {{-20, -20}, {20, 20}}, rotation = -90), iconTransformation(extent = {{-20, 80}, {20, 120}}, rotation = -90))); + Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium, m_flow(min = if not checkValve then -Modelica.Constants.inf else 0)) + annotation ( + Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium, m_flow(max = if not checkValve then +Modelica.Constants.inf else 0)) + annotation ( + Placement(visible = true, transformation(origin = {100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +protected + + Modelica.Blocks.Interfaces.RealInput V_flow_set_internal + "Needed to connect to conditional connector"; + +equation + + // Internal connector value when use_m_flow_set = false + if not use_V_flow_set then + V_flow_set_internal = V_flow_nominal; + end if; + connect(V_flow_set, V_flow_set_internal) + annotation ( + Line); + + // Get the state at inlet + state = Medium.setState_phX(p = port_a.p, h = if checkValve then inStream(port_a.h_outflow) else actualStream(port_a.h_outflow)); + + // + dp = port_a.p - port_b.p; + V_flow = V_flow_set_internal; + V_flow = m_flow / d; + d = Medium.density(state); + head = -dp / (d * Modelica.Constants.g_n); + P = -dp * V_flow / eta; + + // Ports handover + // port_a + port_a.m_flow = m_flow; + port_a.h_outflow = if checkValve then inStream(port_a.h_outflow) else inStream(port_b.h_outflow); + port_a.Xi_outflow = if checkValve then inStream(port_a.Xi_outflow) else inStream(port_b.Xi_outflow); + port_a.C_outflow = if checkValve then inStream(port_a.C_outflow) else inStream(port_b.C_outflow); + // port_b + port_a.m_flow + port_b.m_flow = 0.0; + port_b.h_outflow = noEvent(if abs(m_flow) > 10 * Modelica.Constants.eps then P / m_flow + inStream(port_a.h_outflow) else inStream(port_a.h_outflow)); + port_b.Xi_outflow = inStream(port_a.Xi_outflow); + port_b.C_outflow = inStream(port_a.C_outflow); + + annotation ( + defaultComponentName = "pump", + Documentation( + info = " +

      + This model describes a pump with ideally controlled volume flow rate. +

      +

      + The input connectors V_flow_set can optionally be enabled via use_V_flow_set to provide time varying set points. +

      +

      + Use this model if the pump characteristics is of secondary interest. + The actual characteristics can be configured later on for the appropriate rotational speed N. + Then the model can be replaced with a PrescribedPump. +

      +"), + Icon( + graphics = { + Polygon( + lineColor = {0, 0, 255}, + pattern = LinePattern.None, + fillPattern = FillPattern.VerticalCylinder, + points = {{-48, -60}, {-72, -100}, {72, -100}, {48, -60}, {-48, -60}}), + Rectangle( + fillColor = {0, 127, 255}, + fillPattern = FillPattern.HorizontalCylinder, + extent = {{-100, 46}, {100, -46}}), + Ellipse( + visible = Fan, + lineColor = {0, 0, 127}, + fillColor = {255, 255, 255}, + fillPattern = FillPattern.Solid, + lineThickness = 0.5, + extent = {{-80, 80}, {80, -80}}, + endAngle = 360), + Polygon( + visible = Fan, + origin = {0, 39}, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + lineThickness = 0.5, + points = {{0, -39}, {-12, 35}, {0, 39}, {12, 35}, {0, -39}}), + Polygon( + visible = Fan, + origin = {40, -1}, + rotation = -90, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + lineThickness = 0.5, + points = {{0, -39}, {-12, 35}, {0, 39}, {12, 35}, {0, -39}}), + Polygon( + visible = Fan, + origin = {0, -39}, + rotation = 180, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + lineThickness = 0.5, + points = {{0, -39}, {-12, 35}, {0, 39}, {12, 35}, {0, -39}}), + Polygon( + visible = Fan, + origin = {-40, -1}, + rotation = 90, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + lineThickness = 0.5, + points = {{0, -39}, {-12, 35}, {0, 39}, {12, 35}, {0, -39}}), + Ellipse( + visible = Fan, + origin = {0, -2}, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Sphere, + lineThickness = 1, + extent = {{-10, -10}, {10, 10}}, + endAngle = 360), + Ellipse( + visible = not Fan, + extent = {{-80, 80}, {80, -80}}, + fillPattern = FillPattern.Sphere, + fillColor = {0, 100, 199}), + Polygon( + visible = not Fan, + points = {{-28, 30}, {-28, -30}, {50, -2}, {-28, 30}}, + pattern = LinePattern.None, + fillPattern = FillPattern.HorizontalCylinder, + fillColor = {255, 255, 255})})); + +end ControlledVolumeFlowPump; diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Machines/PrescribedPump.mo b/src/TAeZoSysPro/FluidDynamics/Components/Machines/PrescribedPump.mo new file mode 100644 index 0000000..bb52173 --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Machines/PrescribedPump.mo @@ -0,0 +1,48 @@ +within TAeZoSysPro.FluidDynamics.Components.Machines; + +model PrescribedPump + "Pump with ideally controlled speed" + + extends BaseClasses.PartialPump; + + //User defined parameters + parameter Boolean use_N_in = false + "Get the rotational speed from the input connector"; + parameter Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm N_const = N_nominal + "Constant rotational speed" + annotation (Dialog(enable = not use_N_in)); + + //Imported modules + Modelica.Blocks.Interfaces.RealInput N_in(unit = "rev/min") if use_N_in + "Prescribed rotational speed" + annotation ( + Placement( + transformation( + extent = {{-20, -20}, {20, 20}}, + rotation = -90, + origin = {0, 100}), + iconTransformation( + extent = {{-20, -20}, {20, 20}}, + rotation = -90, + origin = {0, 100}))); + +protected + + Modelica.Blocks.Interfaces.RealInput N_in_internal(unit = "rev/min") + "Needed to connect to conditional connector"; + +equation + + // Connect statement active only if use_p_in = true + connect(N_in, N_in_internal); + + // Internal connector value when use_p_in = false + if not use_N_in then + N_in_internal = N_const; + end if; + + // Set N with a lower limit to avoid singularities at zero speed + N = max(N_in_internal, 1e-3) + "Rotational speed"; + +end PrescribedPump; diff --git a/FluidDynamics/Components/Machines/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Machines/package.mo similarity index 98% rename from FluidDynamics/Components/Machines/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Machines/package.mo index 98281ff..ba9f693 100644 --- a/FluidDynamics/Components/Machines/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Machines/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components; package Machines + extends Modelica.Icons.VariantsPackage; + end Machines; diff --git a/FluidDynamics/Components/Machines/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Machines/package.order similarity index 100% rename from FluidDynamics/Components/Machines/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Machines/package.order diff --git a/FluidDynamics/Components/MassExchangers/AnalyticWetExchanger.mo b/src/TAeZoSysPro/FluidDynamics/Components/MassExchangers/AnalyticWetExchanger.mo similarity index 70% rename from FluidDynamics/Components/MassExchangers/AnalyticWetExchanger.mo rename to src/TAeZoSysPro/FluidDynamics/Components/MassExchangers/AnalyticWetExchanger.mo index 66b1afc..fafd327 100644 --- a/FluidDynamics/Components/MassExchangers/AnalyticWetExchanger.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/MassExchangers/AnalyticWetExchanger.mo @@ -1,6 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components.MassExchangers; model AnalyticWetExchanger + //extends TAeZoSysPro.HeatTransfer.BasesClasses.PartialHeatExchanger(final S = ExchangeSurface); // import SI = Modelica.SIunits; @@ -17,172 +18,229 @@ model AnalyticWetExchanger replaceable package MediumB = Modelica.Media.Water.WaterIF97_ph; //replaceable package MediumB = Modelica.Media.Air.MoistAir ; // User defined parameters - parameter SI.Area CrossSectionA = 4.26 "Cross section of the pipe for the fluid A" annotation( - Dialog(group = "Geometrical parameters")); - parameter SI.Area CrossSectionB = 4.26 "Cross section of the pipe for the fluid B" annotation( - Dialog(group = "Geometrical parameters")); - parameter SI.Area ExchangeSurface = 0.0 "Largest exchange surface area" annotation( - Dialog(group = "Geometrical parameters")); - parameter Real ksi_fixedA = 1.0 annotation( - Dialog(group = "Flow parameters")); - parameter Real ksi_fixedB = 1.0 annotation( - Dialog(group = "Flow parameters")); - parameter SI.CoefficientOfHeatTransfer K_global "Global heat transfer coeffcient" annotation( - Dialog(group = "Exchange parameters")); - parameter SI.CoefficientOfHeatTransfer hcv_A "Heat transfer coeffcient Wall<->Fluid A" annotation( - Dialog(group = "Exchange parameters")); + parameter SI.Area CrossSectionA = 4.26 + "Cross section of the pipe for the fluid A" + annotation ( + Dialog(group = "Geometrical parameters")); + parameter SI.Area CrossSectionB = 4.26 + "Cross section of the pipe for the fluid B" + annotation ( + Dialog(group = "Geometrical parameters")); + parameter SI.Area ExchangeSurface = 0.0 + "Largest exchange surface area" + annotation ( + Dialog(group = "Geometrical parameters")); + parameter Real ksi_fixedA = 1.0 + annotation ( + Dialog(group = "Flow parameters")); + parameter Real ksi_fixedB = 1.0 + annotation ( + Dialog(group = "Flow parameters")); + parameter SI.CoefficientOfHeatTransfer K_global + "Global heat transfer coeffcient" + annotation ( + Dialog(group = "Exchange parameters")); + parameter SI.CoefficientOfHeatTransfer hcv_A + "Heat transfer coeffcient Wall<->Fluid A" + annotation ( + Dialog(group = "Exchange parameters")); parameter Real phi_out = 0.8; // define constants - constant SI.SpecificEnergy Ll = 2501e3 "Latent heat of liquifaction at 0°C"; + constant SI.SpecificEnergy Ll = 2501e3 + "Latent heat of liquifaction at 0°C"; final parameter SI.CoefficientOfHeatTransfer hcv_B = (1 / K_global - 1 / hcv_A) ^ (-1); // Internal variables // variables common to all configurations - MediumA.ThermodynamicState stateA_in "State of fluid A a inlet"; - MediumB.ThermodynamicState stateB_in "State of fluid B a inlet"; + MediumA.ThermodynamicState stateA_in + "State of fluid A a inlet"; + MediumB.ThermodynamicState stateB_in + "State of fluid B a inlet"; SI.SpecificHeatCapacity cpA; SI.SpecificHeatCapacity cpB; - SI.MassFlowRate m_flowA "Mass flow rate of fluid A"; - SI.MassFlowRate m_flowB "Mass flow rate of fluid B"; - SI.ThermalConductance QcA(min = 0) "Thermal flow rate unit"; - SI.ThermalConductance QcB(min = 0) "Thermal flow rate unit"; + SI.MassFlowRate m_flowA + "Mass flow rate of fluid A"; + SI.MassFlowRate m_flowB + "Mass flow rate of fluid B"; + SI.ThermalConductance QcA(min = 0) + "Thermal flow rate unit"; + SI.ThermalConductance QcB(min = 0) + "Thermal flow rate unit"; SI.Temperature TA_in, TA_out, TB_in, TB_out; - SI.Power Pex "exchanged power"; + SI.Power Pex + "exchanged power"; // variables for the "no condensation" model - Real NTU_1 "Number of transfer unit"; - Real Cr_1 "Ration of thermal condutance"; - SI.Efficiency Eff_1 "Exchanger effectiveness"; + Real NTU_1 + "Number of transfer unit"; + Real Cr_1 + "Ration of thermal condutance"; + SI.Efficiency Eff_1 + "Exchanger effectiveness"; SI.Temperature TA_out_1, TB_out_1; SI.Power Pex_1; // variables for the "condensation" model SI.Temperature TA_mid_2, TA_mid_buffer, TB_mid_2, TB_out_2, TA_out_2, Tdew, Tsat_out; SI.Pressure p_water; - Real NTU_2, NTU_wet "Number of transfer unit"; + Real + NTU_2, + NTU_wet + "Number of transfer unit"; Real Cr_wet; - SI.Efficiency Eff_2, Eff_wet "Exchanger effectiveness"; - SI.Area S_sensible "Sensible surface to achieved saturation on moist air"; - SI.Area S_wet "Sensible surface to achieved saturation on moist air"; - SI.MassFraction wsat_eq_in, wA_in, wsat_out, wA_out_2, XA_out_2, wA_out "Moisture content peer kg of dry air"; - SI.SpecificEnthalpy hsat_eq_in, hA_mid_2, hA_out_2, hcond_out, hA_sat_in "Enthalpies peer kg of dry air"; - SI.SpecificHeatCapacity cp_eq "Specific heat capacity of the fictive fluid"; - SI.MassFlowRate m_flow_eq "Mass flow rate of the fictive fluid"; + SI.Efficiency + Eff_2, + Eff_wet + "Exchanger effectiveness"; + SI.Area S_sensible + "Sensible surface to achieved saturation on moist air"; + SI.Area S_wet + "Sensible surface to achieved saturation on moist air"; + SI.MassFraction + wsat_eq_in, + wA_in, + wsat_out, + wA_out_2, + XA_out_2, + wA_out + "Moisture content peer kg of dry air"; + SI.SpecificEnthalpy + hsat_eq_in, + hA_mid_2, + hA_out_2, + hcond_out, + hA_sat_in + "Enthalpies peer kg of dry air"; + SI.SpecificHeatCapacity cp_eq + "Specific heat capacity of the fictive fluid"; + SI.MassFlowRate m_flow_eq + "Mass flow rate of the fictive fluid"; SI.Power Q_flow_wet, Q_flow_dry, Q_flow_wet_2, Q_flow_dry_2; - SI.Power P_sensible "Sensible exchanged power"; - SI.Power P_latent "Latent exchanged power"; - + SI.Power P_sensible + "Sensible exchanged power"; + SI.Power P_latent + "Latent exchanged power"; + // Imported modules - Modelica.Fluid.Interfaces.FluidPort_a port_in_A(redeclare package Medium = MediumA) annotation ( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {80, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_out_A(redeclare package Medium = MediumA) annotation ( - Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-80, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_a port_in_B(redeclare package Medium = MediumB) annotation ( - Placement(visible = true, transformation(origin = {-68, 88}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_out_B(redeclare package Medium = MediumB) annotation ( - Placement(visible = true, transformation(origin = {66, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_in_A(redeclare package Medium = MediumA) + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {80, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_out_A(redeclare package Medium = MediumA) + annotation ( + Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-80, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_in_B(redeclare package Medium = MediumB) + annotation ( + Placement(visible = true, transformation(origin = {-68, 88}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_out_B(redeclare package Medium = MediumB) + annotation ( + Placement(visible = true, transformation(origin = {66, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + //initial algorithm //TA_mid_2.start := TA_in ; equation -// + + // stateA_in = MediumA.setState_phX(port_in_A.p, inStream(port_in_A.h_outflow), inStream(port_in_A.Xi_outflow)); stateB_in = MediumB.setState_phX(port_in_B.p, inStream(port_in_B.h_outflow), inStream(port_in_B.Xi_outflow)); -// compute thermodynamical properties + // compute thermodynamical properties cpA = MediumA.specificHeatCapacityCp(stateA_in); cpB = MediumB.specificHeatCapacityCp(stateB_in); -// + // QcA = m_flowA * cpA; QcB = m_flowB * cpB; -// + // TA_in = MediumA.temperature(stateA_in); TB_in = MediumB.temperature(stateB_in); -//momentum - steady assumptions + //momentum - steady assumptions m_flowA = CrossSectionA * TAeZoSysPro.FluidDynamics.Utilities.regRoot2(x = port_in_A.p - port_out_A.p, x_small = 10, k1 = 2 * MediumA.density(stateA_in) / ksi_fixedA, k2 = 2 * MediumA.density(stateA_in) / ksi_fixedA); m_flowB = CrossSectionB * TAeZoSysPro.FluidDynamics.Utilities.regRoot2(x = port_in_B.p - port_out_B.p, x_small = 10, k1 = 2 * MediumB.density(stateB_in) / ksi_fixedB, k2 = 2 * MediumB.density(stateB_in) / ksi_fixedB); - -/*---------- Calculation of a fully dry exchanger ----------*/ + + /*---------- Calculation of a fully dry exchanger ----------*/ Cr_1 = min(QcA, QcB) / max(max(QcA, QcB), 1e3 * Modelica.Constants.small); NTU_1 = K_global * ExchangeSurface / max(min(QcA, QcB), 1e3 * Modelica.Constants.small); Eff_1 = (1 - exp(-NTU_1 * (1.0 - Cr_1))) / (1.0 - Cr_1 * exp(-NTU_1 * (1.0 - Cr_1))); Pex_1 = Eff_1 * min(QcA, QcB) * (TA_in - TB_in); Pex_1 + QcA * (TA_out_1 - TA_in) = 0; QcA * (TA_out_1 - TA_in) + QcB * (TB_out_1 - TB_in) = 0; - -/*---------- Calculation of the sensible part for condensation configuration ----------*/ -// Compute the saturation temperature of the moist air + + /*---------- Calculation of the sensible part for condensation configuration ----------*/ + // Compute the saturation temperature of the moist air p_water / port_in_A.p = stateA_in.X[MediumA.Water] * Modelica.Constants.R / MediumA.MMX[MediumA.Water] / MediumA.gasConstant(stateA_in); Tdew = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = p_water - 625, x_small = 5.0, y1 = Modelica.Media.Water.StandardWater.saturationTemperature(max(620, p_water)), y2 = 273.15 + 0.1); -// Determination of the temperature of the gas which corresponds to the dew temperature of the external surface knowing the thermal resistance + // Determination of the temperature of the gas which corresponds to the dew temperature of the external surface knowing the thermal resistance hcv_A * (TA_mid_buffer - Tdew) = K_global * (TA_mid_buffer - TB_mid_2); -//TA_mid_2 = min(TA_mid_buffer, TA_in) ; + //TA_mid_2 = min(TA_mid_buffer, TA_in) ; TA_mid_2 = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = TA_in - TA_mid_buffer - 0.01, x_small = 0.01, y1 = TA_mid_buffer, y2 = TA_in); QcA * (TA_mid_2 - TA_in) + QcB * (TB_out_2 - TB_mid_2) = 0.0; -// Determination of the dry surface necessary for the surface temperature to achieve the dew temperature + // Determination of the dry surface necessary for the surface temperature to achieve the dew temperature NTU_2 = K_global * S_sensible / max(min(QcA, QcB), 1e3 * Modelica.Constants.small); Eff_2 = (1 - exp(-NTU_2 * (1.0 - Cr_1))) / (1.0 - Cr_1 * exp(-NTU_2 * (1.0 - Cr_1))); Eff_2 = QcA * (TA_in - TA_mid_2) / (max(min(QcA, QcB), 1e3 * Modelica.Constants.small) * (TA_in - TB_mid_2)); Q_flow_dry_2 = QcA * (TA_in - TA_mid_2); -/*---------- Calculation of the latent part for condensation configuration ----------*/ -/* As enthalpy is used rather than temperatures to compute the exchange, the air is considered to exchange with a fictive air at the same temperature than the water but gaving a moisture content always saturated. Therefore, the mass flow rate and the heat capacity of this fictive fluid are computed to well fit the real behavior that is having the water.*/ -// Calculation of the saturated moisture content at the boundaries of the wet part of the exchanger + /*---------- Calculation of the latent part for condensation configuration ----------*/ + /* As enthalpy is used rather than temperatures to compute the exchange, the air is considered to exchange with a fictive air at the same temperature than the water but gaving a moisture content always saturated. Therefore, the mass flow rate and the heat capacity of this fictive fluid are computed to well fit the real behavior that is having the water.*/ + // Calculation of the saturated moisture content at the boundaries of the wet part of the exchanger wsat_eq_in = MediumA.xsaturation_pT(p = port_in_A.p, T = TB_in); -// Calculation of the moisture content at the boundaries of the wet part of the exchanger + // Calculation of the moisture content at the boundaries of the wet part of the exchanger wA_in = stateA_in.X[MediumA.Water] / stateA_in.X[MediumA.Air]; -// Calculation of the saturated enthalpies of the equivalent fictive fluid at the boundaries + // Calculation of the saturated enthalpies of the equivalent fictive fluid at the boundaries hsat_eq_in = cpA * (TB_in - 273.15) + wsat_eq_in * Ll; -// Caculation of enthalpy with respect to temperature and moisture content + // Caculation of enthalpy with respect to temperature and moisture content hA_mid_2 = cpA * (TA_mid_2 - 273.15) + wA_in * Ll; -/* hgas_out is computed from the wet part of the exchanger. TA_out is computed from the hypothesis that the moisture content at the outlet is equal + /* hgas_out is computed from the wet part of the exchanger. TA_out is computed from the hypothesis that the moisture content at the outlet is equal to the moisture content of the saturated gas at the contact of the condensation film of the outlet */ hA_out_2 = cpA * (TA_out_2 - 273.15) + wA_out_2 * Ll; -// Calculation of an heat capacity that would have the fictive fluid encompassing the latent exchange + // Calculation of an heat capacity that would have the fictive fluid encompassing the latent exchange hA_sat_in = cpA * (Tdew - 273.15) + wA_in * Ll; cp_eq = (hA_sat_in - hsat_eq_in) / (Tdew - TB_in); -// calculation of an equivalent mass flow rate of this fictive gas + // calculation of an equivalent mass flow rate of this fictive gas m_flow_eq = m_flowB * cpB / cp_eq; -// Calculation of the ration of the thermal flow rate for wet part + // Calculation of the ration of the thermal flow rate for wet part Cr_wet = min(m_flowA, m_flow_eq) / max(max(m_flowA, m_flow_eq), 1e3 * Modelica.Constants.small); -// + // NTU_wet = (cpA / hcv_B + cp_eq / hcv_A) ^ (-1) * S_wet / min(m_flowA, m_flow_eq); -// + // Eff_wet = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = 0.98 - Cr_wet, x_small = 1.0e-2, y1 = (1.0 - exp(-NTU_wet * (1.0 - Cr_wet))) / (1.0 - Cr_wet * exp(-NTU_wet * (1.0 - Cr_wet))), y2 = NTU_wet / (NTU_wet + 1.0)); Eff_wet = m_flowA / min(m_flowA, m_flow_eq) * (hA_mid_2 - hA_out_2) / (hA_mid_2 - hsat_eq_in); -// + // Q_flow_wet_2 + m_flowA * stateA_in.X[MediumA.Air] * (hA_out_2 - hA_mid_2) = 0.0; QcB * (TB_in - TB_mid_2) + Q_flow_wet = 0.0; -// + // ExchangeSurface = S_sensible + S_wet; -// Determination of the outlet air temperature and humidity + // Determination of the outlet air temperature and humidity (hcond_out - hsat_eq_in) / (cp_eq / hcv_B) = (hA_out_2 - hsat_eq_in) / (cp_eq / hcv_B + cpA / hcv_A); hcond_out = cpA * (Tsat_out - 273.15) + wsat_out * Ll; wsat_out = MediumA.xsaturation_pT(p = port_out_A.p, T = Tsat_out); -//hcv_A * (TA_out_2 - Tsat_out) + hcv_A / cpA * (wA_out_2 - wsat_eq_in) * Ll = hcv_B * (Tsat_out - TB_in) ; + //hcv_A * (TA_out_2 - Tsat_out) + hcv_A / cpA * (wA_out_2 - wsat_eq_in) * Ll = hcv_B * (Tsat_out - TB_in) ; XA_out_2 = MediumA.massFraction_pTphi(p = port_out_A.p, T = TA_out_2, phi = phi_out); - wA_out_2 = XA_out_2 / (1-XA_out_2) "80% of the saturation moisture content at outlet"; -//retained configuration + wA_out_2 = XA_out_2 / (1 - XA_out_2) + "80% of the saturation moisture content at outlet"; + //retained configuration TA_out = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = S_wet - 1e-2, x_small = 1e-2, y1 = TA_out_2, y2 = TA_out_1); wA_out = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = S_wet - 1e-2, x_small = 1e-2, y1 = wA_out_2, y2 = wA_in); Q_flow_dry = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = S_wet - 1e-2, x_small = 1e-2, y1 = Q_flow_dry_2, y2 = Pex_1); Q_flow_wet = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = S_wet - 1e-2, x_small = 1e-2, y1 = Q_flow_wet_2, y2 = 0.0); - P_sensible = m_flowA * cpA * (TA_in-TA_out) ; - P_latent = m_flowA * stateA_in.X[MediumA.Air] * (wA_in-wA_out_2) * Ll ; + P_sensible = m_flowA * cpA * (TA_in - TA_out); + P_latent = m_flowA * stateA_in.X[MediumA.Air] * (wA_in - wA_out_2) * Ll; Pex = Q_flow_dry + Q_flow_wet; QcB * (TB_out - TB_in) - Pex = 0.0; -// ports handover + // ports handover port_in_A.m_flow = m_flowA; port_in_A.h_outflow = inStream(port_in_A.h_outflow); -// reverse flow not modelled + // reverse flow not modelled port_in_A.Xi_outflow = inStream(port_in_A.Xi_outflow); port_out_A.m_flow + port_in_A.m_flow = 0.0; m_flowA * (inStream(port_in_A.h_outflow) - port_out_A.h_outflow) = Pex; port_out_A.Xi_outflow = if S_wet > 1e-2 then {XA_out_2} else inStream(port_out_A.Xi_outflow); -// + // port_in_B.m_flow = m_flowB; port_in_B.h_outflow = inStream(port_in_B.h_outflow); -// reverse flow not modelled + // reverse flow not modelled port_in_B.Xi_outflow = inStream(port_in_B.Xi_outflow); port_out_B.m_flow + port_in_B.m_flow = 0.0; m_flowB * (inStream(port_in_B.h_outflow) - port_out_B.h_outflow) = -Pex; port_out_B.Xi_outflow = inStream(port_out_B.Xi_outflow); - annotation( - Documentation(info = " + + annotation ( + Documentation( + info = " WetExchanger @@ -359,5 +417,6 @@ equation "), - Icon(coordinateSystem(initialScale = 0.1), graphics = {Polygon(origin = {18, 50}, rotation = 180, fillColor = {213, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 0.5, points = {{-72, 36}, {-72, 14}, {88, 14}, {88, -16}, {108, -16}, {108, 36}, {-72, 36}}), Polygon(origin = {-18, -50}, fillColor = {255, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 0.5, points = {{-72, 36}, {-72, 14}, {88, 14}, {88, -18}, {108, -18}, {108, 36}, {-72, 36}}), Rectangle(origin = {-2, 0}, lineColor = {0, 161, 241}, fillColor = {211, 211, 211}, pattern = LinePattern.None, fillPattern = FillPattern.HorizontalCylinder, lineThickness = 0.5, extent = {{-86, 14}, {90, -14}}), Text(origin = {-40, -6}, lineThickness = 0.5, extent = {{ 12, 16}, {72, -4}}, textString = "Fluid B"), Text(origin = {-2, 30}, lineThickness = 0.5, extent = {{-26, 6}, {34, -14}}, textString = "Fluid A"), Line(origin = {-48.1691, -0.0769465}, points = {{-12, 0}, {12, 0}}, color = {94, 94, 94}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {45.8309, -0.336488}, points = {{-12, 0}, {12, 0}}, color = {94, 94, 94}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {79.0506, -52.8561}, rotation = 90, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-79.2242, 50.9302}, rotation = 90, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-41.4227, 25.3271}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {37.5697, -26.3828}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-35.3005, -26.0775}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {43.5697, 25.5256}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5)})); + Icon(coordinateSystem(initialScale = 0.1), graphics = {Polygon(origin = {18, 50}, rotation = 180, fillColor = {213, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 0.5, points = {{-72, 36}, {-72, 14}, {88, 14}, {88, -16}, {108, -16}, {108, 36}, {-72, 36}}), Polygon(origin = {-18, -50}, fillColor = {255, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 0.5, points = {{-72, 36}, {-72, 14}, {88, 14}, {88, -18}, {108, -18}, {108, 36}, {-72, 36}}), Rectangle(origin = {-2, 0}, lineColor = {0, 161, 241}, fillColor = {211, 211, 211}, pattern = LinePattern.None, fillPattern = FillPattern.HorizontalCylinder, lineThickness = 0.5, extent = {{-86, 14}, {90, -14}}), Text(origin = {-40, -6}, lineThickness = 0.5, extent = {{12, 16}, {72, -4}}, textString = "Fluid B"), Text(origin = {-2, 30}, lineThickness = 0.5, extent = {{-26, 6}, {34, -14}}, textString = "Fluid A"), Line(origin = {-48.1691, -0.0769465}, points = {{-12, 0}, {12, 0}}, color = {94, 94, 94}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {45.8309, -0.336488}, points = {{-12, 0}, {12, 0}}, color = {94, 94, 94}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {79.0506, -52.8561}, rotation = 90, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-79.2242, 50.9302}, rotation = 90, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-41.4227, 25.3271}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {37.5697, -26.3828}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-35.3005, -26.0775}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {43.5697, 25.5256}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5)})); + end AnalyticWetExchanger; diff --git a/FluidDynamics/Components/MassExchangers/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/MassExchangers/package.mo similarity index 98% rename from FluidDynamics/Components/MassExchangers/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/MassExchangers/package.mo index 76ea93a..7d3d451 100644 --- a/FluidDynamics/Components/MassExchangers/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/MassExchangers/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components; package MassExchangers + extends Modelica.Icons.VariantsPackage; + end MassExchangers; diff --git a/FluidDynamics/Components/MassExchangers/package.order b/src/TAeZoSysPro/FluidDynamics/Components/MassExchangers/package.order similarity index 100% rename from FluidDynamics/Components/MassExchangers/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/MassExchangers/package.order diff --git a/FluidDynamics/Components/Orifices/HorizontalOpening.mo b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/HorizontalOpening.mo similarity index 68% rename from FluidDynamics/Components/Orifices/HorizontalOpening.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Orifices/HorizontalOpening.mo index 43843ca..7706004 100644 --- a/FluidDynamics/Components/Orifices/HorizontalOpening.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/HorizontalOpening.mo @@ -1,123 +1,151 @@ within TAeZoSysPro.FluidDynamics.Components.Orifices; model HorizontalOpening - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - + + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters - parameter Real Cd = 0.61 "discharge coefficient"; - parameter Modelica.SIunits.CrossSection A = 1 "Opening cross section"; - parameter Modelica.SIunits.Diameter Dh = sqrt(A) "Hydraulic diameter"; - parameter Integer N = 5 "Number discrete layer along the height of the opening"; - parameter Modelica.SIunits.Length NotionalLength = 1e-4 "Opening's thickness"; - parameter Dynamics massDynamics = Dynamics.SteadyStateInitial "Formulation of mass balance"; - parameter Modelica.SIunits.Velocity Vel_start = 0.0 "Start value for velocity, if not steady state"; - - parameter Modelica.SIunits.Length Alt_a = 1.0 "Altitude of port_a"; - parameter Modelica.SIunits.Length Alt_b = 1.0 "Altitude of port_b"; - parameter Modelica.SIunits.Length Alt_opening = 1.0 "Altitude at the opening center"; - + parameter Real Cd = 0.61 + "discharge coefficient"; + parameter Modelica.SIunits.CrossSection A = 1 + "Opening cross section"; + parameter Modelica.SIunits.Diameter Dh = sqrt(A) + "Hydraulic diameter"; + parameter Integer N = 5 + "Number discrete layer along the height of the opening"; + parameter Modelica.SIunits.Length NotionalLength = 1e-4 + "Opening's thickness"; + parameter Dynamics massDynamics = Dynamics.SteadyStateInitial + "Formulation of mass balance"; + parameter Modelica.SIunits.Velocity Vel_start = 0.0 + "Start value for velocity, if not steady state"; + + parameter Modelica.SIunits.Length Alt_a = 1.0 + "Altitude of port_a"; + parameter Modelica.SIunits.Length Alt_b = 1.0 + "Altitude of port_b"; + parameter Modelica.SIunits.Length Alt_opening = 1.0 + "Altitude at the opening center"; + // Internal variables - Modelica.SIunits.Pressure p_a "Pressure at port_a"; - Modelica.SIunits.Pressure p_b "Pressure at port_b"; + Modelica.SIunits.Pressure p_a + "Pressure at port_a"; + Modelica.SIunits.Pressure p_b + "Pressure at port_b"; Modelica.SIunits.PressureDifference dp_i[N]; Modelica.SIunits.PressureDifference dp; - Modelica.SIunits.MassFlowRate m_flow_i[N] ; - Modelica.SIunits.Velocity Vel[N] ; - Modelica.SIunits.MassFlowRate m_flow "Mass flow rate throught the opening"; + Modelica.SIunits.MassFlowRate m_flow_i[N]; + Modelica.SIunits.Velocity Vel[N]; + Modelica.SIunits.MassFlowRate m_flow + "Mass flow rate throught the opening"; Modelica.SIunits.Density d[N]; - Modelica.SIunits.IsentropicExponent gamma "Isentropic exponent"; - Modelica.SIunits.MachNumber M "Mach number at the opening"; + Modelica.SIunits.IsentropicExponent gamma + "Isentropic exponent"; + Modelica.SIunits.MachNumber M + "Mach number at the opening"; Medium.ThermodynamicState state, state_a, state_b; - Integer buoyancy "if density port_a < port_b, buoyancy is taken account and equal to 1 and 0 otherwise"; - + Integer buoyancy + "if density port_a < port_b, buoyancy is taken account and equal to 1 and 0 otherwise"; + // Imported modules - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-58, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {38, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-58, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {38, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected - Modelica.SIunits.MassFlowRate mX_flow_i[N, Medium.nX] ; - Modelica.SIunits.SpecificEnthalpy h_a "Specific enthalpy from port_a" ; - Modelica.SIunits.SpecificEnthalpy h_b "Specific enthalpy from port_b" ; - parameter Modelica.SIunits.Velocity Vel_small = 0.001 ; + + Modelica.SIunits.MassFlowRate mX_flow_i[N, Medium.nX]; + Modelica.SIunits.SpecificEnthalpy h_a + "Specific enthalpy from port_a"; + Modelica.SIunits.SpecificEnthalpy h_b + "Specific enthalpy from port_b"; + parameter Modelica.SIunits.Velocity Vel_small = 0.001; initial equation + if massDynamics == Dynamics.SteadyStateInitial then der(Vel) = fill(0.0, N); - + elseif massDynamics == Dynamics.FixedInitial then - Vel = fill(Vel_start, N) ; + Vel = fill(Vel_start, N); end if; - + equation -// + + // state_a = Medium.setState_dTX(d = sum(port_a.d), T = port_a.T, X = port_a.d / sum(port_a.d)); state_b = Medium.setState_dTX(d = sum(port_b.d), T = port_b.T, X = port_b.d / sum(port_b.d)); -// pressure reconstruction - p_a = Medium.pressure(state_a) + sum(port_a.d) * Modelica.Constants.g_n * (Alt_a-Alt_opening); - p_b = Medium.pressure(state_b) + sum(port_b.d) * Modelica.Constants.g_n * (Alt_b-Alt_opening); + // pressure reconstruction + p_a = Medium.pressure(state_a) + sum(port_a.d) * Modelica.Constants.g_n * (Alt_a - Alt_opening); + p_b = Medium.pressure(state_b) + sum(port_b.d) * Modelica.Constants.g_n * (Alt_b - Alt_opening); dp = p_a - p_b; - -// specific enthalpy reconstruction + + // specific enthalpy reconstruction h_a = Medium.specificEnthalpy(state_a); h_b = Medium.specificEnthalpy(state_b); - -/* + + /* If the density at the lower altitude is below the density at a higher, in case of low static pressure difference, a crossing flow can occur. In such a case, the HorizontalOpening is assumed behaves like a VerticalOpening where the its heigh is the hydraulic diameter */ buoyancy = if sum(port_a.d) < sum(port_b.d) then 1 else 0; -// - for i in 1:N loop + // + for i in 1 : N loop dp_i[i] = dp + Modelica.Constants.g_n * (Dh / 2 - Dh * (i - 1 / 2) / N) * min(sum(port_a.d) - sum(port_b.d), 0.0); d[i] = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = Vel[i], x_small = 1e-10, y1 = sum(port_a.d), y2 = sum(port_b.d)); if massDynamics == Dynamics.SteadyState then dp_i[i] - 1 / 2 * Modelica.Fluid.Utilities.regSquare2(x = Vel[i], x_small = Vel_small, k1 = sum(port_a.d), k2 = sum(port_b.d)) = 0.0; else -/* inertial opening */ + /* inertial opening */ dp_i[i] - 1 / 2 * Modelica.Fluid.Utilities.regSquare2(x = Vel[i], x_small = Vel_small, k1 = sum(port_a.d), k2 = sum(port_b.d)) = NotionalLength * d[i] * der(Vel[i]); end if; m_flow_i[i] = Vel[i] * Cd * A / N * d[i]; end for; - - mX_flow_i = {m_flow_i[i] * TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Vel[i], - x_small = 1e-14, - y1 = port_a.d/sum(port_a.d), - y2 = port_b.d/sum(port_b.d) ) for i in 1:N} ; - m_flow = sum(m_flow_i) ; + mX_flow_i = { + m_flow_i[i] * TAeZoSysPro.FluidDynamics.Utilities.regStep( + x = Vel[i], + x_small = 1e-14, + y1 = port_a.d / sum(port_a.d), + y2 = port_b.d / sum(port_b.d)) + for i in 1 : N}; + + m_flow = sum(m_flow_i); -// assertion, Mach number has to remain bellow 0.3 to keep the assumption of an uncrompressible flow valid + // assertion, Mach number has to remain bellow 0.3 to keep the assumption of an uncrompressible flow valid state = Medium.setSmoothState( - x = sum(Vel)/N, - x_small = Vel_small, - state_a = state_a, + x = sum(Vel) / N, + x_small = Vel_small, + state_a = state_a, state_b = state_b); gamma = Medium.isentropicExponent(state); -/* gamma is supposed contant along the flow */ -// Mach number calculation: The pressure at the orifice is the downstream node pressure + /* gamma is supposed contant along the flow */ + // Mach number calculation: The pressure at the orifice is the downstream node pressure M = min(1, (2 / (gamma - 1) * ((min(p_a, p_b) / max(p_a, p_b)) ^ ((1 - gamma) / gamma) - 1)) ^ 0.5); - assert(M<=0.3,"Mach number > 0.3, the flow becomes compressible. The assumption of uncrompressible flow is not valid", AssertionLevel.warning) ; - -// Port handover - port_a.m_flow = {sum(mX_flow_i[:, i]) for i in 1:Medium.nX} ; + assert(M <= 0.3, "Mach number > 0.3, the flow becomes compressible. The assumption of uncrompressible flow is not valid", AssertionLevel.warning); + + // Port handover + port_a.m_flow = {sum(mX_flow_i[:, i]) for i in 1 : Medium.nX}; port_a.m_flow + port_b.m_flow = fill(0.0, Medium.nX); - -// port_a.H_flow = sum( smooth(0, if dp_i[i] >= 0.0 then m_flow_i[i] * h_a else m_flow_i[i] * h_b) for i in 1:N); + + // port_a.H_flow = sum( smooth(0, if dp_i[i] >= 0.0 then m_flow_i[i] * h_a else m_flow_i[i] * h_b) for i in 1:N); port_a.H_flow = m_flow_i * TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Vel, - x_small = 1e-3, - y1 = h_a + Modelica.Constants.g_n * (Alt_a - Alt_b), + x = Vel, + x_small = 1e-3, + y1 = h_a + Modelica.Constants.g_n * (Alt_a - Alt_b), y2 = h_b - Modelica.Constants.g_n * (Alt_a - Alt_b)); port_a.H_flow + port_b.H_flow = 0; - - annotation(defaultComponentName="opening", -Documentation(info = " + + annotation ( + defaultComponentName = "opening", + Documentation( + info = " HorizontalOpening @@ -216,5 +244,4 @@ Documentation(info = " "), Icon(coordinateSystem(initialScale = 0.1), graphics = {Line(origin = {-20, 30}, points = {{-60, -30}, {0, -30}}, thickness = 2), Text(origin = {6, -37}, extent = {{-46, 33}, {34, 13}}, textString = "A=%A"), Line(origin = {-49.9541, -27.3945}, points = {{0, 25}, {0, -31}}, thickness = 0.75, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {20, -30}, points = {{0, 30}, {60, 30}}, thickness = 2), Line(origin = {49.9541, 34.6789}, points = {{0, 25}, {0, -31}}, thickness = 0.75, arrow = {Arrow.Filled, Arrow.Filled}), Text(origin = {46, -113}, extent = {{-26, 33}, {54, 13}}, textString = "Alt_a=%Alt_a"), Text(origin = {-74, 67}, extent = {{-26, 33}, {54, 13}}, textString = "Alt_b=%Alt_b"), Text(origin = {-54, -113}, lineColor = {242, 21, 21}, extent = {{-46, 33}, {34, 13}}, textString = "Down"), Text(origin = {66, 67}, lineColor = {242, 21, 21}, extent = {{-46, 33}, {34, 13}}, textString = "Up"), Text(origin = {-42, -7}, extent = {{-38, 33}, {82, 13}}, textString = "Alt_opening=%Alt_opening")})); - -end HorizontalOpening; \ No newline at end of file +end HorizontalOpening; diff --git a/FluidDynamics/Components/Orifices/Opening.mo b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/Opening.mo similarity index 67% rename from FluidDynamics/Components/Orifices/Opening.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Orifices/Opening.mo index 4a3b948..7b22112 100644 --- a/FluidDynamics/Components/Orifices/Opening.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/Opening.mo @@ -1,114 +1,141 @@ within TAeZoSysPro.FluidDynamics.Components.Orifices; model Opening - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - + + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters - parameter Real Cd = 0.61 "discharge coefficient"; - parameter Modelica.SIunits.CrossSection A = 1 "Opening cross section"; - parameter Modelica.SIunits.Height H = 1 "Opening's Height"; - parameter Integer N = 5 "Number discrete layer along the height of the opening"; - parameter Modelica.SIunits.Length NotionalLength = 1e-4 "Opening's thickness"; - parameter Dynamics massDynamics = Dynamics.SteadyStateInitial "Formulation of mass balance"; - parameter Modelica.SIunits.Velocity Vel_start = 0.0 "Start value for velocity, if not steady state"; - - parameter Modelica.SIunits.Length Alt_a = 1.0 "Altitude of port_a"; - parameter Modelica.SIunits.Length Alt_b = 1.0 "Altitude of port_b"; - parameter Modelica.SIunits.Length Alt_opening = 1.0 "Altitude at the opening center"; - + parameter Real Cd = 0.61 + "discharge coefficient"; + parameter Modelica.SIunits.CrossSection A = 1 + "Opening cross section"; + parameter Modelica.SIunits.Height H = 1 + "Opening's Height"; + parameter Integer N = 5 + "Number discrete layer along the height of the opening"; + parameter Modelica.SIunits.Length NotionalLength = 1e-4 + "Opening's thickness"; + parameter Dynamics massDynamics = Dynamics.SteadyStateInitial + "Formulation of mass balance"; + parameter Modelica.SIunits.Velocity Vel_start = 0.0 + "Start value for velocity, if not steady state"; + + parameter Modelica.SIunits.Length Alt_a = 1.0 + "Altitude of port_a"; + parameter Modelica.SIunits.Length Alt_b = 1.0 + "Altitude of port_b"; + parameter Modelica.SIunits.Length Alt_opening = 1.0 + "Altitude at the opening center"; + // Internal variables - Modelica.SIunits.Pressure p_a "Pressure at port_a"; - Modelica.SIunits.Pressure p_b "Pressure at port_b"; + Modelica.SIunits.Pressure p_a + "Pressure at port_a"; + Modelica.SIunits.Pressure p_b + "Pressure at port_b"; Modelica.SIunits.PressureDifference dp_i[N]; Modelica.SIunits.PressureDifference dp; - Modelica.SIunits.MassFlowRate m_flow_i[N] ; - Modelica.SIunits.Velocity Vel[N] ; - Modelica.SIunits.MassFlowRate m_flow "Mass flow rate throught the opening"; + Modelica.SIunits.MassFlowRate m_flow_i[N]; + Modelica.SIunits.Velocity Vel[N]; + Modelica.SIunits.MassFlowRate m_flow + "Mass flow rate throught the opening"; Modelica.SIunits.Density d[N]; - Modelica.SIunits.IsentropicExponent gamma "Isentropic exponent"; - Modelica.SIunits.MachNumber M "Mach number at the opening"; + Modelica.SIunits.IsentropicExponent gamma + "Isentropic exponent"; + Modelica.SIunits.MachNumber M + "Mach number at the opening"; Medium.ThermodynamicState state, state_a, state_b; - + // Imported modules - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-58, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {38, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-58, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {38, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected - Modelica.SIunits.MassFlowRate mX_flow_i[N, Medium.nX] ; - Modelica.SIunits.SpecificEnthalpy h_a "Specific enthalpy from port_a" ; - Modelica.SIunits.SpecificEnthalpy h_b "Specific enthalpy from port_b" ; - parameter Modelica.SIunits.Velocity Vel_small = 0.001 ; + + Modelica.SIunits.MassFlowRate mX_flow_i[N, Medium.nX]; + Modelica.SIunits.SpecificEnthalpy h_a + "Specific enthalpy from port_a"; + Modelica.SIunits.SpecificEnthalpy h_b + "Specific enthalpy from port_b"; + parameter Modelica.SIunits.Velocity Vel_small = 0.001; initial equation + if massDynamics == Dynamics.SteadyStateInitial then der(Vel) = fill(0.0, N); - + elseif massDynamics == Dynamics.FixedInitial then - Vel = fill(Vel_start, N) ; + Vel = fill(Vel_start, N); end if; - + equation -// + + // state_a = Medium.setState_dTX(d = sum(port_a.d), T = port_a.T, X = port_a.d / sum(port_a.d)); state_b = Medium.setState_dTX(d = sum(port_b.d), T = port_b.T, X = port_b.d / sum(port_b.d)); -// pressure reconstruction - p_a = Medium.pressure(state_a) + sum(port_a.d) * Modelica.Constants.g_n * (Alt_a-Alt_opening); - p_b = Medium.pressure(state_b) + sum(port_b.d) * Modelica.Constants.g_n * (Alt_b-Alt_opening); + // pressure reconstruction + p_a = Medium.pressure(state_a) + sum(port_a.d) * Modelica.Constants.g_n * (Alt_a - Alt_opening); + p_b = Medium.pressure(state_b) + sum(port_b.d) * Modelica.Constants.g_n * (Alt_b - Alt_opening); dp = p_a - p_b; - -// specific enthalpy reconstruction + + // specific enthalpy reconstruction h_a = Medium.specificEnthalpy(state_a); h_b = Medium.specificEnthalpy(state_b); - - for i in 1:N loop + + for i in 1 : N loop dp_i[i] = dp + Modelica.Constants.g_n * (H / 2 - H * (i - 1 / 2) / N) * (sum(port_a.d) - sum(port_b.d)); d[i] = TAeZoSysPro.FluidDynamics.Utilities.regStep(x = Vel[i], x_small = 1e-10, y1 = sum(port_a.d), y2 = sum(port_b.d)); if massDynamics == Dynamics.SteadyState then - dp_i[i] - 1 / 2 * Modelica.Fluid.Utilities.regSquare2(x = Vel[i], x_small = Vel_small, k1 = sum(port_a.d), k2 = sum(port_b.d)) = 0.0; - else /* inertial opening */ + dp_i[i] - 1 / 2 * Modelica.Fluid.Utilities.regSquare2(x = Vel[i], x_small = Vel_small, k1 = sum(port_a.d), k2 = sum(port_b.d)) = 0.0; + else /* inertial opening */ dp_i[i] - 1 / 2 * Modelica.Fluid.Utilities.regSquare2(x = Vel[i], x_small = Vel_small, k1 = sum(port_a.d), k2 = sum(port_b.d)) = NotionalLength * d[i] * der(Vel[i]); end if; - m_flow_i[i] = Vel[i] * Cd * A / N * d[i]; - end for ; - - mX_flow_i = {m_flow_i[i] * TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Vel[i], - x_small = 1e-14, - y1 = port_a.d/sum(port_a.d), - y2 = port_b.d/sum(port_b.d) ) for i in 1:N} ; - - m_flow = sum(m_flow_i) ; - -// assertion, Mach number has to remain bellow 0.3 to keep the assumption of an uncrompressible flow valid + m_flow_i[i] = Vel[i] * Cd * A / N * d[i]; + end for; + + mX_flow_i = { + m_flow_i[i] * TAeZoSysPro.FluidDynamics.Utilities.regStep( + x = Vel[i], + x_small = 1e-14, + y1 = port_a.d / sum(port_a.d), + y2 = port_b.d / sum(port_b.d)) + for i in 1 : N}; + + m_flow = sum(m_flow_i); + + // assertion, Mach number has to remain bellow 0.3 to keep the assumption of an uncrompressible flow valid state = Medium.setSmoothState( - x = sum(Vel)/N, - x_small = Vel_small, - state_a = state_a, + x = sum(Vel) / N, + x_small = Vel_small, + state_a = state_a, state_b = state_b); - gamma = Medium.isentropicExponent(state) /* gamma is supposed contant along the flow */; + gamma = Medium.isentropicExponent(state); // Mach number calculation: The pressure at the orifice is the downstream node pressure M = min(1, (2 / (gamma - 1) * ((min(p_a, p_b) / max(p_a, p_b)) ^ ((1 - gamma) / gamma) - 1)) ^ 0.5); - assert(M<=0.3,"Mach number > 0.3, the flow becomes compressible. The assumption of uncrompressible flow is not valid", AssertionLevel.warning) ; - -// Port handover - port_a.m_flow = {sum(mX_flow_i[:, i]) for i in 1:Medium.nX} ; + assert(M <= 0.3, "Mach number > 0.3, the flow becomes compressible. The assumption of uncrompressible flow is not valid", AssertionLevel.warning); + + // Port handover + port_a.m_flow = {sum(mX_flow_i[:, i]) for i in 1 : Medium.nX}; port_a.m_flow + port_b.m_flow = fill(0.0, Medium.nX); - -// port_a.H_flow = sum( smooth(0, if dp_i[i] >= 0.0 then m_flow_i[i] * h_a else m_flow_i[i] * h_b) for i in 1:N); + + // port_a.H_flow = sum( smooth(0, if dp_i[i] >= 0.0 then m_flow_i[i] * h_a else m_flow_i[i] * h_b) for i in 1:N); port_a.H_flow = m_flow_i * TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Vel, - x_small = 1e-3, - y1 = h_a + Modelica.Constants.g_n * (Alt_a - Alt_b), - y2 = h_b - Modelica.Constants.g_n * (Alt_a - Alt_b) ); + x = Vel, + x_small = 1e-3, + y1 = h_a + Modelica.Constants.g_n * (Alt_a - Alt_b), + y2 = h_b - Modelica.Constants.g_n * (Alt_a - Alt_b)); port_a.H_flow + port_b.H_flow = 0; - - annotation(defaultComponentName="opening", -Documentation(info = " + + annotation ( + defaultComponentName = "opening", + Documentation( + info = " Opening @@ -207,5 +234,4 @@ Documentation(info = " "), Icon(graphics = {Line(origin = {0, 50}, points = {{0, 30}, {0, -20}}, thickness = 2), Line(origin = {0, -50}, points = {{0, 20}, {0, -30}}, thickness = 2), Text(origin = {16, -113}, extent = {{-116, 33}, {84, 13}}, textString = "A=%A"), Text(origin = {-43, 88}, extent = {{-57, 12}, {143, -8}}, textString = "%name"), Line(points = {{0, 24}, {0, -24}}, color = {255, 0, 0}, arrow = {Arrow.Filled, Arrow.Filled}, arrowSize = 5), Text(origin = {120, 39}, extent = {{-116, 33}, {-20, 13}}, textString = "H=%H"), Line(points = {{-40, 0}, {40, 0}}, pattern = LinePattern.Dash, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {-1, 27.24}, points = {{-39, 12.7571}, {-19, -7.24287}, {1, -15.2429}, {21, -7.24287}, {41, 12.7571}}, pattern = LinePattern.Dash, arrow = {Arrow.Filled, Arrow.Filled}, smooth = Smooth.Bezier), Line(origin = {1.02, -27.23}, rotation = 180, points = {{-39, 12.7571}, {-19, -7.24287}, {1, -15.2429}, {21, -7.24287}, {41, 12.7571}}, pattern = LinePattern.Dash, arrow = {Arrow.Filled, Arrow.Filled}, smooth = Smooth.Bezier), Line(origin = {6, 32}, points = {{-6, -8}, {44, 22}}, color = {255, 0, 0})}, coordinateSystem(initialScale = 0.1))); - end Opening; diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Orifices/OpeningAnalytic.mo b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/OpeningAnalytic.mo new file mode 100644 index 0000000..f68c3c4 --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/OpeningAnalytic.mo @@ -0,0 +1,123 @@ +within TAeZoSysPro.FluidDynamics.Components.Orifices; + +model OpeningAnalytic + + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + + // User defined parameters + parameter Real Cd = 0.61 + "discharge coefficient"; + parameter Modelica.SIunits.CrossSection A = 1 + "Opening cross section"; + parameter Modelica.SIunits.Height H = 1 + "Opening's Height"; + parameter Modelica.SIunits.Length Alt_a = 1.0 + "Altitude of port_a"; + parameter Modelica.SIunits.Length Alt_b = 1.0 + "Altitude of port_b"; + parameter Modelica.SIunits.Length Alt_opening = 1.0 + "Altitude at the opening center"; + + // Internal variables + Modelica.SIunits.Pressure p_a + "Pressure of node connected to port_a"; + Modelica.SIunits.Pressure p_b + "Pressure of node connected to port_b"; + Modelica.SIunits.PressureDifference dp; + Modelica.SIunits.Density rho_A, rho_B; + Medium.Density[Medium.nX] + rho_up, + rho_down + "Upstream density in upper and lower part of the opening"; + Medium.MassFraction[Medium.nX] X_up, X_down; + Modelica.SIunits.Height HN + "Heigh of the point where flow switches in direction (zero flow)"; + Medium.ThermodynamicState state_a, state_b; + Modelica.SIunits.MassFlowRate + m_flow_up, + m_flow_down + "mass flow rate in upper and lower part of the opening"; + + // Imported modules + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-58, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {38, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +protected + + Modelica.SIunits.SpecificEnthalpy h_a + "Specific enthalpy from port_a"; + Modelica.SIunits.SpecificEnthalpy h_b + "Specific enthalpy from port_b"; + parameter Modelica.SIunits.Velocity Vel_small = 0.001; + constant Modelica.SIunits.Acceleration g = Modelica.Constants.g_n + "Gravitational acceleration"; + +equation + + // + state_a = Medium.setState_dTX(d = sum(port_a.d), T = port_a.T, X = port_a.d / sum(port_a.d)); + state_b = Medium.setState_dTX(d = sum(port_b.d), T = port_b.T, X = port_b.d / sum(port_b.d)); + + // pressure reconstruction + p_a = Medium.pressure(state_a) + sum(port_a.d) * g * (Alt_a - Alt_opening); + p_b = Medium.pressure(state_b) + sum(port_b.d) * g * (Alt_b - Alt_opening); + dp = p_a - p_b; + + // specific enthalpy reconstruction + h_a = Medium.specificEnthalpy(state_a); + h_b = Medium.specificEnthalpy(state_b); + + // density + rho_A = sum(port_a.d); + rho_B = sum(port_b.d); + + // upsteam density + rho_up = smooth(1, if dp - (sum(port_a.d) - sum(port_b.d)) * g * (H - HN) > 0 then port_a.d else port_b.d); + rho_down = port_a.d + port_b.d - rho_up; + + // upstream mass fraction + X_up = rho_up / sum(rho_up); + X_down = port_a.d / rho_A + port_b.d / rho_B - X_up; + + // altidude of change in direction of flow (if change happens) + HN = min(max(dp / ((rho_A - rho_B) * g) + H / 2, 0), H); + + // m_flow = f(dp, Δρ, ΔH) + m_flow_up = Cd * A / H * sqrt(2 * sum(rho_up)) * (Modelica.Fluid.Utilities.regRoot(x = dp, delta = 1e-3) * (H - HN) - Modelica.Fluid.Utilities.regRoot(x = (rho_A - rho_B) * g, delta = 1e-3) * 2 / 3 * (H - HN) ^ (3 / 2)); + m_flow_down = Cd * A / H * sqrt(2 * sum(rho_down)) * (Modelica.Fluid.Utilities.regRoot(x = dp, delta = 1e-3) * (-HN) - Modelica.Fluid.Utilities.regRoot(x = (rho_A - rho_B) * g, delta = 1e-3) * 2 / 3 * (-HN ^ (3 / 2))); + + // Port handover + port_a.m_flow = m_flow_up * X_up + m_flow_down * X_down; + port_a.m_flow + port_b.m_flow = fill(0.0, Medium.nX); + + port_a.H_flow = semiLinear(m_flow_up, h_a + g * (Alt_a - Alt_b), h_b - g * (Alt_a - Alt_b)); + port_a.H_flow + port_b.H_flow = 0; + + annotation ( + Icon(graphics = {Line(origin = {0, 69.8886}, points = {{0, 30}, {0, -30}}, thickness = 2), Line(origin = {0, -70}, points = {{0, 30}, {0, -30}}, thickness = 2)}, coordinateSystem(initialScale = 0.1)), + experiment(StartTime = 0, StopTime = 1000, Tolerance = 1e-06, Interval = 1), + Documentation( + info = " + + Opening + + + +

      + This components allows to model the mass flow rate through from either static boundary pressure difference or buoyancy effect through a vertical orifice in a wall spliting two ambiances. +

      + +

      + To be considered as an orifice, the depth of the hole in the wall has to remain bellow the hydrodynamic entrance region (Distance between the entrance of the hole and the position where the dynamic boundary layers meet). +

      + +

      + See demonstration. +

      +")); + +end OpeningAnalytic; diff --git a/FluidDynamics/Components/Orifices/SimpleOpening.bak-mo b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/SimpleOpening.bak-mo similarity index 100% rename from FluidDynamics/Components/Orifices/SimpleOpening.bak-mo rename to src/TAeZoSysPro/FluidDynamics/Components/Orifices/SimpleOpening.bak-mo diff --git a/FluidDynamics/Components/Orifices/SimpleOpeningComp.mo b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/SimpleOpeningComp.mo similarity index 67% rename from FluidDynamics/Components/Orifices/SimpleOpeningComp.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Orifices/SimpleOpeningComp.mo index 4ea3662..634c94f 100644 --- a/FluidDynamics/Components/Orifices/SimpleOpeningComp.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/SimpleOpeningComp.mo @@ -1,106 +1,130 @@ within TAeZoSysPro.FluidDynamics.Components.Orifices; model SimpleOpeningComp + replaceable package Medium = TAeZoSysPro.Media.MyMedia; - + // User defined parameters - parameter Real Cd = 0.61 "discharge coefficient"; - parameter Modelica.SIunits.CrossSection A = 1 "Opening cross section"; - parameter Modelica.SIunits.Length Alt_a = 1.0 "Altitude of port_a"; - parameter Modelica.SIunits.Length Alt_b = 1.0 "Altitude of port_b"; - parameter Modelica.SIunits.Length Alt_opening = 1.0 "Altitude at the opening center"; - + parameter Real Cd = 0.61 + "discharge coefficient"; + parameter Modelica.SIunits.CrossSection A = 1 + "Opening cross section"; + parameter Modelica.SIunits.Length Alt_a = 1.0 + "Altitude of port_a"; + parameter Modelica.SIunits.Length Alt_b = 1.0 + "Altitude of port_b"; + parameter Modelica.SIunits.Length Alt_opening = 1.0 + "Altitude at the opening center"; + // Internal variables Modelica.SIunits.PressureDifference dp; - Modelica.SIunits.Velocity Vel "Velocity at the orifice"; - Modelica.SIunits.Velocity c "Sound velocity"; - Modelica.SIunits.MassFlowRate m_flow "Mass flow rate throught the opening"; - Modelica.SIunits.Density d "density at the orifice"; - + Modelica.SIunits.Velocity Vel + "Velocity at the orifice"; + Modelica.SIunits.Velocity c + "Sound velocity"; + Modelica.SIunits.MassFlowRate m_flow + "Mass flow rate throught the opening"; + Modelica.SIunits.Density d + "density at the orifice"; + // Modelica.SIunits.Density d_comp "Densite au col"; Modelica.SIunits.AbsolutePressure p_a; Modelica.SIunits.AbsolutePressure p_b; - Modelica.SIunits.IsentropicExponent gamma "isentropic exponent"; - Modelica.SIunits.MachNumber M "Mach number at the orifice"; - Modelica.SIunits.Temperature T "Temperature at the orifice"; - Medium.ThermodynamicState state_upstream "State of upstream flow"; - Medium.ThermodynamicState state_a, state_b "States at ports"; - + Modelica.SIunits.IsentropicExponent gamma + "isentropic exponent"; + Modelica.SIunits.MachNumber M + "Mach number at the orifice"; + Modelica.SIunits.Temperature T + "Temperature at the orifice"; + Medium.ThermodynamicState state_upstream + "State of upstream flow"; + Medium.ThermodynamicState + state_a, + state_b + "States at ports"; + // Imported modules - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected - Modelica.SIunits.SpecificEnthalpy h_a "Specific enthalpy from port_a" ; - Modelica.SIunits.SpecificEnthalpy h_b "Specific enthalpy from port_b" ; - parameter Modelica.SIunits.PressureDifference dp_small = 0.001 ; + + Modelica.SIunits.SpecificEnthalpy h_a + "Specific enthalpy from port_a"; + Modelica.SIunits.SpecificEnthalpy h_b + "Specific enthalpy from port_b"; + parameter Modelica.SIunits.PressureDifference dp_small = 0.001; constant Modelica.SIunits.Acceleration g = Modelica.Constants.g_n; - + equation -// - state_a = Medium.setState_dTX(d = sum(port_a.d), T = port_a.T, X = port_a.d / sum(port_a.d) ); - state_b = Medium.setState_dTX(d = sum(port_b.d), T = port_b.T, X = port_b.d / sum(port_b.d) ); + + // + state_a = Medium.setState_dTX(d = sum(port_a.d), T = port_a.T, X = port_a.d / sum(port_a.d)); + state_b = Medium.setState_dTX(d = sum(port_b.d), T = port_b.T, X = port_b.d / sum(port_b.d)); state_upstream = Medium.setSmoothState( - x = dp, - x_small = dp_small, - state_a = state_a, + x = dp, + x_small = dp_small, + state_a = state_a, state_b = state_b); -// pressure reconstruction + // pressure reconstruction p_a = Medium.pressure(state_a) + sum(port_a.d) * g * (Alt_a - Alt_opening); p_b = Medium.pressure(state_b) + sum(port_b.d) * g * (Alt_b - Alt_opening); dp = p_a - p_b; -// specific enthalpy reconstruction + // specific enthalpy reconstruction h_a = Medium.specificEnthalpy(state_a); h_b = Medium.specificEnthalpy(state_b); - -// gamma is supposed contant along the flow + + // gamma is supposed contant along the flow gamma = Medium.isentropicExponent(state_upstream); - -// Mach number calculation: The pressure at the orifice is the downstream node pressure + + // Mach number calculation: The pressure at the orifice is the downstream node pressure M = min(1, (2 / (gamma - 1) * ((min(p_a, p_b) / max(p_a, p_b)) ^ ((1 - gamma) / gamma) - 1)) ^ 0.5); - -// Calculation temperature at the orifice + + // Calculation temperature at the orifice T = Medium.temperature(state_upstream) / (1 + (gamma - 1) / 2 * M ^ 2); -// Calculation density at the orifice + // Calculation density at the orifice d = Medium.density(state_upstream) / (1 + (gamma - 1) / 2 * M ^ 2) ^ (1 / (1 - gamma)); - -// solution 1: The velocity is computed from the Mach number and the velocity of sound + + // solution 1: The velocity is computed from the Mach number and the velocity of sound //c = Medium.velocityOfSound(Medium.setState_pTX(p = min(p_a, p_b), T = T, X = state.X)); c = sqrt(gamma * min(p_a, p_b) / d); Vel = M * c * sign(dp); m_flow = Vel * A * Cd * d; - -// solution 2: The velocity is computed from the compressible Bernoulli relation -//solution 2.1: more stable around dp = 0 but induces an interation variable -// 2 * gamma / (gamma - 1) * max(p_a, p_b) / Medium.density(state) * (1- (1 + (gamma - 1) / 2 * M ^ 2) ^ (-1)) - Modelica.Fluid.Utilities.regSquare2( -// x = Vel, -// x_small = 0.01, -// k1 = 1, -// k2 = 1) = 0.0 ; -//solution 2.0: infinite derivative at dp = 0 -// Vel = sign(dp) * sqrt(2 * gamma / (gamma - 1) * max(p_a, p_b) / Medium.density(state) * (1- (1 + (gamma - 1) / 2 * M ^ 2) ^ (-1)) ) ; - -//Blocking mass flow calculation -// m_flow_blocked = sign(dp) * max(pa, pb) * (gamma / r / T0) ^ 0.5 * Ar * Cd * ((gamma + 1) / 2) ^ ((1 + gamma) / 2 / (1 - gamma)) "From Barre Saint Venant and Hugoniot"; - - -// Port handover + + // solution 2: The velocity is computed from the compressible Bernoulli relation + //solution 2.1: more stable around dp = 0 but induces an interation variable + // 2 * gamma / (gamma - 1) * max(p_a, p_b) / Medium.density(state) * (1- (1 + (gamma - 1) / 2 * M ^ 2) ^ (-1)) - Modelica.Fluid.Utilities.regSquare2( + // x = Vel, + // x_small = 0.01, + // k1 = 1, + // k2 = 1) = 0.0 ; + //solution 2.0: infinite derivative at dp = 0 + // Vel = sign(dp) * sqrt(2 * gamma / (gamma - 1) * max(p_a, p_b) / Medium.density(state) * (1- (1 + (gamma - 1) / 2 * M ^ 2) ^ (-1)) ) ; + + //Blocking mass flow calculation + // m_flow_blocked = sign(dp) * max(pa, pb) * (gamma / r / T0) ^ 0.5 * Ar * Cd * ((gamma + 1) / 2) ^ ((1 + gamma) / 2 / (1 - gamma)) "From Barre Saint Venant and Hugoniot"; + + // Port handover port_a.m_flow = m_flow * TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = dp, - x_small = dp_small, - y1 = port_a.d/sum(port_a.d), - y2 = port_b.d/sum(port_b.d)); + x = dp, + x_small = dp_small, + y1 = port_a.d / sum(port_a.d), + y2 = port_b.d / sum(port_b.d)); port_a.m_flow + port_b.m_flow = fill(0.0, Medium.nX); - port_a.H_flow = semiLinear(m_flow, h_a + g*(Alt_a - Alt_b), h_b - g*(Alt_a - Alt_b) ); + port_a.H_flow = semiLinear(m_flow, h_a + g * (Alt_a - Alt_b), h_b - g * (Alt_a - Alt_b)); port_a.H_flow + port_b.H_flow = 0; - - annotation(defaultComponentName="SimpleOpeningComp", -Documentation(info =" + + annotation ( + defaultComponentName = "SimpleOpeningComp", + Documentation( + info = " SimpleOpeningComp diff --git a/FluidDynamics/Components/Orifices/VerticalOpening.bak-mo b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/VerticalOpening.bak-mo similarity index 100% rename from FluidDynamics/Components/Orifices/VerticalOpening.bak-mo rename to src/TAeZoSysPro/FluidDynamics/Components/Orifices/VerticalOpening.bak-mo diff --git a/FluidDynamics/Components/Orifices/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/package.mo similarity index 86% rename from FluidDynamics/Components/Orifices/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Orifices/package.mo index e43a81d..5860511 100644 --- a/FluidDynamics/Components/Orifices/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components; package Orifices + extends Modelica.Icons.VariantsPackage; -end Orifices ; + +end Orifices; diff --git a/FluidDynamics/Components/Orifices/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Orifices/package.order similarity index 100% rename from FluidDynamics/Components/Orifices/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Orifices/package.order diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Pipes/DynamicPipe.mo b/src/TAeZoSysPro/FluidDynamics/Components/Pipes/DynamicPipe.mo new file mode 100644 index 0000000..31fa92c --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Pipes/DynamicPipe.mo @@ -0,0 +1,195 @@ +within TAeZoSysPro.FluidDynamics.Components.Pipes; + +model DynamicPipe + + // Imports + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + + // Medium + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters + parameter Modelica.SIunits.Area A + "Inner cross section area" + annotation ( + Dialog(group = "Geometry")); + parameter Modelica.SIunits.Length L + "Pipe length" + annotation ( + Dialog(group = "Geometry")); + parameter Integer N = 3 + "Number of discrete layers"; + parameter Real ksi = 1 + "dynamic pressure loss" + annotation ( + Dialog(group = "Flow")); + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance"; + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial"; + parameter Dynamics massDynamics = Dynamics.SteadyStateInitial + "Formulation of mass balance"; + parameter Modelica.SIunits.Temperature X_start[:] = Medium.X_default + "Start value for mass fractions, if massDynamics = FixedInitial"; + // Internal variables + Modelica.SIunits.Density d_a + "Density if flow positive at port_a"; + Modelica.SIunits.Density d_b + "Density if flow positive at port_b"; + Modelica.SIunits.PressureDifference dp; + Modelica.SIunits.Velocity Vel; + Modelica.SIunits.MassFlowRate m_flow + "Aperture flow kg/s"; + // Imported Modules + Modelica.Fluid.Interfaces.FluidPort_a port_a(replaceable package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_b(replaceable package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.PDE.Transport.UpwindFirstOrder transport[2]( + each N = N, + each CoeffSpaceDer = Vel, + each x = linspace(0.0, L, N + 1), + each SourceTerm = fill(0.0, N), + N_quantity = {1, Medium.nXi}) + annotation ( + Placement(visible = true, transformation(origin = {0, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); + +initial equation + + if energyDynamics == Dynamics.SteadyStateInitial then + der(transport[1].u[:, 1]) = fill(0.0, N); + + elseif energyDynamics == Dynamics.FixedInitial then + for i in 1 : N loop + transport[1].u[i, 1] = Medium.specificEnthalpy_pTX( + p = port_a.p, + T = T_start, + X = {0.00767631}); + end for; + + elseif energyDynamics == Dynamics.SteadyState then + assert(false, "SteadyState pipe is not model, use rather static pipe module", level = AssertionLevel.error); + + end if; + + if massDynamics == Dynamics.SteadyStateInitial then + for index in 1 : Medium.nXi loop + der(transport[2].u[1 : N, index]) = fill(0.0, N); + end for; + + elseif massDynamics == Dynamics.FixedInitial then + transport[2].u[1 : N, 1 : Medium.nXi] = fill(X_start[1 : Medium.nXi], N); + + elseif massDynamics == Dynamics.SteadyState then + assert(false, "SteadyState pipe is not modelled, use rather static pipe module", level = AssertionLevel.error); + + end if; + +equation + + // mass balance + d_a = Medium.density_phX(p = port_a.p, h = inStream(port_a.h_outflow), X = cat(1, inStream(port_a.Xi_outflow), {1 - sum(inStream(port_a.Xi_outflow))})); + d_b = Medium.density_phX( + p = port_b.p, + h = inStream(port_b.h_outflow), + X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))})); + // momentum + dp = port_a.p - port_b.p; + Vel = Modelica.Fluid.Utilities.regRoot2( + x = dp, + x_small = 0.01, + k1 = 2.0 / (ksi * d_a), + k2 = 2.0 / (ksi * d_b)); + Vel * d_a * A = m_flow; + // Transports of enthalpy + // boundary equations + transport[1].u_ghost_left[1] = inStream(port_a.h_outflow) + "left boundary equation"; + transport[1].u_ghost_right[1] = inStream(port_b.h_outflow) + "right boundary equation"; + + // Transports of mass + // boundary equations + transport[2].u_ghost_left[1 : Medium.nXi] = inStream(port_a.Xi_outflow) + "left boundary equation"; + transport[2].u_ghost_right[1 : Medium.nXi] = inStream(port_b.Xi_outflow) + "right boundary equation"; + + // Ports handover + port_a.m_flow = m_flow; + port_a.m_flow + port_b.m_flow = 0.0; + port_a.h_outflow = transport[1].u[1, 1]; + port_b.h_outflow = transport[1].u[N, 1]; + port_a.Xi_outflow = transport[2].u[1, 1 : Medium.nXi]; + port_b.Xi_outflow = transport[2].u[N, 1 : Medium.nXi]; + + annotation ( + defaultComponentName = "dynamicPipe", + Documentation( + info = " + + + StaticPipe + + + +

      + This components allows to model the mass flow rate through a pipe from a pressure difference at boundaries and the pressure loss coefficient ksi. +

      + +

      + Compared with a static pipe, the following assumptions are performed: +

        +
      1. The mass balance is assumed quasi-static +
      2. Density is assumed constant along the exchanger
      3. +
          +
        • Mass conservation within the control volume is not respected
        • +
        • Change of kinetic energy from contraction or expansion in neglected
        • +
        • Change of temperature from kinetic energy variation is neglected
        • +
        +
      +

      + +

      + ksi expresses how many dynamic pressure is lost. + It is assumed to be constant and therefore independent of the flow regime. +

      + + + +

      + The mass flow rate relation derives: +

      + + + +

      + Where: +

        +
      • dp is the pressure difference between port_a.p and port_b.p
      • +
      • ksi is the pressure loss coefficient
      • +
      • d is the upstream density
      • +
      • Vel is fluid velocity
      • +
      • m_flow is the mass flow rate through the pipe
      • +
      • A is cross section of the pipe
      • +
      +

      + +

      + To avoid infinite derivative at dp=0, The square root is replaced by the function regRoot2 of the MSL that replace the square root by a polynomial expression to insure a finite derivative. The threshold to switch between the polynom and the square root is abs(dp≤0.1) Pa +

      + +"), + Icon( + coordinateSystem( + preserveAspectRatio = false, + extent = {{-100, -100}, {100, 100}}), + graphics = {Rectangle(fillColor = {95, 95, 95}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-100, 40}, {100, -40}}), Rectangle(fillColor = {0, 127, 255}, fillPattern = FillPattern.HorizontalCylinder, extent = {{-100, 44}, {100, -44}}), Line(origin = {-40, 12}, points = {{0, 30}, {0, -54}}, color = {150, 150, 150}, thickness = 2), Line(origin = {40, 12}, points = {{0, 30}, {0, -54}}, color = {150, 150, 150}, thickness = 2), Text(origin = {-66, 0}, lineColor = {255, 255, 255}, extent = {{-20, 40}, {20, -40}}, textString = "1"), Text(origin = {66, 0}, lineColor = {255, 255, 255}, extent = {{-20, 40}, {20, -40}}, textString = "N"), Text(lineColor = {255, 255, 255}, extent = {{-20, 40}, {20, -40}}, textString = "...")}), + experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.002)); + +end DynamicPipe; diff --git a/FluidDynamics/Components/Pipes/StaticPipe.mo b/src/TAeZoSysPro/FluidDynamics/Components/Pipes/StaticPipe.mo similarity index 56% rename from FluidDynamics/Components/Pipes/StaticPipe.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Pipes/StaticPipe.mo index 94ba7e5..266fa89 100644 --- a/FluidDynamics/Components/Pipes/StaticPipe.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Pipes/StaticPipe.mo @@ -2,57 +2,71 @@ within TAeZoSysPro.FluidDynamics.Components.Pipes; model StaticPipe - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters - parameter Modelica.SIunits.Area A "Inner cross section area" annotation( - Dialog(group = "Geometry")); - parameter Real ksi = 1 "dynamic pressure loss" annotation( - Dialog(group = "Flow")); - + parameter Modelica.SIunits.Area A + "Inner cross section area" + annotation ( + Dialog(group = "Geometry")); + parameter Real ksi = 1 + "dynamic pressure loss" + annotation ( + Dialog(group = "Flow")); + // Internal variables - Modelica.SIunits.Density d_a "Density if flow positive at port_a" ; - Modelica.SIunits.Density d_b "Density if flow positive at port_b" ; + Modelica.SIunits.Density d_a + "Density if flow positive at port_a"; + Modelica.SIunits.Density d_b + "Density if flow positive at port_b"; Modelica.SIunits.PressureDifference dp; Modelica.SIunits.Velocity Vel; - Modelica.SIunits.MassFlowRate m_flow "Aperture flow kg/s"; - + Modelica.SIunits.MassFlowRate m_flow + "Aperture flow kg/s"; + // Imported Modules - Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium) annotation ( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); // parameter Modelica.SIunits.PressureDifference dp_small = 0.01; equation -// mass balance - d_a = Medium.density_phX(p = port_a.p, - h = inStream(port_a.h_outflow), - X = cat(1, inStream(port_a.Xi_outflow), {1 - sum(inStream(port_a.Xi_outflow))})) ; - d_b = Medium.density_phX(p = port_b.p, - h = inStream(port_b.h_outflow), - X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))})) ; + // mass balance + d_a = Medium.density_phX( + p = port_a.p, + h = inStream(port_a.h_outflow), + X = cat(1, inStream(port_a.Xi_outflow), {1 - sum(inStream(port_a.Xi_outflow))})); + d_b = Medium.density_phX( + p = port_b.p, + h = inStream(port_b.h_outflow), + X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))})); dp = port_a.p - port_b.p; - m_flow = A * Modelica.Fluid.Utilities.regRoot2(x = dp, - x_small = dp_small, - k1 = 2.0 * d_a / ksi, - k2 = 2.0 * d_b / ksi) ; - Vel * d_a * A = m_flow ; + m_flow = A * Modelica.Fluid.Utilities.regRoot2( + x = dp, + x_small = dp_small, + k1 = 2.0 * d_a / ksi, + k2 = 2.0 * d_b / ksi); + Vel * d_a * A = m_flow; -// Ports handover + // Ports handover port_a.m_flow = m_flow; port_a.m_flow + port_b.m_flow = 0.0; port_a.h_outflow = inStream(port_b.h_outflow); port_b.h_outflow = inStream(port_a.h_outflow); port_a.Xi_outflow = inStream(port_b.Xi_outflow); port_b.Xi_outflow = inStream(port_a.Xi_outflow); - - annotation (defaultComponentName="staticPipe", -Documentation(info =" + + annotation ( + defaultComponentName = "staticPipe", + Documentation( + info = " StaticPipe @@ -98,7 +112,10 @@ Documentation(info ="

      "), -Icon(coordinateSystem( - preserveAspectRatio=false, - extent={{-100,-100},{100,100}}), graphics={Rectangle( fillColor = {0, 127, 255}, fillPattern = FillPattern.HorizontalCylinder, extent = {{-100, 44}, {100, -44}})})); + Icon( + coordinateSystem( + preserveAspectRatio = false, + extent = {{-100, -100}, {100, 100}}), + graphics = {Rectangle(fillColor = {0, 127, 255}, fillPattern = FillPattern.HorizontalCylinder, extent = {{-100, 44}, {100, -44}})})); + end StaticPipe; diff --git a/FluidDynamics/Components/Pipes/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Pipes/package.mo similarity index 98% rename from FluidDynamics/Components/Pipes/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Pipes/package.mo index 5aa74f3..84cfdb6 100644 --- a/FluidDynamics/Components/Pipes/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Pipes/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components; package Pipes + extends Modelica.Icons.VariantsPackage; + end Pipes; diff --git a/FluidDynamics/Components/Pipes/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Pipes/package.order similarity index 100% rename from FluidDynamics/Components/Pipes/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Pipes/package.order diff --git a/FluidDynamics/Components/Valves/1807204.svg b/src/TAeZoSysPro/FluidDynamics/Components/Valves/1807204.svg similarity index 100% rename from FluidDynamics/Components/Valves/1807204.svg rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/1807204.svg diff --git a/FluidDynamics/Components/Valves/BaseClasses/PartialDamper.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/PartialDamper.mo similarity index 55% rename from FluidDynamics/Components/Valves/BaseClasses/PartialDamper.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/PartialDamper.mo index b6261d2..519b9b1 100644 --- a/FluidDynamics/Components/Valves/BaseClasses/PartialDamper.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/PartialDamper.mo @@ -1,128 +1,168 @@ within TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses; -model PartialDamper "Base model for dampers" +model PartialDamper + "Base model for dampers" + // Import section import Modelica.Fluid.Types.CvTypes; - import SI = Modelica.SIunits ; + import SI = Modelica.SIunits; // Replaceable classes - replaceable function valveCharacteristic = - Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.linear constrainedby Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.baseFun "Inherent flow characteristic" - annotation(choicesAllMatching=true); - replaceable package Medium = - TAeZoSysPro.Media.MyMedia "Medium in the component" ; - + replaceable function valveCharacteristic = Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.linear + constrainedby Modelica.Fluid.Valves.BaseClasses.ValveCharacteristics.baseFun + "Inherent flow characteristic" + annotation (choicesAllMatching = true); + replaceable package Medium = TAeZoSysPro.Media.MyMedia + "Medium in the component"; + // User defined parameters // *** Asumptions *** - parameter Boolean allowFlowReversal = true "= true to allow flow reversal, false restricts to design direction (port_a -> port_b)" annotation( - Dialog(tab="Assumptions"), Evaluate=true); - parameter Boolean checkValve=false "Reverse flow stopped" annotation( - Dialog(tab="Assumptions")); + parameter Boolean allowFlowReversal = true + "= true to allow flow reversal, false restricts to design direction (port_a -> port_b)" + annotation ( + Dialog(tab = "Assumptions"), + Evaluate = true); + parameter Boolean checkValve = false + "Reverse flow stopped" + annotation ( + Dialog(tab = "Assumptions")); // *** Advanced *** // Note: value of dp_start shall be refined by derived model, basing on local dp_nominal - parameter Medium.AbsolutePressure dp_start(min=-Modelica.Constants.inf) = dp_nominal - "Guess value of dp = port_a.p - port_b.p" - annotation(Dialog(tab = "Advanced")); + parameter Medium.AbsolutePressure dp_start(min = -Modelica.Constants.inf) = dp_nominal + "Guess value of dp = port_a.p - port_b.p" + annotation (Dialog(tab = "Advanced")); parameter Medium.MassFlowRate m_flow_start = m_flow_nominal - "Guess value of m_flow = port_a.m_flow" - annotation(Dialog(tab = "Advanced")); - parameter SI.Pressure dp_small=0.01*dp_nominal "Regularisation of zero flow" - annotation(Dialog(tab="Advanced")); + "Guess value of m_flow = port_a.m_flow" + annotation (Dialog(tab = "Advanced")); + parameter SI.Pressure dp_small = 0.01 * dp_nominal + "Regularisation of zero flow" + annotation (Dialog(tab = "Advanced")); // Note: value of m_flow_small shall be refined by derived model, basing on local m_flow_nominal parameter Medium.MassFlowRate m_flow_small = 0.0 - "Small mass flow rate for regularization of zero flow" - annotation(Dialog(tab = "Advanced")); + "Small mass flow rate for regularization of zero flow" + annotation (Dialog(tab = "Advanced")); // *** Diagnostics *** parameter Boolean show_T = true - "= true, if temperatures at port_a and port_b are computed" - annotation(Dialog(tab="Advanced",group="Diagnostics")); + "= true, if temperatures at port_a and port_b are computed" + annotation (Dialog(tab = "Advanced", group = "Diagnostics")); parameter Boolean show_V_flow = true - "= true, if volume flow rate at inflowing port is computed" - annotation(Dialog(tab="Advanced",group="Diagnostics")); - -// *** General *** - parameter Modelica.Fluid.Types.CvTypes CvData=Modelica.Fluid.Types.CvTypes.OpPoint "Selection of flow coefficient" annotation( - Dialog(group = "Flow Coefficient")); - parameter SI.Area A = 0 "Damper cross section surface area" annotation( - Dialog(group = "Flow Coefficient", enable = (CvData==Modelica.Fluid.Types.CvTypes.Av))); - parameter Real Kv = 0 "Kv (metric) flow coefficient [m3/h]" annotation( - Dialog(group = "Flow Coefficient", enable = (CvData==Modelica.Fluid.Types.CvTypes.Kv))); - parameter Real Cv = 0 "Cv (US) flow coefficient [USG/min]"annotation( - Dialog(group = "Flow Coefficient", enable = (CvData==Modelica.Fluid.Types.CvTypes.Cv))); - parameter SI.Pressure dp_nominal "Nominal pressure drop" annotation( - Dialog(group="Nominal operating point")); - parameter Medium.MassFlowRate m_flow_nominal "Nominal mass flow rate" annotation( - Dialog(group="Nominal operating point")); - parameter Medium.Density rho_nominal=Medium.density_pTX(Medium.p_default, Medium.T_default, Medium.X_default) "Nominal inlet density" annotation( - Dialog(group="Nominal operating point", enable = (CvData==Modelica.Fluid.Types.CvTypes.OpPoint))); - parameter Real opening_nominal(min=0,max=1)=1 "Nominal opening" annotation( - Dialog(group="Nominal operating point", enable = (CvData==Modelica.Fluid.Types.CvTypes.OpPoint))); + "= true, if volume flow rate at inflowing port is computed" + annotation (Dialog(tab = "Advanced", group = "Diagnostics")); + + // *** General *** + parameter Modelica.Fluid.Types.CvTypes CvData = Modelica.Fluid.Types.CvTypes.OpPoint + "Selection of flow coefficient" + annotation ( + Dialog(group = "Flow Coefficient")); + parameter SI.Area A = 0 + "Damper cross section surface area" + annotation ( + Dialog(group = "Flow Coefficient", enable = (CvData == Modelica.Fluid.Types.CvTypes.Av))); + parameter Real Kv = 0 + "Kv (metric) flow coefficient [m3/h]" + annotation ( + Dialog(group = "Flow Coefficient", enable = (CvData == Modelica.Fluid.Types.CvTypes.Kv))); + parameter Real Cv = 0 + "Cv (US) flow coefficient [USG/min]" + annotation ( + Dialog(group = "Flow Coefficient", enable = (CvData == Modelica.Fluid.Types.CvTypes.Cv))); + parameter SI.Pressure dp_nominal + "Nominal pressure drop" + annotation ( + Dialog(group = "Nominal operating point")); + parameter Medium.MassFlowRate m_flow_nominal + "Nominal mass flow rate" + annotation ( + Dialog(group = "Nominal operating point")); + parameter Medium.Density rho_nominal = Medium.density_pTX(Medium.p_default, Medium.T_default, Medium.X_default) + "Nominal inlet density" + annotation ( + Dialog(group = "Nominal operating point", enable = (CvData == Modelica.Fluid.Types.CvTypes.OpPoint))); + parameter Real opening_nominal(min = 0, max = 1) = 1 + "Nominal opening" + annotation ( + Dialog(group = "Nominal operating point", enable = (CvData == Modelica.Fluid.Types.CvTypes.OpPoint))); // Internal variables Medium.MassFlowRate m_flow( - min=if allowFlowReversal then -Modelica.Constants.inf else 0, - start = m_flow_start) "Mass flow rate in design flow direction"; - - Modelica.SIunits.Pressure dp(start=dp_start) - "Pressure difference between port_a and port_b (= port_a.p - port_b.p)"; - - Modelica.SIunits.VolumeFlowRate V_flow= - m_flow/Modelica.Fluid.Utilities.regStep(m_flow, - Medium.density(state_a), - Medium.density(state_b), - m_flow_small) if show_V_flow - "Volume flow rate at inflowing port (positive when flow from port_a to port_b)"; - - Medium.Temperature port_a_T= - Modelica.Fluid.Utilities.regStep(port_a.m_flow, - Medium.temperature(state_a), - Medium.temperature(Medium.setState_phX(port_a.p, port_a.h_outflow, port_a.Xi_outflow)), - m_flow_small) if show_T - "Temperature close to port_a, if show_T = true"; - - Medium.Temperature port_b_T= - Modelica.Fluid.Utilities.regStep(port_b.m_flow, - Medium.temperature(state_b), - Medium.temperature(Medium.setState_phX(port_b.p, port_b.h_outflow, port_b.Xi_outflow)), - m_flow_small) if show_T - "Temperature close to port_b, if show_T = true"; - + min = if allowFlowReversal then -Modelica.Constants.inf else 0, + start = m_flow_start) + "Mass flow rate in design flow direction"; + + Modelica.SIunits.Pressure dp(start = dp_start) + "Pressure difference between port_a and port_b (= port_a.p - port_b.p)"; + + Modelica.SIunits.VolumeFlowRate V_flow = m_flow / Modelica.Fluid.Utilities.regStep( + m_flow, + Medium.density(state_a), + Medium.density(state_b), + m_flow_small) if show_V_flow + "Volume flow rate at inflowing port (positive when flow from port_a to port_b)"; + + Medium.Temperature port_a_T = Modelica.Fluid.Utilities.regStep( + port_a.m_flow, + Medium.temperature(state_a), + Medium.temperature(Medium.setState_phX(port_a.p, port_a.h_outflow, port_a.Xi_outflow)), + m_flow_small) if show_T + "Temperature close to port_a, if show_T = true"; + + Medium.Temperature port_b_T = Modelica.Fluid.Utilities.regStep( + port_b.m_flow, + Medium.temperature(state_b), + Medium.temperature(Medium.setState_phX(port_b.p, port_b.h_outflow, port_b.Xi_outflow)), + m_flow_small) if show_T + "Temperature close to port_b, if show_T = true"; + // Imported modules Modelica.Fluid.Interfaces.FluidPort_a port_a( - redeclare package Medium = Medium, - m_flow(min=if allowFlowReversal then -Modelica.Constants.inf else 0)) + redeclare package Medium = Medium, + m_flow(min = if allowFlowReversal then -Modelica.Constants.inf else 0)) "Fluid connector a (positive design flow direction is from port_a to port_b)" - annotation (Placement(transformation(extent={{-110,-10},{-90,10}}))); + annotation (Placement(transformation(extent = {{-110, -10}, {-90, 10}}))); Modelica.Fluid.Interfaces.FluidPort_b port_b( - redeclare package Medium = Medium, - m_flow(max=if allowFlowReversal then +Modelica.Constants.inf else 0)) + redeclare package Medium = Medium, + m_flow(max = if allowFlowReversal then +Modelica.Constants.inf else 0)) "Fluid connector b (positive design flow direction is from port_a to port_b)" - annotation (Placement(transformation(extent={{110,-10},{90,10}}), iconTransformation(extent={{110,-10},{90,10}}))); - - Modelica.Blocks.Interfaces.RealInput opening(min=0, max=1) "Valve position in the range 0..1" annotation (Placement(visible = true,transformation( - origin={0,90}, - extent={{-20,-20},{20,20}}, - rotation=270), iconTransformation(origin = {8.88178e-16, 86}, extent = {{-14, -14}, {14, 14}}, rotation = 270))); - - protected - Medium.ThermodynamicState state_a "state for medium inflowing through port_a"; - Medium.ThermodynamicState state_b "state for medium inflowing through port_b"; - constant Real N6 = 31.6 "N6 constant of the ISA-75.01.01-2007 standard"; - parameter SI.Area Av(fixed = false) ; + annotation (Placement(transformation(extent = {{110, -10}, {90, 10}}), iconTransformation(extent = {{110, -10}, {90, 10}}))); + + Modelica.Blocks.Interfaces.RealInput opening(min = 0, max = 1) + "Valve position in the range 0..1" + annotation ( + Placement( + visible = true, + transformation( + origin = {0, 90}, + extent = {{-20, -20}, {20, 20}}, + rotation = 270), + iconTransformation(origin = {8.88178e-16, 86}, extent = {{-14, -14}, {14, 14}}, rotation = 270))); + +protected + + Medium.ThermodynamicState state_a + "state for medium inflowing through port_a"; + Medium.ThermodynamicState state_b + "state for medium inflowing through port_b"; + constant Real N6 = 31.6 + "N6 constant of the ISA-75.01.01-2007 standard"; + parameter SI.Area Av(fixed = false); initial equation + if CvData == CvTypes.Kv then - Av = Kv * N6 / 3600 / sqrt(1e5) "Unit conversion"; + Av = Kv * N6 / 3600 / sqrt(1e5) + "Unit conversion"; elseif CvData == CvTypes.Cv then - Av = Cv * 0.865 * N6 "Unit conversion"; + Av = Cv * 0.865 * N6 + "Unit conversion"; elseif CvData == CvTypes.Av then - Av = A * sqrt(2) "Root of 2 is added to compensate for its lack in head expression V_flow = f(head)"; + Av = A * sqrt(2) + "Root of 2 is added to compensate for its lack in head expression V_flow = f(head)"; end if; - equation + // medium states state_a = Medium.setState_phX(port_a.p, inStream(port_a.h_outflow), inStream(port_a.Xi_outflow)); state_b = Medium.setState_phX(port_b.p, inStream(port_b.h_outflow), inStream(port_b.Xi_outflow)); @@ -143,14 +183,15 @@ equation port_a.C_outflow = inStream(port_b.C_outflow); port_b.C_outflow = inStream(port_a.C_outflow); - + // Isenthalpic state transformation (no storage and no loss of energy) port_a.h_outflow = inStream(port_b.h_outflow); port_b.h_outflow = inStream(port_a.h_outflow); - + annotation ( Icon(graphics = {Rectangle(extent = {{-80, 80}, {80, -80}})}), - Documentation(info=" + Documentation( + info = "

      This is the base model for Damper_parallelBlades and Damper_opposedBlades strongly inspired from the PartialValve of Modelica Standard Library (MSL). The model is based on the IEC 534 / ISA-75.01.01-2007 standard for valve sizing. diff --git a/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/baseFunc.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/baseFunc.mo similarity index 67% rename from FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/baseFunc.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/baseFunc.mo index a5b57fd..13c8f97 100644 --- a/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/baseFunc.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/baseFunc.mo @@ -1,11 +1,17 @@ within TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses.ValveCharacteristics; -partial function baseFunc "Base class for valve characteristics" +partial function baseFunc + "Base class for valve characteristics" + extends Modelica.Icons.Function; - input Real pos(min=0, max=1) - "Opening position (0: closed, 1: fully open)"; - output Real rc "Relative flow coefficient (per unit)"; - annotation (Documentation(info=" + input Real pos(min = 0, max = 1) + "Opening position (0: closed, 1: fully open)"; + output Real rc + "Relative flow coefficient (per unit)"; + + annotation ( + Documentation( + info = "

      This is a partial function that defines the interface of valve characteristics. The function returns \"rc = valveCharacteristic\" as function of the @@ -20,4 +26,5 @@ m_flow = rc * Av * sqrt(rho * dp) ")); + end baseFunc; diff --git a/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.mo similarity index 65% rename from FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.mo index f57b521..b47d5c7 100644 --- a/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.mo @@ -1,5 +1,8 @@ within TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses; -package ValveCharacteristics "Functions for valve characteristics" +package ValveCharacteristics + "Functions for valve characteristics" + extends Modelica.Icons.VariantsPackage; + end ValveCharacteristics; diff --git a/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.order similarity index 100% rename from FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/package.order diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/polynomial.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/polynomial.mo new file mode 100644 index 0000000..d2133b7 --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/ValveCharacteristics/polynomial.mo @@ -0,0 +1,25 @@ +within TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses.ValveCharacteristics; + +function polynomial + "Polynomial characteristic: rc = c[1] + c[2]*pos + c[3]*pos^2 + ...." + + extends baseFunc; + input Real c[:] + "Polynomial coefficients"; + +algorithm + + rc := c[size(c, 1)]; + for i in size(c, 1) - 1 : -1 : 1 loop + rc := c[i] + pos * rc; + end for; + + annotation ( + Documentation( + info = " +

      +Evaluate a polynomial using Horner's scheme. +

      +")); + +end polynomial; diff --git a/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/package.mo new file mode 100644 index 0000000..dd7d8c9 --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/package.mo @@ -0,0 +1,8 @@ +within TAeZoSysPro.FluidDynamics.Components.Valves; + +package BaseClasses + "Base classes used in the Valves package (only of interest to build new component models)" + + extends Modelica.Icons.BasesPackage; + +end BaseClasses; diff --git a/FluidDynamics/Components/Valves/BaseClasses/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/package.order similarity index 100% rename from FluidDynamics/Components/Valves/BaseClasses/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/BaseClasses/package.order diff --git a/FluidDynamics/Components/Valves/CommissioningDamper.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/CommissioningDamper.mo similarity index 53% rename from FluidDynamics/Components/Valves/CommissioningDamper.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/CommissioningDamper.mo index e52fe5f..42354c8 100644 --- a/FluidDynamics/Components/Valves/CommissioningDamper.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/CommissioningDamper.mo @@ -1,31 +1,51 @@ within TAeZoSysPro.FluidDynamics.Components.Valves; model CommissioningDamper - replaceable package Medium = TAeZoSysPro.Media.MyMedia "Medium in the component"; + + replaceable package Medium = TAeZoSysPro.Media.MyMedia + "Medium in the component"; // User defined parameters - parameter Medium.MassFlowRate m_flow_nominal "Nominal mass flow rate targeted" annotation(Dialog(group="Nominal operating point")) ; - parameter Modelica.SIunits.Pressure dp_ref=1e5 "Reference pressure drop (Standard states 1e5 Pa )" annotation(Dialog(group="Nominal operating point")) ; - parameter Modelica.SIunits.Temperature T_ref=293.15 "reference temperature used for computed Kv"annotation(Dialog(group="Nominal operating point")); - parameter Modelica.SIunits.Density rho_ref=Medium.density_pTX(Medium.p_default, T_ref, Medium.X_default) annotation(Dialog(group="Nominal operating point")); - parameter Modelica.SIunits.Pressure dp_small = 1 "Regularisation of zero flow" annotation(Dialog(tab="Advanced")); - parameter Real Kv(fixed = false) "(Metric) flow coefficient"; - parameter Real Fxt=0.5 "F_gamma*xt critical ratio"; - + parameter Medium.MassFlowRate m_flow_nominal + "Nominal mass flow rate targeted" + annotation (Dialog(group = "Nominal operating point")); + parameter Modelica.SIunits.Pressure dp_ref = 1e5 + "Reference pressure drop (Standard states 1e5 Pa )" + annotation (Dialog(group = "Nominal operating point")); + parameter Modelica.SIunits.Temperature T_ref = 293.15 + "reference temperature used for computed Kv" + annotation (Dialog(group = "Nominal operating point")); + parameter Modelica.SIunits.Density rho_ref = Medium.density_pTX(Medium.p_default, T_ref, Medium.X_default) + annotation (Dialog(group = "Nominal operating point")); + parameter Modelica.SIunits.Pressure dp_small = 1 + "Regularisation of zero flow" + annotation (Dialog(tab = "Advanced")); + parameter Real Kv(fixed = false) + "(Metric) flow coefficient"; + parameter Real Fxt = 0.5 + "F_gamma*xt critical ratio"; + // Internal variables - Modelica.SIunits.Pressure dp(start=100) "Pressure difference between port_a and port_b (= port_a.p - port_b.p)" ; - Medium.MassFlowRate m_flow(start = m_flow_nominal) "Mass flow rate in design flow direction"; - + Modelica.SIunits.Pressure dp(start = 100) + "Pressure difference between port_a and port_b (= port_a.p - port_b.p)"; + Medium.MassFlowRate m_flow(start = m_flow_nominal) + "Mass flow rate in design flow direction"; + // Imported modules - Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(extent = {{110, -10}, {90, 10}}, rotation = 0), iconTransformation(extent = {{110, -10}, {90, 10}}, rotation = 0))); - Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0), iconTransformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_b port_b(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(extent = {{110, -10}, {90, 10}}, rotation = 0), iconTransformation(extent = {{110, -10}, {90, 10}}, rotation = 0))); + Modelica.Fluid.Interfaces.FluidPort_a port_a(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0), iconTransformation(extent = {{-110, -10}, {-90, 10}}, rotation = 0))); protected - Real xs "Saturated pressure drop ratio"; - Real Y "Compressibility factor"; + + Real xs + "Saturated pressure drop ratio"; + Real Y + "Compressibility factor"; /* initial equation block comment : + was initially intented to help homotopy function inversion @@ -46,42 +66,43 @@ protected // X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))})))) ; equation + // - dp = port_a.p - port_b.p ; - xs = max(-Fxt, min(dp/max(port_a.p, port_b.p), Fxt)); - Y = 1 - abs(xs)/(3*Fxt); - + dp = port_a.p - port_b.p; + xs = max(-Fxt, min(dp / max(port_a.p, port_b.p), Fxt)); + Y = 1 - abs(xs) / (3 * Fxt); + // multiply volumetric flow by rho and integrate it in ssqrt to avoid two call to Medium.Density - m_flow = homotopy(Kv/3600.0 * sqrt(rho_ref) * Y * sqrt(1.0/dp_ref) * Modelica.Fluid.Utilities.regRoot2( - x = dp, - x_small = dp_small, - k1 = Medium.density_phX( - p = port_a.p, - h = inStream(port_a.h_outflow), - X = cat(1, inStream(port_a.Xi_outflow), {1 - sum(inStream(port_a.Xi_outflow))})) , - k2 = Medium.density_phX( - p = port_b.p, - h = inStream(port_b.h_outflow), - X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))}))), - - Kv/3600*dp/dp_ref ); + m_flow = homotopy( + Kv / 3600.0 * sqrt(rho_ref) * Y * sqrt(1.0 / dp_ref) * Modelica.Fluid.Utilities.regRoot2( + x = dp, + x_small = dp_small, + k1 = Medium.density_phX( + p = port_a.p, + h = inStream(port_a.h_outflow), + X = cat(1, inStream(port_a.Xi_outflow), {1 - sum(inStream(port_a.Xi_outflow))})), + k2 = Medium.density_phX( + p = port_b.p, + h = inStream(port_b.h_outflow), + X = cat(1, inStream(port_b.Xi_outflow), {1 - sum(inStream(port_b.Xi_outflow))}))), + Kv / 3600 * dp / dp_ref); // Port handover - port_a.m_flow = m_flow ; - port_a.m_flow + port_b.m_flow = 0.0 ; + port_a.m_flow = m_flow; + port_a.m_flow + port_b.m_flow = 0.0; port_a.h_outflow = inStream(port_b.h_outflow); - port_b.h_outflow = inStream(port_a.h_outflow); - + port_b.h_outflow = inStream(port_a.h_outflow); + port_a.Xi_outflow = inStream(port_b.Xi_outflow); port_b.Xi_outflow = inStream(port_a.Xi_outflow); port_a.C_outflow = inStream(port_b.C_outflow); port_b.C_outflow = inStream(port_a.C_outflow); -annotation( - Documentation(info= -" + annotation ( + Documentation( + info = " CommissioningDamper @@ -104,4 +125,4 @@ annotation( Icon(graphics = {Rectangle(extent = {{-80, 80}, {80, -80}}), Bitmap(extent = {{-60, 60}, {60, -60}}, fileName = "modelica://TAeZoSysPro/FluidDynamics/Components/Valves/setting.png")}), Diagram); -end CommissioningDamper; \ No newline at end of file +end CommissioningDamper; diff --git a/FluidDynamics/Components/Valves/Damper_opposedBlades.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/Damper_opposedBlades.mo similarity index 62% rename from FluidDynamics/Components/Valves/Damper_opposedBlades.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/Damper_opposedBlades.mo index 7588f36..35c3987 100644 --- a/FluidDynamics/Components/Valves/Damper_opposedBlades.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/Damper_opposedBlades.mo @@ -1,72 +1,87 @@ within TAeZoSysPro.FluidDynamics.Components.Valves; model Damper_opposedBlades + extends TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses.PartialDamper( - redeclare function valveCharacteristic = TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses.ValveCharacteristics.polynomial( - c = {0, 0, 0.829, -1.7231, 1.8941}) ) ; + redeclare function valveCharacteristic = TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses.ValveCharacteristics.polynomial( + c = {0, 0, 0.829, -1.7231, 1.8941})); import Modelica.Fluid.Types.CvTypes; - parameter Medium.AbsolutePressure p_nominal "Nominal inlet pressure" annotation(Dialog(group="Nominal operating point")); - parameter Real Fxt=0.5 "F_gamma*xt critical ratio at full opening"; - - Real x "Pressure drop ratio"; - Real xs "Saturated pressure drop ratio"; - Real Y "Compressibility factor"; - Medium.AbsolutePressure p "Inlet pressure"; - Real relativeFlowCoefficient, d_a ; + parameter Medium.AbsolutePressure p_nominal + "Nominal inlet pressure" + annotation (Dialog(group = "Nominal operating point")); + parameter Real Fxt = 0.5 + "F_gamma*xt critical ratio at full opening"; + + Real x + "Pressure drop ratio"; + Real xs + "Saturated pressure drop ratio"; + Real Y + "Compressibility factor"; + Medium.AbsolutePressure p + "Inlet pressure"; + Real relativeFlowCoefficient, d_a; protected - parameter Real Fxt_nominal(fixed=false) "Nominal Fxt"; - parameter Real x_nominal(fixed=false) "Nominal pressure drop ratio"; - parameter Real xs_nominal(fixed=false) + + parameter Real Fxt_nominal(fixed = false) + "Nominal Fxt"; + parameter Real x_nominal(fixed = false) + "Nominal pressure drop ratio"; + parameter Real xs_nominal(fixed = false) "Nominal saturated pressure drop ratio"; - parameter Real Y_nominal(fixed=false) "Nominal compressibility factor"; - + parameter Real Y_nominal(fixed = false) + "Nominal compressibility factor"; + initial equation + if CvData == CvTypes.OpPoint then // Determination of Av by the nominal operating point conditions - Fxt_nominal = Fxt ; - x_nominal = dp_nominal/p_nominal; + Fxt_nominal = Fxt; + x_nominal = dp_nominal / p_nominal; xs_nominal = smooth(0, if x_nominal > Fxt_nominal then Fxt_nominal else x_nominal); - Y_nominal = 1 - abs(xs_nominal)/(3*Fxt_nominal); - m_flow_nominal = valveCharacteristic(opening_nominal)*Av*Y_nominal*sqrt(rho_nominal)*Modelica.Fluid.Utilities.regRoot(p_nominal*xs_nominal, dp_small); + Y_nominal = 1 - abs(xs_nominal) / (3 * Fxt_nominal); + m_flow_nominal = valveCharacteristic(opening_nominal) * Av * Y_nominal * sqrt(rho_nominal) * Modelica.Fluid.Utilities.regRoot(p_nominal * xs_nominal, dp_small); else // Dummy values - Fxt_nominal = 0 ; + Fxt_nominal = 0; x_nominal = 0; xs_nominal = 0; Y_nominal = 0; end if; - + equation + p = max(port_a.p, port_b.p); - x = dp/p; + x = dp / p; xs = max(-Fxt, min(x, Fxt)); - Y = 1 - abs(xs)/(3*Fxt); - + Y = 1 - abs(xs) / (3 * Fxt); + if CvData == CvTypes.OpPoint then - Kv = m_flow_nominal / (N6*Y_nominal*sqrt(xs*p_nominal*rho_nominal)) ; - end if ; - relativeFlowCoefficient = valveCharacteristic(opening) ; - d_a = Medium.density(state_a) ; + Kv = m_flow_nominal / (N6 * Y_nominal * sqrt(xs * p_nominal * rho_nominal)); + end if; + relativeFlowCoefficient = valveCharacteristic(opening); + d_a = Medium.density(state_a); // m_flow = valveCharacteristic(opening)*Av*Y*sqrt(p*xs*d); if checkValve then m_flow = homotopy( - valveCharacteristic(opening) * Av * Y * sqrt(Medium.density(state_a)) * (if xs>=0 then Modelica.Fluid.Utilities.regRoot(p*xs, dp_small) else 0), - valveCharacteristic(opening) * m_flow_nominal * dp/dp_nominal); - + valveCharacteristic(opening) * Av * Y * sqrt(Medium.density(state_a)) * (if xs >= 0 then Modelica.Fluid.Utilities.regRoot(p * xs, dp_small) else 0), + valveCharacteristic(opening) * m_flow_nominal * dp / dp_nominal); + elseif not allowFlowReversal then m_flow = homotopy( - valveCharacteristic(opening) * Av * Y * sqrt(Medium.density(state_a)) * Modelica.Fluid.Utilities.regRoot(p*xs, dp_small), - valveCharacteristic(opening)*m_flow_nominal*dp/dp_nominal); - + valveCharacteristic(opening) * Av * Y * sqrt(Medium.density(state_a)) * Modelica.Fluid.Utilities.regRoot(p * xs, dp_small), + valveCharacteristic(opening) * m_flow_nominal * dp / dp_nominal); + else m_flow = homotopy( - valveCharacteristic(opening) * Av * Y * Modelica.Fluid.Utilities.regRoot2(p*xs, dp_small, Medium.density(state_a), Medium.density(state_b)), - valveCharacteristic(opening)*m_flow_nominal*dp/dp_nominal); + valveCharacteristic(opening) * Av * Y * Modelica.Fluid.Utilities.regRoot2(p * xs, dp_small, Medium.density(state_a), Medium.density(state_b)), + valveCharacteristic(opening) * m_flow_nominal * dp / dp_nominal); end if; -annotation(Documentation(info= -" + annotation ( + Documentation( + info = "

      This component models a blade damper where the blades move in opposition according to the IEC 534/ISA S.75 standards for valve sizing, compressible fluid, no phase change, also covering choked-flow conditions.

      diff --git a/FluidDynamics/Components/Valves/Damper_parallelBlades.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/Damper_parallelBlades.mo similarity index 64% rename from FluidDynamics/Components/Valves/Damper_parallelBlades.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/Damper_parallelBlades.mo index 982d5ae..9039b7c 100644 --- a/FluidDynamics/Components/Valves/Damper_parallelBlades.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/Damper_parallelBlades.mo @@ -1,73 +1,87 @@ within TAeZoSysPro.FluidDynamics.Components.Valves; model Damper_parallelBlades + extends TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses.PartialDamper( redeclare function valveCharacteristic = TAeZoSysPro.FluidDynamics.Components.Valves.BaseClasses.ValveCharacteristics.polynomial( - c = {0, 0.5082, -0.5258, 1.0667, -0.0491}) ) ; + c = {0, 0.5082, -0.5258, 1.0667, -0.0491})); import Modelica.Fluid.Types.CvTypes; - parameter Medium.AbsolutePressure p_nominal "Nominal inlet pressure" annotation(Dialog(group="Nominal operating point")); - parameter Real Fxt=0.5 "F_gamma*xt critical ratio at full opening"; - - Real x "Pressure drop ratio"; - Real xs "Saturated pressure drop ratio"; - Real Y "Compressibility factor"; - Medium.AbsolutePressure p "Inlet pressure"; - Real relativeFlowCoefficient, d_a ; + parameter Medium.AbsolutePressure p_nominal + "Nominal inlet pressure" + annotation (Dialog(group = "Nominal operating point")); + parameter Real Fxt = 0.5 + "F_gamma*xt critical ratio at full opening"; + + Real x + "Pressure drop ratio"; + Real xs + "Saturated pressure drop ratio"; + Real Y + "Compressibility factor"; + Medium.AbsolutePressure p + "Inlet pressure"; + Real relativeFlowCoefficient, d_a; protected - parameter Real Fxt_nominal(fixed=false) "Nominal Fxt"; - parameter Real x_nominal(fixed=false) "Nominal pressure drop ratio"; - parameter Real xs_nominal(fixed=false) + + parameter Real Fxt_nominal(fixed = false) + "Nominal Fxt"; + parameter Real x_nominal(fixed = false) + "Nominal pressure drop ratio"; + parameter Real xs_nominal(fixed = false) "Nominal saturated pressure drop ratio"; - parameter Real Y_nominal(fixed=false) "Nominal compressibility factor"; - + parameter Real Y_nominal(fixed = false) + "Nominal compressibility factor"; + initial equation + if CvData == CvTypes.OpPoint then // Determination of Av by the nominal operating point conditions - Fxt_nominal = Fxt ; - x_nominal = dp_nominal/p_nominal; + Fxt_nominal = Fxt; + x_nominal = dp_nominal / p_nominal; xs_nominal = smooth(0, if x_nominal > Fxt_nominal then Fxt_nominal else x_nominal); - Y_nominal = 1 - abs(xs_nominal)/(3*Fxt_nominal); - m_flow_nominal = valveCharacteristic(opening_nominal)*Av*Y_nominal*sqrt(rho_nominal)*Modelica.Fluid.Utilities.regRoot(p_nominal*xs_nominal, dp_small); + Y_nominal = 1 - abs(xs_nominal) / (3 * Fxt_nominal); + m_flow_nominal = valveCharacteristic(opening_nominal) * Av * Y_nominal * sqrt(rho_nominal) * Modelica.Fluid.Utilities.regRoot(p_nominal * xs_nominal, dp_small); else // Dummy values - Fxt_nominal = 0 ; + Fxt_nominal = 0; x_nominal = 0; xs_nominal = 0; Y_nominal = 0; end if; - + equation + p = max(port_a.p, port_b.p); - x = dp/p; + x = dp / p; xs = max(-Fxt, min(x, Fxt)); - Y = 1 - abs(xs)/(3*Fxt); - + Y = 1 - abs(xs) / (3 * Fxt); + if CvData == CvTypes.OpPoint then - Kv = m_flow_nominal / (N6*Y_nominal*sqrt(xs*p_nominal*rho_nominal)) ; - end if ; - relativeFlowCoefficient = valveCharacteristic(opening) ; - d_a = Medium.density(state_a) ; + Kv = m_flow_nominal / (N6 * Y_nominal * sqrt(xs * p_nominal * rho_nominal)); + end if; + relativeFlowCoefficient = valveCharacteristic(opening); + d_a = Medium.density(state_a); // m_flow = valveCharacteristic(opening)*Av*Y*sqrt(p*xs*d); if checkValve then m_flow = homotopy( - valveCharacteristic(opening) * Av * Y * sqrt(Medium.density(state_a)) * (if xs>=0 then Modelica.Fluid.Utilities.regRoot(p*xs, dp_small) else 0), - valveCharacteristic(opening) * m_flow_nominal * dp/dp_nominal); - + valveCharacteristic(opening) * Av * Y * sqrt(Medium.density(state_a)) * (if xs >= 0 then Modelica.Fluid.Utilities.regRoot(p * xs, dp_small) else 0), + valveCharacteristic(opening) * m_flow_nominal * dp / dp_nominal); + elseif not allowFlowReversal then m_flow = homotopy( - valveCharacteristic(opening) * Av * Y * sqrt(Medium.density(state_a)) * Modelica.Fluid.Utilities.regRoot(p*xs, dp_small), - valveCharacteristic(opening)*m_flow_nominal*dp/dp_nominal); - + valveCharacteristic(opening) * Av * Y * sqrt(Medium.density(state_a)) * Modelica.Fluid.Utilities.regRoot(p * xs, dp_small), + valveCharacteristic(opening) * m_flow_nominal * dp / dp_nominal); + else m_flow = homotopy( - valveCharacteristic(opening) * Av * Y * Modelica.Fluid.Utilities.regRoot2(p*xs, dp_small, Medium.density(state_a), Medium.density(state_b)), - valveCharacteristic(opening)*m_flow_nominal*dp/dp_nominal); + valveCharacteristic(opening) * Av * Y * Modelica.Fluid.Utilities.regRoot2(p * xs, dp_small, Medium.density(state_a), Medium.density(state_b)), + valveCharacteristic(opening) * m_flow_nominal * dp / dp_nominal); end if; -annotation( - Documentation(info= -" + annotation ( + Documentation( + info = "

      This component models a blade damper where the blades move in parallel according to the IEC 534/ISA S.75 standards for valve sizing, compressible fluid, no phase change, also covering choked-flow conditions.

      diff --git a/FluidDynamics/Components/Valves/damper_flow_characteristic_reconstruction.xlsx b/src/TAeZoSysPro/FluidDynamics/Components/Valves/damper_flow_characteristic_reconstruction.xlsx similarity index 100% rename from FluidDynamics/Components/Valves/damper_flow_characteristic_reconstruction.xlsx rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/damper_flow_characteristic_reconstruction.xlsx diff --git a/FluidDynamics/Components/Valves/opposed_blade_damper_flow_characteristic_CIBCE.png b/src/TAeZoSysPro/FluidDynamics/Components/Valves/opposed_blade_damper_flow_characteristic_CIBCE.png similarity index 100% rename from FluidDynamics/Components/Valves/opposed_blade_damper_flow_characteristic_CIBCE.png rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/opposed_blade_damper_flow_characteristic_CIBCE.png diff --git a/FluidDynamics/Components/Valves/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/Valves/package.mo similarity index 98% rename from FluidDynamics/Components/Valves/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/package.mo index 6b37fab..2239f94 100644 --- a/FluidDynamics/Components/Valves/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Components/Valves/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics.Components; package Valves + extends Modelica.Icons.VariantsPackage; + end Valves; diff --git a/FluidDynamics/Components/Valves/package.order b/src/TAeZoSysPro/FluidDynamics/Components/Valves/package.order similarity index 100% rename from FluidDynamics/Components/Valves/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/package.order diff --git a/FluidDynamics/Components/Valves/parallel_blade_damper_flow_characteristic_CIBCE.png b/src/TAeZoSysPro/FluidDynamics/Components/Valves/parallel_blade_damper_flow_characteristic_CIBCE.png similarity index 100% rename from FluidDynamics/Components/Valves/parallel_blade_damper_flow_characteristic_CIBCE.png rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/parallel_blade_damper_flow_characteristic_CIBCE.png diff --git a/FluidDynamics/Components/Valves/setting.png b/src/TAeZoSysPro/FluidDynamics/Components/Valves/setting.png similarity index 100% rename from FluidDynamics/Components/Valves/setting.png rename to src/TAeZoSysPro/FluidDynamics/Components/Valves/setting.png diff --git a/FluidDynamics/Components/package.mo b/src/TAeZoSysPro/FluidDynamics/Components/package.mo similarity index 100% rename from FluidDynamics/Components/package.mo rename to src/TAeZoSysPro/FluidDynamics/Components/package.mo diff --git a/FluidDynamics/Components/package.order b/src/TAeZoSysPro/FluidDynamics/Components/package.order similarity index 100% rename from FluidDynamics/Components/package.order rename to src/TAeZoSysPro/FluidDynamics/Components/package.order diff --git a/FluidDynamics/Examples/Pressure_coocker.mo b/src/TAeZoSysPro/FluidDynamics/Examples/Pressure_coocker.mo similarity index 88% rename from FluidDynamics/Examples/Pressure_coocker.mo rename to src/TAeZoSysPro/FluidDynamics/Examples/Pressure_coocker.mo index 27aed4c..85a3ad7 100644 --- a/FluidDynamics/Examples/Pressure_coocker.mo +++ b/src/TAeZoSysPro/FluidDynamics/Examples/Pressure_coocker.mo @@ -1,59 +1,91 @@ within TAeZoSysPro.FluidDynamics.Examples; model Pressure_coocker + extends Modelica.Icons.Example; - TAeZoSysPro.FluidDynamics.BasesClasses.GasNode_two_phases gasNode_two_phases(V = 0.0191) annotation( - Placement(visible = true, transformation(origin = {-30, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.LiquidNode liquidNode(V_start = 0.0021, nPorts = 1) annotation( - Placement(visible = true, transformation(origin = {-10, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.BasesClasses.Interface_liq_gas interface_liq_gas(A = 3.14 * 0.3 ^ 2 / 4) annotation( - Placement(visible = true, transformation(origin = {-10, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Components.Buildings.Wall wall(A = 0.4239, Lc = 0.3,N = 2, Th = 0.003, cp = 480, d = 7800, energyDynamics = TAeZoSysPro.HeatTransfer.Types.Dynamics.FixedInitial, eps_a = 0.3, eps_b = 0.3, k = 50, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.uniform) annotation( - Placement(visible = true, transformation(origin = {50, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Sources.Atmosphere atmosphere annotation( - Placement(visible = true, transformation(origin = {90, 70}, extent = {{10, -10}, {-10, 10}}, rotation = 0))); - inner TAeZoSysPro.HeatTransfer.Components.FviewCalculator fviewCalculator(N = 2) annotation( - Placement(visible = true, transformation(origin = {25, -25}, extent = {{-5, -5}, {5, 5}}, rotation = -90))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollNode carrollNode annotation( - Placement(visible = true, transformation(origin = {10, 10}, extent = {{-8, -8}, {8, 8}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Sources.FixedHeatFlow heat_load(Q_flow = 1000) annotation( - Placement(visible = true, transformation(origin = {-50, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.FluidDynamics.Components.Orifices.SimpleOpening simpleOpening(A = 5e-5, massDynamics = TAeZoSysPro.HeatTransfer.Types.Dynamics.SteadyState) annotation( - Placement(visible = true, transformation(origin = {-30, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + package Medium = TAeZoSysPro.Media.Air.MoistAir + "Condensable medium required by the two-phase gas node"; + TAeZoSysPro.FluidDynamics.BasesClasses.GasNode_two_phases gasNode_two_phases(redeclare package Medium = Medium, V = 0.0191) + annotation ( + Placement(visible = true, transformation(origin = {-30, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.LiquidNode liquidNode(redeclare package MediumGas = Medium, V_start = 0.0021, nPorts = 1) + annotation ( + Placement(visible = true, transformation(origin = {-10, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.BasesClasses.Interface_liq_gas interface_liq_gas(redeclare package Medium = Medium, A = 3.14 * 0.3 ^ 2 / 4) + annotation ( + Placement(visible = true, transformation(origin = {-10, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Components.Buildings.Wall wall(redeclare package Medium = Medium, A = 0.4239, Lc = 0.3, N = 2, Th = 0.003, cp = 480, d = 7800, energyDynamics = TAeZoSysPro.HeatTransfer.Types.Dynamics.FixedInitial, eps_a = 0.3, eps_b = 0.3, k = 50, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.uniform) + annotation ( + Placement(visible = true, transformation(origin = {50, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Sources.Atmosphere atmosphere(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {90, 70}, extent = {{10, -10}, {-10, 10}}, rotation = 0))); + inner TAeZoSysPro.HeatTransfer.Components.FviewCalculator fviewCalculator(N = 2) + annotation ( + Placement(visible = true, transformation(origin = {25, -25}, extent = {{-5, -5}, {5, 5}}, rotation = -90))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollNode carrollNode + annotation ( + Placement(visible = true, transformation(origin = {10, 10}, extent = {{-8, -8}, {8, 8}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Sources.FixedHeatFlow heat_load(Q_flow = 1000) + annotation ( + Placement(visible = true, transformation(origin = {-50, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Components.Orifices.Opening simpleOpening(redeclare package Medium = Medium, A = 5e-5, massDynamics = TAeZoSysPro.HeatTransfer.Types.Dynamics.SteadyState) + annotation ( + Placement(visible = true, transformation(origin = {-30, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + equation - connect(liquidNode.heatPort, interface_liq_gas.heatPort_a) annotation( - Line(points = {{-14, -80}, {-16, -80}, {-16, -58}, {-16, -58}}, color = {191, 0, 0})); - connect(liquidNode.fluidPort[1], interface_liq_gas.fluidPort_a) annotation( - Line(points = {{-4, -80}, {-4, -80}, {-4, -58}, {-4, -58}}, color = {0, 127, 255})); - connect(interface_liq_gas.A_wall, fviewCalculator.A_wall[1]) annotation( - Line(points = {{-14, -40}, {-14, -40}, {-14, -20}, {24, -20}, {24, -20}}, color = {0, 0, 127})); - connect(interface_liq_gas.F_view, fviewCalculator.F_view[1]) annotation( - Line(points = {{-10, -40}, {-10, -40}, {-10, -30}, {26, -30}, {26, -30}}, color = {0, 0, 127})); - connect(wall.A_wall_a, fviewCalculator.A_wall[2]) annotation( - Line(points = {{40, 4}, {26, 4}, {26, -20}, {24, -20}}, color = {0, 0, 127})); - connect(wall.F_view_a, fviewCalculator.F_view[2]) annotation( - Line(points = {{40, 8}, {36, 8}, {36, 6}, {34, 6}, {34, 0}, {36, 0}, {36, -30}, {26, -30}}, color = {0, 0, 127})); - connect(interface_liq_gas.port_rad, carrollNode.port_a) annotation( - Line(points = {{-16, -40}, {-18, -40}, {-18, -12}, {10, -12}, {10, 10}, {10, 10}}, color = {191, 0, 0})); - connect(interface_liq_gas.flowPort_b, gasNode_two_phases.flowPort) annotation( - Line(points = {{-2, -40}, {-4, -40}, {-4, -32}, {-2, -32}, {-2, -10}, {-4, -10}, {-4, 10}, {-32, 10}, {-32, 10}}, color = {0, 85, 255})); - connect(wall.port_a, gasNode_two_phases.flowPort) annotation( - Line(points = {{40, 18}, {-4, 18}, {-4, 10}, {-32, 10}, {-32, 10}}, color = {0, 85, 255})); - connect(wall.A_wall_b, wall.F_view_b) annotation( - Line(points = {{60, 4}, {64, 4}, {64, 8}, {60, 8}, {60, 8}}, color = {0, 0, 127})); - connect(wall.port_b, atmosphere.Flowport) annotation( - Line(points = {{60, 18}, {70, 18}, {70, 70}, {90, 70}, {90, 70}}, color = {0, 85, 255})); - connect(wall.port_a_rad, carrollNode.port_a) annotation( - Line(points = {{42, 2}, {10, 2}, {10, 10}, {10, 10}}, color = {191, 0, 0})); - connect(wall.port_b_rad, wall.port_surface_b) annotation( - Line(points = {{60, 2}, {66, 2}, {66, 12}, {54, 12}, {54, 12}}, color = {191, 0, 0})); - connect(heat_load.port, liquidNode.heatPort) annotation( - Line(points = {{-40, -90}, {-32, -90}, {-32, -80}, {-14, -80}, {-14, -80}}, color = {191, 0, 0})); - connect(simpleOpening.port_b, atmosphere.Flowport) annotation( - Line(points = {{-22, 70}, {90, 70}, {90, 70}, {90, 70}}, color = {0, 85, 255})); - connect(simpleOpening.port_a, gasNode_two_phases.flowPort) annotation( - Line(points = {{-36, 70}, {-50, 70}, {-50, 10}, {-32, 10}, {-32, 10}}, color = {0, 85, 255})); -annotation( + + connect(liquidNode.heatPort, interface_liq_gas.heatPort_a) + annotation ( + Line(points = {{-14, -80}, {-16, -80}, {-16, -58}, {-16, -58}}, color = {191, 0, 0})); + connect(liquidNode.fluidPort[1], interface_liq_gas.fluidPort_a) + annotation ( + Line(points = {{-4, -80}, {-4, -80}, {-4, -58}, {-4, -58}}, color = {0, 127, 255})); + connect(interface_liq_gas.A_wall, fviewCalculator.A_wall[1]) + annotation ( + Line(points = {{-14, -40}, {-14, -40}, {-14, -20}, {24, -20}, {24, -20}}, color = {0, 0, 127})); + connect(interface_liq_gas.F_view, fviewCalculator.F_view[1]) + annotation ( + Line(points = {{-10, -40}, {-10, -40}, {-10, -30}, {26, -30}, {26, -30}}, color = {0, 0, 127})); + connect(wall.A_wall_a, fviewCalculator.A_wall[2]) + annotation ( + Line(points = {{40, 4}, {26, 4}, {26, -20}, {24, -20}}, color = {0, 0, 127})); + connect(wall.F_view_a, fviewCalculator.F_view[2]) + annotation ( + Line(points = {{40, 8}, {36, 8}, {36, 6}, {34, 6}, {34, 0}, {36, 0}, {36, -30}, {26, -30}}, color = {0, 0, 127})); + connect(interface_liq_gas.port_rad, carrollNode.port_a) + annotation ( + Line(points = {{-16, -40}, {-18, -40}, {-18, -12}, {10, -12}, {10, 10}, {10, 10}}, color = {191, 0, 0})); + connect(interface_liq_gas.flowPort_b, gasNode_two_phases.flowPort) + annotation ( + Line(points = {{-2, -40}, {-4, -40}, {-4, -32}, {-2, -32}, {-2, -10}, {-4, -10}, {-4, 10}, {-32, 10}, {-32, 10}}, color = {0, 85, 255})); + connect(wall.port_a, gasNode_two_phases.flowPort) + annotation ( + Line(points = {{40, 18}, {-4, 18}, {-4, 10}, {-32, 10}, {-32, 10}}, color = {0, 85, 255})); + connect(wall.A_wall_b, wall.F_view_b) + annotation ( + Line(points = {{60, 4}, {64, 4}, {64, 8}, {60, 8}, {60, 8}}, color = {0, 0, 127})); + connect(wall.port_b, atmosphere.Flowport) + annotation ( + Line(points = {{60, 18}, {70, 18}, {70, 70}, {90, 70}, {90, 70}}, color = {0, 85, 255})); + connect(wall.port_a_rad, carrollNode.port_a) + annotation ( + Line(points = {{42, 2}, {10, 2}, {10, 10}, {10, 10}}, color = {191, 0, 0})); + connect(wall.port_b_rad, wall.port_surface_b) + annotation ( + Line(points = {{60, 2}, {66, 2}, {66, 12}, {54, 12}, {54, 12}}, color = {191, 0, 0})); + connect(heat_load.port, liquidNode.heatPort) + annotation ( + Line(points = {{-40, -90}, {-32, -90}, {-32, -80}, {-14, -80}, {-14, -80}}, color = {191, 0, 0})); + connect(simpleOpening.port_b, atmosphere.Flowport) + annotation ( + Line(points = {{-22, 70}, {90, 70}, {90, 70}, {90, 70}}, color = {0, 85, 255})); + connect(simpleOpening.port_a, gasNode_two_phases.flowPort) + annotation ( + Line(points = {{-36, 70}, {-50, 70}, {-50, 10}, {-32, 10}, {-32, 10}}, color = {0, 85, 255})); + + annotation ( experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-6, Interval = 7.2), Diagram(coordinateSystem(extent = {{-200, -100}, {100, 100}}), graphics = {Bitmap(origin = {-140, 40}, rotation = 180, extent = {{40, 40}, {-40, -40}}, imageSource = "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"), Bitmap(origin = {-164, -56}, rotation = 180, extent = {{16, 24}, {-16, -24}}, imageSource = "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")})); + end Pressure_coocker; diff --git a/FluidDynamics/Examples/Pressure_coocker_data.xlsx b/src/TAeZoSysPro/FluidDynamics/Examples/Pressure_coocker_data.xlsx similarity index 100% rename from FluidDynamics/Examples/Pressure_coocker_data.xlsx rename to src/TAeZoSysPro/FluidDynamics/Examples/Pressure_coocker_data.xlsx diff --git a/FluidDynamics/Examples/package.mo b/src/TAeZoSysPro/FluidDynamics/Examples/package.mo similarity index 61% rename from FluidDynamics/Examples/package.mo rename to src/TAeZoSysPro/FluidDynamics/Examples/package.mo index cfa9a9e..20d288b 100644 --- a/FluidDynamics/Examples/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Examples/package.mo @@ -2,6 +2,6 @@ within TAeZoSysPro.FluidDynamics; package Examples - extends Modelica.Icons.ExamplesPackage ; + extends Modelica.Icons.ExamplesPackage; end Examples; diff --git a/FluidDynamics/Examples/package.order b/src/TAeZoSysPro/FluidDynamics/Examples/package.order similarity index 100% rename from FluidDynamics/Examples/package.order rename to src/TAeZoSysPro/FluidDynamics/Examples/package.order diff --git a/FluidDynamics/Functions/package.mo b/src/TAeZoSysPro/FluidDynamics/Functions/package.mo similarity index 84% rename from FluidDynamics/Functions/package.mo rename to src/TAeZoSysPro/FluidDynamics/Functions/package.mo index 494a6a6..eebe56b 100644 --- a/FluidDynamics/Functions/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Functions/package.mo @@ -2,9 +2,9 @@ within TAeZoSysPro.FluidDynamics; package Functions - extends Modelica.Icons.Package ; + extends Modelica.Icons.Package; - annotation( + annotation ( Icon(graphics = {Bitmap(extent = {{-80, 80}, {80, -80}}, fileName = "modelica://TAeZoSysPro/Information/HeatTransfer/Functions/image_package.png")}, coordinateSystem(initialScale = 0.1))); end Functions; diff --git a/FluidDynamics/Functions/package.order b/src/TAeZoSysPro/FluidDynamics/Functions/package.order similarity index 100% rename from FluidDynamics/Functions/package.order rename to src/TAeZoSysPro/FluidDynamics/Functions/package.order diff --git a/FluidDynamics/Functions/rootsPolyOrder3.mo b/src/TAeZoSysPro/FluidDynamics/Functions/rootsPolyOrder3.mo similarity index 63% rename from FluidDynamics/Functions/rootsPolyOrder3.mo rename to src/TAeZoSysPro/FluidDynamics/Functions/rootsPolyOrder3.mo index ca078aa..a3e2e10 100644 --- a/FluidDynamics/Functions/rootsPolyOrder3.mo +++ b/src/TAeZoSysPro/FluidDynamics/Functions/rootsPolyOrder3.mo @@ -1,76 +1,87 @@ within TAeZoSysPro.FluidDynamics.Functions; -function rootsPolyOrder3 "Find the roots of a 3 order polynome of kind ax3 + bx2 + cx + d = 0" +function rootsPolyOrder3 + "Find the roots of a 3 order polynome of kind ax3 + bx2 + cx + d = 0" - extends Modelica.Icons.Function ; + extends Modelica.Icons.Function; - input Real a "Polynom coefficients"; - input Real b "Polynom coefficients"; - input Real c "Polynom coefficients"; - input Real d "Polynom coefficients"; - output Real roots[3] ; + input Real a + "Polynom coefficients"; + input Real b + "Polynom coefficients"; + input Real c + "Polynom coefficients"; + input Real d + "Polynom coefficients"; + output Real roots[3]; protected - Real p, q ; - Real discriminant ; - Real x1 "First root of the polynom"; - Real x2 "Second roots of the polynom"; - Real x3 "Third roots of the polynom"; - + + Real p, q; + Real discriminant; + Real x1 + "First root of the polynom"; + Real x2 + "Second roots of the polynom"; + Real x3 + "Third roots of the polynom"; + algorithm -// default value - x1 := 0.0 ; - x2 := 0.0 ; - x3 := 0.0 ; - p := 0.0 ; - q := 0.0 ; - discriminant := 0.0 ; - -// check that is high enough to consider the polynom as a third order + + // default value + x1 := 0.0; + x2 := 0.0; + x3 := 0.0; + p := 0.0; + q := 0.0; + discriminant := 0.0; + + // check that is high enough to consider the polynom as a third order if abs(a) <= 1e-10 then /* 2nd order polynom */ if abs(b) <= 1e-10 then /* 1st order polynom */ - x1 := -d / c ; - + x1 := -d / c; + else /* 2nd order polynom */ - discriminant := c^2 - 4*b*d ; + discriminant := c ^ 2 - 4 * b * d; if discriminant < 0.0 then - assert(discriminant >= 0.0, "Negative discriminant, no real roots", AssertionLevel.error) ; - + assert(discriminant >= 0.0, "Negative discriminant, no real roots", AssertionLevel.error); + elseif discriminant == 0.0 then - x1 := -c / (2*b) ; - + x1 := -c / (2 * b); + else /*discriminant > 0.0 */ - x1 := (- c - sqrt(discriminant) ) / (2*b) ; - x2 := (- c + sqrt(discriminant) ) / (2*b) ; + x1 := (-c - sqrt(discriminant)) / (2 * b); + x2 := (-c + sqrt(discriminant)) / (2 * b); + + end if; + + end if; - end if ; - - end if ; - else /* 3rd order polynom */ -// first a change of variable is performed to derives to the following equation solvable via the Cardan method: X^3 + pX + q = 0 - p := (3*a*c - b^2) / (3*a^2) ; - q := (2*b^3 - 9*a*b*c + 27*a^2*d) / (27*a^3) ; - discriminant := -(27*q^2 + 4*p^3) ; + // first a change of variable is performed to derives to the following equation solvable via the Cardan method: X^3 + pX + q = 0 + p := (3 * a * c - b ^ 2) / (3 * a ^ 2); + q := (2 * b ^ 3 - 9 * a * b * c + 27 * a ^ 2 * d) / (27 * a ^ 3); + discriminant := -(27 * q ^ 2 + 4 * p ^ 3); if discriminant < 0.0 then // get only the real root and not the complex roots - x1 := ((-q + sqrt(-discriminant/27)) / 2)^(1/3) + ((-q - sqrt(-discriminant/27)) / 2)^(1/3) - b/(3*a) ; + x1 := ((-q + sqrt(-discriminant / 27)) / 2) ^ (1 / 3) + ((-q - sqrt(-discriminant / 27)) / 2) ^ (1 / 3) - b / (3 * a); elseif discriminant == 0.0 then - x1 := 3*q/p - b/(3*a) ; - x2 := -3*q/(2*p) - b/(3*a) ; - + x1 := 3 * q / p - b / (3 * a); + x2 := -3 * q / (2 * p) - b / (3 * a); + else /*discriminant > 0.0 */ - x1 := 2*sqrt(-p/3)*cos(acos(3*q/(2*p)*sqrt(-3/p))/3) - b / (3*a) ; - x2 := 2*sqrt(-p/3)*cos( (acos(3*q/(2*p)*sqrt(-3/p)) + 2*Modelica.Constants.pi) / 3) - b / (3*a) ; - x3 := 2*sqrt(-p/3)*cos( (acos(3*q/(2*p)*sqrt(-3/p)) - 2*Modelica.Constants.pi) / 3) - b / (3*a) ; - end if ; - - end if ; + x1 := 2 * sqrt(-p / 3) * cos(acos(3 * q / (2 * p) * sqrt(-3 / p)) / 3) - b / (3 * a); + x2 := 2 * sqrt(-p / 3) * cos((acos(3 * q / (2 * p) * sqrt(-3 / p)) + 2 * Modelica.Constants.pi) / 3) - b / (3 * a); + x3 := 2 * sqrt(-p / 3) * cos((acos(3 * q / (2 * p) * sqrt(-3 / p)) - 2 * Modelica.Constants.pi) / 3) - b / (3 * a); + end if; + + end if; - roots := {x1, x2, x3} ; + roots := {x1, x2, x3}; -annotation( - Documentation(info = " + annotation ( + Documentation( + info = " rootsPolyOrder3 @@ -157,6 +168,6 @@ annotation(

      -")) ; +")); end rootsPolyOrder3; diff --git a/FluidDynamics/Interfaces/FlowPort.mo b/src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort.mo similarity index 77% rename from FluidDynamics/Interfaces/FlowPort.mo rename to src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort.mo index 1da7716..041c5b2 100644 --- a/FluidDynamics/Interfaces/FlowPort.mo +++ b/src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort.mo @@ -1,16 +1,20 @@ within TAeZoSysPro.FluidDynamics.Interfaces; -connector FlowPort "Connector flow port" +connector FlowPort + "Connector flow port" - replaceable package Medium = Modelica.Media.Interfaces.PartialMedium "Medium model" annotation( - choicesAllMatching = true); + replaceable package Medium = Modelica.Media.Interfaces.PartialMedium + "Medium model" + annotation ( + choicesAllMatching = true); Medium.Temperature T; Medium.Density[Medium.nX] d; flow Medium.MassFlowRate[Medium.nX] m_flow; flow Modelica.SIunits.EnthalpyFlowRate H_flow; - - annotation( - Documentation(info = " + + annotation ( + Documentation( + info = " Basic definition of the connector.
      State variables:
        diff --git a/FluidDynamics/Interfaces/FlowPort_HeatPort_Converter.mo b/src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_HeatPort_Converter.mo similarity index 97% rename from FluidDynamics/Interfaces/FlowPort_HeatPort_Converter.mo rename to src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_HeatPort_Converter.mo index 55df440..07fa3e2 100644 --- a/FluidDynamics/Interfaces/FlowPort_HeatPort_Converter.mo +++ b/src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_HeatPort_Converter.mo @@ -1,21 +1,25 @@ within TAeZoSysPro.FluidDynamics.Interfaces; model FlowPort_HeatPort_Converter - replaceable package Medium = Modelica.Media.Air.MoistAir ; - TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort(redeclare package Medium = Medium) annotation( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort annotation( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + + replaceable package Medium = Modelica.Media.Air.MoistAir; + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_a flowPort(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); equation -flowPort.m_flow = fill(0.0, Medium.nX) ; -flowPort.H_flow + heatPort.Q_flow = 0.0 ; -flowPort.T = heatPort.T ; + flowPort.m_flow = fill(0.0, Medium.nX); + flowPort.H_flow + heatPort.Q_flow = 0.0; + flowPort.T = heatPort.T; -annotation( + annotation ( Icon(graphics = {Bitmap(origin = {-1, 1}, extent = {{-79, 79}, {81, -81}}, imageSource = "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")}), - Documentation(info = " + Documentation( + info = " FlowPort_HeatPort_Converter @@ -58,5 +62,5 @@ annotation( ")); - + end FlowPort_HeatPort_Converter; diff --git a/FluidDynamics/Interfaces/FlowPort_a.mo b/src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_a.mo similarity index 88% rename from FluidDynamics/Interfaces/FlowPort_a.mo rename to src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_a.mo index b44c091..1b6eb95 100644 --- a/FluidDynamics/Interfaces/FlowPort_a.mo +++ b/src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_a.mo @@ -1,11 +1,16 @@ within TAeZoSysPro.FluidDynamics.Interfaces; -connector FlowPort_a "Filled flow port (used upstream)" +connector FlowPort_a + "Filled flow port (used upstream)" + extends FlowPort; - annotation( - Documentation(info = " + + annotation ( + Documentation( + info = " Same as FlowPort, but icon allows to differentiate direction of flow. "), Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(lineColor = {0, 85, 255}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {100, -100}}), Ellipse(lineColor = {0, 0, 255}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-98, 98}, {98, -98}}, endAngle = 360)}), Diagram(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(lineColor = {0, 85, 255}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-50, 50}, {50, -50}}), Ellipse(lineColor = {0, 0, 255}, fillColor = {0, 0, 255}, fillPattern = FillPattern.Solid, extent = {{-48, 48}, {48, -48}}, endAngle = 360), Text(lineColor = {0, 0, 255}, extent = {{-100, 110}, {100, 50}}, textString = "%name")})); + end FlowPort_a; diff --git a/FluidDynamics/Interfaces/FlowPort_b.mo b/src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_b.mo similarity index 87% rename from FluidDynamics/Interfaces/FlowPort_b.mo rename to src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_b.mo index 97f7574..dd366e8 100644 --- a/FluidDynamics/Interfaces/FlowPort_b.mo +++ b/src/TAeZoSysPro/FluidDynamics/Interfaces/FlowPort_b.mo @@ -1,11 +1,16 @@ within TAeZoSysPro.FluidDynamics.Interfaces; -connector FlowPort_b "Hollow flow port (used downstream)" +connector FlowPort_b + "Hollow flow port (used downstream)" + extends FlowPort; - annotation( - Documentation(info = " + + annotation ( + Documentation( + info = " Same as FlowPort, but icon allows to differentiate direction of flow. "), Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(lineColor = {0, 85, 255}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {100, -100}}), Ellipse(lineColor = {0, 0, 255}, extent = {{-98, 98}, {98, -98}}, endAngle = 360)}), Diagram(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(lineColor = {0, 85, 255}, fillColor = {255, 255, 255}, fillPattern = FillPattern.Solid, extent = {{-50, 50}, {50, -50}}), Ellipse(lineColor = {0, 0, 255}, extent = {{-48, 48}, {48, -48}}, endAngle = 360), Text(lineColor = {0, 0, 255}, extent = {{-100, 110}, {100, 50}}, textString = "%name")})); + end FlowPort_b; diff --git a/FluidDynamics/Interfaces/package.mo b/src/TAeZoSysPro/FluidDynamics/Interfaces/package.mo similarity index 61% rename from FluidDynamics/Interfaces/package.mo rename to src/TAeZoSysPro/FluidDynamics/Interfaces/package.mo index b391c9f..e4180bb 100644 --- a/FluidDynamics/Interfaces/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Interfaces/package.mo @@ -2,6 +2,6 @@ within TAeZoSysPro.FluidDynamics; package Interfaces - extends Modelica.Icons.InterfacesPackage ; + extends Modelica.Icons.InterfacesPackage; end Interfaces; diff --git a/FluidDynamics/Interfaces/package.order b/src/TAeZoSysPro/FluidDynamics/Interfaces/package.order similarity index 100% rename from FluidDynamics/Interfaces/package.order rename to src/TAeZoSysPro/FluidDynamics/Interfaces/package.order diff --git a/src/TAeZoSysPro/FluidDynamics/Sources/Atmosphere.mo b/src/TAeZoSysPro/FluidDynamics/Sources/Atmosphere.mo new file mode 100644 index 0000000..77a14cd --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Sources/Atmosphere.mo @@ -0,0 +1,154 @@ +within TAeZoSysPro.FluidDynamics.Sources; + +model Atmosphere + + // Medium declaration + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + /*Get TAeZoSysPro reference moist air Media*/ + package Medium_MoistAirTAezo = TAeZoSysPro.Media.Air.MoistAir; + + // User defined parameters + parameter Boolean use_p_in = false + "Get the pressure from the input connector" + annotation ( + Evaluate = true, + HideResult = true, + choices(checkBox = true)); + parameter Boolean use_T_in = false + "Get the temperature from the input connector" + annotation ( + Evaluate = true, + HideResult = true, + choices(checkBox = true)); + parameter Boolean use_RH_in = false + "Get the relative humidity from the input connector" + annotation ( + Evaluate = true, + HideResult = true, + choices(checkBox = true)); + + parameter Modelica.SIunits.Temperature T = 293.15 + "Atmosphere temperature"; + parameter Modelica.SIunits.Pressure p = 101325 + "Atmosphere Pressure"; + parameter Real RH = 0.6 + "Atmosphere relative humidity - Only accounted if medium == Moist air"; + parameter Medium.MassFraction X[Medium.nX] = Medium.X_default + "usefull except for Moist Air"; + + parameter Integer nPorts = 0 + "Number of fluidport" + annotation (Dialog(connectorSizing = true)); + // Internal variables + Medium.ThermodynamicState state; + + // Imported module + Modelica.Fluid.Interfaces.FluidPort_a[nPorts] Fluidport(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-30, 26}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.FluidDynamics.Interfaces.FlowPort_b Flowport(redeclare package Medium = Medium) + annotation ( + Placement(visible = true, transformation(origin = {-26, -46}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b Heatport + annotation ( + Placement(visible = true, transformation(origin = {-44, -14}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -40}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput p_in if use_p_in + annotation ( + Placement(visible = true, transformation(origin = {-72, 56}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-95, 59}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput T_in if use_T_in + annotation ( + Placement(visible = true, transformation(origin = {-74, 14}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-95, -1}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput RH_in if use_RH_in + annotation ( + Placement(visible = true, transformation(origin = {-70, -30}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-95, -61}, extent = {{-15, -15}, {15, 15}}, rotation = 0))); + +protected + + /*Using TAeZoSysPro medium function ensure no fail with new OM frontend (function exist whatever medium used*/ + TAeZoSysPro.Media.Air.MoistAir.MassFraction X_moist[TAeZoSysPro.Media.Air.MoistAir.nX]; + + /*depending on chosen medium, parameter X vector to be adjusted*/ + Medium.MassFraction X_final[Medium.nX]; + + Modelica.Blocks.Interfaces.RealInput T_internal + "Temperature at ports. Needed to connect to conditional connector"; + Modelica.Blocks.Interfaces.RealInput p_internal + "Pressure at ports. Needed to connect to conditional connector"; + Modelica.Blocks.Interfaces.RealInput RH_internal + "Relative humidity at ports. Needed to connect to conditional connector"; + +equation + + connect(T_internal, T_in); + connect(p_internal, p_in); + connect(RH_internal, RH_in); + + if not use_p_in then + p_internal = p; + end if; + + if not use_T_in then + T_internal = T; + end if; + + if not use_RH_in then + RH_internal = RH; + end if; + + X_moist = cat(1, {TAeZoSysPro.Media.Air.MoistAir.massFraction_pTphi(p = p_internal, T = T_internal, phi = RH_internal)}, {1 - TAeZoSysPro.Media.Air.MoistAir.massFraction_pTphi(p = p_internal, T = T_internal, phi = RH_internal)}); + X_final = if Medium.mediumName == "Moist air" then X_moist else X; + state = Medium.setState_pTX( + p = p_internal, + T = T_internal, + X = X_final); + + // Ports handover + // Flowport + Flowport.T = T_internal; + Flowport.d = Medium.density(state) * X_final; + // Heatport + Heatport.T = T_internal; + // Fluidport + for i in 1 : nPorts loop + Fluidport[i].p = p_internal; + Fluidport[i].h_outflow = Medium.specificEnthalpy(state); + Fluidport[i].Xi_outflow = X_final[1 : Medium.nXi]; + end for; + + annotation ( + Icon(coordinateSystem(initialScale = 0.1), graphics = {Ellipse(origin = {-8, 23}, extent = {{-52, 37}, {68, -83}}, endAngle = 360), Text(origin = {-65, 87}, extent = {{-35, 13}, {165, -7}}, textString = "P=%p"), Text(origin = {-37, 33}, extent = {{-63, 47}, {137, 27}}, textString = "T=%T"), Text(origin = {-17, -97}, extent = {{-83, 17}, {117, -3}}, textString = "RH=%RH")}), + Documentation( + info = " + + + Atmosphere + + + +

        + This components supplies boundaries with prescribed temperature, pression and composition. +

        + +

        + If use_p_in is false (default option), the p parameter is used as boundary pressure, and the p_in input connector is disabled.
        + if use_p_in is true, then the p parameter is ignored, and the value provided by the input connector is used instead. +

        + +

        + The same thing goes for the temperature and composition. +

        + +

        + Note, that boundary temperature and mass fractions have only an effect if the mass flow is from the boundary into the port. + If mass is flowing from the port into the boundary, the boundary definitions, with exception of boundary pressure, do not have an effect. +

        + +

        + This module has been developped to be used with an Air or Moist air Media. Indeed, specific function are required when modelling moist air.
        + When modelling Moist Air, the atmosphere component can supply an over saturated ambiance (meanning that the ambiance contains liquid water = foggy). +

        + + +")); + +end Atmosphere; diff --git a/src/TAeZoSysPro/FluidDynamics/Sources/Boundary_p.mo b/src/TAeZoSysPro/FluidDynamics/Sources/Boundary_p.mo new file mode 100644 index 0000000..78c58a3 --- /dev/null +++ b/src/TAeZoSysPro/FluidDynamics/Sources/Boundary_p.mo @@ -0,0 +1,68 @@ +within TAeZoSysPro.FluidDynamics.Sources; + +model Boundary_p + "Boundary with prescribed pressure" + + replaceable package Medium = Modelica.Media.Water.WaterIF97_ph + "Medium model within the source" + annotation (choicesAllMatching = true); + parameter Integer nPorts = 0 + "Number of ports" + annotation (Dialog(connectorSizing = true)); + parameter Boolean use_p_in = false + "Get the pressure from the input connector" + annotation (Evaluate = true, HideResult = true, choices(checkBox = true)); + parameter Medium.AbsolutePressure p = Medium.p_default + "Fixed value of pressure" + annotation (Dialog(enable = not use_p_in)); + Modelica.Blocks.Interfaces.RealInput p_in if use_p_in + "Prescribed boundary pressure" + annotation ( + Placement(visible = true, transformation(extent = {{-140, 60}, {-100, 100}}, rotation = 0), iconTransformation(extent = {{-140, -18}, {-100, 22}}, rotation = 0))); + + Modelica.Fluid.Interfaces.FluidPorts_b ports[nPorts]( + redeclare each package Medium = Medium) + annotation ( + Placement(transformation(extent = {{90, 40}, {110, -40}}))); + +protected + + Modelica.Blocks.Interfaces.RealInput p_in_internal + "Needed to connect to conditional connector"; + +equation + + connect(p_in, p_in_internal); + if not use_p_in then + p_in_internal = p; + end if; + for i in 1 : nPorts loop + ports[i].p = p_in_internal; + ports[i].m_flow = 0.0; + ports[i].h_outflow = inStream(ports[i].h_outflow); + ports[i].Xi_outflow = inStream(ports[i].Xi_outflow); + ports[i].C_outflow = inStream(ports[i].C_outflow); + end for; + + annotation ( + defaultComponentName = "boundary_p", + Documentation( + info = " +

        +Component to set the pressure at ports. The m_flow is set to zero. The 'outflow' properties are set to 'inStream' properties. +

        +

        +This component is mainly used to set the pressure of a liquid node +

        + +"), + Icon( + coordinateSystem( + preserveAspectRatio = true, + extent = {{-100, -100}, {100, 100}}), + graphics = { + Ellipse(fillColor = {0, 127, 255}, fillPattern = FillPattern.Sphere, extent = {{-100, 100}, {100, -100}}, endAngle = 360), + Text(lineColor = {0, 0, 255}, extent = {{-150, 120}, {150, 160}}, textString = "%name"), + Text(origin = {-4, -72}, extent = {{-152, 134}, {-68, 94}}, textString = "p")})); + +end Boundary_p; diff --git a/FluidDynamics/Sources/package.mo b/src/TAeZoSysPro/FluidDynamics/Sources/package.mo similarity index 61% rename from FluidDynamics/Sources/package.mo rename to src/TAeZoSysPro/FluidDynamics/Sources/package.mo index d3d7a23..aa707ef 100644 --- a/FluidDynamics/Sources/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Sources/package.mo @@ -2,6 +2,6 @@ within TAeZoSysPro.FluidDynamics; package Sources - extends Modelica.Icons.SourcesPackage ; + extends Modelica.Icons.SourcesPackage; end Sources; diff --git a/FluidDynamics/Sources/package.order b/src/TAeZoSysPro/FluidDynamics/Sources/package.order similarity index 100% rename from FluidDynamics/Sources/package.order rename to src/TAeZoSysPro/FluidDynamics/Sources/package.order diff --git a/FluidDynamics/Utilities/package.mo b/src/TAeZoSysPro/FluidDynamics/Utilities/package.mo similarity index 98% rename from FluidDynamics/Utilities/package.mo rename to src/TAeZoSysPro/FluidDynamics/Utilities/package.mo index 464fac2..4c995e4 100644 --- a/FluidDynamics/Utilities/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/Utilities/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.FluidDynamics; package Utilities + extends Modelica.Icons.UtilitiesPackage; + end Utilities; diff --git a/FluidDynamics/Utilities/package.order b/src/TAeZoSysPro/FluidDynamics/Utilities/package.order similarity index 100% rename from FluidDynamics/Utilities/package.order rename to src/TAeZoSysPro/FluidDynamics/Utilities/package.order diff --git a/FluidDynamics/Utilities/regRoot2.mo b/src/TAeZoSysPro/FluidDynamics/Utilities/regRoot2.mo similarity index 63% rename from FluidDynamics/Utilities/regRoot2.mo rename to src/TAeZoSysPro/FluidDynamics/Utilities/regRoot2.mo index 1e5ab8b..bf407ee 100644 --- a/FluidDynamics/Utilities/regRoot2.mo +++ b/src/TAeZoSysPro/FluidDynamics/Utilities/regRoot2.mo @@ -4,65 +4,84 @@ function regRoot2 "Anti-symmetric approximation of square root with discontinuous factor so that the first derivative is finite and continuous" extends Modelica.Icons.Function; - input Real x "Abscissa value"; - input Real x_small(min=0)=0.01 "Approximation of function for |x| <= x_small"; - input Real k1(min=0)=1 "y = if x>=0 then sqrt(k1*x) else -sqrt(k2*|x|)"; - input Real k2(min=0)=1 "y = if x>=0 then sqrt(k1*x) else -sqrt(k2*|x|)"; - input Boolean use_yd0 = false "= true, if yd0 shall be used"; - input Real yd0(min=0)=1 "Desired derivative at x=0: dy/dx = yd0"; - output Real y "Ordinate value"; + input Real x + "Abscissa value"; + input Real x_small(min = 0) = 0.01 + "Approximation of function for |x| <= x_small"; + input Real k1(min = 0) = 1 + "y = if x>=0 then sqrt(k1*x) else -sqrt(k2*|x|)"; + input Real k2(min = 0) = 1 + "y = if x>=0 then sqrt(k1*x) else -sqrt(k2*|x|)"; + input Boolean use_yd0 = false + "= true, if yd0 shall be used"; + input Real yd0(min = 0) = 1 + "Desired derivative at x=0: dy/dx = yd0"; + output Real y + "Ordinate value"; + protected + Real sqrt_k1 = if k1 > 0 then sqrt(k1) else 0; Real sqrt_k2 = if k2 > 0 then sqrt(k2) else 0; encapsulated function regRoot2_utility "Interpolating with two 3-order polynomials with a prescribed derivative at x=0" + import Modelica; extends Modelica.Icons.Function; import Modelica.Fluid.Utilities.evaluatePoly3_derivativeAtZero; input Real x; - input Real x1 "Approximation of function abs(x) < x1"; - input Real k1 "y = if x>=0 then sqrt(k1*x) else -sqrt(k2*|x|); k1 >= k2"; - input Real k2 "y = if x>=0 then sqrt(k1*x) else -sqrt(k2*|x|))"; - input Boolean use_yd0 "= true, if yd0 shall be used"; - input Real yd0(min=0) "Desired derivative at x=0: dy/dx = yd0"; + input Real x1 + "Approximation of function abs(x) < x1"; + input Real k1 + "y = if x>=0 then sqrt(k1*x) else -sqrt(k2*|x|); k1 >= k2"; + input Real k2 + "y = if x>=0 then sqrt(k1*x) else -sqrt(k2*|x|))"; + input Boolean use_yd0 + "= true, if yd0 shall be used"; + input Real yd0(min = 0) + "Desired derivative at x=0: dy/dx = yd0"; output Real y; + protected - Real x2; - Real xsqrt1; - Real xsqrt2; - Real y1; - Real y2; - Real y1d; - Real y2d; - Real w; - Real y0d; - Real w1; - Real w2; - Real sqrt_k1 = if k1 > 0 then sqrt(k1) else 0; - Real sqrt_k2 = if k2 > 0 then sqrt(k2) else 0; + + Real x2; + Real xsqrt1; + Real xsqrt2; + Real y1; + Real y2; + Real y1d; + Real y2d; + Real w; + Real y0d; + Real w1; + Real w2; + Real sqrt_k1 = if k1 > 0 then sqrt(k1) else 0; + Real sqrt_k2 = if k2 > 0 then sqrt(k2) else 0; + algorithm - if k2 > 0 then - // Since k1 >= k2 required, k2 > 0 means that k1 > 0 - x2 :=-x1*(k2/k1); - elseif k1 > 0 then - x2 := -x1; - else - y := 0; - return; - end if; - - if x <= x2 then - y := -sqrt_k2*sqrt(abs(x)); - else - y1 :=sqrt_k1*sqrt(x1); - y2 :=-sqrt_k2*sqrt(abs(x2)); - y1d :=sqrt_k1/sqrt(x1)/2; - y2d :=sqrt_k2/sqrt(abs(x2))/2; - - if use_yd0 then - y0d :=yd0; - else - /* Determine derivative, such that first and second derivative + + if k2 > 0 then + // Since k1 >= k2 required, k2 > 0 means that k1 > 0 + x2 := -x1 * (k2 / k1); + elseif k1 > 0 then + x2 := -x1; + else + y := 0; + return; + end if; + + if x <= x2 then + y := -sqrt_k2 * sqrt(abs(x)); + else + y1 := sqrt_k1 * sqrt(x1); + y2 := -sqrt_k2 * sqrt(abs(x2)); + y1d := sqrt_k1 / sqrt(x1) / 2; + y2d := sqrt_k2 / sqrt(abs(x2)) / 2; + + if use_yd0 then + y0d := yd0; + else + /* Determine derivative, such that first and second derivative of left and right polynomial are identical at x=0: _ Basic equations: @@ -99,33 +118,51 @@ protected Solving these equations results in y0d below (note, the denominator "(1-w)" is always non-zero, because w is negative) */ - w :=x2/x1; - y0d := ( (3*y2 - x2*y2d)/w - (3*y1 - x1*y1d)*w) /(2*x1*(1 - w)); - end if; + w := x2 / x1; + y0d := ((3 * y2 - x2 * y2d) / w - (3 * y1 - x1 * y1d) * w) / (2 * x1 * (1 - w)); + end if; - /* Modify derivative y0d, such that the polynomial is + /* Modify derivative y0d, such that the polynomial is monotonically increasing. A sufficient condition is 0 <= y0d <= sqrt(8.75*k_i/|x_i|) */ - w1 :=sqrt_k1*sqrt(8.75/x1); - w2 :=sqrt_k2*sqrt(8.75/abs(x2)); - y0d :=smooth(2, min(y0d, 0.9*min(w1, w2))); + w1 := sqrt_k1 * sqrt(8.75 / x1); + w2 := sqrt_k2 * sqrt(8.75 / abs(x2)); + y0d := smooth(2, min(y0d, 0.9 * min(w1, w2))); - /* Perform interpolation in scaled polynomial: + /* Perform interpolation in scaled polynomial: y_new = y/y1 x_new = x/x1 */ - y := y1*(if x >= 0 then evaluatePoly3_derivativeAtZero(x/x1,1,1,y1d*x1/y1,y0d*x1/y1) else - evaluatePoly3_derivativeAtZero(x/x1,x2/x1,y2/y1,y2d*x1/y1,y0d*x1/y1)); - end if; - annotation(smoothOrder=2); + y := y1 * (if x >= 0 then + evaluatePoly3_derivativeAtZero(x / x1, 1, 1, y1d * x1 / y1, y0d * x1 / y1) + else + evaluatePoly3_derivativeAtZero(x / x1, x2 / x1, y2 / y1, y2d * x1 / y1, y0d * x1 / y1)); + end if; + + annotation (smoothOrder = 2); + end regRoot2_utility; + algorithm - y := smooth(2, if x >= x_small then sqrt_k1*sqrt(x) else - if x <= -x_small then -sqrt_k2*sqrt(abs(x)) else - if k1 >= k2 then regRoot2_utility(x,x_small,k1,k2,use_yd0,yd0) else - -regRoot2_utility(-x,x_small,k2,k1,use_yd0,yd0)); - annotation(smoothOrder=2, Documentation(info=" + + y := smooth( + 2, + if x >= x_small then + sqrt_k1 * sqrt(x) + else + if x <= -x_small then + -sqrt_k2 * sqrt(abs(x)) + else + if k1 >= k2 then + regRoot2_utility(x, x_small, k1, k2, use_yd0, yd0) + else + -regRoot2_utility(-x, x_small, k2, k1, use_yd0, yd0)); + + annotation ( + smoothOrder = 2, + Documentation( + info = "

        This function is a copy pasting of the same function from the MSL library with Modelica 3.2.3 . The function is copied rather than inherited to avoid regression issues due to an update of the function in further version of the MSL. @@ -187,7 +224,8 @@ k1=1, k2=3 is shown in the next figure:

        Monotone piecewise cubic interpolation. SIAM J. Numerc. Anal., Vol. 17, No. 2, April 1980, pp. 238-246
        -", revisions=" +", + revisions = "
        • Sept., 2010 by Martin Otter:
          @@ -197,4 +235,5 @@ k1=1, k2=3 is shown in the next figure:

          Designed and implemented.
        ")); + end regRoot2; diff --git a/FluidDynamics/Utilities/regStep.mo b/src/TAeZoSysPro/FluidDynamics/Utilities/regStep.mo similarity index 72% rename from FluidDynamics/Utilities/regStep.mo rename to src/TAeZoSysPro/FluidDynamics/Utilities/regStep.mo index 530f47f..a363c52 100644 --- a/FluidDynamics/Utilities/regStep.mo +++ b/src/TAeZoSysPro/FluidDynamics/Utilities/regStep.mo @@ -2,18 +2,34 @@ within TAeZoSysPro.FluidDynamics.Utilities; function regStep "Approximation of a general step, such that the characteristic is continuous and differentiable" + extends Modelica.Icons.Function; - input Real x "Abscissa value"; - input Real y1 "Ordinate value for x > 0"; - input Real y2 "Ordinate value for x < 0"; - input Real x_small(min=0) = 1e-5 + input Real x + "Abscissa value"; + input Real y1 + "Ordinate value for x > 0"; + input Real y2 + "Ordinate value for x < 0"; + input Real x_small(min = 0) = 1e-5 "Approximation of step for -x_small <= x <= x_small; x_small >= 0 required"; - output Real y "Ordinate value to approximate y = if x > 0 then y1 else y2"; + output Real y + "Ordinate value to approximate y = if x > 0 then y1 else y2"; + algorithm - y := smooth(1, if x > x_small then y1 else - if x < -x_small then y2 else - if x_small > 0 then (x/x_small)*((x/x_small)^2 - 3)*(y2-y1)/4 + (y1+y2)/2 else (y1+y2)/2); - annotation(Documentation(revisions=" + + y := smooth( + 1, + if x > x_small then + y1 + else + if x < -x_small then + y2 + else + if x_small > 0 then (x / x_small) * ((x / x_small) ^ 2 - 3) * (y2 - y1) / 4 + (y1 + y2) / 2 else (y1 + y2) / 2); + + annotation ( + Documentation( + revisions = "
        • April 29, 2008 by Martin Otter:
          @@ -22,7 +38,8 @@ algorithm by Michael Sielemann:
          Minor modification to cover the limit case x_small -> 0 without division by zero.
        -", info=" +", + info = "

        This function is a copy pasting of the same function from the MSL library with Modelica 3.2.3 . The function is copied rather than inherited to avoid regression issues due to an update of the function in further version of the MSL. @@ -49,4 +66,5 @@ In the region -x_small < x < x_small a 2nd order polynomial is used for a smooth transition from y1 to y2.

        ")); + end regStep; diff --git a/FluidDynamics/package.mo b/src/TAeZoSysPro/FluidDynamics/package.mo similarity index 74% rename from FluidDynamics/package.mo rename to src/TAeZoSysPro/FluidDynamics/package.mo index c4c61af..5971895 100644 --- a/FluidDynamics/package.mo +++ b/src/TAeZoSysPro/FluidDynamics/package.mo @@ -2,10 +2,11 @@ within TAeZoSysPro; package FluidDynamics - extends Modelica.Icons.Package ; - -annotation( - Documentation(info = " + extends Modelica.Icons.Package; + + annotation ( + Documentation( + info = " FluidDynamics @@ -80,6 +81,6 @@ annotation( "), - Icon(coordinateSystem(extent = {{-100.0, -100.0}, {100.0, 100.0}}), graphics = {Line(origin = {-47.5, 11.6667}, points = {{-2.5, -91.6667}, {17.5, -71.6667}, {-22.5, -51.6667}, {17.5, -31.6667}, {-22.5, -11.667}, {17.5, 8.3333}, {-2.5, 28.3333}, {-2.5, 48.3333}}, smooth = Smooth.Bezier), Polygon(origin = {-50.0, 68.333}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{0.0, 21.667}, {-10.0, -8.333}, {10.0, -8.333}}), Line(origin = {2.5, 11.6667}, points = {{-2.5, -91.6667}, {17.5, -71.6667}, {-22.5, -51.6667}, {17.5, -31.6667}, {-22.5, -11.667}, {17.5, 8.3333}, {-2.5, 28.3333}, {-2.5, 48.3333}}, smooth = Smooth.Bezier), Polygon(origin = {0.0, 68.333}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{0.0, 21.667}, {-10.0, -8.333}, {10.0, -8.333}}), Line(origin = {52.5, 11.6667}, points = {{-2.5, -91.6667}, {17.5, -71.6667}, {-22.5, -51.6667}, {17.5, -31.6667}, {-22.5, -11.667}, {17.5, 8.3333}, {-2.5, 28.3333}, {-2.5, 48.3333}}, smooth = Smooth.Bezier), Polygon(origin = {50.0, 68.333}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{0.0, 21.667}, {-10.0, -8.333}, {10.0, -8.333}})}) ); + Icon(coordinateSystem(extent = {{-100.0, -100.0}, {100.0, 100.0}}), graphics = {Line(origin = {-47.5, 11.6667}, points = {{-2.5, -91.6667}, {17.5, -71.6667}, {-22.5, -51.6667}, {17.5, -31.6667}, {-22.5, -11.667}, {17.5, 8.3333}, {-2.5, 28.3333}, {-2.5, 48.3333}}, smooth = Smooth.Bezier), Polygon(origin = {-50.0, 68.333}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{0.0, 21.667}, {-10.0, -8.333}, {10.0, -8.333}}), Line(origin = {2.5, 11.6667}, points = {{-2.5, -91.6667}, {17.5, -71.6667}, {-22.5, -51.6667}, {17.5, -31.6667}, {-22.5, -11.667}, {17.5, 8.3333}, {-2.5, 28.3333}, {-2.5, 48.3333}}, smooth = Smooth.Bezier), Polygon(origin = {0.0, 68.333}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{0.0, 21.667}, {-10.0, -8.333}, {10.0, -8.333}}), Line(origin = {52.5, 11.6667}, points = {{-2.5, -91.6667}, {17.5, -71.6667}, {-22.5, -51.6667}, {17.5, -31.6667}, {-22.5, -11.667}, {17.5, 8.3333}, {-2.5, 28.3333}, {-2.5, 48.3333}}, smooth = Smooth.Bezier), Polygon(origin = {50.0, 68.333}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{0.0, 21.667}, {-10.0, -8.333}, {10.0, -8.333}})})); end FluidDynamics; diff --git a/FluidDynamics/package.order b/src/TAeZoSysPro/FluidDynamics/package.order similarity index 100% rename from FluidDynamics/package.order rename to src/TAeZoSysPro/FluidDynamics/package.order diff --git a/HeatTransfer/BasesClasses/CarrollNode.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/CarrollNode.mo similarity index 72% rename from HeatTransfer/BasesClasses/CarrollNode.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/CarrollNode.mo index c80a3b5..f178d76 100644 --- a/HeatTransfer/BasesClasses/CarrollNode.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/CarrollNode.mo @@ -1,44 +1,55 @@ within TAeZoSysPro.HeatTransfer.BasesClasses; model CarrollNode - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; + + import TAeZoSysPro.HeatTransfer.Types.Dynamics; // User defined parameters - parameter Dynamics energyDynamics = Dynamics.SteadyState "Formulation of energy balance"; - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if not steady state"; - parameter Modelica.SIunits.HeatCapacity C = 0.0 "Virtual capacity to avoid non linear iteration variable on temperature"; - + parameter Dynamics energyDynamics = Dynamics.SteadyState + "Formulation of energy balance"; + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if not steady state"; + parameter Modelica.SIunits.HeatCapacity C = 0.0 + "Virtual capacity to avoid non linear iteration variable on temperature"; + //Internal variables - Modelica.SIunits.Energy E "Energy storage"; + Modelica.SIunits.Energy E + "Energy storage"; // - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a annotation( - Placement(visible = true, transformation(origin = {2, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {2, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); initial equation - E = 0.0 ; -// Initialisation + + E = 0.0; + // Initialisation if energyDynamics == Dynamics.SteadyStateInitial then - der(port_a.T) = 0 "Zero time derivative at initilisation" ; - + der(port_a.T) = 0 + "Zero time derivative at initilisation"; + elseif energyDynamics == Dynamics.FixedInitial then - port_a.T = T_start "Initial temperature" ; - + port_a.T = T_start + "Initial temperature"; + end if; + equation -// Energy balance + // Energy balance if energyDynamics == Dynamics.SteadyState then port_a.Q_flow = 0; else C * der(port_a.T) = port_a.Q_flow; end if; der(E) = port_a.Q_flow; - - annotation( + + annotation ( Diagram(coordinateSystem(grid = {2, 2})), Icon(graphics = {Ellipse(lineColor = {255, 0, 0}, extent = {{-99, -99}, {99, 99}}, endAngle = 360), Ellipse(lineColor = {255, 0, 0}, lineThickness = 1, extent = {{-80, -80}, {80, 80}}, endAngle = 360), Ellipse(lineColor = {255, 0, 0}, lineThickness = 1.75, extent = {{-51, -51}, {51, 51}}, endAngle = 360), Line(origin = {-20, 20}, rotation = 45, points = {{0, 9}, {0, -9}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {20, 19.6794}, rotation = -45, points = {{0, 9}, {0, -9}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {20, -20}, rotation = 225, points = {{0, 9}, {0, -9}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {-20.3206, -20.9618}, rotation = 135, points = {{0, 9}, {0, -9}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), - Documentation(info=" + Documentation( + info = " CarrollNode @@ -61,6 +72,6 @@ equation /> -") ); +")); end CarrollNode; diff --git a/HeatTransfer/BasesClasses/CarrollRadiation.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/CarrollRadiation.mo similarity index 84% rename from HeatTransfer/BasesClasses/CarrollRadiation.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/CarrollRadiation.mo index df7479a..0732400 100644 --- a/HeatTransfer/BasesClasses/CarrollRadiation.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/CarrollRadiation.mo @@ -1,40 +1,54 @@ within TAeZoSysPro.HeatTransfer.BasesClasses; -model CarrollRadiation +model CarrollRadiation + + extends Modelica.Thermal.HeatTransfer.Interfaces.Element1D; - extends Modelica.Thermal.HeatTransfer.Interfaces.Element1D ; - // User defined parameters - parameter Real add_on = 1 "Custom add-on"; - parameter Modelica.SIunits.Area A = 0 "Wall Surface Area " annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Emissivity eps = 1 "Grey wall surface emissivity" annotation( - Dialog(group="Radiative properties")); + parameter Real add_on = 1 + "Custom add-on"; + parameter Modelica.SIunits.Area A = 0 + "Wall Surface Area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Emissivity eps = 1 + "Grey wall surface emissivity" + annotation ( + Dialog(group = "Radiative properties")); // Constants - constant Real sigma = Modelica.Constants.sigma "Stefan-Boltzmann constant"; - + constant Real sigma = Modelica.Constants.sigma + "Stefan-Boltzmann constant"; + // Internal variables - Modelica.SIunits.CoefficientOfHeatTransfer h_rad "Heat transfer coefficient"; - Modelica.SIunits.Energy E "Energy passed throught the component" ; - + Modelica.SIunits.CoefficientOfHeatTransfer h_rad + "Heat transfer coefficient"; + Modelica.SIunits.Energy E + "Energy passed throught the component"; + // Imported components - Modelica.Blocks.Interfaces.RealInput Fview annotation( - Placement(visible = true, transformation(origin = {-93, 88}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-80, -80}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput Fview + annotation ( + Placement(visible = true, transformation(origin = {-93, 88}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-80, -80}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); initial equation - E = 0.0 ; + + E = 0.0; equation -// linearization of the radiative equation - h_rad = TAeZoSysPro.HeatTransfer.Functions.Radiation.h_rad(T_A = port_a.T, - T_B = port_b.T, - R_th = ((1 - eps) / eps + Fview ^ (-1))) ; - -// Heat flux calculation - Q_flow = h_rad * A * dT ; - der(E) = Q_flow ; - - annotation(Documentation(info = " + + // linearization of the radiative equation + h_rad = TAeZoSysPro.HeatTransfer.Functions.Radiation.h_rad( + T_A = port_a.T, + T_B = port_b.T, + R_th = ((1 - eps) / eps + Fview ^ (-1))); + + // Heat flux calculation + Q_flow = h_rad * A * dT; + der(E) = Q_flow; + + annotation ( + Documentation( + info = " CarrollRadiation @@ -113,5 +127,5 @@ equation "), Icon(graphics = {Rectangle(origin = {0, 70}, fillColor = {106, 105, 108}, fillPattern = FillPattern.Cross, extent = {{-40, 10}, {40, -10}}), Rectangle(origin = {-70, 0}, fillColor = {106, 105, 108}, fillPattern = FillPattern.Cross, extent = {{-10, 40}, {10, -40}}), Rectangle(origin = {0, -70}, fillColor = {106, 105, 108}, fillPattern = FillPattern.Cross, extent = {{-40, -10}, {40, 10}}), Rectangle(origin = {70, 0}, fillColor = {106, 105, 108}, fillPattern = FillPattern.Cross, extent = {{-10, 40}, {10, -40}}), Rectangle(origin = {-59, 0}, fillColor = {255, 0, 0}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{1, -40}, {-1, 40}}), Rectangle(origin = {59, 0}, fillColor = {255, 0, 0}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{1, -40}, {-1, 40}}), Rectangle(origin = {0, 59}, fillColor = {255, 0, 0}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-40, 1}, {40, -1}}), Rectangle(origin = {0, -59}, fillColor = {255, 0, 0}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-40, 1}, {40, -1}}), Ellipse(fillPattern = FillPattern.Solid, extent = {{-6, -6}, {6, 6}}, endAngle = 360), Line(origin = {0, -31}, points = {{0, 23}, {0, -27}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {-31, 0}, points = {{23, 0}, {-27, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {33, 0}, points = {{27, 0}, {-25, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Text(origin = {95, 21}, extent = {{-9, -11}, {17, 9}}, textString = "MRT", fontSize = 8), Line(origin = {-30, 21}, points = {{-28, 19}, {24, -15}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {-30, -20}, points = {{-28, -18}, {24, 14}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {-21, 30}, points = {{-19, 28}, {15, -24}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {23, 32}, points = {{19, 28}, {-17, -26}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {31, 22}, points = {{27, 18}, {-25, -16}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {0, 31}, points = {{0, 27}, {0, -23}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {30, -21}, points = {{28, -19}, {-24, 15}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {22, -31}, points = {{18, -27}, {-16, 25}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Line(origin = {-23, -32}, points = {{-19, -28}, {17, 26}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}), Text(origin = {-105, 21}, rotation = 180, extent = {{-19, -9}, {9, 11}}, textString = "Wall", fontSize = 8)}, coordinateSystem(initialScale = 0.1))); - + end CarrollRadiation; diff --git a/HeatTransfer/BasesClasses/Conduction.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/Conduction.mo similarity index 55% rename from HeatTransfer/BasesClasses/Conduction.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/Conduction.mo index 7b93b1d..c178943 100644 --- a/HeatTransfer/BasesClasses/Conduction.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/Conduction.mo @@ -1,35 +1,53 @@ -within TAeZoSysPro.HeatTransfer.BasesClasses; +within TAeZoSysPro.HeatTransfer.BasesClasses; model Conduction + encapsulated type ConductionType = enumeration( - Linear - "linear conduction", - Radial - "cylindric conduction") "Enumeration defining the type of conduction"; + Linear + "linear conduction", + Radial + "cylindric conduction") + "Enumeration defining the type of conduction"; // extends Modelica.Thermal.HeatTransfer.Interfaces.Element1D; // User defined parameters - parameter Real add_on = 1 "Custom add-on"; - parameter Modelica.SIunits.ThermalConductivity k = 0 "Thermal conductivity" annotation ( - Dialog(group="Thermal properties")); - parameter ConductionType conduction = ConductionType.Linear annotation ( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Thickness Th = 0 "Material thickness" annotation ( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Area A = 0 "Cross section (if linear conduction)" annotation ( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Length L = 0 "Cylinder length (if cylindric conduction)" annotation ( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Radius Ri = 0 "Internal radius(if cylindric conduction)" annotation ( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg Angle = 360 "Angle of cylindrical part (if cylindric conduction)" annotation ( - Dialog(group="Geometrical properties")); + parameter Real add_on = 1 + "Custom add-on"; + parameter Modelica.SIunits.ThermalConductivity k = 0 + "Thermal conductivity" + annotation ( + Dialog(group = "Thermal properties")); + parameter ConductionType conduction = ConductionType.Linear + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Thickness Th = 0 + "Material thickness" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Area A = 0 + "Cross section (if linear conduction)" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Length L = 0 + "Cylinder length (if cylindric conduction)" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Radius Ri = 0 + "Internal radius(if cylindric conduction)" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Conversions.NonSIunits.Angle_deg Angle = 360 + "Angle of cylindrical part (if cylindric conduction)" + annotation ( + Dialog(group = "Geometrical properties")); // Internal variables - Modelica.SIunits.Energy E "Energy passed throught the component"; + Modelica.SIunits.Energy E + "Energy passed throught the component"; initial equation + E = 0.0; equation @@ -45,7 +63,8 @@ equation der(E) = Q_flow; annotation ( - Documentation(info = " + Documentation( + info = " Conduction @@ -100,7 +119,19 @@ equation "), Diagram, - Icon(graphics={ Line(origin = {20, 61}, points = {{0, 19}}), Line(origin = {13, 75}, points = {{-13, 3}}), Rectangle(origin = {-3, -1}, fillColor = {156, 156, 156}, - fillPattern = FillPattern.Cross, extent = {{-37, 101}, {43, -99}}), Line(origin = {-9, 78}, points = {{-47, 0}, {71, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {2, 0}, points = {{-58, 0}, {60, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {2, -76}, points = {{-58, 0}, {60, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), - __OpenModelica_commandLineOptions = ""); + Icon( + graphics = { + Line(origin = {20, 61}, points = {{0, 19}}), + Line(origin = {13, 75}, points = {{-13, 3}}), + Rectangle( + origin = {-3, -1}, + fillColor = {156, 156, 156}, + fillPattern = FillPattern.Cross, + extent = {{-37, 101}, {43, -99}}), + Line(origin = {-9, 78}, points = {{-47, 0}, {71, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), + Line(origin = {2, 0}, points = {{-58, 0}, {60, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), + Line(origin = {2, -76}, points = {{-58, 0}, {60, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled})}, + coordinateSystem(initialScale = 0.1)), + __OpenModelica_commandLineOptions = ""); + end Conduction; diff --git a/HeatTransfer/BasesClasses/ForcedConvection.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/ForcedConvection.mo similarity index 52% rename from HeatTransfer/BasesClasses/ForcedConvection.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/ForcedConvection.mo index 4863c3b..404f640 100644 --- a/HeatTransfer/BasesClasses/ForcedConvection.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/ForcedConvection.mo @@ -8,54 +8,79 @@ model ForcedConvection // replaceable package Medium = TAeZoSysPro.Media.MyMedia; // User defined parameters - parameter Real add_on = 1 "Custom add-on"; - parameter SI.Area A = 0 "Wall surface Area " annotation ( - Dialog(group="Geometrical properties")); - parameter SI.Length Lc = 1 "characteritic dimension for correlation" annotation ( - Dialog(group="Geometrical properties")); - parameter TAeZoSysPro.HeatTransfer.Types.ForcedConvectionCorrelation correlation = Correlations.flat_plate_ASHRAE "Forced convection Correlation" annotation ( - Dialog(group="Flow properties")); - parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 "Constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation ( - Dialog(group="Flow properties")); + parameter Real add_on = 1 + "Custom add-on"; + parameter SI.Area A = 0 + "Wall surface Area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter SI.Length Lc = 1 + "characteritic dimension for correlation" + annotation ( + Dialog(group = "Geometrical properties")); + parameter TAeZoSysPro.HeatTransfer.Types.ForcedConvectionCorrelation correlation = Correlations.flat_plate_ASHRAE + "Forced convection Correlation" + annotation ( + Dialog(group = "Flow properties")); + parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 + "Constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Flow properties")); // Internal variables - Medium.Temperature T_mean "Mean temperature"; - SI.CoefficientOfHeatTransfer h_cv "Heat transfert coefficient"; - SI.Density d "Density of fluid at T_mean"; - SI.SpecificHeatCapacity cp "Specific heat capacity of fluid at T_mean"; - SI.DynamicViscosity mu "Dynamic viscosity of fluid at T_mean"; - SI.ThermalConductivity k "Thermal conductivity of fluid at T_mean"; - SI.PrandtlNumber Pr "Prandtl Number"; - SI.ReynoldsNumber Re "Reynolds Number"; - SI.NusseltNumber Nu "Nusselt Number"; - SI.Energy E "Energy passed throught the component"; + Medium.Temperature T_mean + "Mean temperature"; + SI.CoefficientOfHeatTransfer h_cv + "Heat transfert coefficient"; + SI.Density d + "Density of fluid at T_mean"; + SI.SpecificHeatCapacity cp + "Specific heat capacity of fluid at T_mean"; + SI.DynamicViscosity mu + "Dynamic viscosity of fluid at T_mean"; + SI.ThermalConductivity k + "Thermal conductivity of fluid at T_mean"; + SI.PrandtlNumber Pr + "Prandtl Number"; + SI.ReynoldsNumber Re + "Reynolds Number"; + SI.NusseltNumber Nu + "Nusselt Number"; + SI.Energy E + "Energy passed throught the component"; // Imported modules - Modelica.Blocks.Interfaces.RealInput Vel "Velocity of fluid out of boundary layer" annotation ( - Placement(visible = true, transformation(origin = {56, 84}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {50, 80}, extent = {{-20, -20}, {20, 20}}, rotation = -90))); + Modelica.Blocks.Interfaces.RealInput Vel + "Velocity of fluid out of boundary layer" + annotation ( + Placement(visible = true, transformation(origin = {56, 84}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {50, 80}, extent = {{-20, -20}, {20, 20}}, rotation = -90))); + protected + Medium.ThermodynamicState state; initial equation + E = 0.0; equation - T_mean = (port_a.T + port_b.T) / 2 "port_a and port_b are defined in Element1D"; + T_mean = (port_a.T + port_b.T) / 2 + "port_a and port_b are defined in Element1D"; state = Medium.setState_pTX(p = Medium.reference_p, T = T_mean); -// Thermodynamic perperties calculation + // Thermodynamic perperties calculation d = state.d; mu = Medium.dynamicViscosity(state); cp = Medium.specificHeatCapacityCp(state); k = Medium.thermalConductivity(state); -// Calculation of characteristic numbers for convection + // Calculation of characteristic numbers for convection Pr = mu * cp / k; Re = d * Vel * Lc / mu; -// Correlation selection -//Nu = hcv * carac_length / k ; + // Correlation selection + //Nu = hcv * carac_length / k ; if correlation == Correlations.internal_pipe_ASHRAE then Nu = Functions.internal_pipe_ASHRAE(Pr = Pr, Re = Re, dT = dT); @@ -73,16 +98,16 @@ equation assert(false, "The correlation selected is not yet implemented of not applicable", AssertionLevel.error); end if; -//Convective heat transfer calculation + //Convective heat transfer calculation h_cv = Nu * k / Lc; -// Heat flux calculation + // Heat flux calculation Q_flow = add_on * h_cv * A * dT; der(E) = Q_flow; annotation ( - Documentation(info= - " + Documentation( + info = " Convection @@ -127,8 +152,27 @@ equation "), - Icon(coordinateSystem(initialScale = 0.1), graphics={ Rectangle(origin = {-54, 0}, fillColor = {140, 138, 145}, - fillPattern = FillPattern.Cross, extent = {{-26, 100}, {14, -100}}), Line(origin = {-10, 0}, points = {{0, 60}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {30, 0}, points = {{0, 60}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {70, 0}, points = {{0, 60}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {26, 4}, extent = {{-28, 24}, {28, -24}}, textString = "hcv"), Line(origin = {25, 0}, points = {{-27, -22}, {27, 22}}, thickness = 1.75, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-112, 21}, rotation = 180, extent = {{-28, 5}, {6, -5}}, textString = "Wall", fontSize = 8), Text(origin = {82, 19}, extent = {{2, 9}, {32, -5}}, textString = "Fluid", fontSize = 8), Ellipse(origin = {-2, 80}, extent = {{-20, 20}, {20, -20}}, endAngle = 360), Polygon(origin = {0, 89}, points = {{-2, -9}, {-2, 9}, {0, 9}, {2, 7}, {-2, -9}}), Polygon(origin = {8, 77}, rotation = -90, points = {{-2, -9}, {-2, 9}, {0, 9}, {2, 7}, {-2, -9}}), Polygon(origin = {-4, 71}, rotation = 180, points = {{-2, -9}, {-2, 9}, {0, 9}, {2, 7}, {-2, -9}}), Polygon(origin = {-12, 81}, rotation = 90, points = {{-2, -9}, {-2, 9}, {0, 9}, {2, 7}, {-2, -9}})}), + Icon( + coordinateSystem(initialScale = 0.1), + graphics = { + Rectangle( + origin = {-54, 0}, + fillColor = {140, 138, 145}, + fillPattern = FillPattern.Cross, + extent = {{-26, 100}, {14, -100}}), + Line(origin = {-10, 0}, points = {{0, 60}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), + Line(origin = {30, 0}, points = {{0, 60}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), + Line(origin = {70, 0}, points = {{0, 60}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), + Text(origin = {26, 4}, extent = {{-28, 24}, {28, -24}}, textString = "hcv"), + Line(origin = {25, 0}, points = {{-27, -22}, {27, 22}}, thickness = 1.75, arrow = {Arrow.None, Arrow.Filled}), + Text(origin = {-112, 21}, rotation = 180, extent = {{-28, 5}, {6, -5}}, textString = "Wall", fontSize = 8), + Text(origin = {82, 19}, extent = {{2, 9}, {32, -5}}, textString = "Fluid", fontSize = 8), + Ellipse(origin = {-2, 80}, extent = {{-20, 20}, {20, -20}}, endAngle = 360), + Polygon(origin = {0, 89}, points = {{-2, -9}, {-2, 9}, {0, 9}, {2, 7}, {-2, -9}}), + Polygon(origin = {8, 77}, rotation = -90, points = {{-2, -9}, {-2, 9}, {0, 9}, {2, 7}, {-2, -9}}), + Polygon(origin = {-4, 71}, rotation = 180, points = {{-2, -9}, {-2, 9}, {0, 9}, {2, 7}, {-2, -9}}), + Polygon(origin = {-12, 81}, rotation = 90, points = {{-2, -9}, {-2, 9}, {0, 9}, {2, 7}, {-2, -9}})}), Diagram(coordinateSystem(initialScale = 0.1, grid = {1, 1})), - __OpenModelica_commandLineOptions = ""); + __OpenModelica_commandLineOptions = ""); + end ForcedConvection; diff --git a/HeatTransfer/BasesClasses/FreeConvection.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/FreeConvection.mo similarity index 60% rename from HeatTransfer/BasesClasses/FreeConvection.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/FreeConvection.mo index 16f1e33..2b64360 100644 --- a/HeatTransfer/BasesClasses/FreeConvection.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/FreeConvection.mo @@ -2,56 +2,79 @@ within TAeZoSysPro.HeatTransfer.BasesClasses; model FreeConvection - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import Functions = TAeZoSysPro.HeatTransfer.Functions.FreeConvection ; - import SI = Modelica.SIunits ; + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import Functions = TAeZoSysPro.HeatTransfer.Functions.FreeConvection; + import SI = Modelica.SIunits; extends Modelica.Thermal.HeatTransfer.Interfaces.Element1D; // replaceable package Medium = TAeZoSysPro.Media.MyMedia; // User defined parameters - parameter Real add_on = 1 "Custom add-on"; - parameter SI.Area A = 0 "Wall surface Area" annotation( - Dialog(group="Geometrical properties")); - parameter SI.Length Lc = 1 "characteritic dimension for correlation" annotation( - Dialog(group="Geometrical properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE "Free convection Correlation" annotation( - Dialog(group="Flow properties")); - parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group="Flow properties")); + parameter Real add_on = 1 + "Custom add-on"; + parameter SI.Area A = 0 + "Wall surface Area" + annotation ( + Dialog(group = "Geometrical properties")); + parameter SI.Length Lc = 1 + "characteritic dimension for correlation" + annotation ( + Dialog(group = "Geometrical properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE + "Free convection Correlation" + annotation ( + Dialog(group = "Flow properties")); + parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Flow properties")); + + // Internal variables + Medium.Temperature T_mean + "Mean temperature between fluid and wall"; + SI.CoefficientOfHeatTransfer h_cv + "Heat transfert coefficient"; + SI.Density d + "Density of fluid at T_mean"; + SI.SpecificHeatCapacity cp + "Specific heat capacity of fluid at T_mean"; + SI.DynamicViscosity mu + "Dynamic viscosity of fluid at T_mean"; + SI.ThermalConductivity k + "Thermal Conductivity of fluid at T_mean"; + SI.PrandtlNumber Pr + "Prandtl Number"; + SI.GrashofNumber Gr + "Grashof Number"; + SI.RayleighNumber Ra + "Rayleigh Number"; + SI.NusseltNumber Nu + "Nusselt Number"; + SI.Energy E + "Energy passed throught the component"; + +protected -// Internal variables - Medium.Temperature T_mean "Mean temperature between fluid and wall"; - SI.CoefficientOfHeatTransfer h_cv "Heat transfert coefficient"; - SI.Density d "Density of fluid at T_mean"; - SI.SpecificHeatCapacity cp "Specific heat capacity of fluid at T_mean"; - SI.DynamicViscosity mu "Dynamic viscosity of fluid at T_mean"; - SI.ThermalConductivity k "Thermal Conductivity of fluid at T_mean"; - SI.PrandtlNumber Pr "Prandtl Number"; - SI.GrashofNumber Gr "Grashof Number"; - SI.RayleighNumber Ra "Rayleigh Number"; - SI.NusseltNumber Nu "Nusselt Number"; - SI.Energy E "Energy passed throught the component" ; - - protected Medium.ThermodynamicState state; - + initial equation - E = 0.0 ; - + + E = 0.0; + equation - T_mean = (port_a.T + port_b.T) / 2 "port_a and port_b are defined in Element1D"; - state = Medium.setState_pTX(p = Medium.reference_p, T = T_mean, X=Medium.reference_X); -// Thermodynamic properties calculation + T_mean = (port_a.T + port_b.T) / 2 + "port_a and port_b are defined in Element1D"; + state = Medium.setState_pTX(p = Medium.reference_p, T = T_mean, X = Medium.reference_X); + // Thermodynamic properties calculation d = Medium.density(state); mu = Medium.dynamicViscosity(state); cp = Medium.specificHeatCapacityCp(state); k = Medium.thermalConductivity(state); -// Calculation of characteristic numbers for convection + // Calculation of characteristic numbers for convection Pr = mu * cp / k; - Gr = 9.81 * 1/port_b.T * d^2 * abs(dT) * Lc^3 / mu^2 ; - Ra = Gr * Pr ; -// Selection of the correlation + Gr = 9.81 * 1 / port_b.T * d ^ 2 * abs(dT) * Lc ^ 3 / mu ^ 2; + Ra = Gr * Pr; + // Selection of the correlation if correlation == Correlations.vertical_plate_ASHRAE then Nu = Functions.vertical_plate_ASHRAE(Pr = Pr, Ra = Ra); elseif correlation == Correlations.vertical_plate_Recknagel then @@ -68,15 +91,15 @@ equation Nu = 0; assert(false, "The correlation selected is not yet implemented of not applicable", AssertionLevel.error); end if; -//Convective heat transfer calculation + //Convective heat transfer calculation h_cv = Nu * k / Lc; -// Heat flux calculation + // Heat flux calculation Q_flow = add_on * h_cv * A * dT; - der(E) = Q_flow ; - - annotation( - Documentation(info = - " + der(E) = Q_flow; + + annotation ( + Documentation( + info = " FreeConvection @@ -122,8 +145,8 @@ equation "), - Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(origin = {-54, 0}, fillColor = {140, 138, 145}, fillPattern = FillPattern.Cross, extent = {{-26, 100}, {14, -100}}), Line(origin = {-10, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {30, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {70, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {25, 40}, points = {{-55, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {25, -40}, points = {{-55, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {26, 4}, extent = {{-28, 24}, {28, -24}}, textString = "hcv"), Line(origin = {25, 0}, points = {{-27, -22}, {27, 22}}, thickness = 1.75, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-88, 23}, rotation = 180, extent = {{-4, 11}, {28, -5}}, textString = "Wall", fontSize = 8), Text(origin = {114, 23}, extent = {{-28, 5}, {0, -9}}, textString = "Fluid", fontSize = 8)}), + Icon(coordinateSystem(initialScale = 0.1), graphics = {Rectangle(origin = {-54, 0}, fillColor = {140, 138, 145}, fillPattern = FillPattern.Cross, extent = {{-26, 100}, {14, -100}}), Line(origin = {-10, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {30, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {70, 0}, points = {{0, 80}, {0, -80}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {25, 40}, points = {{-55, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {25, -40}, points = {{-55, 0}, {55, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {26, 4}, extent = {{-28, 24}, {28, -24}}, textString = "hcv"), Line(origin = {25, 0}, points = {{-27, -22}, {27, 22}}, thickness = 1.75, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-88, 23}, rotation = 180, extent = {{-4, 11}, {28, -5}}, textString = "Wall", fontSize = 8), Text(origin = {114, 23}, extent = {{-28, 5}, {0, -9}}, textString = "Fluid", fontSize = 8)}), Diagram(graphics = {Rectangle(origin = {-56, -3}, fillColor = {172, 172, 172}, fillPattern = FillPattern.Cross, extent = {{-22, 85}, {22, -85}}), Line(origin = {-1, 42}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-1, 0}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {1, -44}, points = {{-23, 0}, {23, 0}}, arrow = {Arrow.None, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), - __OpenModelica_commandLineOptions = ""); + __OpenModelica_commandLineOptions = ""); end FreeConvection; diff --git a/HeatTransfer/BasesClasses/FreeConvection_dT_decoupled.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/FreeConvection_dT_decoupled.mo similarity index 66% rename from HeatTransfer/BasesClasses/FreeConvection_dT_decoupled.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/FreeConvection_dT_decoupled.mo index 736d7b6..536c04c 100644 --- a/HeatTransfer/BasesClasses/FreeConvection_dT_decoupled.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/FreeConvection_dT_decoupled.mo @@ -1,67 +1,97 @@ within TAeZoSysPro.HeatTransfer.BasesClasses; model FreeConvection_dT_decoupled + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; import Functions = TAeZoSysPro.HeatTransfer.Functions.FreeConvection; import SI = Modelica.SIunits; // replaceable package Medium = TAeZoSysPro.Media.MyMedia; // User defined parameters - parameter Real add_on = 1 "Custom add-on"; - parameter SI.Area A = 0 "Wall surface Area" annotation( - Dialog(group = "Geometrical properties")); - parameter SI.Length Lc = 1 "characteritic dimension for correlation" annotation( - Dialog(group = "Geometrical properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE "Free convection Correlation" annotation( - Dialog(group = "Flow properties")); - parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Flow properties")); + parameter Real add_on = 1 + "Custom add-on"; + parameter SI.Area A = 0 + "Wall surface Area" + annotation ( + Dialog(group = "Geometrical properties")); + parameter SI.Length Lc = 1 + "characteritic dimension for correlation" + annotation ( + Dialog(group = "Geometrical properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE + "Free convection Correlation" + annotation ( + Dialog(group = "Flow properties")); + parameter SI.CoefficientOfHeatTransfer h_cv_const = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Flow properties")); // Internal variables - Medium.Temperature T_mean "Mean temperature between fluid and wall"; - Modelica.SIunits.TemperatureDifference dT "port_a.T - T_fluid"; - SI.CoefficientOfHeatTransfer h_cv "Heat transfert coefficient"; - SI.Density d "Density of fluid at T_mean"; - SI.SpecificHeatCapacity cp "Specific heat capacity of fluid at T_mean"; - SI.DynamicViscosity mu "Dynamic viscosity of fluid at T_mean"; - SI.ThermalConductivity k "Thermal Conductivity of fluid at T_mean"; - SI.PrandtlNumber Pr "Prandtl Number"; - SI.GrashofNumber Gr "Grashof Number"; - SI.RayleighNumber Ra "Rayleigh Number"; - SI.NusseltNumber Nu "Nusselt Number"; - Modelica.SIunits.HeatFlowRate Q_flow "Heat flow rate from port_a -> port_b"; - SI.Energy E "Energy passed throught the component"; + Medium.Temperature T_mean + "Mean temperature between fluid and wall"; + Modelica.SIunits.TemperatureDifference dT + "port_a.T - T_fluid"; + SI.CoefficientOfHeatTransfer h_cv + "Heat transfert coefficient"; + SI.Density d + "Density of fluid at T_mean"; + SI.SpecificHeatCapacity cp + "Specific heat capacity of fluid at T_mean"; + SI.DynamicViscosity mu + "Dynamic viscosity of fluid at T_mean"; + SI.ThermalConductivity k + "Thermal Conductivity of fluid at T_mean"; + SI.PrandtlNumber Pr + "Prandtl Number"; + SI.GrashofNumber Gr + "Grashof Number"; + SI.RayleighNumber Ra + "Rayleigh Number"; + SI.NusseltNumber Nu + "Nusselt Number"; + Modelica.SIunits.HeatFlowRate Q_flow + "Heat flow rate from port_a -> port_b"; + SI.Energy E + "Energy passed throught the component"; // Imported modules - Modelica.Blocks.Interfaces.RealInput T_fluid annotation( - Placement(visible = true, transformation(origin = {0, 80}, extent = {{-20, -20}, {20, 20}}, rotation = -90), iconTransformation(origin = {20, 86}, extent = {{-14, -14}, {14, 14}}, rotation = -90))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a annotation( - Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b annotation( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput T_fluid + annotation ( + Placement(visible = true, transformation(origin = {0, 80}, extent = {{-20, -20}, {20, 20}}, rotation = -90), iconTransformation(origin = {20, 86}, extent = {{-14, -14}, {14, 14}}, rotation = -90))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); protected + Medium.ThermodynamicState state; - // Imported modules + +// Imported modules initial equation + E = 0.0; - + equation dT = port_a.T - T_fluid; port_a.Q_flow = Q_flow; port_b.Q_flow = -Q_flow; - - T_mean = (port_a.T + T_fluid) / 2 "port_a and port_b are defined in Element1D"; + + T_mean = (port_a.T + T_fluid) / 2 + "port_a and port_b are defined in Element1D"; state = Medium.setState_pTX(p = Medium.reference_p, T = T_mean); -// Thermodynamic properties calculation + // Thermodynamic properties calculation d = Medium.density(state); mu = Medium.dynamicViscosity(state); cp = Medium.specificHeatCapacityCp(state); k = Medium.thermalConductivity(state); -// Calculation of characteristic numbers for convection + // Calculation of characteristic numbers for convection Pr = mu * cp / k; Gr = 9.81 * 1 / port_b.T * d ^ 2 * abs(dT) * Lc ^ 3 / mu ^ 2; Ra = Gr * Pr; -// Selection of the correlation + // Selection of the correlation if correlation == Correlations.vertical_plate_ASHRAE then Nu = Functions.vertical_plate_ASHRAE(Pr = Pr, Ra = Ra); elseif correlation == Correlations.vertical_plate_Recknagel then @@ -78,14 +108,15 @@ equation Nu = 0; assert(false, "The correlation selected is not yet implemented of not applicable", AssertionLevel.error); end if; -//Convective heat transfer calculation + //Convective heat transfer calculation h_cv = Nu * k / Lc; -// Heat flux calculation + // Heat flux calculation Q_flow = add_on * h_cv * A * dT; der(E) = Q_flow; - - annotation( - Documentation(info = " + + annotation ( + Documentation( + info = " FreeConvection_dT_decoupled diff --git a/HeatTransfer/BasesClasses/HeatCapacitor.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/HeatCapacitor.mo similarity index 59% rename from HeatTransfer/BasesClasses/HeatCapacitor.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/HeatCapacitor.mo index d07d609..fd4eb54 100644 --- a/HeatTransfer/BasesClasses/HeatCapacitor.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/HeatCapacitor.mo @@ -1,54 +1,67 @@ within TAeZoSysPro.HeatTransfer.BasesClasses; model HeatCapacitor - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - -// User defined parameters : - parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 "Specific heat capacity of element" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.Mass m = 0 "Mass of element"; - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance"; - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if not steady state"; - + + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + + // User defined parameters : + parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 + "Specific heat capacity of element" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.Mass m = 0 + "Mass of element"; + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance"; + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if not steady state"; + // Internal variables - Modelica.SIunits.Temperature T "Temperature of element"; - Modelica.SIunits.Energy E "Energy storage"; - + Modelica.SIunits.Temperature T + "Temperature of element"; + Modelica.SIunits.Energy E + "Energy storage"; + // Imported components - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port annotation( - Placement(visible = true, transformation(origin = {0, -98}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -98}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port + annotation ( + Placement(visible = true, transformation(origin = {0, -98}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -98}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + initial equation - E = 0 " Energy at time 0s is equal to 0J" ; - + + E = 0 + " Energy at time 0s is equal to 0J"; + if energyDynamics == Dynamics.SteadyStateInitial then //der(T) = 0; - port.Q_flow = 0.0 ; - + port.Q_flow = 0.0; + elseif energyDynamics == Dynamics.FixedInitial then - T = T_start ; + T = T_start; end if; equation + if energyDynamics == Dynamics.SteadyState then - port.Q_flow = 0.0 ; + port.Q_flow = 0.0; else - // enthalpy balance + // enthalpy balance m * cp * der(T) = port.Q_flow; - - end if ; + + end if; // energy storage calculation - der(E) = port.Q_flow; - + der(E) = port.Q_flow; + // port handover - port.T = T; - - annotation( - Icon(coordinateSystem(initialScale = 0.1), graphics = {Text(origin = {0, -2},lineColor = {0, 0, 255}, extent = {{-150, 110}, {150, 70}}, textString = "%name"), Polygon(lineColor = {160, 160, 164}, fillColor = {192, 192, 192}, fillPattern = FillPattern.Solid, points = {{0, 67}, {-20, 63}, {-40, 57}, {-52, 43}, {-58, 35}, {-68, 25}, {-72, 13}, {-76, -1}, {-78, -15}, {-76, -31}, {-76, -43}, {-76, -53}, {-70, -65}, {-64, -73}, {-48, -77}, {-30, -83}, {-18, -83}, {-2, -85}, {8, -89}, {22, -89}, {32, -87}, {42, -81}, {54, -75}, {56, -73}, {66, -61}, {68, -53}, {70, -51}, {72, -35}, {76, -21}, {78, -13}, {78, 3}, {74, 15}, {66, 25}, {54, 33}, {44, 41}, {36, 57}, {26, 65}, {0, 67}}), Polygon(fillColor = {160, 160, 164}, fillPattern = FillPattern.Solid, points = {{-58, 35}, {-68, 25}, {-72, 13}, {-76, -1}, {-78, -15}, {-76, -31}, {-76, -43}, {-76, -53}, {-70, -65}, {-64, -73}, {-48, -77}, {-30, -83}, {-18, -83}, {-2, -85}, {8, -89}, {22, -89}, {32, -87}, {42, -81}, {54, -75}, {42, -77}, {40, -77}, {30, -79}, {20, -81}, {18, -81}, {10, -81}, {2, -77}, {-12, -73}, {-22, -73}, {-30, -71}, {-40, -65}, {-50, -55}, {-56, -43}, {-58, -35}, {-58, -25}, {-60, -13}, {-60, -5}, {-60, 7}, {-58, 17}, {-56, 19}, {-52, 27}, {-48, 35}, {-44, 45}, {-40, 57}, {-58, 35}}), Text(origin = {-30, 52},extent = {{-69, 7}, {129, -12}}, textString = "Mass = %Mass", fontSize = 8), Text(origin = {-30, -8}, extent = {{-69, 7}, {129, -12}}, textString = "Cp = %Cp", fontSize = 8)}), + port.T = T; + + annotation ( + Icon(coordinateSystem(initialScale = 0.1), graphics = {Text(origin = {0, -2}, lineColor = {0, 0, 255}, extent = {{-150, 110}, {150, 70}}, textString = "%name"), Polygon(lineColor = {160, 160, 164}, fillColor = {192, 192, 192}, fillPattern = FillPattern.Solid, points = {{0, 67}, {-20, 63}, {-40, 57}, {-52, 43}, {-58, 35}, {-68, 25}, {-72, 13}, {-76, -1}, {-78, -15}, {-76, -31}, {-76, -43}, {-76, -53}, {-70, -65}, {-64, -73}, {-48, -77}, {-30, -83}, {-18, -83}, {-2, -85}, {8, -89}, {22, -89}, {32, -87}, {42, -81}, {54, -75}, {56, -73}, {66, -61}, {68, -53}, {70, -51}, {72, -35}, {76, -21}, {78, -13}, {78, 3}, {74, 15}, {66, 25}, {54, 33}, {44, 41}, {36, 57}, {26, 65}, {0, 67}}), Polygon(fillColor = {160, 160, 164}, fillPattern = FillPattern.Solid, points = {{-58, 35}, {-68, 25}, {-72, 13}, {-76, -1}, {-78, -15}, {-76, -31}, {-76, -43}, {-76, -53}, {-70, -65}, {-64, -73}, {-48, -77}, {-30, -83}, {-18, -83}, {-2, -85}, {8, -89}, {22, -89}, {32, -87}, {42, -81}, {54, -75}, {42, -77}, {40, -77}, {30, -79}, {20, -81}, {18, -81}, {10, -81}, {2, -77}, {-12, -73}, {-22, -73}, {-30, -71}, {-40, -65}, {-50, -55}, {-56, -43}, {-58, -35}, {-58, -25}, {-60, -13}, {-60, -5}, {-60, 7}, {-58, 17}, {-56, 19}, {-52, 27}, {-48, 35}, {-44, 45}, {-40, 57}, {-58, 35}}), Text(origin = {-30, 52}, extent = {{-69, 7}, {129, -12}}, textString = "Mass = %Mass", fontSize = 8), Text(origin = {-30, -8}, extent = {{-69, 7}, {129, -12}}, textString = "Cp = %Cp", fontSize = 8)}), Diagram(coordinateSystem(preserveAspectRatio = true, extent = {{-100, -100}, {100, 100}}), graphics = {Polygon(points = {{0, 67}, {-20, 63}, {-40, 57}, {-52, 43}, {-58, 35}, {-68, 25}, {-72, 13}, {-76, -1}, {-78, -15}, {-76, -31}, {-76, -43}, {-76, -53}, {-70, -65}, {-64, -73}, {-48, -77}, {-30, -83}, {-18, -83}, {-2, -85}, {8, -89}, {22, -89}, {32, -87}, {42, -81}, {54, -75}, {56, -73}, {66, -61}, {68, -53}, {70, -51}, {72, -35}, {76, -21}, {78, -13}, {78, 3}, {74, 15}, {66, 25}, {54, 33}, {44, 41}, {36, 57}, {26, 65}, {0, 67}}, lineColor = {160, 160, 164}, fillColor = {192, 192, 192}, fillPattern = FillPattern.Solid), Polygon(points = {{-58, 35}, {-68, 25}, {-72, 13}, {-76, -1}, {-78, -15}, {-76, -31}, {-76, -43}, {-76, -53}, {-70, -65}, {-64, -73}, {-48, -77}, {-30, -83}, {-18, -83}, {-2, -85}, {8, -89}, {22, -89}, {32, -87}, {42, -81}, {54, -75}, {42, -77}, {40, -77}, {30, -79}, {20, -81}, {18, -81}, {10, -81}, {2, -77}, {-12, -73}, {-22, -73}, {-30, -71}, {-40, -65}, {-50, -55}, {-56, -43}, {-58, -35}, {-58, -25}, {-60, -13}, {-60, -5}, {-60, 7}, {-58, 17}, {-56, 19}, {-52, 27}, {-48, 35}, {-44, 45}, {-40, 57}, {-58, 35}}, lineColor = {0, 0, 0}, fillColor = {160, 160, 164}, fillPattern = FillPattern.Solid), Ellipse(extent = {{-6, -1}, {6, -12}}, lineColor = {255, 0, 0}, fillColor = {191, 0, 0}, fillPattern = FillPattern.Solid), Text(extent = {{11, 13}, {50, -25}}, lineColor = {0, 0, 0}, textString = "T"), Line(points = {{0, -12}, {0, -96}}, color = {255, 0, 0})}), - Documentation(info = " + Documentation( + info = " HeatCapacitor diff --git a/HeatTransfer/BasesClasses/LumpVolume.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/LumpVolume.mo similarity index 68% rename from HeatTransfer/BasesClasses/LumpVolume.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/LumpVolume.mo index 1c3a733..741952d 100644 --- a/HeatTransfer/BasesClasses/LumpVolume.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/LumpVolume.mo @@ -1,60 +1,74 @@ within TAeZoSysPro.HeatTransfer.BasesClasses; model LumpVolume - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; + + import TAeZoSysPro.HeatTransfer.Types.Dynamics; // Medium is declared //replaceable package Medium = Modelica.Media.Air.ReferenceAir.Air_pT; -// replaceable package Medium = TAeZoSysPro.Media.Air.SimpleAir ; - - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; - Medium.BaseProperties medium(preferredMediumStates= true, p = p, Xi = Medium.reference_X[1:Medium.nXi]) ; //preferredMediumStates = true for having a static state selection - + // replaceable package Medium = TAeZoSysPro.Media.Air.SimpleAir ; + + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + Medium.BaseProperties medium(preferredMediumStates = true, p = p, Xi = Medium.reference_X[1 : Medium.nXi]); //preferredMediumStates = true for having a static state selection + // User defined parameters - parameter Modelica.SIunits.Volume V = 1 "Air node volume [m3]"; - parameter Dynamics energyDynamics = Dynamics.FixedInitial "Formulation of energy balance"; - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if not steady state"; - final parameter Modelica.SIunits.Pressure p = Medium.reference_p "Constant pressure"; - + parameter Modelica.SIunits.Volume V = 1 + "Air node volume [m3]"; + parameter Dynamics energyDynamics = Dynamics.FixedInitial + "Formulation of energy balance"; + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if not steady state"; + final parameter Modelica.SIunits.Pressure p = Medium.reference_p + "Constant pressure"; + //Internal variables - Modelica.SIunits.Energy E "Energy storage"; - Modelica.SIunits.Mass m "Mass of the volume"; - Medium.Temperature T "temperature of the fluid"; + Modelica.SIunits.Energy E + "Energy storage"; + Modelica.SIunits.Mass m + "Mass of the volume"; + Medium.Temperature T + "temperature of the fluid"; - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a annotation( - Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -4}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -4}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); initial equation - E = 0.0 ; -// Initialisation + + E = 0.0; + // Initialisation if energyDynamics == Dynamics.SteadyStateInitial then - der(medium.T) = 0 "Zero time derivative at initilisation" ; - + der(medium.T) = 0 + "Zero time derivative at initilisation"; + elseif energyDynamics == Dynamics.FixedInitial then - T = T_start "Initial temperature" ; - + T = T_start + "Initial temperature"; + end if; - + equation T = medium.T; - -// Mass balance + + // Mass balance m = medium.d * V; - -// Energy balance + + // Energy balance if energyDynamics == Dynamics.SteadyState then port_a.Q_flow = 0; else m * der(medium.h) = port_a.Q_flow; end if; der(E) = port_a.Q_flow; - -// Port handover + + // Port handover port_a.T = T; - annotation( + + annotation ( Icon(graphics = {Ellipse(lineColor = {85, 85, 255}, fillColor = {85, 170, 255}, fillPattern = FillPattern.Solid, extent = {{100, 100}, {-100, -100}}, endAngle = 360), Text(origin = {24, -43}, extent = {{76, -17}, {-124, -57}}, textString = "V=%V")}, coordinateSystem(initialScale = 0.1)), - Documentation(info=" + Documentation( + info = " LumpVolume diff --git a/HeatTransfer/BasesClasses/PartialHeatExchanger.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/PartialHeatExchanger.mo similarity index 80% rename from HeatTransfer/BasesClasses/PartialHeatExchanger.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/PartialHeatExchanger.mo index ed49e79..d45e6d9 100644 --- a/HeatTransfer/BasesClasses/PartialHeatExchanger.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/PartialHeatExchanger.mo @@ -3,37 +3,49 @@ within TAeZoSysPro.HeatTransfer.BasesClasses; partial model PartialHeatExchanger //User defined parameters - parameter Modelica.SIunits.Area A = 1.0 "equivalent exchange surface area" annotation(Dialog(group="Geometrical parameters")); - + parameter Modelica.SIunits.Area A = 1.0 + "equivalent exchange surface area" + annotation (Dialog(group = "Geometrical parameters")); + // Internal variables - Real NTU "Number of transfer unit"; - Real Cr "Ratio of thermal condutance"; - Modelica.SIunits.Efficiency Eff "Exchanger effectiveness"; - Modelica.SIunits.ThermalConductance Qc_A(min=0) "Thermal flow rate unit of fluid A"; - Modelica.SIunits.ThermalConductance Qc_B(min=0) "Thermal flow rate unit of fluid B"; + Real NTU + "Number of transfer unit"; + Real Cr + "Ratio of thermal condutance"; + Modelica.SIunits.Efficiency Eff + "Exchanger effectiveness"; + Modelica.SIunits.ThermalConductance Qc_A(min = 0) + "Thermal flow rate unit of fluid A"; + Modelica.SIunits.ThermalConductance Qc_B(min = 0) + "Thermal flow rate unit of fluid B"; Modelica.SIunits.Temperature T_A_in, T_A_out, T_B_in, T_B_out; - Modelica.SIunits.CoefficientOfHeatTransfer h_global "Heat transfer coeffcient between fluid A and B" ; - Modelica.SIunits.HeatFlowRate Q_flow "Heat flow exchanged"; - Modelica.SIunits.Energy E "Energy passed throught the component" ; - - //Imported modules + Modelica.SIunits.CoefficientOfHeatTransfer h_global + "Heat transfer coeffcient between fluid A and B"; + Modelica.SIunits.HeatFlowRate Q_flow + "Heat flow exchanged"; + Modelica.SIunits.Energy E + "Energy passed throught the component"; + +//Imported modules initial equation - E = 0.0 ; + + E = 0.0; equation - Cr = min(Qc_A, Qc_B) / max( max(Qc_A, Qc_B), 1e3*Modelica.Constants.small) ; - NTU = h_global * A / max( min(Qc_A, Qc_B), 1e3*Modelica.Constants.small ) ; - Q_flow = Eff * min(Qc_A, Qc_B) * (T_A_in - T_B_in) ; - Q_flow + Qc_A * (T_A_out - T_A_in) = 0 ; - Qc_A * (T_A_out - T_A_in) + Qc_B * (T_B_out - T_B_in) = 0 ; - - der(E) = abs(Q_flow) ; - -annotation( + Cr = min(Qc_A, Qc_B) / max(max(Qc_A, Qc_B), 1e3 * Modelica.Constants.small); + NTU = h_global * A / max(min(Qc_A, Qc_B), 1e3 * Modelica.Constants.small); + Q_flow = Eff * min(Qc_A, Qc_B) * (T_A_in - T_B_in); + Q_flow + Qc_A * (T_A_out - T_A_in) = 0; + Qc_A * (T_A_out - T_A_in) + Qc_B * (T_B_out - T_B_in) = 0; + + der(E) = abs(Q_flow); + + annotation ( Icon(coordinateSystem(initialScale = 0.1), graphics = {Polygon(origin = {18, 50}, rotation = 180, fillColor = {213, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 0.5, points = {{-62, 36}, {-62, 14}, {78, 14}, {78, -16}, {98, -16}, {98, 36}, {-62, 36}}), Polygon(origin = {-18, -50}, fillColor = {255, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 0.5, points = {{-62, 36}, {-62, 14}, {78, 14}, {78, -18}, {98, -18}, {98, 36}, {-62, 36}}), Rectangle(origin = {-2, 0}, lineColor = {0, 161, 241}, fillColor = {211, 211, 211}, pattern = LinePattern.None, fillPattern = FillPattern.HorizontalCylinder, lineThickness = 0.5, extent = {{-86, 14}, {90, -14}}), Text(origin = {-48, -2}, lineThickness = 0.5, extent = {{-26, 12}, {122, -8}}, textString = "Fluid A", fontSize = 8), Text(origin = {-48, 28}, lineThickness = 0.5, extent = {{-26, 6}, {122, -8}}, textString = "Fluid B", fontSize = 8), Line(origin = {-48.1691, -0.0769465}, points = {{-12, 0}, {12, 0}}, color = {94, 94, 94}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {45.8309, -0.336488}, points = {{-12, 0}, {12, 0}}, color = {94, 94, 94}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {69.0506, -52.8561}, rotation = 90, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-69.2242, 50.9302}, rotation = 90, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-35.4227, 27.3271}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {33.5697, -26.3828}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {-35.3005, -26.0775}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5), Line(origin = {33.5697, 27.5256}, rotation = 180, points = {{-12, 0}, {12, 0}}, color = {207, 207, 207}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5)}), - Documentation(info = " + Documentation( + info = " PartialHeatExchanger diff --git a/HeatTransfer/BasesClasses/PartialWall.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/PartialWall.mo similarity index 57% rename from HeatTransfer/BasesClasses/PartialWall.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/PartialWall.mo index 8f0d62d..67a3ce1 100644 --- a/HeatTransfer/BasesClasses/PartialWall.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/PartialWall.mo @@ -1,106 +1,142 @@ within TAeZoSysPro.HeatTransfer.BasesClasses; model PartialWall + // imports - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid ; - import TAeZoSysPro.HeatTransfer.Types.MeshGrid ; - + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid; + import TAeZoSysPro.HeatTransfer.Types.MeshGrid; + // User defined parameters - parameter Integer N = integer(max(2, 5 * Th / 0.2 * 1e-6 / D_th) ) "Number of discrete layer from 2" annotation( - Dialog(group = "Mesh properties")); - parameter MeshGrid mesh = MeshGrid.uniform "Shape function selection for the mesh" annotation( - Dialog(group = "Mesh properties")); - parameter Real q = 1.2 "Growth rate (if geometricalGrowth)" annotation( - Dialog(group = "Mesh properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 "Decoupled value of the heat transfer coefficient (if biot)" annotation( - Dialog(group = "Mesh properties")); - parameter Boolean symmetricalMesh = true "Axial symmetry mesh where the axis is the middle of the domain" annotation( - Dialog(group = "Mesh properties")); - final parameter Modelica.SIunits.Position x[:] = - if mesh == MeshGrid.uniform then - MeshFunction.uniformGrid(L=Th, N=N) - elseif mesh == MeshGrid.geometricalGrowth then - MeshFunction.geometricalGrowthGrid(L=Th, N=N, q=q) - elseif mesh == MeshGrid.biotAndUniform then - MeshFunction.biotAndUniformGrid(L=Th, N=N, h=h, k=k) - elseif mesh == MeshGrid.biotAndGeometricalGrowth then - MeshFunction.biotAndGeometricalGrowthGrid(L=Th, N=N, h=h, k=k, q=q) - else - MeshFunction.uniformGrid(Th, N) "position of the vertices of the mesh" ; - - parameter Real add_on = 1 "Custom add-on"; - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance"; - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial"; + parameter Integer N = integer(max(2, 5 * Th / 0.2 * 1e-6 / D_th)) + "Number of discrete layer from 2" + annotation ( + Dialog(group = "Mesh properties")); + parameter MeshGrid mesh = MeshGrid.uniform + "Shape function selection for the mesh" + annotation ( + Dialog(group = "Mesh properties")); + parameter Real q = 1.2 + "Growth rate (if geometricalGrowth)" + annotation ( + Dialog(group = "Mesh properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 + "Decoupled value of the heat transfer coefficient (if biot)" + annotation ( + Dialog(group = "Mesh properties")); + parameter Boolean symmetricalMesh = true + "Axial symmetry mesh where the axis is the middle of the domain" + annotation ( + Dialog(group = "Mesh properties")); + final parameter Modelica.SIunits.Position x[:] = + if mesh == MeshGrid.uniform then + MeshFunction.uniformGrid(L = Th, N = N) + elseif mesh == MeshGrid.geometricalGrowth then + MeshFunction.geometricalGrowthGrid(L = Th, N = N, q = q) + elseif mesh == MeshGrid.biotAndUniform then + MeshFunction.biotAndUniformGrid(L = Th, N = N, h = h, k = k) + elseif mesh == MeshGrid.biotAndGeometricalGrowth then + MeshFunction.biotAndGeometricalGrowthGrid(L = Th, N = N, h = h, k = k, q = q) + else + MeshFunction.uniformGrid(Th, N) + "position of the vertices of the mesh"; + + parameter Real add_on = 1 + "Custom add-on"; + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance"; + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial"; // - parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 "Wall specific heat capacity" annotation( - Dialog(group = "Medium properties")); - parameter Modelica.SIunits.Density d = 0 "Wall density" annotation( - Dialog(group = "Medium properties")); - parameter Modelica.SIunits.ThermalConductivity k = 0 "Wall conductivity" annotation( - Dialog(group = "Medium properties")); + parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 + "Wall specific heat capacity" + annotation ( + Dialog(group = "Medium properties")); + parameter Modelica.SIunits.Density d = 0 + "Wall density" + annotation ( + Dialog(group = "Medium properties")); + parameter Modelica.SIunits.ThermalConductivity k = 0 + "Wall conductivity" + annotation ( + Dialog(group = "Medium properties")); // - parameter Modelica.SIunits.Thickness Th = 0 "Material thickness" annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Area A = 1 "Wall area" annotation( - Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Thickness Th = 0 + "Material thickness" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Area A = 1 + "Wall area" + annotation ( + Dialog(group = "Geometrical properties")); // Internal variables - Modelica.SIunits.Energy E "Energy stored in the wall"; - /*final parameter */Modelica.SIunits.Position[N+2] x_node = cat(1, {0},{(x[i+1]+x[i])/2 for i in 1:N}, {Th}) ; + Modelica.SIunits.Energy E + "Energy stored in the wall"; + /*final parameter */ + Modelica.SIunits.Position[N + 2] x_node = cat(1, {0}, {(x[i + 1] + x[i]) / 2 for i in 1 : N}, {Th}); // Imported components - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a annotation( - Placement(visible = true, transformation(origin = {-98, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-98, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b annotation( - Placement(visible = true, transformation(origin = {98, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {98, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - PDE.ThermalDiffusion.CentralSecondOrder centralSecondOrder( - N = N, - CoeffTimeDer=if energyDynamics == Dynamics.SteadyState then 0.0 else 1.0, - CoeffSpaceDer=-D_th, - SourceTerm = fill(0.0, N), - x=x, - SteadyState = energyDynamics == Dynamics.SteadyState) annotation( - Placement(visible = true, transformation(origin = {-2, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - - -final parameter Modelica.SIunits.ThermalDiffusionCoefficient D_th = k*add_on / (d * cp) "Thermal diffusivity"; + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {-98, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-98, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b + annotation ( + Placement(visible = true, transformation(origin = {98, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {98, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + PDE.ThermalDiffusion.CentralSecondOrder centralSecondOrder( + N = N, + CoeffTimeDer = if energyDynamics == Dynamics.SteadyState then 0.0 else 1.0, + CoeffSpaceDer = -D_th, + SourceTerm = fill(0.0, N), + x = x, + SteadyState = energyDynamics == Dynamics.SteadyState) + annotation ( + Placement(visible = true, transformation(origin = {-2, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + + final parameter Modelica.SIunits.ThermalDiffusionCoefficient D_th = k * add_on / (d * cp) + "Thermal diffusivity"; initial equation + // Energy at time 0 second is equal to 0J E = 0; - + if energyDynamics == Dynamics.SteadyStateInitial then -// centralSecondOrder.u[2:end - 1] = {port_a.T - (port_a.T - port_b.T) / Th * (x[i - 1] + (x[i] - x[i - 1]) / 2) for i in 2:N + 1}; - der(centralSecondOrder.u[2:end-1]) = fill(0.0, N) ; - + // centralSecondOrder.u[2:end - 1] = {port_a.T - (port_a.T - port_b.T) / Th * (x[i - 1] + (x[i] - x[i - 1]) / 2) for i in 2:N + 1}; + der(centralSecondOrder.u[2 : end - 1]) = fill(0.0, N); + elseif energyDynamics == Dynamics.FixedInitial then - centralSecondOrder.u[2:end - 1] = fill(T_start, N) "Initial Condition"; - + centralSecondOrder.u[2 : end - 1] = fill(T_start, N) + "Initial Condition"; + end if; - + equation + // Energy is calculated - der(E) = port_a.Q_flow + port_b.Q_flow "Energy stored"; + der(E) = port_a.Q_flow + port_b.Q_flow + "Energy stored"; // - //D_th = k / (d * cp); + //D_th = k / (d * cp); //PDE - // determination of ghost node value - port_a.Q_flow + (centralSecondOrder.u[2] - centralSecondOrder.u[1]) / ((x[2] - x[1])/2) * k*add_on * A = 0.0 "flux conservation"; - - port_b.Q_flow - (centralSecondOrder.u[end] - centralSecondOrder.u[end-1]) / ((x[end]-x[end-1])/2) * k*add_on * A = 0.0 "flux conservation" ; - - - port_a.T = centralSecondOrder.u[1] ; - port_b.T = centralSecondOrder.u[end] ; + // determination of ghost node value + port_a.Q_flow + (centralSecondOrder.u[2] - centralSecondOrder.u[1]) / ((x[2] - x[1]) / 2) * k * add_on * A = 0.0 + "flux conservation"; + + port_b.Q_flow - (centralSecondOrder.u[end] - centralSecondOrder.u[end - 1]) / ((x[end] - x[end - 1]) / 2) * k * add_on * A = 0.0 + "flux conservation"; + + port_a.T = centralSecondOrder.u[1]; + port_b.T = centralSecondOrder.u[end]; + // for increasing stability, the following boundary condition can be used -// port_a.T = centralSecondOrder.u[2]; -// port_b.T = centralSecondOrder.u[end-1] ; - - - annotation( - Documentation(info = " + // port_a.T = centralSecondOrder.u[2]; + // port_b.T = centralSecondOrder.u[end-1] ; + + annotation ( + Documentation( + info = " PartialWall @@ -179,7 +215,8 @@ equation

        -"),uses(Modelica(version = "3.2.3")), +"), + uses(Modelica(version = "3.2.3")), Icon(graphics = {Line(origin = {-90, 0}, points = {{-10, 0}, {20, 0}}, thickness = 1), Rectangle(origin = {-60, -1}, lineThickness = 1, extent = {{10, -3}, {-10, 5}}), Rectangle(origin = {-20, -1}, lineThickness = 1, extent = {{10, -3}, {-10, 5}}), Rectangle(origin = {20, -1}, lineThickness = 1, extent = {{10, -3}, {-10, 5}}), Rectangle(origin = {60, -1}, lineThickness = 1, extent = {{10, -3}, {-10, 5}}), Line(origin = {80, 0}, points = {{-10, 0}, {20, 0}}, thickness = 1), Line(origin = {-40, -10}, points = {{0, 10}, {0, -10}}, thickness = 1), Line(points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {40, 0}, points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {-40, 0}, points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {-40, -20}, points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {-40, -26}, points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {0, -20}, points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {0, -26}, points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {40, -20}, points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {40, -26}, points = {{-10, 0}, {10, 0}}, thickness = 1), Line(origin = {0, -10}, points = {{0, 10}, {0, -10}}, thickness = 1), Line(origin = {40, -10}, points = {{0, 10}, {0, -10}}, thickness = 1), Line(origin = {-40, -36}, points = {{0, 10}, {0, -4}}, thickness = 1), Line(origin = {0, -36}, points = {{0, 10}, {0, -4}}, thickness = 1), Line(origin = {40, -36}, points = {{0, 10}, {0, -4}}, thickness = 1), Line(origin = {-38, -40}, points = {{-10, 0}, {6, 0}}, thickness = 1), Line(origin = {-34, -44}, points = {{-10, 0}, {-2, 0}}, thickness = 1), Line(origin = {2, -40}, points = {{-10, 0}, {6, 0}}, thickness = 1), Line(origin = {42, -40}, points = {{-10, 0}, {6, 0}}, thickness = 1), Line(origin = {6, -44}, points = {{-10, 0}, {-2, 0}}, thickness = 1), Line(origin = {46, -44}, points = {{-10, 0}, {-2, 0}}, thickness = 1), Rectangle(fillColor = {229, 229, 229}, lineThickness = 1, extent = {{-80, 80}, {80, -80}})}, coordinateSystem(initialScale = 0.1))); end PartialWall; diff --git a/HeatTransfer/BasesClasses/package.mo b/src/TAeZoSysPro/HeatTransfer/BasesClasses/package.mo similarity index 98% rename from HeatTransfer/BasesClasses/package.mo rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/package.mo index 892d34b..0fedae1 100644 --- a/HeatTransfer/BasesClasses/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/BasesClasses/package.mo @@ -1,5 +1,7 @@ within TAeZoSysPro.HeatTransfer; package BasesClasses + extends Modelica.Icons.BasesPackage; + end BasesClasses; diff --git a/HeatTransfer/BasesClasses/package.order b/src/TAeZoSysPro/HeatTransfer/BasesClasses/package.order similarity index 100% rename from HeatTransfer/BasesClasses/package.order rename to src/TAeZoSysPro/HeatTransfer/BasesClasses/package.order diff --git a/HeatTransfer/Components/CabinetPower.mo b/src/TAeZoSysPro/HeatTransfer/Components/CabinetPower.mo similarity index 53% rename from HeatTransfer/Components/CabinetPower.mo rename to src/TAeZoSysPro/HeatTransfer/Components/CabinetPower.mo index 7d36979..7215284 100644 --- a/HeatTransfer/Components/CabinetPower.mo +++ b/src/TAeZoSysPro/HeatTransfer/Components/CabinetPower.mo @@ -1,126 +1,197 @@ within TAeZoSysPro.HeatTransfer.Components; model CabinetPower - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - // Media - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; + + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + // Media + replaceable package Medium = TAeZoSysPro.Media.MyMedia; // User defined temperature - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance" annotation( - Dialog(group="Dynamic properties")); - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial" annotation( - Dialog(group="Dynamic properties")); - parameter Real add_on_conv = 1 "Custom add_on for convection" annotation( - Dialog(group="Dynamic properties")); - + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Real add_on_conv = 1 + "Custom add_on for convection" + annotation ( + Dialog(group = "Dynamic properties")); + // - parameter Modelica.SIunits.Area A_conv_emitter = 0 "Convection area emitter" annotation( - Dialog(group = "Emitter")); - parameter Modelica.SIunits.Area A_rad_emitter = 0 "Radiative area emitter" annotation( - Dialog(group = "Emitter")); - parameter Modelica.SIunits.Height Lc_emitter = 0 "Characteristic length emitter for convection correlation" annotation( - Dialog(group = "Emitter")); - parameter Modelica.SIunits.SpecificHeatCapacity cp_emitter = 0 "Specific heat capacity of emitter" annotation( - Dialog(group = "Emitter")); - parameter Modelica.SIunits.Mass m_emitter = 0 "Mass of emitter" annotation( - Dialog(group = "Emitter")); - parameter Modelica.SIunits.Emissivity eps_emitter = 1 "Emitter emissivity" annotation( - Dialog(group = "Emitter")); + parameter Modelica.SIunits.Area A_conv_emitter = 0 + "Convection area emitter" + annotation ( + Dialog(group = "Emitter")); + parameter Modelica.SIunits.Area A_rad_emitter = 0 + "Radiative area emitter" + annotation ( + Dialog(group = "Emitter")); + parameter Modelica.SIunits.Height Lc_emitter = 0 + "Characteristic length emitter for convection correlation" + annotation ( + Dialog(group = "Emitter")); + parameter Modelica.SIunits.SpecificHeatCapacity cp_emitter = 0 + "Specific heat capacity of emitter" + annotation ( + Dialog(group = "Emitter")); + parameter Modelica.SIunits.Mass m_emitter = 0 + "Mass of emitter" + annotation ( + Dialog(group = "Emitter")); + parameter Modelica.SIunits.Emissivity eps_emitter = 1 + "Emitter emissivity" + annotation ( + Dialog(group = "Emitter")); // - parameter Modelica.SIunits.Area A_in_casing = 0 "Inner area of casing" annotation( - Dialog(group = "Assembly")); - parameter Modelica.SIunits.Area A_conv_casing = 0 "Convection outer area of casing" annotation( - Dialog(group = "Assembly")); - parameter Modelica.SIunits.Area A_rad_casing = 0 "Radiative outer area of casing" annotation( - Dialog(group = "Assembly")); - parameter Modelica.SIunits.Height Lc_casing = 0 "Characteristic length of casing" annotation( - Dialog(group = "Assembly")); - parameter Modelica.SIunits.SpecificHeatCapacity cp_casing = 0 "Specific heat capacity of assembly" annotation( - Dialog(group = "Assembly")); - parameter Modelica.SIunits.Mass m_casing = 0 "Mass of Casing" annotation( - Dialog(group = "Assembly")); - parameter Modelica.SIunits.Emissivity eps_casing = 1 "Casing emissivity" annotation( - Dialog(group = "Assembly")); + parameter Modelica.SIunits.Area A_in_casing = 0 + "Inner area of casing" + annotation ( + Dialog(group = "Assembly")); + parameter Modelica.SIunits.Area A_conv_casing = 0 + "Convection outer area of casing" + annotation ( + Dialog(group = "Assembly")); + parameter Modelica.SIunits.Area A_rad_casing = 0 + "Radiative outer area of casing" + annotation ( + Dialog(group = "Assembly")); + parameter Modelica.SIunits.Height Lc_casing = 0 + "Characteristic length of casing" + annotation ( + Dialog(group = "Assembly")); + parameter Modelica.SIunits.SpecificHeatCapacity cp_casing = 0 + "Specific heat capacity of assembly" + annotation ( + Dialog(group = "Assembly")); + parameter Modelica.SIunits.Mass m_casing = 0 + "Mass of Casing" + annotation ( + Dialog(group = "Assembly")); + parameter Modelica.SIunits.Emissivity eps_casing = 1 + "Casing emissivity" + annotation ( + Dialog(group = "Assembly")); // Internal variables - Modelica.SIunits.Energy E_released "Energy released into the environement"; + Modelica.SIunits.Energy E_released + "Energy released into the environement"; // Imported modules - Modelica.Thermal.HeatTransfer.Components.BodyRadiation radiation_emitter_casing(Gr = A_rad_emitter / (1 / eps_emitter + A_rad_emitter / A_in_casing * (1 / eps_casing - 1))) annotation( - Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation radiation_outer_casing(A = A_rad_casing, eps = eps_casing) annotation( - Placement(visible = true, transformation(origin = {60, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_conv "To air thermal mass" annotation( - Placement(visible = true, transformation(origin = {102, 28}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_rad "To J MRT" annotation( - Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_hood annotation( - Placement(visible = true, transformation(origin = {48, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {1, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput F_view annotation( - Placement(visible = true, transformation(origin = {107, -34}, extent = {{-20, -20}, {20, 20}}, rotation = 180), iconTransformation(origin = {-99, 79}, extent = {{-11, -11}, {11, 11}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall annotation( - Placement(visible = true, transformation(origin = {109, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 34}, extent = {{-10, -10}, {10, 10}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor mass_emitter(T_start = T_start, cp = cp_emitter,energyDynamics = energyDynamics, m = m_emitter) annotation( - Placement(visible = true, transformation(origin = {-57, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput Heatload_Variable annotation( - Placement(visible = true, transformation(origin = {-115, 16}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-1.9984e-15, -100}, extent = {{-20, -20}, {20, 20}}, rotation = 90))); - TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor mass_casing(T_start = T_start, cp = cp_casing, energyDynamics = energyDynamics, m = m_casing) annotation( - Placement(visible = true, transformation(origin = {31, -28}, extent = {{-10, -10}, {10, 10}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor Inlet_Air_Temperature annotation( - Placement(visible = true, transformation(origin = {59.5, 49.5}, extent = {{-5.5, -5.5}, {5.5, 5.5}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection_dT_decoupled convection_emitter( A = A_conv_emitter, Lc = Lc_emitter, add_on = add_on_conv, correlation = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation.vertical_plate_ASHRAE) annotation( - Placement(visible = true, transformation(origin = {-57, 64}, extent = {{-10, 10}, {10, -10}}, rotation = 90))); - TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection_dT_decoupled convection_inner_casing( A = A_in_casing, Lc = Lc_casing, add_on = add_on_conv, correlation = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation.vertical_plate_ASHRAE) annotation( - Placement(visible = true, transformation(origin = {31, 64}, extent = {{-10, 10}, {10, -10}}, rotation = 90))); - TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection convection_outer_casing( A = A_conv_casing, Lc = Lc_casing, add_on = add_on_conv, correlation = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation.vertical_plate_ASHRAE) annotation( - Placement(visible = true, transformation(origin = {60, 28}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow prescribedHeatFlow annotation( - Placement(visible = true, transformation(origin = {-74, 16}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Components.BodyRadiation radiation_emitter_casing(Gr = A_rad_emitter / (1 / eps_emitter + A_rad_emitter / A_in_casing * (1 / eps_casing - 1))) + annotation ( + Placement(visible = true, transformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation radiation_outer_casing(A = A_rad_casing, eps = eps_casing) + annotation ( + Placement(visible = true, transformation(origin = {60, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_conv + "To air thermal mass" + annotation ( + Placement(visible = true, transformation(origin = {102, 28}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_rad + "To J MRT" + annotation ( + Placement(visible = true, transformation(origin = {102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_hood + annotation ( + Placement(visible = true, transformation(origin = {48, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {1, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput F_view + annotation ( + Placement(visible = true, transformation(origin = {107, -34}, extent = {{-20, -20}, {20, 20}}, rotation = 180), iconTransformation(origin = {-99, 79}, extent = {{-11, -11}, {11, 11}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall + annotation ( + Placement(visible = true, transformation(origin = {109, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 34}, extent = {{-10, -10}, {10, 10}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor mass_emitter(T_start = T_start, cp = cp_emitter, energyDynamics = energyDynamics, m = m_emitter) + annotation ( + Placement(visible = true, transformation(origin = {-57, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput Heatload_Variable + annotation ( + Placement(visible = true, transformation(origin = {-115, 16}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-1.9984e-15, -100}, extent = {{-20, -20}, {20, 20}}, rotation = 90))); + TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor mass_casing(T_start = T_start, cp = cp_casing, energyDynamics = energyDynamics, m = m_casing) + annotation ( + Placement(visible = true, transformation(origin = {31, -28}, extent = {{-10, -10}, {10, 10}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor Inlet_Air_Temperature + annotation ( + Placement(visible = true, transformation(origin = {59.5, 49.5}, extent = {{-5.5, -5.5}, {5.5, 5.5}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection_dT_decoupled convection_emitter(A = A_conv_emitter, Lc = Lc_emitter, add_on = add_on_conv, correlation = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation.vertical_plate_ASHRAE) + annotation ( + Placement(visible = true, transformation(origin = {-57, 64}, extent = {{-10, 10}, {10, -10}}, rotation = 90))); + TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection_dT_decoupled convection_inner_casing(A = A_in_casing, Lc = Lc_casing, add_on = add_on_conv, correlation = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation.vertical_plate_ASHRAE) + annotation ( + Placement(visible = true, transformation(origin = {31, 64}, extent = {{-10, 10}, {10, -10}}, rotation = 90))); + TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection convection_outer_casing(A = A_conv_casing, Lc = Lc_casing, add_on = add_on_conv, correlation = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation.vertical_plate_ASHRAE) + annotation ( + Placement(visible = true, transformation(origin = {60, 28}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow prescribedHeatFlow + annotation ( + Placement(visible = true, transformation(origin = {-74, 16}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); initial equation - E_released = 0.0 ; + + E_released = 0.0; equation - connect(F_view, radiation_outer_casing.Fview) annotation( - Line(points = {{107, -34}, {52, -34}, {52, -8}, {52, -8}}, color = {0, 0, 127})); - connect(prescribedHeatFlow.port, mass_emitter.port) annotation( - Line(points = {{-64, 16}, {-57, 16}, {-57, -20}, {-57, -20}}, color = {191, 0, 0})); - connect(radiation_emitter_casing.port_a, mass_emitter.port) annotation( - Line(points = {{-10, 0}, {-57, 0}, {-57, -20}, {-57, -20}}, color = {191, 0, 0})); - connect(mass_casing.port, convection_inner_casing.port_a) annotation( - Line(points = {{31, -18.2}, {31, -18.2}, {31, 53.8}, {31, 53.8}}, color = {191, 0, 0})); - connect(convection_outer_casing.port_a, mass_casing.port) annotation( - Line(points = {{50, 28}, {31, 28}, {31, -18}, {31, -18}}, color = {191, 0, 0})); - connect(convection_outer_casing.port_b, port_conv) annotation( - Line(points = {{70, 28}, {100, 28}, {100, 28}, {102, 28}}, color = {191, 0, 0})); - connect(Inlet_Air_Temperature.port, port_conv) annotation( - Line(points = {{65, 49.5}, {83, 49.5}, {83, 27.5}, {102, 27.5}, {102, 27.5}}, color = {191, 0, 0})); - connect(radiation_outer_casing.port_b, port_rad) annotation( - Line(points = {{70, 0}, {104, 0}, {104, 0}, {102, 0}}, color = {191, 0, 0})); - connect(convection_emitter.port_b, port_hood) annotation( - Line(points = {{-57, 74}, {-57, 74}, {-57, 92}, {48, 92}, {48, 90}}, color = {191, 0, 0})); - connect(convection_inner_casing.port_b, port_hood) annotation( - Line(points = {{31, 74}, {31, 92}, {48, 92}, {48, 90}}, color = {191, 0, 0})); - connect(Heatload_Variable, prescribedHeatFlow.Q_flow) annotation( - Line(points = {{-115, 16}, {-86, 16}, {-86, 16}, {-84, 16}}, color = {0, 0, 127})); - connect(Inlet_Air_Temperature.T, convection_emitter.T_fluid) annotation( - Line(points = {{54, 49.5}, {-32, 49.5}, {-32, 65.5}, {-49, 65.5}, {-49, 65.5}}, color = {0, 0, 127})); - connect(Inlet_Air_Temperature.T, convection_inner_casing.T_fluid) annotation( - Line(points = {{54, 49.5}, {46, 49.5}, {46, 65.5}, {39, 65.5}}, color = {0, 0, 127})); - connect(prescribedHeatFlow.port, convection_emitter.port_a) annotation( - Line(points = {{-64, 16}, {-57, 16}, {-57, 54}, {-57, 54}}, color = {191, 0, 0})); -// Energy released is calculated + + connect(F_view, radiation_outer_casing.Fview) + annotation ( + Line(points = {{107, -34}, {52, -34}, {52, -8}, {52, -8}}, color = {0, 0, 127})); + connect(prescribedHeatFlow.port, mass_emitter.port) + annotation ( + Line(points = {{-64, 16}, {-57, 16}, {-57, -20}, {-57, -20}}, color = {191, 0, 0})); + connect(radiation_emitter_casing.port_a, mass_emitter.port) + annotation ( + Line(points = {{-10, 0}, {-57, 0}, {-57, -20}, {-57, -20}}, color = {191, 0, 0})); + connect(mass_casing.port, convection_inner_casing.port_a) + annotation ( + Line(points = {{31, -18.2}, {31, -18.2}, {31, 53.8}, {31, 53.8}}, color = {191, 0, 0})); + connect(convection_outer_casing.port_a, mass_casing.port) + annotation ( + Line(points = {{50, 28}, {31, 28}, {31, -18}, {31, -18}}, color = {191, 0, 0})); + connect(convection_outer_casing.port_b, port_conv) + annotation ( + Line(points = {{70, 28}, {100, 28}, {100, 28}, {102, 28}}, color = {191, 0, 0})); + connect(Inlet_Air_Temperature.port, port_conv) + annotation ( + Line(points = {{65, 49.5}, {83, 49.5}, {83, 27.5}, {102, 27.5}, {102, 27.5}}, color = {191, 0, 0})); + connect(radiation_outer_casing.port_b, port_rad) + annotation ( + Line(points = {{70, 0}, {104, 0}, {104, 0}, {102, 0}}, color = {191, 0, 0})); + connect(convection_emitter.port_b, port_hood) + annotation ( + Line(points = {{-57, 74}, {-57, 74}, {-57, 92}, {48, 92}, {48, 90}}, color = {191, 0, 0})); + connect(convection_inner_casing.port_b, port_hood) + annotation ( + Line(points = {{31, 74}, {31, 92}, {48, 92}, {48, 90}}, color = {191, 0, 0})); + connect(Heatload_Variable, prescribedHeatFlow.Q_flow) + annotation ( + Line(points = {{-115, 16}, {-86, 16}, {-86, 16}, {-84, 16}}, color = {0, 0, 127})); + connect(Inlet_Air_Temperature.T, convection_emitter.T_fluid) + annotation ( + Line(points = {{54, 49.5}, {-32, 49.5}, {-32, 65.5}, {-49, 65.5}, {-49, 65.5}}, color = {0, 0, 127})); + connect(Inlet_Air_Temperature.T, convection_inner_casing.T_fluid) + annotation ( + Line(points = {{54, 49.5}, {46, 49.5}, {46, 65.5}, {39, 65.5}}, color = {0, 0, 127})); + connect(prescribedHeatFlow.port, convection_emitter.port_a) + annotation ( + Line(points = {{-64, 16}, {-57, 16}, {-57, 54}, {-57, 54}}, color = {191, 0, 0})); + // Energy released is calculated der(E_released) = port_hood.Q_flow + port_conv.Q_flow + port_rad.Q_flow; -// Ports handover + // Ports handover A_wall = A_rad_casing; - connect(radiation_outer_casing.port_a, mass_casing.port) annotation( - Line(points = {{50, 0}, {30, 0}, {30, -18}, {32, -18}}, color = {191, 0, 0})); - connect(radiation_emitter_casing.port_b, mass_casing.port) annotation( - Line(points = {{10, 0}, {30, 0}, {30, -18}, {32, -18}}, color = {191, 0, 0})); - annotation( + connect(radiation_outer_casing.port_a, mass_casing.port) + annotation ( + Line(points = {{50, 0}, {30, 0}, {30, -18}, {32, -18}}, color = {191, 0, 0})); + connect(radiation_emitter_casing.port_b, mass_casing.port) + annotation ( + Line(points = {{10, 0}, {30, 0}, {30, -18}, {32, -18}}, color = {191, 0, 0})); + + annotation ( uses(Modelica(version = "3.2.3")), Dialog(group = "Component two"), Diagram(graphics = {Rectangle(origin = {-54.5, -3}, fillColor = {222, 222, 222}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-39.5, 93}, {39.5, -93}}), Rectangle(origin = {51.5, -3}, fillColor = {222, 222, 222}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-39.5, 93}, {39.5, -93}}), Text(origin = {-66, -89}, lineThickness = 1, extent = {{-29, -7}, {51, 9}}, textString = "Emitter"), Text(origin = {54.5, -88}, lineThickness = 1, extent = {{-42.5, -8}, {36.5, 8}}, textString = "Casing"), Text(origin = {75.5, 80}, lineThickness = 1, extent = {{-42.5, -8}, {13.5, 2}}, textString = "Hood node")}, coordinateSystem(initialScale = 0.1)), Icon(graphics = {Text(origin = {66, -104}, extent = {{2, -8}, {-46, 14}}, textString = "Heat Load"), Text(origin = {-114, -14}, rotation = 180, extent = {{6, -2}, {-34, 18}}, textString = "J_MRT"), Rectangle(fillColor = {184, 51, 11}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-20, 20}, {20, -20}}), Line(origin = {0, -50.55}, rotation = 180, points = {{0, -26}, {0, 18}}, color = {255, 0, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-50, -0.55}, rotation = 90, points = {{0, -26}, {0, -8}}, color = {255, 0, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-40, 82}, extent = {{-22, -6}, {-46, 14}}, textString = "F_view"), Text(origin = {-60, 46}, extent = {{-6, -6}, {-46, 14}}, textString = "A_rad_casing"), Text(origin = {18, 112}, extent = {{32, -12}, {2, 8}}, textString = "Hood"), Text(origin = {78, 22}, extent = {{40, -10}, {4, 6}}, textString = "Fluid"), Line(origin = {-40, 20}, points = {{-20, -80}, {-20, 60}, {20, 60}}, thickness = 2), Line(origin = {40, 20}, points = {{20, -80}, {20, 60}, {-20, 60}}, thickness = 2), Line(origin = {0, -80}, points = {{-60, 0}, {60, 0}}, thickness = 2), Ellipse(origin = {-3, 91}, lineThickness = 2, extent = {{-17, -1}, {23, -21}}, endAngle = 360), Line(origin = {-50.5454, -69.0254}, points = {{-10, -11}, {-10, 9}}, pattern = LinePattern.Dot, thickness = 1), Line(origin = {70.3659, -68.8599}, points = {{-10, -11}, {-10, 9}}, pattern = LinePattern.Dot, thickness = 1), Line(origin = {-41, 15}, points = {{-39, -85}, {-19, -85}, {-11, -83}, {-9, -75}, {-9, 45}, {-3, 51}, {5, 55}, {21, 55}, {29, 57}, {33, 65}, {33, 85}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}, arrowSize = 5), Line(origin = {44, 15}, points = {{36, -85}, {16, -85}, {8, -83}, {6, -75}, {6, 45}, {4, 53}, {-4, 55}, {-24, 55}, {-32, 57}, {-34, 65}, {-34, 85}}, color = {0, 85, 255}, thickness = 1, arrow = {Arrow.Filled, Arrow.Filled}, arrowSize = 5), Line(origin = {50.07, -0.38}, rotation = -90, points = {{0, -26}, {0, -8}}, color = {255, 0, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {15.64, -3}, points = {{-17.6391, 53}, {-17.6391, 43}, {-13.6391, 35}, {-5.63908, 33}, {2.3609, 33}, {8.3609, 29}, {12.3609, 23}, {12.3609, -17}, {10.3609, -25}, {2.36092, -29}, {0.36092, -29}, {-5.63908, -31}, {-7.6391, -37}, {-7.6391, -47}}, color = {0, 85, 255}, thickness = 0.75, arrow = {Arrow.Filled, Arrow.Filled}, arrowSize = 4), Line(origin = {-18, -0.36}, points = {{8, -51.6391}, {8, -41.6391}, {6, -33.6391}, {-2, -31.6391}, {-4, -31.6391}, {-10, -27.6391}, {-12, -21.6391}, {-12, 18.3609}, {-8, 24.3609}, {-2, 28.3609}, {4, 28.3609}, {14, 30.3609}, {18, 38.3609}}, color = {0, 85, 255}, thickness = 0.75, arrow = {Arrow.Filled, Arrow.None}, arrowSize = 4), Line(origin = {-28.7119, 40.0462}, rotation = -90, points = {{0, -26}, {0, -8}}, color = {255, 0, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-29.0928, -39.557}, rotation = -90, points = {{0, -26}, {0, -8}}, color = {255, 0, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {30.4806, 39.4998}, rotation = 90, points = {{0, -26}, {0, -8}}, color = {255, 0, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {30.0997, -40.1034}, rotation = 90, points = {{0, -26}, {0, -8}}, color = {255, 0, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-73, 0}, points = {{11, 0}, {7, 0}, {5, -6}, {1, 6}, {-3, -6}, {-7, 6}, {-9, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 0.75, arrow = {Arrow.None, Arrow.Filled}, arrowSize = 5)}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " + Documentation( + info = " CabinetPower diff --git a/HeatTransfer/Components/ConnectionSwith.mo b/src/TAeZoSysPro/HeatTransfer/Components/ConnectionSwith.mo similarity index 69% rename from HeatTransfer/Components/ConnectionSwith.mo rename to src/TAeZoSysPro/HeatTransfer/Components/ConnectionSwith.mo index f8deafb..0012dbf 100644 --- a/HeatTransfer/Components/ConnectionSwith.mo +++ b/src/TAeZoSysPro/HeatTransfer/Components/ConnectionSwith.mo @@ -1,31 +1,37 @@ within TAeZoSysPro.HeatTransfer.Components; model ConnectionSwith - Modelica.Blocks.Interfaces.BooleanInput Control annotation( - Placement(visible = true, transformation(origin = { 0, 100}, extent = {{-20, -20}, {20, 20}}, rotation = -90), iconTransformation(origin = {0, 100}, extent = {{-20, -20}, {20, 20}}, rotation = -90))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a annotation( - Placement(visible = true, transformation(origin = {-99, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b1 annotation( - Placement(visible = true, transformation(origin = {98, 64}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b2 annotation( - Placement(visible = true, transformation(origin = {98, -62}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {98, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + + Modelica.Blocks.Interfaces.BooleanInput Control + annotation ( + Placement(visible = true, transformation(origin = {0, 100}, extent = {{-20, -20}, {20, 20}}, rotation = -90), iconTransformation(origin = {0, 100}, extent = {{-20, -20}, {20, 20}}, rotation = -90))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {-99, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-102, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b1 + annotation ( + Placement(visible = true, transformation(origin = {98, 64}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b2 + annotation ( + Placement(visible = true, transformation(origin = {98, -62}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {98, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); equation - if Control == true then /* port_a is connected to port_b1, port_b2 has a zero flow equation */ + if Control == true then /* port_a is connected to port_b1, port_b2 has a zero flow equation */ port_b1.T = port_a.T; port_b1.Q_flow + port_a.Q_flow = 0.0; port_b2.Q_flow = 0; - + else /* port_a is connected to port_b2, port_b1 has a zero flow equation */ port_b2.T = port_a.T; port_b2.Q_flow + port_a.Q_flow = 0.0; port_b1.Q_flow = 0; - -end if ; - annotation( - Documentation(info = " + end if; + + annotation ( + Documentation( + info = " ConnectionSwith @@ -51,4 +57,5 @@ end if ; "), Diagram(coordinateSystem(grid = {1, 1})), Icon(graphics = {Rectangle(origin = {0, 1}, lineThickness = 1, extent = {{-100, 99}, {100, -101}}), Line(origin = {-58.6794, -0.73282}, points = {{-37, 0}, {11, 0}}, color = {255, 0, 0}, thickness = 1), Ellipse(origin = {-44, 0}, fillColor = {255, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{2, -2}, {-2, 2}}, endAngle = 360), Ellipse(origin = {40, 50}, fillColor = {255, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{2, -2}, {-2, 2}}, endAngle = 360), Line(origin = {68, 50}, points = {{-28, 0}, {28, 0}, {28, 0}}, color = {255, 0, 0}, thickness = 1), Line(origin = {-1, 10}, points = {{-43, -10}, {37, 40}}, color = {255, 0, 0}, thickness = 1), Line(origin = {0, 15.5}, points = {{0, 64.5}, {0, 12.5}, {0, 28.5}}, color = {255, 0, 255}, thickness = 1), Text(origin = {61, 60}, lineThickness = 1, extent = {{35, 20}, {-45, 0}}, textString = "Control = true"), Ellipse(origin = {40, -50}, fillColor = {255, 0, 0}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{2, -2}, {-2, 2}}, endAngle = 360), Line(origin = {68.3817, -50.3206}, points = {{-28, 0}, {28, 0}, {28, 0}}, color = {255, 0, 0}, thickness = 1), Text(origin = {61, -78}, lineThickness = 1, extent = {{35, 20}, {-45, 0}}, textString = "Control = false"), Text(origin = {-35, 80}, lineColor = {255, 0, 255}, fillColor = {255, 0, 255}, lineThickness = 1, extent = {{35, 20}, {-45, 0}}, textString = "Control")}, coordinateSystem(initialScale = 0.1))); + end ConnectionSwith; diff --git a/src/TAeZoSysPro/HeatTransfer/Components/FanVentilation.mo b/src/TAeZoSysPro/HeatTransfer/Components/FanVentilation.mo new file mode 100644 index 0000000..07888b6 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Components/FanVentilation.mo @@ -0,0 +1,175 @@ +within TAeZoSysPro.HeatTransfer.Components; +model FanVentilation + + replaceable package Medium = TAeZoSysPro.Media.MyMedia + "Medium in the component"; + + // User defined parameters + parameter Boolean Use_External_MassFlow = false; + parameter Modelica.SIunits.Power Q_flow_aero_nominal = 0 + "Fan power given to fluid at nominal conditions"; + parameter Modelica.SIunits.VolumeFlowRate V_flow_nominal = 0 + "Volume flow rate at nominal conditions"; + + // Internal variables + Modelica.SIunits.Power Q_flow_aero + "Fan power given to fluid"; + Modelica.SIunits.SpecificHeatCapacity cp + "Mean specific heat capacity"; + Modelica.SIunits.Density d; + Modelica.SIunits.MassFlowRate m_flow; + Modelica.SIunits.Energy E + "Energy passed throught the component"; + // + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b + annotation ( + Placement(visible = true, transformation(origin = {0, 98}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {-1, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-101, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput m_flow_in if Use_External_MassFlow + annotation ( + Placement(visible = true, transformation(origin = {-106, 78}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, 84}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput V_flow_in if not Use_External_MassFlow + annotation ( + Placement(visible = true, transformation(origin = {-106, -40}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, -86}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +protected + + Modelica.Blocks.Interfaces.RealInput m_flow_in_internal + "Needed to connect to conditional connector"; + Modelica.Blocks.Interfaces.RealInput V_flow_in_internal + "Needed to connect to conditional connector"; + +initial equation + + E = 0.0; + +equation + + connect(m_flow_in, m_flow_in_internal); + connect(V_flow_in, V_flow_in_internal); + + cp = Medium.specificHeatCapacityCp(Medium.setState_pTX(p = Medium.reference_p, T = (port_a.T + port_b.T) / 2)); + + d = Medium.density_pTX(p = Medium.reference_p, T = port_a.T, X = Medium.reference_X); + + if Use_External_MassFlow then + m_flow = m_flow_in_internal; + V_flow_in_internal = m_flow_in_internal / d; + else + m_flow = V_flow_in_internal * d; + m_flow_in_internal = V_flow_in_internal * d; + end if; + + // Fan power + Q_flow_aero = Q_flow_aero_nominal * ((m_flow / d) / V_flow_nominal) ^ 2; + + // Energy balance + port_b.Q_flow = m_flow * cp * (port_b.T - port_a.T) - Q_flow_aero; + der(E) = port_b.Q_flow; + + // ports handover + port_a.Q_flow = 0; + + annotation ( + Diagram(coordinateSystem(grid = {2, 2}, initialScale = 0.1)), + Icon( + graphics = { + Ellipse(lineThickness = 1, extent = {{-100, -100}, {100, 100}}, endAngle = 360), + Ellipse( + lineColor = {182, 182, 182}, + lineThickness = 2, + extent = {{-98, -98}, {98, 98}}, + endAngle = 360), + Polygon( + origin = {44.28, 19.95}, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), + Polygon( + origin = {-43.72, -20.05}, + rotation = 180, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), + Polygon( + origin = {-19.72, 43.95}, + rotation = 90, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), + Polygon( + origin = {20.28, -44.05}, + rotation = -90, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), + Ellipse( + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Sphere, + lineThickness = 1, + extent = {{-10, -10}, {10, 10}}, + endAngle = 360), + Text(origin = {-82, 85}, extent = {{-10, 7}, {24, -7}}, textString = "[kg / s]", fontSize = 6), + Text(origin = {-82, -81}, extent = {{-10, 5}, {26, -13}}, textString = "[m3 / s]", fontSize = 6)}, + coordinateSystem(initialScale = 0.1)), + Documentation( + info = " + + + Ventilation + + + + +

        + This components computes the heat flow balance between the heat flow from the supply ventilation where fan in present between inlet conditions and the blowing in the control volume and the exhaust assuming steady pressure balance thus steady mass flow balance. +

        + +

        + Beacause of the thermal mode only, it assumes that the inlet mass flow rate is always equal to the outlet (the dynamic mass balance is reached generally much faster that the thermal balance). + The exhaust temperature is the temperature at port_b and the supply at port_a. +

        + +

        + It is assumed that the fan curve pressure vs volume flow rate is linear to the volume flow rate. + The aeraulic power is the product of the pressure difference at the boundary of the fan and the volume flow rate a suction. +

        + + + +

        + The enthalpy flow balance to the volume that receive mass derives: +

        + + + +

        + Where : +

          +
        • ∆p_fan is pressure difference at fan boundaries
        • +
        • a a is the proportionality coefficient between the pressure difference and the flow
        • +
        • V_flow is the volume flow rate at fan suction
        • +
        • H_flow is the enthalpy flow rate
        • +
        • m_flow is the mass flow rate
        • +
        • h is the specific enthalpy
        • +
        • cp is the specific heat capacity
        • +
        • T is the temperature
        • +
        +

        + +

        + It is supposed that the specific heat capacity varies linearly with the temperature therefore the mean specific capacity is the specific capacity at the mean temperature. +

        + + + + ")); + +end FanVentilation; diff --git a/HeatTransfer/Components/FviewCalculator.mo b/src/TAeZoSysPro/HeatTransfer/Components/FviewCalculator.mo similarity index 58% rename from HeatTransfer/Components/FviewCalculator.mo rename to src/TAeZoSysPro/HeatTransfer/Components/FviewCalculator.mo index 7d42e7e..a9d207f 100644 --- a/HeatTransfer/Components/FviewCalculator.mo +++ b/src/TAeZoSysPro/HeatTransfer/Components/FviewCalculator.mo @@ -1,26 +1,31 @@ within TAeZoSysPro.HeatTransfer.Components; block FviewCalculator - - parameter Integer N = 3 ; - Modelica.Blocks.Interfaces.RealVectorInput A_wall[N] annotation( + + parameter Integer N = 3; + Modelica.Blocks.Interfaces.RealVectorInput A_wall[N] + annotation ( Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, -4}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealVectorOutput[N] F_view annotation( + Modelica.Blocks.Interfaces.RealVectorOutput[N] F_view + annotation ( Placement(visible = true, transformation(origin = {100, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); + equation - + when initial() then - if N==2 then // face to face surfaces - F_view = fill(min(A_wall)*1*(1/A_wall[1] + 1/A_wall[2]), 2) ; + if N == 2 then // face to face surfaces + F_view = fill(min(A_wall) * 1 * (1 / A_wall[1] + 1 / A_wall[2]), 2); else - F_view = Functions.fviewFunction(A_wall) ; - end if ; - - end when ; - - annotation(Diagram(coordinateSystem(grid = {2, 2})), - Icon(graphics = {Ellipse(origin = {0, -2}, lineColor = {0, 0, 127}, fillColor = {0, 0, 127}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-15, -15}, {15, 15}}, endAngle = 360), Line(origin = {-50, 45}, points = {{-50, 45}, {50, -45}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, 29}, points = {{-50, 29}, {50, -29}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, 14}, points = {{-50, 14}, {50, -14}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, -1}, points = {{-50, -1}, {50, 1}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, -45}, points = {{-50, -45}, {50, 45}, {50, 45}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50.42, -31.19}, points = {{-49.575, -30.8116}, {50.425, 31.1884}, {48.425, 31.1884}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, -16}, points = {{-50, -16}, {50, 16}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40, 46}, points = {{-40, -46}, {60, 46}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40, 29}, points = {{-40, -29}, {60, 31}}, color = {0, 0, 127}, thickness = 1), Line(origin = {38.53, 13.84}, points = {{-40.5268, -13.8396}, {61.4732, 14.1604}, {61.4732, 14.1604}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40, -1}, points = {{-40, 1}, {60, -1}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40, -16}, points = {{-40, 16}, {60, -16}, {60, -16}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40.65, -31.69}, points = {{-40.6518, 31.6924}, {59.3482, -30.3076}, {59.3482, -30.3076}}, color = {0, 0, 127}, thickness = 1), Line(origin = {41, -46}, points = {{-41, 46}, {59, -46}}, color = {0, 0, 127}, thickness = 1), Rectangle(lineColor = {0, 0, 127}, lineThickness = 1, extent = {{-100, 100}, {100, -100}}), Text(origin = {17, -62}, lineThickness = 1, extent = {{-71, -38}, {45, 18}}, textString = "View Factor", fontSize = 15), Text(origin = {-79, 52}, lineThickness = 1, extent = {{-67, -38}, {-17, -14}}, textString = "Awall", fontSize = 12), Text(origin = {165, 56}, lineThickness = 1, extent = {{-67, -38}, {-17, -14}}, textString = "Fview", fontSize = 12)}, coordinateSystem(initialScale = 0.1)), - Documentation(info = " + F_view = Functions.fviewFunction(A_wall); + end if; + + end when; + + annotation ( + Diagram(coordinateSystem(grid = {2, 2})), + Icon(graphics = {Ellipse(origin = {0, -2}, lineColor = {0, 0, 127}, fillColor = {0, 0, 127}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-15, -15}, {15, 15}}, endAngle = 360), Line(origin = {-50, 45}, points = {{-50, 45}, {50, -45}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, 29}, points = {{-50, 29}, {50, -29}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, 14}, points = {{-50, 14}, {50, -14}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, -1}, points = {{-50, -1}, {50, 1}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, -45}, points = {{-50, -45}, {50, 45}, {50, 45}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50.42, -31.19}, points = {{-49.575, -30.8116}, {50.425, 31.1884}, {48.425, 31.1884}}, color = {0, 0, 127}, thickness = 1), Line(origin = {-50, -16}, points = {{-50, -16}, {50, 16}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40, 46}, points = {{-40, -46}, {60, 46}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40, 29}, points = {{-40, -29}, {60, 31}}, color = {0, 0, 127}, thickness = 1), Line(origin = {38.53, 13.84}, points = {{-40.5268, -13.8396}, {61.4732, 14.1604}, {61.4732, 14.1604}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40, -1}, points = {{-40, 1}, {60, -1}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40, -16}, points = {{-40, 16}, {60, -16}, {60, -16}}, color = {0, 0, 127}, thickness = 1), Line(origin = {40.65, -31.69}, points = {{-40.6518, 31.6924}, {59.3482, -30.3076}, {59.3482, -30.3076}}, color = {0, 0, 127}, thickness = 1), Line(origin = {41, -46}, points = {{-41, 46}, {59, -46}}, color = {0, 0, 127}, thickness = 1), Rectangle(lineColor = {0, 0, 127}, lineThickness = 1, extent = {{-100, 100}, {100, -100}}), Text(origin = {17, -62}, lineThickness = 1, extent = {{-71, -38}, {45, 18}}, textString = "View Factor", fontSize = 15), Text(origin = {-79, 52}, lineThickness = 1, extent = {{-67, -38}, {-17, -14}}, textString = "Awall", fontSize = 12), Text(origin = {165, 56}, lineThickness = 1, extent = {{-67, -38}, {-17, -14}}, textString = "Fview", fontSize = 12)}, coordinateSystem(initialScale = 0.1)), + Documentation( + info = " FviewCalculator @@ -101,7 +106,8 @@ equation

        - "),defaultComponentPrefixes="inner", - defaultComponentName="fviewCalculator"); + "), + defaultComponentPrefixes = "inner", + defaultComponentName = "fviewCalculator"); end FviewCalculator; diff --git a/src/TAeZoSysPro/HeatTransfer/Components/HalfWall.mo b/src/TAeZoSysPro/HeatTransfer/Components/HalfWall.mo new file mode 100644 index 0000000..d199b67 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Components/HalfWall.mo @@ -0,0 +1,218 @@ +within TAeZoSysPro.HeatTransfer.Components; + +model HalfWall + + // + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + import TAeZoSysPro.HeatTransfer.Types.MeshGrid; + import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid; + + //Media + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters + parameter MeshGrid mesh = MeshGrid.biotAndGeometricalGrowth + "Selection of meshing function" + annotation ( + Dialog(group = "Meshing properties")); + parameter Real q = 1.2 + "Growth rate (if geometricalGrowth chosen)" + annotation ( + Dialog(group = "Meshing properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 + "Decoupled value of the heat transfer (if biot segment chosen)" + annotation ( + Dialog(group = "Meshing properties")); + parameter Integer N(min = 1) = integer(max(1, 5 * Th / 0.2 * 1e-6 * d * cp / k)) + "Number of layers : 1 to 65535" + annotation ( + Dialog(group = "Meshing properties")); + + parameter Modelica.SIunits.Area A = 0 + "Wall area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Height Lc = 0 + "Wall characteristic length" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Length Th = 0 + "Wall thickness" + annotation ( + Dialog(group = "Geometrical properties")); + + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial" + annotation ( + Dialog(group = "Dynamic properties")); + + parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 + "Wall specific heat capacity" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.Density d(displayUnit = "kg/m3") = 0 + "Wall density" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.ThermalConductivity k = 0 + "Wall conductivity" + annotation ( + Dialog(group = "Thermal properties")); + + parameter Real add_on_conv = 1 + "Custom add-on" + annotation ( + Dialog(group = "Convection properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE + "free convection Correlation" + annotation ( + Dialog(group = "Convection properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Convection properties")); + // + parameter Modelica.SIunits.Emissivity eps = 0 + "Wall emissivity " + annotation ( + Dialog(group = "Radiative properties")); + parameter Real add_on_rad = 1 + "Custom add-on" + annotation ( + Dialog(group = "Radiative properties")); + + // Internal variables + Modelica.SIunits.BiotNumber Bi; + + // Components inside wall are defined + TAeZoSysPro.HeatTransfer.BasesClasses.PartialWall partialWall(A = A, N = N, T_start = T_start, Th = Th, cp = cp, d = d, energyDynamics = energyDynamics, h = h, k = k, mesh = mesh, q = q, symmetricalMesh = false) if N > 1 + annotation ( + Placement(visible = true, transformation(origin = {4.5, 22.5}, extent = {{-29.5, -29.5}, {29.5, 29.5}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection convection( + redeclare package Medium = Medium, + A = A, + Lc = Lc, + add_on = add_on_conv, + correlation = correlation, + h_cv_const = h_cv_const) + annotation ( + Placement(visible = true, transformation(origin = {-47, 70}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A, add_on = add_on_rad, eps = eps) + annotation ( + Placement(visible = true, transformation(origin = {-56.5, -70.5}, extent = {{-22.5, -22.5}, {22.5, 22.5}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_conv + annotation ( + Placement(visible = true, transformation(origin = {-101, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad + annotation ( + Placement(visible = true, transformation(origin = {-101, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall + annotation ( + Placement(visible = true, transformation(origin = {-92, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput F_view + annotation ( + Placement(visible = true, transformation(origin = {-90, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b + annotation ( + Placement(visible = true, transformation(origin = {99, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface + annotation ( + Placement(visible = true, transformation(origin = {-100, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start, cp = cp, energyDynamics = energyDynamics, m = Th * A * d) if N == 1 + annotation ( + Placement(visible = true, transformation(origin = {4, -50}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); + +equation + + connect(port_surface, partialWall.port_a) + annotation ( + Line(points = {{-100, 30}, {-24, 30}, {-24, 22.5}}, color = {191, 0, 0})); + connect(port_a_conv, convection.port_b) + annotation ( + Line(points = {{-101, 70}, {-65, 70}}, color = {191, 0, 0})); + connect(convection.port_a, partialWall.port_a) + annotation ( + Line(points = {{-29, 70}, {-24, 70}, {-24, 22.5}}, color = {191, 0, 0})); + connect(F_view, carrollRadiation.Fview) + annotation ( + Line(points = {{-90, -30}, {-38.5, -30}, {-38.5, -52.5}}, color = {0, 0, 127})); + connect(port_a_rad, carrollRadiation.port_b) + annotation ( + Line(points = {{-101, -70}, {-88, -70}, {-88, -70.5}, {-79, -70.5}}, color = {191, 0, 0})); + connect(carrollRadiation.port_a, partialWall.port_a) + annotation ( + Line(points = {{-34, -70.5}, {-24, -70.5}, {-24, 22.5}}, color = {191, 0, 0})); + connect(partialWall.port_b, port_b) + annotation ( + Line(points = {{33, 22.5}, {68, 22.5}, {68, 0}, {100, 0}}, color = {191, 0, 0})); + + if N > 1 then + Bi = convection.h_cv * (partialWall.x[2] - partialWall.x[1]) / k; + else + Bi = 0.0; + end if; + + A_wall = A; + connect(convection.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-28, 70}, {-24, 70}, {-24, -40}, {4, -40}}, color = {191, 0, 0})); + connect(port_surface, heatCapacitor.port) + annotation ( + Line(points = {{-100, 30}, {-24, 30}, {-24, -40}, {4, -40}}, color = {191, 0, 0})); + connect(carrollRadiation.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-34, -70}, {-24, -70}, {-24, -40}, {4, -40}}, color = {191, 0, 0})); + connect(port_b, heatCapacitor.port) + annotation ( + Line(points = {{100, 0}, {68, 0}, {68, -40}, {4, -40}}, color = {191, 0, 0})); //output y is set to Awall and it can be connected to FviewCalculator + + annotation ( + Diagram(graphics = {Rectangle(origin = {3.5, -1}, fillColor = {218, 218, 218}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-42.5, 101}, {36.5, -99}}), Text(origin = {4, 58}, extent = {{-20, 10}, {20, -10}}, textString = "If N > 1"), Text(origin = {4, -28}, extent = {{-20, 10}, {20, -10}}, textString = "If N = 1")}, coordinateSystem(initialScale = 0.1)), + Icon(graphics = {Rectangle(origin = {11, 9}, fillColor = {191, 191, 191}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-51, 91}, {29, -109}}), Line(origin = {-70, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 88.1389}, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 54.1389}, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-93, 93}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "Fluid"), Text(origin = {-93, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Text(origin = {-73, -25}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view"), Text(origin = {-73, -49}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall"), Line(origin = {-52.1559, -79.8606}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52.5726, -99.7217}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled})}, coordinateSystem(initialScale = 0.1)), + Documentation( + info = " + + + HalfWall + + + + + + +

        + This component models the thermal response of half wall in interface with a rest ambiance where the thermal exchanges are mainly driven by natural convection and radiation. +

        + +

        + This component is an assembly of the PartialWall module, the FreeConvection module and a CarrollRadiation module. The solid wall is dicretises in N along its depth to model the heat propagation. By defaut the value of N is computed from the depth and the thermal diffusivty of the wall.
        + When the number of layers N is equal to one, the PartialWall is replaced by a HeatCapacitor. +

        + +

        + A port name port_surface is connected to the boundary port of the PartialWall. + It can be usefull for specific applications when another modules is required et can be latter connected to this empty heat port. +

        + +

        + The HalfWall supplies as output the surface area of the wall, via its A_wall port, to the FviewCalculator module and get from this last the form (or view) factor as input via the F_view port. The connection is performed explicitely via the graphic connectors. +

        + +"), + experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-06, Interval = 36)); + +end HalfWall; diff --git a/HeatTransfer/Components/HeatExchanger.mo b/src/TAeZoSysPro/HeatTransfer/Components/HeatExchanger.mo similarity index 60% rename from HeatTransfer/Components/HeatExchanger.mo rename to src/TAeZoSysPro/HeatTransfer/Components/HeatExchanger.mo index 4a3c124..8d92d9a 100644 --- a/HeatTransfer/Components/HeatExchanger.mo +++ b/src/TAeZoSysPro/HeatTransfer/Components/HeatExchanger.mo @@ -1,5 +1,6 @@ within TAeZoSysPro.HeatTransfer.Components; model HeatExchanger + extends BasesClasses.PartialHeatExchanger; import TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness; import TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; @@ -10,18 +11,24 @@ model HeatExchanger MediumB.ThermodynamicState stateB; // Imported Modules - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_A_in annotation ( - Placement(visible = true, transformation(origin = {-88, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_A_out annotation ( - Placement(visible = true, transformation(origin = {96, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_B_in annotation ( - Placement(visible = true, transformation(origin = {82, -82}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_B_out annotation ( - Placement(visible = true, transformation(origin = {-92, 94}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput m_flowA annotation ( - Placement(visible = true, transformation(origin = {-78, -50}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealInput m_flowB annotation ( - Placement(visible = true, transformation(origin = {34, -78}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {40, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 90))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_A_in + annotation ( + Placement(visible = true, transformation(origin = {-88, 2}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_A_out + annotation ( + Placement(visible = true, transformation(origin = {96, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_B_in + annotation ( + Placement(visible = true, transformation(origin = {82, -82}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {70, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_B_out + annotation ( + Placement(visible = true, transformation(origin = {-92, 94}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-70, 90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput m_flowA + annotation ( + Placement(visible = true, transformation(origin = {-78, -50}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput m_flowB + annotation ( + Placement(visible = true, transformation(origin = {34, -78}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {40, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 90))); // replaceable function effectiveness = ExchangerEffectiveness.counterCurrent; @@ -29,8 +36,8 @@ model HeatExchanger equation - stateA = MediumA.setState_pTX(p=MediumA.reference_p, T = T_A_in); - stateB = MediumB.setState_pTX(p=MediumB.reference_p, T = T_B_in); + stateA = MediumA.setState_pTX(p = MediumA.reference_p, T = T_A_in); + stateB = MediumB.setState_pTX(p = MediumB.reference_p, T = T_B_in); T_A_in = port_A_in.T; T_B_in = port_B_in.T; @@ -42,14 +49,15 @@ equation Eff = effectiveness(NTU = NTU, Cr = Cr); - // port handovers port_A_in.Q_flow = 0; port_B_in.Q_flow = 0; port_A_out.Q_flow = Qc_A * (port_A_out.T - T_A_out); port_B_out.Q_flow = Qc_B * (port_B_out.T - T_B_out); -annotation(Documentation(info = " + annotation ( + Documentation( + info = " HeatExchanger @@ -79,4 +87,5 @@ annotation(Documentation(info = " ")); + end HeatExchanger; diff --git a/HeatTransfer/Components/InertMass.mo b/src/TAeZoSysPro/HeatTransfer/Components/InertMass.mo similarity index 55% rename from HeatTransfer/Components/InertMass.mo rename to src/TAeZoSysPro/HeatTransfer/Components/InertMass.mo index 98d82b9..cf03cd0 100644 --- a/HeatTransfer/Components/InertMass.mo +++ b/src/TAeZoSysPro/HeatTransfer/Components/InertMass.mo @@ -1,82 +1,127 @@ within TAeZoSysPro.HeatTransfer.Components; model InertMass + // - import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation ; - import TAeZoSysPro.HeatTransfer.Types.Dynamics ; - + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import TAeZoSysPro.HeatTransfer.Types.Dynamics; -//Media - replaceable package Medium = TAeZoSysPro.Media.MyMedia ; + //Media + replaceable package Medium = TAeZoSysPro.Media.MyMedia; // User defined parameters - parameter Modelica.SIunits.Area A_conv = 0 "Convective surface area " annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Area A_rad = A_conv "Radiative surface area " annotation( - Dialog(group="Geometrical properties")); - parameter Modelica.SIunits.Length Lc = 1 "characteritic dimension for correlation" annotation( - Dialog(group="Geometrical properties")); - - parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial "Formulation of energy balance" annotation( - Dialog(group="Dynamic properties")); - parameter Modelica.SIunits.Temperature T_start = 293.15 "Start value for temperature, if energyDynamics = FixedInitial" annotation( - Dialog(group="Dynamic properties")); - - parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 "Specific heat capacity" annotation( - Dialog(group="Thermal properties")); - parameter Modelica.SIunits.Mass m= 0 "Mass of the component" annotation( - Dialog(group="Thermal properties")); - - parameter Real add_on_conv = 1 "Custom add-on" annotation( - Dialog(group = "Convection properties")); - parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE "free convection Correlation" annotation( - Dialog(group = "Convection properties")); - parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const = 0 "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" annotation( - Dialog(group = "Convection properties")); + parameter Modelica.SIunits.Area A_conv = 0 + "Convective surface area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Area A_rad = A_conv + "Radiative surface area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Length Lc = 1 + "characteritic dimension for correlation" + annotation ( + Dialog(group = "Geometrical properties")); + + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial" + annotation ( + Dialog(group = "Dynamic properties")); + + parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 + "Specific heat capacity" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.Mass m = 0 + "Mass of the component" + annotation ( + Dialog(group = "Thermal properties")); + + parameter Real add_on_conv = 1 + "Custom add-on" + annotation ( + Dialog(group = "Convection properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation = Correlations.vertical_plate_ASHRAE + "free convection Correlation" + annotation ( + Dialog(group = "Convection properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Convection properties")); // - parameter Modelica.SIunits.Emissivity eps = 0 "Wall emissivity " annotation( - Dialog(group = "Radiative properties")); - parameter Real add_on_rad = 1 "Custom add-on" annotation( - Dialog(group = "Radiative properties")); + parameter Modelica.SIunits.Emissivity eps = 0 + "Wall emissivity " + annotation ( + Dialog(group = "Radiative properties")); + parameter Real add_on_rad = 1 + "Custom add-on" + annotation ( + Dialog(group = "Radiative properties")); + + // imported module + TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection convection( + redeclare package Medium = Medium, + A = A_conv, + Lc = Lc, + add_on = add_on_conv, + correlation = correlation, + h_cv_const = h_cv_const) + annotation ( + Placement(visible = true, transformation(origin = {-47, 70}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A_rad, add_on = add_on_rad, eps = eps) + annotation ( + Placement(visible = true, transformation(origin = {-56.5, -70.5}, extent = {{-22.5, -22.5}, {22.5, 22.5}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_conv + annotation ( + Placement(visible = true, transformation(origin = {-101, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad + annotation ( + Placement(visible = true, transformation(origin = {-101, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall + annotation ( + Placement(visible = true, transformation(origin = {-92, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput F_view + annotation ( + Placement(visible = true, transformation(origin = {-90, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface + annotation ( + Placement(visible = true, transformation(origin = {-100, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start, cp = cp, energyDynamics = energyDynamics, m = m) + annotation ( + Placement(visible = true, transformation(origin = {0, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); -// imported module - TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection convection(redeclare - package Medium = Medium, A = A_conv, Lc = Lc, add_on = add_on_conv, correlation = correlation, h_cv_const = h_cv_const) annotation ( - Placement(visible = true, transformation(origin = {-47, 70}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation(A = A_rad, add_on = add_on_rad, eps = eps) annotation( - Placement(visible = true, transformation(origin = {-56.5, -70.5}, extent = {{-22.5, -22.5}, {22.5, 22.5}}, rotation = 180))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_conv annotation( - Placement(visible = true, transformation(origin = {-101, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad annotation( - Placement(visible = true, transformation(origin = {-101, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Interfaces.RealOutput A_wall annotation( - Placement(visible = true, transformation(origin = {-92, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); - Modelica.Blocks.Interfaces.RealInput F_view annotation( - Placement(visible = true, transformation(origin = {-90, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface annotation( - Placement(visible = true, transformation(origin = {-100, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start, cp = cp, energyDynamics = energyDynamics, m = m) annotation( - Placement(visible = true, transformation(origin = {0, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); equation - connect(port_a_conv, convection.port_b) annotation( - Line(points = {{-101, 70}, {-65, 70}}, color = {191, 0, 0})); - connect(F_view, carrollRadiation.Fview) annotation( - Line(points = {{-90, -30}, {-38.5, -30}, {-38.5, -52.5}}, color = {0, 0, 127})); - connect(port_a_rad, carrollRadiation.port_b) annotation( - Line(points = {{-101, -70}, {-88, -70}, {-88, -70.5}, {-79, -70.5}}, color = {191, 0, 0})); - - A_wall = A_rad ; + connect(port_a_conv, convection.port_b) + annotation ( + Line(points = {{-101, 70}, {-65, 70}}, color = {191, 0, 0})); + connect(F_view, carrollRadiation.Fview) + annotation ( + Line(points = {{-90, -30}, {-38.5, -30}, {-38.5, -52.5}}, color = {0, 0, 127})); + connect(port_a_rad, carrollRadiation.port_b) + annotation ( + Line(points = {{-101, -70}, {-88, -70}, {-88, -70.5}, {-79, -70.5}}, color = {191, 0, 0})); + + A_wall = A_rad; - connect(convection.port_a, heatCapacitor.port) annotation( - Line(points = {{-28, 70}, {-20, 70}, {-20, 0}, {0, 0}, {0, 0}}, color = {191, 0, 0})); - connect(carrollRadiation.port_a, heatCapacitor.port) annotation( - Line(points = {{-34, -70}, {-20, -70}, {-20, 0}, {0, 0}, {0, 0}}, color = {191, 0, 0})); - connect(port_surface, heatCapacitor.port) annotation( - Line(points = {{-100, 30}, {-20, 30}, {-20, 0}, {0, 0}, {0, 0}}, color = {191, 0, 0})); + connect(convection.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-28, 70}, {-20, 70}, {-20, 0}, {0, 0}, {0, 0}}, color = {191, 0, 0})); + connect(carrollRadiation.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-34, -70}, {-20, -70}, {-20, 0}, {0, 0}, {0, 0}}, color = {191, 0, 0})); + connect(port_surface, heatCapacitor.port) + annotation ( + Line(points = {{-100, 30}, {-20, 30}, {-20, 0}, {0, 0}, {0, 0}}, color = {191, 0, 0})); - annotation( - defaultComponentName = "inertMass", - Documentation(info = " + annotation ( + defaultComponentName = "inertMass", + Documentation( + info = " InertMass diff --git a/src/TAeZoSysPro/HeatTransfer/Components/Ventilation.mo b/src/TAeZoSysPro/HeatTransfer/Components/Ventilation.mo new file mode 100644 index 0000000..f4aeb26 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Components/Ventilation.mo @@ -0,0 +1,151 @@ +within TAeZoSysPro.HeatTransfer.Components; +model Ventilation + + replaceable package Medium = TAeZoSysPro.Media.MyMedia + "Medium in the component"; + // User defined parameters + parameter Boolean Use_External_MassFlow = false; + // Internal variables + Modelica.SIunits.SpecificHeatCapacity cp + "Mean specific heat capacity"; + Modelica.SIunits.Density d; + Modelica.SIunits.MassFlowRate m_flow; + Modelica.SIunits.Energy E + "Energy passed throught the component"; + // + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b + annotation ( + Placement(visible = true, transformation(origin = {0, 98}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {-1, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-101, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput m_flow_in if Use_External_MassFlow + annotation ( + Placement(visible = true, transformation(origin = {-106, 78}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, 84}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput V_flow_in if not Use_External_MassFlow + annotation ( + Placement(visible = true, transformation(origin = {-106, -40}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, -86}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +protected + + Modelica.Blocks.Interfaces.RealInput m_flow_in_internal + "Needed to connect to conditional connector"; + Modelica.Blocks.Interfaces.RealInput V_flow_in_internal + "Needed to connect to conditional connector"; + +initial equation + + E = 0.0; + +equation + + connect(m_flow_in, m_flow_in_internal); + connect(V_flow_in, V_flow_in_internal); + + cp = Medium.specificHeatCapacityCp(Medium.setState_pTX(p = Medium.reference_p, T = (port_a.T + port_b.T) / 2)); + + d = Medium.density_pTX(p = Medium.reference_p, T = port_a.T, X = Medium.reference_X); + + if Use_External_MassFlow then + m_flow = m_flow_in_internal; + V_flow_in_internal = m_flow_in_internal / d; + else + m_flow = V_flow_in_internal * d; + m_flow_in_internal = V_flow_in_internal * d; + end if; + + port_b.Q_flow = m_flow * cp * (port_b.T - port_a.T); + der(E) = port_b.Q_flow; + + // ports handover + port_a.Q_flow = 0; + + annotation ( + Diagram(coordinateSystem(grid = {2, 2}, initialScale = 0.1)), + Icon( + graphics = { + Ellipse(lineThickness = 1, extent = {{-100, -100}, {100, 100}}, endAngle = 360), + Ellipse( + lineColor = {182, 182, 182}, + lineThickness = 2, + extent = {{-98, -98}, {98, 98}}, + endAngle = 360), + Polygon( + origin = {44.28, 19.95}, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), + Polygon( + origin = {-43.72, -20.05}, + rotation = 180, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), + Polygon( + origin = {-19.72, 43.95}, + rotation = 90, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), + Polygon( + origin = {20.28, -44.05}, + rotation = -90, + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Solid, + points = {{-44.2764, -19.9472}, {43.7236, -19.9472}, {43.7236, -19.9472}, {45.7236, -7.9472}, {45.7236, -7.94721}, {45.7236, 0.0527902}, {43.7236, 8.05279}, {39.7236, 14.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {35.7236, 20.0528}, {-44.2764, -19.9472}}), + Ellipse( + fillColor = {182, 182, 182}, + fillPattern = FillPattern.Sphere, + lineThickness = 1, + extent = {{-10, -10}, {10, 10}}, + endAngle = 360), + Text(origin = {-82, 85}, extent = {{-10, 7}, {24, -7}}, textString = "[kg / s]", fontSize = 6), + Text(origin = {-82, -81}, extent = {{-10, 5}, {26, -13}}, textString = "[m3 / s]", fontSize = 6)}, + coordinateSystem(initialScale = 0.1)), + Documentation( + info = " + + + Ventilation + + + + +

        + This components computes the heat flow balance between the heat flow from the supply ventilation and the exhaust assuming steady pressure balance thus steady mass flow balance. +

        + +

        + Beacause of the thermal mode only, it assumes that the inlet mass flow rate is always equal to the outlet (the dynamic mass balance is reached generally much faster that the thermal balance). + The exhaust temperature is the temperature at port_b and the supply at port_a. +

        + +

        + The enthalpy flow balance to the volume that receive mass derives: +

        + + + +

        + Where : +

          +
        • H_flow is the enthalpy flow rate
        • +
        • m_flow is the mass flow rate
        • +
        • h is the specific enthalpy
        • +
        • cp is the specific heat capacity
        • +
        • T is the temperature
        • +
        +

        + +

        + It is supposed that the specific heat capacity varies linearly with the temperature therefore the mean specific capacity is the specific capacity at the mean temperature. +

        + + + + ")); + +end Ventilation; diff --git a/src/TAeZoSysPro/HeatTransfer/Components/VerticalOpening.mo b/src/TAeZoSysPro/HeatTransfer/Components/VerticalOpening.mo new file mode 100644 index 0000000..fd5b2c5 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Components/VerticalOpening.mo @@ -0,0 +1,98 @@ +within TAeZoSysPro.HeatTransfer.Components; + +model VerticalOpening + + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // + constant Modelica.SIunits.Acceleration g_n = Modelica.Constants.g_n; + constant Modelica.SIunits.Pressure p = Medium.reference_p + "fluid pressure"; + parameter Boolean mass_conservation = true + "If true, mass flow profile is assumed symmetrical from either side of the middle of the opening"; + parameter Real Cd = 0.61 + "discharge coefficient"; + parameter Modelica.SIunits.CrossSection A = 1 + "Opening's section"; + parameter Modelica.SIunits.Length H = 1 + "Opening's Height"; + + // Internal variable + Medium.ThermodynamicState state_A; + Medium.ThermodynamicState state_B; + Modelica.SIunits.TemperatureDifference dT + "port_a.T - port_b.T"; + Modelica.SIunits.Density rho_A, rho_B; + Modelica.SIunits.Density + rho_up, + rho_down + "Upstream density in upper and lower part of the opening"; + Medium.SpecificEnthalpy h_A, h_B; + Modelica.SIunits.MassFlowRate + m_flow_up, + m_flow_down + "mass flow rate in upper and lower part of the opening"; + Modelica.SIunits.Height HN + "Heigh of the point where flow switches in direction (zero flow)"; + + // Imported components + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a + annotation ( + Placement(visible = true, transformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b + annotation ( + Placement(visible = true, transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +equation + + // + state_A = Medium.setState_pTX(p = p, T = port_a.T); + state_B = Medium.setState_pTX(p = p, T = port_b.T); + // state_Mean = Medium.setState_pTX(p = p, T = (Heatport_a.T+Heatport_b.T)/2); + dT = port_a.T - port_b.T; + rho_A = Medium.density(state_A); + rho_B = Medium.density(state_B); + rho_up = smooth(1, if port_a.T >= port_b.T then rho_A else rho_B); + rho_down = rho_A + rho_B - rho_up; + h_A = Medium.specificEnthalpy(state_A); + h_B = Medium.specificEnthalpy(state_B); + + // quasi static flow assumption. Analytic integration over the height of m_flow(z) = f(dp(z)) + m_flow_up = Cd * A / H * Modelica.Fluid.Utilities.regRoot( + x = 2 * rho_up * g_n * (rho_B - rho_A), + delta = 1e-3) * 2 / 3 * (H - HN) ^ (3 / 2); + m_flow_down = Cd * A / H * Modelica.Fluid.Utilities.regRoot( + x = 2 * rho_down * g_n * (rho_B - rho_A), + delta = 1e-3) * 2 / 3 * (-HN ^ (3 / 2)); + + // if mass_conservation then the heigh of the 0 flow is compute to insure that m_flow_up = m_flow_down in absolute value + HN = if mass_conservation then H / ((rho_down / rho_up) ^ (1 / 3) + 1) else H / 2; + + // port handover + port_a.Q_flow = smooth(0, if sign(port_a.T - port_b.T) > 0 then m_flow_down * (h_B - h_A) else m_flow_up * (h_B - h_A)); + port_b.Q_flow = smooth(0, if sign(port_a.T - port_b.T) > 0 then -m_flow_up * (h_A - h_B) else -m_flow_down * (h_A - h_B)); + + annotation ( + Icon(graphics = {Line(origin = {0, 69.8886}, points = {{0, 30}, {0, -30}}, thickness = 2), Line(origin = {0, -70}, points = {{0, 30}, {0, -30}}, thickness = 2)}, coordinateSystem(initialScale = 0.1)), + experiment(StartTime = 0, StopTime = 1000, Tolerance = 1e-06, Interval = 1), + Documentation( + info = " + + Vertical Opening + + + +

        + This module allows to model the net heat flow induces by air movement only from bouyancy through an opening that links two ambiances. +

        + +

        + See demonstration. +

        + +

        + When mass conservation is set to true, the height HN where the flow changes in direction is computed to insure that m_flow_up and m_flow_down are equal is absolute value. If not HN is equal to H/2 +

        + +")); + +end VerticalOpening; diff --git a/src/TAeZoSysPro/HeatTransfer/Components/Wall.mo b/src/TAeZoSysPro/HeatTransfer/Components/Wall.mo new file mode 100644 index 0000000..02ad9a9 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Components/Wall.mo @@ -0,0 +1,271 @@ +within TAeZoSysPro.HeatTransfer.Components; + +model Wall + + // + import Correlations = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation; + import TAeZoSysPro.HeatTransfer.Types.Dynamics; + import TAeZoSysPro.HeatTransfer.Types.MeshGrid; + import MeshFunction = TAeZoSysPro.HeatTransfer.Functions.MeshGrid; + + //Media + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + // User defined parameters + parameter MeshGrid mesh = MeshGrid.biotAndGeometricalGrowth + "Selection of meshing function" + annotation ( + Dialog(group = "Meshing properties")); + parameter Real q = 1.2 + "Growth rate (if geometricalGrowth chosen)" + annotation ( + Dialog(group = "Meshing properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10 + "Decoupled value of the heat transfer (if biot segment chosen)" + annotation ( + Dialog(group = "Meshing properties")); + parameter Integer N(min = 1) = integer(max(1, 5 * Th / 0.2 * 1e-6 * d * cp / k)) + "Number of layers : 1 to 65535" + annotation ( + Dialog(group = "Meshing properties")); + + parameter Modelica.SIunits.Area A = 0 + "Wall area " + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Height Lc = 0 + "Wall characteristic length" + annotation ( + Dialog(group = "Geometrical properties")); + parameter Modelica.SIunits.Length Th = 0 + "Wall thickness" + annotation ( + Dialog(group = "Geometrical properties")); + + parameter Dynamics energyDynamics = Dynamics.SteadyStateInitial + "Formulation of energy balance" + annotation ( + Dialog(group = "Dynamic properties")); + parameter Modelica.SIunits.Temperature T_start = 293.15 + "Start value for temperature, if energyDynamics = FixedInitial" + annotation ( + Dialog(group = "Dynamic properties")); + + parameter Modelica.SIunits.SpecificHeatCapacity cp = 0 + "Wall specific heat capacity" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.Density d(displayUnit = "kg/m3") = 0 + "Wall density" + annotation ( + Dialog(group = "Thermal properties")); + parameter Modelica.SIunits.ThermalConductivity k = 0 + "Wall conductivity" + annotation ( + Dialog(group = "Thermal properties")); + + parameter Real add_on_conv = 1 + "Custom add-on" + annotation ( + Dialog(group = "Convection properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation_a = Correlations.vertical_plate_ASHRAE + "free convection Correlation" + annotation ( + Dialog(group = "Convection properties")); + parameter TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation correlation_b = if correlation_a == Correlations.ceiling_ASHRAE then Correlations.ground_ASHRAE elseif correlation_a == Correlations.ground_ASHRAE then Correlations.ceiling_ASHRAE else correlation_a + "free convection Correlation" + annotation ( + Dialog(group = "Convection properties")); + parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const_a = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Convection properties")); + + parameter Modelica.SIunits.CoefficientOfHeatTransfer h_cv_const_b = 0 + "constant heat transfer coefficient (optional: if correlation 'Constant' choosen)" + annotation ( + Dialog(group = "Convection properties")); + // + parameter Modelica.SIunits.Emissivity eps_a = 0 + "Wall emissivity " + annotation ( + Dialog(group = "Radiative properties")); + parameter Modelica.SIunits.Emissivity eps_b = 0 + "Wall emissivity " + annotation ( + Dialog(group = "Radiative properties")); + parameter Real add_on_rad = 1 + "Custom add-on" + annotation ( + Dialog(group = "Radiative properties")); + + // Internal variables + Modelica.SIunits.BiotNumber Bi_a, Bi_b; + + // Components inside wall are defined + TAeZoSysPro.HeatTransfer.BasesClasses.PartialWall partialWall(A = A, N = N, T_start = T_start, Th = Th, cp = cp, d = d, energyDynamics = energyDynamics, h = h, k = k, mesh = mesh, q = q, symmetricalMesh = true) if N > 1 + annotation ( + Placement(visible = true, transformation(origin = {0.5, 26.5}, extent = {{-29.5, -29.5}, {29.5, 29.5}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection freeConvection_a(redeclare package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation_a, h_cv_const = h_cv_const_a) + annotation ( + Placement(visible = true, transformation(origin = {-55, 70}, extent = {{-18, -18}, {18, 18}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation_a(A = A, add_on = add_on_rad, eps = eps_a) + annotation ( + Placement(visible = true, transformation(origin = {-58.5, -70.5}, extent = {{-22.5, -22.5}, {22.5, 22.5}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_conv + annotation ( + Placement(visible = true, transformation(origin = {-101, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a port_a_rad + annotation ( + Placement(visible = true, transformation(origin = {-101, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall_a + annotation ( + Placement(visible = true, transformation(origin = {-92, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 180), iconTransformation(origin = {-93, -53}, extent = {{-7, -7}, {7, 7}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput F_view_a + annotation ( + Placement(visible = true, transformation(origin = {-90, -30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-93, -27}, extent = {{-7, -7}, {7, 7}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b_conv + annotation ( + Placement(visible = true, transformation(origin = {101, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port_surface_a + annotation ( + Placement(visible = true, transformation(origin = {-100, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {-40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.FreeConvection freeConvection_b(redeclare package Medium = Medium, A = A, Lc = Lc, add_on = add_on_conv, correlation = correlation_b, h_cv_const = h_cv_const_b) + annotation ( + Placement(visible = true, transformation(origin = {57, 70}, extent = {{18, -18}, {-18, 18}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollRadiation carrollRadiation_b(A = A, add_on = add_on_rad, eps = eps_b) + annotation ( + Placement(visible = true, transformation(origin = {59.5, -70.5}, extent = {{22.5, -22.5}, {-22.5, 22.5}}, rotation = 180))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_b_rad + annotation ( + Placement(visible = true, transformation(origin = {101, -70}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {90, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealOutput A_wall_b + annotation ( + Placement(visible = true, transformation(origin = {90, -2}, extent = {{10, -10}, {-10, 10}}, rotation = 180), iconTransformation(origin = {93, -53}, extent = {{7, -7}, {-7, 7}}, rotation = 180))); + Modelica.Blocks.Interfaces.RealInput F_view_b + annotation ( + Placement(visible = true, transformation(origin = {92, -30}, extent = {{10, -10}, {-10, 10}}, rotation = 0), iconTransformation(origin = {93, -27}, extent = {{7, -7}, {-7, 7}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_b port_surface_b + annotation ( + Placement(visible = true, transformation(origin = {99, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {40, 10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.HeatCapacitor heatCapacitor(T_start = T_start, cp = cp, energyDynamics = energyDynamics, m = Th * A * d) if N == 1 + annotation ( + Placement(visible = true, transformation(origin = {0, -46}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); + +equation + + connect(port_a_conv, freeConvection_a.port_b) + annotation ( + Line(points = {{-101, 70}, {-73, 70}}, color = {191, 0, 0})); + connect(port_a_rad, carrollRadiation_a.port_b) + annotation ( + Line(points = {{-101, -70}, {-88, -70}, {-88, -70.5}, {-81, -70.5}}, color = {191, 0, 0})); + if N > 1 then + Bi_a = freeConvection_a.h_cv * (partialWall.x[2] - partialWall.x[1]) / k; + Bi_b = freeConvection_b.h_cv * (partialWall.x[end] - partialWall.x[end - 1]) / k; + else + Bi_a = 0.0; + Bi_b = 0.0; + end if; + + A_wall_a = A; + A_wall_b = A; + //output y is set to Awall and it can be connected to FviewCalculator + connect(freeConvection_a.port_a, partialWall.port_a) + annotation ( + Line(points = {{-36, 70}, {-28, 70}, {-28, 26.5}}, color = {191, 0, 0})); + connect(carrollRadiation_a.port_a, partialWall.port_a) + annotation ( + Line(points = {{-36, -70.5}, {-28, -70.5}, {-28, 26.5}}, color = {191, 0, 0})); + connect(freeConvection_b.port_a, partialWall.port_b) + annotation ( + Line(points = {{39, 70}, {28, 70}, {28, 26.5}, {29, 26.5}}, color = {191, 0, 0})); + connect(carrollRadiation_b.port_a, partialWall.port_b) + annotation ( + Line(points = {{38, -70}, {28, -70}, {28, 26.5}, {29, 26.5}}, color = {191, 0, 0})); + connect(freeConvection_b.port_b, port_b_conv) + annotation ( + Line(points = {{75, 70}, {102, 70}}, color = {191, 0, 0})); + connect(carrollRadiation_b.port_b, port_b_rad) + annotation ( + Line(points = {{82, -70}, {100, -70}, {100, -70}, {102, -70}}, color = {191, 0, 0})); + connect(port_surface_a, partialWall.port_a) + annotation ( + Line(points = {{-100, 30}, {-28, 30}, {-28, 26.5}}, color = {191, 0, 0})); + connect(port_surface_b, partialWall.port_b) + annotation ( + Line(points = {{100, 30}, {28, 30}, {28, 26.5}, {29, 26.5}}, color = {191, 0, 0})); + connect(F_view_a, carrollRadiation_a.Fview) + annotation ( + Line(points = {{-90, -30}, {-42, -30}, {-42, -52}, {-40, -52}}, color = {0, 0, 127})); + connect(F_view_b, carrollRadiation_b.Fview) + annotation ( + Line(points = {{92, -30}, {44, -30}, {44, -52}, {42, -52}}, color = {0, 0, 127})); + connect(freeConvection_a.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-36, 70}, {-28, 70}, {-28, -36}, {0, -36}}, color = {191, 0, 0})); + connect(port_surface_a, heatCapacitor.port) + annotation ( + Line(points = {{-100, 30}, {-28, 30}, {-28, -36}, {0, -36}}, color = {191, 0, 0})); + connect(carrollRadiation_a.port_a, heatCapacitor.port) + annotation ( + Line(points = {{-36, -70}, {-28, -70}, {-28, -36}, {0, -36}}, color = {191, 0, 0})); + connect(freeConvection_b.port_a, heatCapacitor.port) + annotation ( + Line(points = {{40, 70}, {28, 70}, {28, -36}, {0, -36}}, color = {191, 0, 0})); + connect(port_surface_b, heatCapacitor.port) + annotation ( + Line(points = {{100, 30}, {28, 30}, {28, -36}, {0, -36}}, color = {191, 0, 0})); + connect(carrollRadiation_b.port_a, heatCapacitor.port) + annotation ( + Line(points = {{38, -70}, {28, -70}, {28, -36}, {0, -36}}, color = {191, 0, 0})); + + annotation ( + Diagram(graphics = {Rectangle(origin = {3.5, -1}, fillColor = {218, 218, 218}, fillPattern = FillPattern.Solid, lineThickness = 1, extent = {{-42.5, 101}, {36.5, -99}}), Text(origin = {2, 60}, extent = {{-20, 10}, {20, -10}}, textString = "If N > 1"), Text(origin = {2, -26}, extent = {{-20, 10}, {20, -10}}, textString = "If N = 1")}, coordinateSystem(initialScale = 0.1)), + Icon(graphics = {Rectangle(origin = {11, 9}, fillColor = {191, 191, 191}, fillPattern = FillPattern.Cross, lineThickness = 1, extent = {{-51, 91}, {29, -109}}), Line(origin = {-70, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52, 70.1389}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 88.1389}, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-61, 54.1389}, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-93, 93}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "Fluid"), Text(origin = {-93, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT"), Text(origin = {-73, -27}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view_a"), Text(origin = {-73, -49}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall_a"), Line(origin = {-52.1559, -79.8606}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-52.5726, -99.7217}, rotation = 180, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {67, -47}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "A_wall_b"), Text(origin = {67, -27}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "F_view_b"), Line(origin = {52.8486, -80.2659}, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {52.4319, -100.127}, points = {{-9, 0}, {-7, 0}, {-7, 4}, {-3, -4}, {1, 4}, {5, -4}, {9, 4}, {13, -4}, {13, 0}, {21, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {68.8387, 69.7336}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {59.8387, 53.7336}, rotation = 180, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {59.8387, 87.7336}, rotation = 180, points = {{17, 0}, {-17, 0}}, color = {255, 0, 0}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {50.8387, 69.7336}, points = {{0, 30}, {0, -30}}, color = {0, 0, 255}, thickness = 1, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {87, 93}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "Fluid"), Text(origin = {87, -67}, lineThickness = 1, extent = {{-7, 7}, {13, -13}}, textString = "J_MRT")}, coordinateSystem(initialScale = 0.1)), + Documentation( + info = " + + + Wall + + + + + + +

        + This component models the thermal response of wall in interface with a rest ambiances where the thermal exchanges are mainly driven by natural convection and radiation. +

        + +

        + The suffix '..._a' refers to side where the ports 'port_a' are. +

        + +

        + This component is an assembly of the PartialWall module, the FreeConvection modules and a CarrollRadiation modules. The solid wall is dicretises in N along its depth to model the heat propagation. By defaut the value of N is computed from the depth and the thermal diffusivty of the wall.
        + When the number of layers N is equal to one, the PartialWall is replaced by a HeatCapacitor. +

        + +

        + Ports name port_surface are connected to boundary ports of the PartialWall. + It can be usefull for specific applications when another modules is required et can be latter connected to this empty heat port. +

        + +

        + The Wall supplies as output the surface area of the wall, via its A_wall ports, to the FviewCalculator module and get from this last the form (or view) factor as input via the F_view ports. The connection is performed explicitely via the graphic connectors. +

        + +"), + experiment(StartTime = 0, StopTime = 3600, Tolerance = 1e-06, Interval = 36)); + +end Wall; diff --git a/src/TAeZoSysPro/HeatTransfer/Components/package.mo b/src/TAeZoSysPro/HeatTransfer/Components/package.mo new file mode 100644 index 0000000..aa3258e --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Components/package.mo @@ -0,0 +1,89 @@ +within TAeZoSysPro.HeatTransfer; + +package Components + + extends Modelica.Icons.Package; + + annotation ( + Icon( + coordinateSystem(preserveAspectRatio = true, extent = {{-100, -100}, {100, 100}}), + graphics = { + Rectangle( + origin = {12, 40}, + fillColor = {192, 192, 192}, + fillPattern = FillPattern.Backward, + extent = {{-100, -100}, {-70, 18}}), + Line( + origin = {12, 40}, + points = {{-44, 16}, {-44, -100}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{-4, 16}, {-4, -100}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{30, 18}, {30, -100}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{66, 18}, {66, -100}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{66, -100}, {76, -80}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{66, -100}, {56, -80}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{30, -100}, {40, -80}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{30, -100}, {20, -80}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{-4, -100}, {6, -80}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{-4, -100}, {-14, -80}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{-44, -100}, {-34, -80}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{-44, -100}, {-54, -80}}, + color = {0, 127, 255}), + Line( + origin = {12, 40}, + points = {{-70, -60}, {66, -60}}, + color = {191, 0, 0}), + Line( + origin = {12, 40}, + points = {{46, -70}, {66, -60}}, + color = {191, 0, 0}), + Line( + origin = {12, 40}, + points = {{46, -50}, {66, -60}}, + color = {191, 0, 0}), + Line( + origin = {12, 40}, + points = {{46, -30}, {66, -20}}, + color = {191, 0, 0}), + Line( + origin = {12, 40}, + points = {{46, -10}, {66, -20}}, + color = {191, 0, 0}), + Line( + origin = {12, 40}, + points = {{-70, -20}, {66, -20}}, + color = {191, 0, 0})})); + +end Components; diff --git a/HeatTransfer/Components/package.order b/src/TAeZoSysPro/HeatTransfer/Components/package.order similarity index 100% rename from HeatTransfer/Components/package.order rename to src/TAeZoSysPro/HeatTransfer/Components/package.order diff --git a/HeatTransfer/Examples/Room_with_wood_burner.mo b/src/TAeZoSysPro/HeatTransfer/Examples/Room_with_wood_burner.mo similarity index 85% rename from HeatTransfer/Examples/Room_with_wood_burner.mo rename to src/TAeZoSysPro/HeatTransfer/Examples/Room_with_wood_burner.mo index d3ab18a..5267b68 100644 --- a/HeatTransfer/Examples/Room_with_wood_burner.mo +++ b/src/TAeZoSysPro/HeatTransfer/Examples/Room_with_wood_burner.mo @@ -1,140 +1,209 @@ within TAeZoSysPro.HeatTransfer.Examples; model Room_with_wood_burner + extends Modelica.Icons.Example; - TAeZoSysPro.HeatTransfer.BasesClasses.LumpVolume lumpVolume(T_start = 293.15, V = 4 * 5 * 2.5) annotation( - Placement(visible = true, transformation(origin = {-40, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.BasesClasses.CarrollNode carrollNode annotation( - Placement(visible = true, transformation(origin = {0, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Components.Wall north_wall(A = 5 * 2.5, Lc = 2.5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) annotation( - Placement(visible = true, transformation(origin = {90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Components.Wall ceiling(A = 4 * 5, Lc = 2 * 4 + 2 * 5, N = 5, Th = 20, correlation_a = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation.ceiling_ASHRAE, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) annotation( - Placement(visible = true, transformation(origin = {90, -90}, extent = {{10, 10}, {-10, -10}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.Components.Wall ground(A = 4 * 5, Lc = 2 * 4 + 2 * 5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) annotation( - Placement(visible = true, transformation(origin = {90, -130}, extent = {{10, 10}, {-10, -10}}, rotation = 180))); - TAeZoSysPro.HeatTransfer.Components.CabinetPower wood_burner(A_conv_casing = 3, A_conv_emitter = 0.1727, A_in_casing = 3, A_rad_casing = 3, A_rad_emitter = 0.1727, Lc_casing = 0.7, Lc_emitter = 0.1, cp_casing = 390, cp_emitter = 1950, eps_casing = 0.7, eps_emitter = 0.93, m_casing = 121, m_emitter = 6) annotation( - Placement(visible = true, transformation(origin = {-80, -160}, extent = {{20, -20}, {-20, 20}}, rotation = 0))); - inner TAeZoSysPro.HeatTransfer.Components.FviewCalculator fviewCalculator(N = 7) annotation( - Placement(visible = true, transformation(origin = {40, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Sources.FixedTemperature outside_temperature(T (displayUnit = "K") = 278.15) annotation( - Placement(visible = true, transformation(origin = {-100, -110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Blocks.Sources.Constant wood_burning_heat_load(k = 5000) annotation( - Placement(visible = true, transformation(origin = {-110, -212}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Sources.FixedTemperature ceiling_adjacent_temperature(T (displayUnit = "degC") = 288.15) annotation( - Placement(visible = true, transformation(origin = {130, -90}, extent = {{10, -10}, {-10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Sources.FixedTemperature lateral_walls_adjacent_temperature(T = 288.15) annotation( - Placement(visible = true, transformation(origin = {130, 70}, extent = {{10, -10}, {-10, 10}}, rotation = 0))); - Modelica.Thermal.HeatTransfer.Sources.FixedTemperature ground_adjacent_temperature(T (displayUnit = "degC") = 283.15) annotation( - Placement(visible = true, transformation(origin = {130, -130}, extent = {{10, -10}, {-10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Components.Wall east_wall(A = 4 * 2.5, Lc = 2.5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) annotation( - Placement(visible = true, transformation(origin = {90, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Components.Wall south_wall(A = 5 * 2.5, Lc = 2.5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) annotation( - Placement(visible = true, transformation(origin = {90, -10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Components.Wall west_wall(A = 4 * 2.5, Lc = 2.5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) annotation( - Placement(visible = true, transformation(origin = {90, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); - TAeZoSysPro.HeatTransfer.Components.Ventilation ventilation annotation( - Placement(visible = true, transformation(origin = {-72, 110}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); - Modelica.Blocks.Sources.Constant Ventilation_flow_rate(k = 30 / 3600) annotation( - Placement(visible = true, transformation(origin = {-130, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.LumpVolume lumpVolume(T_start = 293.15, V = 4 * 5 * 2.5) + annotation ( + Placement(visible = true, transformation(origin = {-40, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.BasesClasses.CarrollNode carrollNode + annotation ( + Placement(visible = true, transformation(origin = {0, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Components.Wall north_wall(A = 5 * 2.5, Lc = 2.5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) + annotation ( + Placement(visible = true, transformation(origin = {90, 70}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Components.Wall ceiling(A = 4 * 5, Lc = 2 * 4 + 2 * 5, N = 5, Th = 20, correlation_a = TAeZoSysPro.HeatTransfer.Types.FreeConvectionCorrelation.ceiling_ASHRAE, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) + annotation ( + Placement(visible = true, transformation(origin = {90, -90}, extent = {{10, 10}, {-10, -10}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.Components.Wall ground(A = 4 * 5, Lc = 2 * 4 + 2 * 5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) + annotation ( + Placement(visible = true, transformation(origin = {90, -130}, extent = {{10, 10}, {-10, -10}}, rotation = 180))); + TAeZoSysPro.HeatTransfer.Components.CabinetPower wood_burner(A_conv_casing = 3, A_conv_emitter = 0.1727, A_in_casing = 3, A_rad_casing = 3, A_rad_emitter = 0.1727, Lc_casing = 0.7, Lc_emitter = 0.1, cp_casing = 390, cp_emitter = 1950, eps_casing = 0.7, eps_emitter = 0.93, m_casing = 121, m_emitter = 6) + annotation ( + Placement(visible = true, transformation(origin = {-80, -160}, extent = {{20, -20}, {-20, 20}}, rotation = 0))); + inner TAeZoSysPro.HeatTransfer.Components.FviewCalculator fviewCalculator(N = 7) + annotation ( + Placement(visible = true, transformation(origin = {40, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Sources.FixedTemperature outside_temperature(T(displayUnit = "K") = 278.15) + annotation ( + Placement(visible = true, transformation(origin = {-100, -110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Sources.Constant wood_burning_heat_load(k = 5000) + annotation ( + Placement(visible = true, transformation(origin = {-110, -212}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Sources.FixedTemperature ceiling_adjacent_temperature(T(displayUnit = "degC") = 288.15) + annotation ( + Placement(visible = true, transformation(origin = {130, -90}, extent = {{10, -10}, {-10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Sources.FixedTemperature lateral_walls_adjacent_temperature(T = 288.15) + annotation ( + Placement(visible = true, transformation(origin = {130, 70}, extent = {{10, -10}, {-10, 10}}, rotation = 0))); + Modelica.Thermal.HeatTransfer.Sources.FixedTemperature ground_adjacent_temperature(T(displayUnit = "degC") = 283.15) + annotation ( + Placement(visible = true, transformation(origin = {130, -130}, extent = {{10, -10}, {-10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Components.Wall east_wall(A = 4 * 2.5, Lc = 2.5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) + annotation ( + Placement(visible = true, transformation(origin = {90, 30}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Components.Wall south_wall(A = 5 * 2.5, Lc = 2.5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) + annotation ( + Placement(visible = true, transformation(origin = {90, -10}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Components.Wall west_wall(A = 4 * 2.5, Lc = 2.5, N = 5, Th = 20, cp = 1000, d = 2500, eps_a = 0.8, eps_b = 0.8, k = 2.3, mesh = TAeZoSysPro.HeatTransfer.Types.MeshGrid.biotAndUniform) + annotation ( + Placement(visible = true, transformation(origin = {90, -50}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + TAeZoSysPro.HeatTransfer.Components.Ventilation ventilation + annotation ( + Placement(visible = true, transformation(origin = {-72, 110}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); + Modelica.Blocks.Sources.Constant Ventilation_flow_rate(k = 30 / 3600) + annotation ( + Placement(visible = true, transformation(origin = {-130, 110}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + equation - connect(north_wall.port_a_conv, lumpVolume.port_a) annotation( - Line(points = {{82, 78}, {-40, 78}, {-40, 110}, {-40, 110}}, color = {191, 0, 0})); - connect(north_wall.port_a_rad, carrollNode.port_a) annotation( - Line(points = {{82, 62}, {0, 62}, {0, 110}, {0, 110}}, color = {191, 0, 0})); - connect(ceiling.port_a_conv, lumpVolume.port_a) annotation( - Line(points = {{81, -83}, {-40, -83}, {-40, 110}}, color = {191, 0, 0})); - connect(ground.port_a_conv, lumpVolume.port_a) annotation( - Line(points = {{81, -123}, {-40, -123}, {-40, 110}}, color = {191, 0, 0})); - connect(north_wall.A_wall_a, fviewCalculator.A_wall[1]) annotation( - Line(points = {{80, 64}, {30, 64}, {30, 110}, {30, 110}}, color = {0, 0, 127})); - connect(north_wall.F_view_a, fviewCalculator.F_view[1]) annotation( - Line(points = {{80, 68}, {50, 68}, {50, 110}, {50, 110}}, color = {0, 0, 127})); - connect(wood_burner.port_rad, carrollNode.port_a) annotation( - Line(points = {{-60, -160}, {0, -160}, {0, 110}}, color = {191, 0, 0})); - connect(wood_burner.port_conv, lumpVolume.port_a) annotation( - Line(points = {{-100, -160}, {-120, -160}, {-120, 38}, {-40, 38}, {-40, 110}}, color = {191, 0, 0})); - connect(outside_temperature.port, wood_burner.port_hood) annotation( - Line(points = {{-90, -110}, {-80, -110}, {-80, -138}, {-80, -138}}, color = {191, 0, 0})); - connect(wood_burning_heat_load.y, wood_burner.Heatload_Variable) annotation( - Line(points = {{-99, -212}, {-80, -212}, {-80, -180}}, color = {0, 0, 127})); - connect(north_wall.A_wall_b, north_wall.F_view_b) annotation( - Line(points = {{100, 64}, {102, 64}, {102, 68}, {100, 68}, {100, 68}}, color = {0, 0, 127})); - connect(north_wall.port_b_rad, north_wall.port_surface_b) annotation( - Line(points = {{100, 62}, {104, 62}, {104, 72}, {94, 72}, {94, 72}}, color = {191, 0, 0})); - connect(north_wall.port_b_conv, lateral_walls_adjacent_temperature.port) annotation( - Line(points = {{100, 78}, {110, 78}, {110, 70}, {120, 70}, {120, 70}}, color = {191, 0, 0})); - connect(ceiling.port_b_conv, ceiling_adjacent_temperature.port) annotation( - Line(points = {{99, -83}, {109, -83}, {109, -91}, {119, -91}, {119, -91}}, color = {191, 0, 0})); - connect(ground.port_b_conv, ground_adjacent_temperature.port) annotation( - Line(points = {{99, -123}, {109, -123}, {109, -131}, {119, -131}, {119, -131}}, color = {191, 0, 0})); - connect(ceiling.A_wall_b, ceiling.F_view_b) annotation( - Line(points = {{99.3, -95.3}, {101.3, -95.3}, {101.3, -91.3}, {99.3, -91.3}, {99.3, -91.3}}, color = {0, 0, 127})); - connect(ceiling.port_b_rad, ceiling.port_surface_b) annotation( - Line(points = {{99, -99}, {103, -99}, {103, -89}, {93, -89}, {93, -89}}, color = {191, 0, 0})); - connect(ground.A_wall_b, ground.F_view_b) annotation( - Line(points = {{99.3, -135.3}, {101.3, -135.3}, {101.3, -131.3}, {99.3, -131.3}, {99.3, -131.3}}, color = {0, 0, 127})); - connect(ground.port_b_rad, ground.port_surface_b) annotation( - Line(points = {{99, -139}, {103, -139}, {103, -129}, {93, -129}, {93, -129}}, color = {191, 0, 0})); - connect(east_wall.port_a_conv, lumpVolume.port_a) annotation( - Line(points = {{82, 38}, {-40, 38}, {-40, 110}, {-40, 110}}, color = {191, 0, 0})); - connect(east_wall.port_a_rad, carrollNode.port_a) annotation( - Line(points = {{82, 22}, {0, 22}, {0, 110}, {0, 110}}, color = {191, 0, 0})); - connect(south_wall.port_a_conv, lumpVolume.port_a) annotation( - Line(points = {{82, -2}, {-40, -2}, {-40, 110}, {-40, 110}}, color = {191, 0, 0})); - connect(south_wall.port_a_rad, carrollNode.port_a) annotation( - Line(points = {{82, -18}, {0, -18}, {0, 110}, {0, 110}}, color = {191, 0, 0})); - connect(west_wall.port_a_conv, lumpVolume.port_a) annotation( - Line(points = {{82, -42}, {-40, -42}, {-40, 110}, {-40, 110}}, color = {191, 0, 0})); - connect(west_wall.port_a_rad, carrollNode.port_a) annotation( - Line(points = {{82, -58}, {0, -58}, {0, 110}, {0, 110}}, color = {191, 0, 0})); - connect(east_wall.port_b_conv, lateral_walls_adjacent_temperature.port) annotation( - Line(points = {{100, 38}, {110, 38}, {110, 70}, {120, 70}, {120, 70}}, color = {191, 0, 0})); - connect(south_wall.port_b_conv, lateral_walls_adjacent_temperature.port) annotation( - Line(points = {{100, -2}, {110, -2}, {110, 70}, {120, 70}, {120, 70}}, color = {191, 0, 0})); - connect(west_wall.port_b_conv, lateral_walls_adjacent_temperature.port) annotation( - Line(points = {{100, -42}, {110, -42}, {110, 70}, {120, 70}, {120, 70}}, color = {191, 0, 0})); - connect(east_wall.A_wall_b, east_wall.F_view_b) annotation( - Line(points = {{100, 24}, {102, 24}, {102, 28}, {100, 28}, {100, 28}}, color = {0, 0, 127})); - connect(east_wall.port_b_rad, east_wall.port_surface_b) annotation( - Line(points = {{100, 22}, {104, 22}, {104, 32}, {94, 32}, {94, 32}}, color = {191, 0, 0})); - connect(south_wall.A_wall_b, south_wall.F_view_b) annotation( - Line(points = {{100, -16}, {102, -16}, {102, -12}, {100, -12}, {100, -12}}, color = {0, 0, 127})); - connect(south_wall.port_b_rad, south_wall.port_surface_b) annotation( - Line(points = {{100, -18}, {104, -18}, {104, -8}, {94, -8}, {94, -8}}, color = {191, 0, 0})); - connect(west_wall.A_wall_b, west_wall.F_view_b) annotation( - Line(points = {{100, -56}, {102, -56}, {102, -52}, {100, -52}, {100, -52}}, color = {0, 0, 127})); - connect(west_wall.port_b_rad, west_wall.port_surface_b) annotation( - Line(points = {{100, -58}, {104, -58}, {104, -48}, {94, -48}, {94, -48}}, color = {191, 0, 0})); - connect(east_wall.A_wall_a, fviewCalculator.A_wall[2]) annotation( - Line(points = {{80, 24}, {30, 24}, {30, 110}, {30, 110}}, color = {0, 0, 127})); - connect(east_wall.F_view_a, fviewCalculator.F_view[2]) annotation( - Line(points = {{80, 28}, {50, 28}, {50, 110}, {50, 110}}, color = {0, 0, 127})); - connect(south_wall.A_wall_a, fviewCalculator.A_wall[3]) annotation( - Line(points = {{80, -16}, {30, -16}, {30, 110}, {30, 110}}, color = {0, 0, 127})); - connect(south_wall.F_view_a, fviewCalculator.F_view[3]) annotation( - Line(points = {{80, -12}, {50, -12}, {50, 110}, {50, 110}}, color = {0, 0, 127})); - connect(west_wall.A_wall_a, fviewCalculator.A_wall[4]) annotation( - Line(points = {{80, -56}, {30, -56}, {30, 110}, {30, 110}}, color = {0, 0, 127})); - connect(west_wall.F_view_a, fviewCalculator.F_view[4]) annotation( - Line(points = {{80, -52}, {50, -52}, {50, 110}, {50, 110}}, color = {0, 0, 127})); - connect(ceiling.A_wall_a, fviewCalculator.A_wall[5]) annotation( - Line(points = {{80, -96}, {30, -96}, {30, 110}, {30, 110}}, color = {0, 0, 127})); - connect(ceiling.F_view_a, fviewCalculator.F_view[5]) annotation( - Line(points = {{80, -92}, {50, -92}, {50, 110}, {50, 110}}, color = {0, 0, 127})); - connect(ground.A_wall_a, fviewCalculator.A_wall[6]) annotation( - Line(points = {{80, -136}, {30, -136}, {30, 110}, {30, 110}}, color = {0, 0, 127})); - connect(ground.F_view_a, fviewCalculator.F_view[6]) annotation( - Line(points = {{80, -132}, {50, -132}, {50, 110}, {50, 110}}, color = {0, 0, 127})); - connect(wood_burner.A_wall, fviewCalculator.A_wall[7]) annotation( - Line(points = {{-60, -153}, {30, -153}, {30, 110}}, color = {0, 0, 127})); - connect(wood_burner.F_view, fviewCalculator.F_view[7]) annotation( - Line(points = {{-60, -144}, {50, -144}, {50, 110}}, color = {0, 0, 127})); - connect(outside_temperature.port, ventilation.port_a) annotation( - Line(points = {{-90, -110}, {-90, 34}, {-86, 34}, {-86, 44}, {-90, 44}, {-90, 110}, {-82, 110}}, color = {191, 0, 0})); - connect(Ventilation_flow_rate.y, ventilation.V_flow_in) annotation( - Line(points = {{-118, 110}, {-112, 110}, {-112, 118}, {-82, 118}, {-82, 118}}, color = {0, 0, 127})); -annotation( + connect(north_wall.port_a_conv, lumpVolume.port_a) + annotation ( + Line(points = {{82, 78}, {-40, 78}, {-40, 110}, {-40, 110}}, color = {191, 0, 0})); + connect(north_wall.port_a_rad, carrollNode.port_a) + annotation ( + Line(points = {{82, 62}, {0, 62}, {0, 110}, {0, 110}}, color = {191, 0, 0})); + connect(ceiling.port_a_conv, lumpVolume.port_a) + annotation ( + Line(points = {{81, -83}, {-40, -83}, {-40, 110}}, color = {191, 0, 0})); + connect(ground.port_a_conv, lumpVolume.port_a) + annotation ( + Line(points = {{81, -123}, {-40, -123}, {-40, 110}}, color = {191, 0, 0})); + connect(north_wall.A_wall_a, fviewCalculator.A_wall[1]) + annotation ( + Line(points = {{80, 64}, {30, 64}, {30, 110}, {30, 110}}, color = {0, 0, 127})); + connect(north_wall.F_view_a, fviewCalculator.F_view[1]) + annotation ( + Line(points = {{80, 68}, {50, 68}, {50, 110}, {50, 110}}, color = {0, 0, 127})); + connect(wood_burner.port_rad, carrollNode.port_a) + annotation ( + Line(points = {{-60, -160}, {0, -160}, {0, 110}}, color = {191, 0, 0})); + connect(wood_burner.port_conv, lumpVolume.port_a) + annotation ( + Line(points = {{-100, -160}, {-120, -160}, {-120, 38}, {-40, 38}, {-40, 110}}, color = {191, 0, 0})); + connect(outside_temperature.port, wood_burner.port_hood) + annotation ( + Line(points = {{-90, -110}, {-80, -110}, {-80, -138}, {-80, -138}}, color = {191, 0, 0})); + connect(wood_burning_heat_load.y, wood_burner.Heatload_Variable) + annotation ( + Line(points = {{-99, -212}, {-80, -212}, {-80, -180}}, color = {0, 0, 127})); + connect(north_wall.A_wall_b, north_wall.F_view_b) + annotation ( + Line(points = {{100, 64}, {102, 64}, {102, 68}, {100, 68}, {100, 68}}, color = {0, 0, 127})); + connect(north_wall.port_b_rad, north_wall.port_surface_b) + annotation ( + Line(points = {{100, 62}, {104, 62}, {104, 72}, {94, 72}, {94, 72}}, color = {191, 0, 0})); + connect(north_wall.port_b_conv, lateral_walls_adjacent_temperature.port) + annotation ( + Line(points = {{100, 78}, {110, 78}, {110, 70}, {120, 70}, {120, 70}}, color = {191, 0, 0})); + connect(ceiling.port_b_conv, ceiling_adjacent_temperature.port) + annotation ( + Line(points = {{99, -83}, {109, -83}, {109, -91}, {119, -91}, {119, -91}}, color = {191, 0, 0})); + connect(ground.port_b_conv, ground_adjacent_temperature.port) + annotation ( + Line(points = {{99, -123}, {109, -123}, {109, -131}, {119, -131}, {119, -131}}, color = {191, 0, 0})); + connect(ceiling.A_wall_b, ceiling.F_view_b) + annotation ( + Line(points = {{99.3, -95.3}, {101.3, -95.3}, {101.3, -91.3}, {99.3, -91.3}, {99.3, -91.3}}, color = {0, 0, 127})); + connect(ceiling.port_b_rad, ceiling.port_surface_b) + annotation ( + Line(points = {{99, -99}, {103, -99}, {103, -89}, {93, -89}, {93, -89}}, color = {191, 0, 0})); + connect(ground.A_wall_b, ground.F_view_b) + annotation ( + Line(points = {{99.3, -135.3}, {101.3, -135.3}, {101.3, -131.3}, {99.3, -131.3}, {99.3, -131.3}}, color = {0, 0, 127})); + connect(ground.port_b_rad, ground.port_surface_b) + annotation ( + Line(points = {{99, -139}, {103, -139}, {103, -129}, {93, -129}, {93, -129}}, color = {191, 0, 0})); + connect(east_wall.port_a_conv, lumpVolume.port_a) + annotation ( + Line(points = {{82, 38}, {-40, 38}, {-40, 110}, {-40, 110}}, color = {191, 0, 0})); + connect(east_wall.port_a_rad, carrollNode.port_a) + annotation ( + Line(points = {{82, 22}, {0, 22}, {0, 110}, {0, 110}}, color = {191, 0, 0})); + connect(south_wall.port_a_conv, lumpVolume.port_a) + annotation ( + Line(points = {{82, -2}, {-40, -2}, {-40, 110}, {-40, 110}}, color = {191, 0, 0})); + connect(south_wall.port_a_rad, carrollNode.port_a) + annotation ( + Line(points = {{82, -18}, {0, -18}, {0, 110}, {0, 110}}, color = {191, 0, 0})); + connect(west_wall.port_a_conv, lumpVolume.port_a) + annotation ( + Line(points = {{82, -42}, {-40, -42}, {-40, 110}, {-40, 110}}, color = {191, 0, 0})); + connect(west_wall.port_a_rad, carrollNode.port_a) + annotation ( + Line(points = {{82, -58}, {0, -58}, {0, 110}, {0, 110}}, color = {191, 0, 0})); + connect(east_wall.port_b_conv, lateral_walls_adjacent_temperature.port) + annotation ( + Line(points = {{100, 38}, {110, 38}, {110, 70}, {120, 70}, {120, 70}}, color = {191, 0, 0})); + connect(south_wall.port_b_conv, lateral_walls_adjacent_temperature.port) + annotation ( + Line(points = {{100, -2}, {110, -2}, {110, 70}, {120, 70}, {120, 70}}, color = {191, 0, 0})); + connect(west_wall.port_b_conv, lateral_walls_adjacent_temperature.port) + annotation ( + Line(points = {{100, -42}, {110, -42}, {110, 70}, {120, 70}, {120, 70}}, color = {191, 0, 0})); + connect(east_wall.A_wall_b, east_wall.F_view_b) + annotation ( + Line(points = {{100, 24}, {102, 24}, {102, 28}, {100, 28}, {100, 28}}, color = {0, 0, 127})); + connect(east_wall.port_b_rad, east_wall.port_surface_b) + annotation ( + Line(points = {{100, 22}, {104, 22}, {104, 32}, {94, 32}, {94, 32}}, color = {191, 0, 0})); + connect(south_wall.A_wall_b, south_wall.F_view_b) + annotation ( + Line(points = {{100, -16}, {102, -16}, {102, -12}, {100, -12}, {100, -12}}, color = {0, 0, 127})); + connect(south_wall.port_b_rad, south_wall.port_surface_b) + annotation ( + Line(points = {{100, -18}, {104, -18}, {104, -8}, {94, -8}, {94, -8}}, color = {191, 0, 0})); + connect(west_wall.A_wall_b, west_wall.F_view_b) + annotation ( + Line(points = {{100, -56}, {102, -56}, {102, -52}, {100, -52}, {100, -52}}, color = {0, 0, 127})); + connect(west_wall.port_b_rad, west_wall.port_surface_b) + annotation ( + Line(points = {{100, -58}, {104, -58}, {104, -48}, {94, -48}, {94, -48}}, color = {191, 0, 0})); + connect(east_wall.A_wall_a, fviewCalculator.A_wall[2]) + annotation ( + Line(points = {{80, 24}, {30, 24}, {30, 110}, {30, 110}}, color = {0, 0, 127})); + connect(east_wall.F_view_a, fviewCalculator.F_view[2]) + annotation ( + Line(points = {{80, 28}, {50, 28}, {50, 110}, {50, 110}}, color = {0, 0, 127})); + connect(south_wall.A_wall_a, fviewCalculator.A_wall[3]) + annotation ( + Line(points = {{80, -16}, {30, -16}, {30, 110}, {30, 110}}, color = {0, 0, 127})); + connect(south_wall.F_view_a, fviewCalculator.F_view[3]) + annotation ( + Line(points = {{80, -12}, {50, -12}, {50, 110}, {50, 110}}, color = {0, 0, 127})); + connect(west_wall.A_wall_a, fviewCalculator.A_wall[4]) + annotation ( + Line(points = {{80, -56}, {30, -56}, {30, 110}, {30, 110}}, color = {0, 0, 127})); + connect(west_wall.F_view_a, fviewCalculator.F_view[4]) + annotation ( + Line(points = {{80, -52}, {50, -52}, {50, 110}, {50, 110}}, color = {0, 0, 127})); + connect(ceiling.A_wall_a, fviewCalculator.A_wall[5]) + annotation ( + Line(points = {{80, -96}, {30, -96}, {30, 110}, {30, 110}}, color = {0, 0, 127})); + connect(ceiling.F_view_a, fviewCalculator.F_view[5]) + annotation ( + Line(points = {{80, -92}, {50, -92}, {50, 110}, {50, 110}}, color = {0, 0, 127})); + connect(ground.A_wall_a, fviewCalculator.A_wall[6]) + annotation ( + Line(points = {{80, -136}, {30, -136}, {30, 110}, {30, 110}}, color = {0, 0, 127})); + connect(ground.F_view_a, fviewCalculator.F_view[6]) + annotation ( + Line(points = {{80, -132}, {50, -132}, {50, 110}, {50, 110}}, color = {0, 0, 127})); + connect(wood_burner.A_wall, fviewCalculator.A_wall[7]) + annotation ( + Line(points = {{-60, -153}, {30, -153}, {30, 110}}, color = {0, 0, 127})); + connect(wood_burner.F_view, fviewCalculator.F_view[7]) + annotation ( + Line(points = {{-60, -144}, {50, -144}, {50, 110}}, color = {0, 0, 127})); + connect(outside_temperature.port, ventilation.port_a) + annotation ( + Line(points = {{-90, -110}, {-90, 34}, {-86, 34}, {-86, 44}, {-90, 44}, {-90, 110}, {-82, 110}}, color = {191, 0, 0})); + connect(Ventilation_flow_rate.y, ventilation.V_flow_in) + annotation ( + Line(points = {{-118, 110}, {-112, 110}, {-112, 118}, {-82, 118}, {-82, 118}}, color = {0, 0, 127})); + + annotation ( Diagram(graphics = {Rectangle(origin = {-360, -30}, extent = {{-100, -70}, {100, 70}}), Polygon(origin = {-340, 60}, points = {{-120, -20}, {-80, 20}, {120, 20}, {80, -20}, {-120, -20}}), Line(origin = {-240.267, -10.0043}, points = {{-19.7929, -89.7929}, {20.2071, -49.7929}, {20.2071, 90.2071}}), Line(origin = {-440.27, -10.0072}, points = {{-19.7929, -89.7929}, {20.2071, -49.7929}, {20.2071, 90.2071}}, pattern = LinePattern.Dash), Line(origin = {-361.06, -119.797}, points = {{-101, 0}, {101, 0}}, arrow = {Arrow.Open, Arrow.Open}), Line(origin = {-220.06, -79.7971}, points = {{-20, -20}, {20, 20}}, arrow = {Arrow.Open, Arrow.Open}), Text(origin = {-370, -130}, extent = {{-30, 10}, {30, -10}}, textString = "5 m"), Text(origin = {-198, -84}, extent = {{-30, 10}, {30, -10}}, textString = "4 m"), Line(origin = {-459.913, 100.193}, points = {{0, -20}, {0, 20}}, arrow = {Arrow.Open, Arrow.Open}), Line(origin = {-460.032, 100.193}, points = {{-20, 0}, {20, 0}}, arrow = {Arrow.Open, Arrow.Open}), Text(origin = {-460, 127}, extent = {{-6, 5}, {6, -5}}, textString = "N"), Text(origin = {-434, 101}, extent = {{-6, 5}, {6, -5}}, textString = "E"), Text(origin = {-460, 75}, extent = {{-6, 5}, {6, -5}}, textString = "S"), Text(origin = {-486, 101}, extent = {{-6, 5}, {6, -5}}, textString = "W"), Ellipse(origin = {-394.96, 61.2651}, extent = {{-15.0403, 4.73492}, {15.0403, -4.73492}}, endAngle = 360), Ellipse(origin = {-270.96, 61.2651}, extent = {{-15.0403, 4.73492}, {15.0403, -4.73492}}, endAngle = 360), Line(origin = {-396, 41}, points = {{0, 11}, {0, -11}}, color = {0, 85, 255}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}), Line(origin = {-271.07, 42.19}, rotation = 180, points = {{0, 11}, {0, -11}}, color = {255, 0, 0}, thickness = 0.5, arrow = {Arrow.None, Arrow.Filled}), Text(origin = {-386, 73}, extent = {{-30, 5}, {30, -5}}, textString = "Ventilation supply"), Text(origin = {-272, 73}, extent = {{-30, 5}, {30, -5}}, textString = "Ventilation exhaust"), Bitmap(origin = {-344, -58}, rotation = 180, extent = {{-34, 34}, {34, -34}}, imageSource = "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"), Line(origin = {-320.188, -59.3656}, points = {{-100, -1}, {100, -1}}, pattern = LinePattern.Dash), Rectangle(origin = {-340, 28}, fillColor = {62, 62, 62}, fillPattern = FillPattern.Solid, extent = {{4, -62}, {-4, 62}}), Bitmap(origin = {-430, -198}, rotation = 180, extent = {{70, 42}, {-70, -42}}, imageSource = "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"), Bitmap(origin = {-280, -197}, extent = {{-70, -41}, {70, 41}}, imageSource = "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")}, coordinateSystem(extent = {{-500, -240}, {140, 140}})), experiment(StartTime = 0, StopTime = 7200, Tolerance = 1e-6, Interval = 7.2)); + end Room_with_wood_burner; diff --git a/HeatTransfer/Examples/Wood_burner_data.xlsx b/src/TAeZoSysPro/HeatTransfer/Examples/Wood_burner_data.xlsx similarity index 100% rename from HeatTransfer/Examples/Wood_burner_data.xlsx rename to src/TAeZoSysPro/HeatTransfer/Examples/Wood_burner_data.xlsx diff --git a/HeatTransfer/Examples/package.mo b/src/TAeZoSysPro/HeatTransfer/Examples/package.mo similarity index 60% rename from HeatTransfer/Examples/package.mo rename to src/TAeZoSysPro/HeatTransfer/Examples/package.mo index 6549e3a..fa2074f 100644 --- a/HeatTransfer/Examples/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Examples/package.mo @@ -2,6 +2,6 @@ within TAeZoSysPro.HeatTransfer; package Examples - extends Modelica.Icons.ExamplesPackage ; + extends Modelica.Icons.ExamplesPackage; end Examples; diff --git a/HeatTransfer/Examples/package.order b/src/TAeZoSysPro/HeatTransfer/Examples/package.order similarity index 100% rename from HeatTransfer/Examples/package.order rename to src/TAeZoSysPro/HeatTransfer/Examples/package.order diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_coCurrent.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_coCurrent.mo similarity index 75% rename from HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_coCurrent.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_coCurrent.mo index 0f388c6..328fc43 100644 --- a/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_coCurrent.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_coCurrent.mo @@ -4,17 +4,21 @@ function NTU_coCurrent extends Modelica.Icons.Function; - input Modelica.SIunits.Efficiency Eff "Exchanger effectiveness"; - input Real Cr "Ratio of thermal condutance"; - output Real NTU "Number of transfer unit"; + input Modelica.SIunits.Efficiency Eff + "Exchanger effectiveness"; + input Real Cr + "Ratio of thermal condutance"; + output Real NTU + "Number of transfer unit"; algorithm - NTU := -log(1.0-Eff*(1+Cr))/(1+Cr); + NTU := -log(1.0 - Eff * (1 + Cr)) / (1 + Cr); annotation ( inverse(Eff = TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.counterCurrent(NTU = NTU, Cr = Cr)), - Documentation(info = " + Documentation( + info = " NTU_coCurrent @@ -31,4 +35,5 @@ algorithm ")); + end NTU_coCurrent; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_counterCurrent.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_counterCurrent.mo similarity index 83% rename from HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_counterCurrent.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_counterCurrent.mo index 4701cb6..ebf5f53 100644 --- a/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_counterCurrent.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/NTU_counterCurrent.mo @@ -3,21 +3,25 @@ function NTU_counterCurrent extends Modelica.Icons.Function; - input Modelica.SIunits.Efficiency Eff "Exchanger effectiveness"; - input Real Cr "Ratio of thermal condutance"; - output Real NTU "Number of transfer unit"; + input Modelica.SIunits.Efficiency Eff + "Exchanger effectiveness"; + input Real Cr + "Ratio of thermal condutance"; + output Real NTU + "Number of transfer unit"; algorithm NTU := Modelica.Fluid.Utilities.regStep( x = 0.98 - Cr, x_small = 1.0e-2, - y1 = 1.0 / (Cr-1.0) * log((min(Eff, 0.999)-1.0) / (min(Eff, 0.999)*Cr-1.0)), + y1 = 1.0 / (Cr - 1.0) * log((min(Eff, 0.999) - 1.0) / (min(Eff, 0.999) * Cr - 1.0)), y2 = Eff / (1.0 - min(Eff, 0.999))); annotation ( inverse(Eff = TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.counterCurrent(NTU = NTU, Cr = Cr)), - Documentation(info = " + Documentation( + info = " NTU_counterCurrent @@ -44,4 +48,5 @@ algorithm ")); + end NTU_counterCurrent; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.mo similarity index 98% rename from HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.mo index 10dc68c..c2e9998 100644 --- a/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.mo @@ -1,4 +1,5 @@ within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness; package Inverse + end Inverse; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.order similarity index 100% rename from HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Inverse/package.order diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.mo similarity index 98% rename from HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.mo index 6580486..21db062 100644 --- a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.mo @@ -1,4 +1,5 @@ within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness; package Tests + end Tests; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.order similarity index 100% rename from HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/package.order diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_coCurrent.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_coCurrent.mo new file mode 100644 index 0000000..45dbf6a --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_coCurrent.mo @@ -0,0 +1,23 @@ +within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.Tests; + +model test_coCurrent + + parameter Real NTU = 10 + "Number of transfer unit"; + Real Cr + "Ratio of thermal condutance"; + Modelica.SIunits.Efficiency Eff + "Exchanger effectiveness"; + Modelica.Blocks.Sources.Ramp ramp1(duration = 1, height = 1) + annotation ( + Placement(visible = true, transformation(origin = {-10, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +equation + + Cr = ramp1.y; + Eff = TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.coCurrent(NTU = NTU, Cr = Cr); + + annotation ( + experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.01)); + +end test_coCurrent; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_counterCurrent.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_counterCurrent.mo new file mode 100644 index 0000000..aa1a320 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_counterCurrent.mo @@ -0,0 +1,24 @@ +within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.Tests; + +model test_counterCurrent + + parameter Real NTU = 10 + "Number of transfer unit"; + Real Cr + "Ratio of thermal condutance"; + Modelica.SIunits.Efficiency Eff + "Exchanger effectiveness"; + // Cr stops at 0.99: counterCurrent evaluates its general formula (0/0 at Cr = 1) even where regStep only uses the Cr = 1 limit + Modelica.Blocks.Sources.Ramp ramp1(duration = 1, height = 0.99) + annotation ( + Placement(visible = true, transformation(origin = {-10, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +equation + + Cr = ramp1.y; + Eff = TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.counterCurrent(NTU = NTU, Cr = Cr); + + annotation ( + experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.01)); + +end test_counterCurrent; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_crossCurrent.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_crossCurrent.mo similarity index 70% rename from HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_crossCurrent.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_crossCurrent.mo index a2aa3a5..12c8e4f 100644 --- a/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_crossCurrent.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/Tests/test_crossCurrent.mo @@ -1,11 +1,18 @@ within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.Tests; model test_crossCurrent - parameter Real NTU = 10 "Number of transfer unit"; - Real Cr "Ratio of thermal condutance"; - Modelica.SIunits.Efficiency Eff_both_unmixed, Eff_fluidA_mixed, Eff_fluidB_mixed "Exchanger effectiveness"; - Modelica.Blocks.Sources.Ramp ramp1(duration = 1, height = 1) annotation ( - Placement(visible = true, transformation(origin = {-10, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + parameter Real NTU = 10 + "Number of transfer unit"; + Real Cr + "Ratio of thermal condutance"; + Modelica.SIunits.Efficiency + Eff_both_unmixed, + Eff_fluidA_mixed, + Eff_fluidB_mixed + "Exchanger effectiveness"; + Modelica.Blocks.Sources.Ramp ramp1(duration = 1, height = 1) + annotation ( + Placement(visible = true, transformation(origin = {-10, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); Real Qc_A, Qc_B; equation @@ -34,6 +41,7 @@ equation Qc_A = Qc_A, Qc_B = Qc_B); -annotation ( + annotation ( experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.01)); + end test_crossCurrent; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/baseFunc.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/baseFunc.mo new file mode 100644 index 0000000..c346a93 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/baseFunc.mo @@ -0,0 +1,14 @@ +within TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness; + +function baseFunc + + extends Modelica.Icons.Function; + // + input Real NTU + "Number of transfer unit"; + input Real Cr + "Ratio of thermal condutance"; + output Modelica.SIunits.Efficiency Eff + "Exchanger effectiveness"; + +end baseFunc; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/coCurrent.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/coCurrent.mo similarity index 86% rename from HeatTransfer/Functions/ExchangerEffectiveness/coCurrent.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/coCurrent.mo index 5d49799..210056e 100644 --- a/HeatTransfer/Functions/ExchangerEffectiveness/coCurrent.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/coCurrent.mo @@ -6,12 +6,12 @@ function coCurrent algorithm - Eff := (1.0 - exp(-NTU * (1.0 + Cr))) / (1.0 + Cr ); + Eff := (1.0 - exp(-NTU * (1.0 + Cr))) / (1.0 + Cr); annotation ( inverse(NTU = TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.Inverse.NTU_coCurrent(Eff = Eff, Cr = Cr)), - Documentation(info = -" + Documentation( + info = " coCurrent diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/counterCurrent.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/counterCurrent.mo similarity index 97% rename from HeatTransfer/Functions/ExchangerEffectiveness/counterCurrent.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/counterCurrent.mo index 9bb06c5..eb9e690 100644 --- a/HeatTransfer/Functions/ExchangerEffectiveness/counterCurrent.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/counterCurrent.mo @@ -13,7 +13,8 @@ algorithm annotation ( inverse(NTU = TAeZoSysPro.HeatTransfer.Functions.ExchangerEffectiveness.Inverse.NTU_counterCurrent(Eff = Eff, Cr = Cr)), - Documentation(info = " + Documentation( + info = " counterCurrent @@ -37,4 +38,5 @@ algorithm ")); + end counterCurrent; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/crossCurrent.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/crossCurrent.mo similarity index 80% rename from HeatTransfer/Functions/ExchangerEffectiveness/crossCurrent.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/crossCurrent.mo index 10e274a..002c63a 100644 --- a/HeatTransfer/Functions/ExchangerEffectiveness/crossCurrent.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/crossCurrent.mo @@ -7,58 +7,60 @@ function crossCurrent input Real Qc_A, Qc_B; protected + Real gamma; constant Real Cr_small = 1e-3; algorithm - if Cr<=Cr_small then - gamma:= 0.0; - Eff := 1-exp(-NTU); + + if Cr <= Cr_small then + gamma := 0.0; + Eff := 1 - exp(-NTU); else if arrangement == CrossFlow_arrangement.both_unmixed then - gamma := exp(-Cr*NTU^0.78)-1; + gamma := exp(-Cr * NTU ^ 0.78) - 1; Eff := TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Cr-2*Cr_small, + x = Cr - 2 * Cr_small, x_small = Cr_small, - y1 = 1.0 - exp(NTU^(0.22)*gamma/Cr), - y2 = 1-exp(-NTU)); + y1 = 1.0 - exp(NTU ^ (0.22) * gamma / Cr), + y2 = 1 - exp(-NTU)); elseif arrangement == CrossFlow_arrangement.fluidA_mixed_fluidB_unmixed then if Qc_A == max(Qc_A, Qc_B) then - gamma := 1-exp(-NTU); + gamma := 1 - exp(-NTU); Eff := TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Cr-2*Cr_small, + x = Cr - 2 * Cr_small, x_small = Cr_small, - y1 = (1-exp(-Cr*gamma))/Cr, - y2 = 1-exp(-NTU)); + y1 = (1 - exp(-Cr * gamma)) / Cr, + y2 = 1 - exp(-NTU)); else - gamma := 1-exp(-NTU*Cr); + gamma := 1 - exp(-NTU * Cr); Eff := TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Cr-2*Cr_small, + x = Cr - 2 * Cr_small, x_small = Cr_small, - y1 = (1-exp(-gamma/Cr)), - y2 = 1-exp(-NTU)); + y1 = (1 - exp(-gamma / Cr)), + y2 = 1 - exp(-NTU)); end if; elseif arrangement == CrossFlow_arrangement.fluidB_mixed_fluidA_unmixed then if Qc_A == max(Qc_A, Qc_B) then - gamma := 1-exp(-NTU*Cr); + gamma := 1 - exp(-NTU * Cr); Eff := TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Cr-2*Cr_small, + x = Cr - 2 * Cr_small, x_small = Cr_small, - y1 = (1-exp(-gamma/Cr)), - y2 = 1-exp(-NTU)); + y1 = (1 - exp(-gamma / Cr)), + y2 = 1 - exp(-NTU)); else - gamma := 1-exp(-NTU); + gamma := 1 - exp(-NTU); Eff := TAeZoSysPro.FluidDynamics.Utilities.regStep( - x = Cr-2*Cr_small, + x = Cr - 2 * Cr_small, x_small = Cr_small, - y1 = (1-exp(-Cr*gamma))/Cr, - y2 = 1-exp(-NTU)); + y1 = (1 - exp(-Cr * gamma)) / Cr, + y2 = 1 - exp(-NTU)); end if; @@ -71,7 +73,8 @@ algorithm end if; annotation ( - Documentation(info=" + Documentation( + info = " crossCurrent @@ -135,4 +138,5 @@ algorithm ")); + end crossCurrent; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/package.mo new file mode 100644 index 0000000..63733ec --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/package.mo @@ -0,0 +1,8 @@ +within TAeZoSysPro.HeatTransfer.Functions; + +package ExchangerEffectiveness + "Package of functions to compute the effectiveness of an exchanger" + + extends Modelica.Icons.FunctionsPackage; + +end ExchangerEffectiveness; diff --git a/HeatTransfer/Functions/ExchangerEffectiveness/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/package.order similarity index 100% rename from HeatTransfer/Functions/ExchangerEffectiveness/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerEffectiveness/package.order diff --git a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.mo similarity index 98% rename from HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.mo index 2ae6d95..9fb25c1 100644 --- a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.mo @@ -1,4 +1,5 @@ within TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; package Tests + end Tests; diff --git a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.order similarity index 100% rename from HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/package.order diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/test_from_correlations.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/test_from_correlations.mo new file mode 100644 index 0000000..d2c33e5 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/Tests/test_from_correlations.mo @@ -0,0 +1,43 @@ +within TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff.Tests; + +model test_from_correlations + + parameter Modelica.SIunits.ReynoldsNumber Re_A = 1e5 + "Reynolds number for flow A"; + parameter Modelica.SIunits.PrandtlNumber Pr_A = 7 + "Prandtl number for fluid A"; + parameter Modelica.SIunits.Length Lc_A = 0.2 + "Charactereistic length for flow A"; + parameter Modelica.SIunits.ThermalConductivity k_A = 0.06 + "Thermal conductivity for fluid A"; + parameter Modelica.SIunits.ReynoldsNumber Re_B = 1e6 + "Reynolds number for flow A"; + parameter Modelica.SIunits.PrandtlNumber Pr_B = 1 + "Prandtl number for fluid A"; + parameter Modelica.SIunits.Length Lc_B = 1 + "Charactereistic length for flow A"; + parameter Modelica.SIunits.ThermalConductivity k_B = 0.03 + "Thermal conductivity for fluid A"; + Modelica.SIunits.CoefficientOfHeatTransfer + h, + h_A, + h_B + "Heat transfer Coefficient"; + +equation + + h = TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff.from_correlations( + Re_A = Re_A, + Pr_A = Pr_A, + Lc_A = Lc_A, + k_A = k_A, + Re_B = Re_B, + Pr_B = Pr_B, + Lc_B = Lc_B, + k_B = k_B); + + h_A = TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.internal_pipe_ASHRAE(Re = Re_A, Pr = Pr_A, dT = 0.0) * k_A / Lc_A; + + h_B = TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.flat_plate_ASHRAE(Re = Re_B, Pr = Pr_B) * k_B / Lc_B; + +end test_from_correlations; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/baseFun.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/baseFun.mo new file mode 100644 index 0000000..da301d5 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/baseFun.mo @@ -0,0 +1,11 @@ +within TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; + +partial function baseFun + "Base class for heat transfer coefficient calculation in heat exchanger" + + extends Modelica.Icons.Function; + // + output Modelica.SIunits.CoefficientOfHeatTransfer h + "Heat transfer Coefficient"; + +end baseFun; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/from_correlations.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/from_correlations.mo new file mode 100644 index 0000000..d226d9b --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/from_correlations.mo @@ -0,0 +1,35 @@ +within TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; + +function from_correlations + + extends baseFun; + input Modelica.SIunits.ReynoldsNumber Re_A + "Reynolds number for flow A"; + input Modelica.SIunits.PrandtlNumber Pr_A + "Prandtl number for fluid A"; + input Modelica.SIunits.Length Lc_A + "Charactereistic length for flow A"; + input Modelica.SIunits.ThermalConductivity k_A + "Thermal conductivity for fluid A"; + input Modelica.SIunits.ReynoldsNumber Re_B + "Reynolds number for flow A"; + input Modelica.SIunits.PrandtlNumber Pr_B + "Prandtl number for fluid A"; + input Modelica.SIunits.Length Lc_B + "Charactereistic length for flow A"; + input Modelica.SIunits.ThermalConductivity k_B + "Thermal conductivity for fluid A"; + +protected + + Modelica.SIunits.NusseltNumber Nu_A; + Modelica.SIunits.NusseltNumber Nu_B; + +algorithm + + Nu_A := TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.internal_pipe_ASHRAE(Re = Re_A, Pr = Pr_A, dT = 0.0); + Nu_B := TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.flat_plate_ASHRAE(Re = Re_B, Pr = Pr_B); + + h := (Lc_A / (Nu_A * k_A) + Lc_B / (Nu_B * k_B)) ^ (-1); + +end from_correlations; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.mo new file mode 100644 index 0000000..3f39868 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.mo @@ -0,0 +1,8 @@ +within TAeZoSysPro.HeatTransfer.Functions; + +package ExchangerHeatTransferCoeff + "Package of functions to compute the heat transfer coefficient between the two fluids of an exchanger" + + extends Modelica.Icons.FunctionsPackage; + +end ExchangerHeatTransferCoeff; diff --git a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.order similarity index 100% rename from HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/package.order diff --git a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/user_defined.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/user_defined.mo similarity index 55% rename from HeatTransfer/Functions/ExchangerHeatTransferCoeff/user_defined.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/user_defined.mo index a7256a1..109fed4 100644 --- a/HeatTransfer/Functions/ExchangerHeatTransferCoeff/user_defined.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ExchangerHeatTransferCoeff/user_defined.mo @@ -1,11 +1,12 @@ within TAeZoSysPro.HeatTransfer.Functions.ExchangerHeatTransferCoeff; function user_defined - extends baseFun ; - input Modelica.SIunits.CoefficientOfHeatTransfer h_in = 1 ; - + + extends baseFun; + input Modelica.SIunits.CoefficientOfHeatTransfer h_in = 1; + algorithm - h := h_in ; + h := h_in; end user_defined; diff --git a/HeatTransfer/Functions/ForcedConvection/Tests/crossFlow_cylinder_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/crossFlow_cylinder_ASHRAE.mo similarity index 95% rename from HeatTransfer/Functions/ForcedConvection/Tests/crossFlow_cylinder_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/crossFlow_cylinder_ASHRAE.mo index 9c9290a..deacf16 100644 --- a/HeatTransfer/Functions/ForcedConvection/Tests/crossFlow_cylinder_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/crossFlow_cylinder_ASHRAE.mo @@ -4,13 +4,13 @@ model crossFlow_cylinder_ASHRAE Modelica.SIunits.NusseltNumber Nu; Modelica.SIunits.ReynoldsNumber Re; - + equation Re = 10 ^ time; Nu = Functions.ForcedConvection.crossFlow_cylinder_ASHRAE(Pr = 1, Re = Re); - - annotation( + + annotation ( experiment(StartTime = 0, StopTime = 13, Tolerance = 1e-06, Interval = 0.1)); end crossFlow_cylinder_ASHRAE; diff --git a/HeatTransfer/Functions/ForcedConvection/Tests/flat_plate_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/flat_plate_ASHRAE.mo similarity index 68% rename from HeatTransfer/Functions/ForcedConvection/Tests/flat_plate_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/flat_plate_ASHRAE.mo index e647483..dd088ce 100644 --- a/HeatTransfer/Functions/ForcedConvection/Tests/flat_plate_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/flat_plate_ASHRAE.mo @@ -2,15 +2,15 @@ within TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.Tests; model flat_plate_ASHRAE - Modelica.SIunits.NusseltNumber Nu ; - Modelica.SIunits.ReynoldsNumber Re ; + Modelica.SIunits.NusseltNumber Nu; + Modelica.SIunits.ReynoldsNumber Re; equation - Re = 5 * 10^(time+5) ; - Nu = Functions.ForcedConvection.flat_plate_ASHRAE(Pr = 1, Re = Re) ; + Re = 5 * 10 ^ (time + 5); + Nu = Functions.ForcedConvection.flat_plate_ASHRAE(Pr = 1, Re = Re); -annotation( + annotation ( experiment(StartTime = 0, StopTime = 6, Tolerance = 1e-6, Interval = 0.06)); end flat_plate_ASHRAE; diff --git a/HeatTransfer/Functions/ForcedConvection/Tests/internal_pipe_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/internal_pipe_ASHRAE.mo similarity index 75% rename from HeatTransfer/Functions/ForcedConvection/Tests/internal_pipe_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/internal_pipe_ASHRAE.mo index d32ccd8..0ff7b98 100644 --- a/HeatTransfer/Functions/ForcedConvection/Tests/internal_pipe_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/internal_pipe_ASHRAE.mo @@ -1,16 +1,19 @@ within TAeZoSysPro.HeatTransfer.Functions.ForcedConvection.Tests; model internal_pipe_ASHRAE - Modelica.SIunits.TemperatureDifference dT "Temperature difference between wall and fluid"; + + Modelica.SIunits.TemperatureDifference dT + "Temperature difference between wall and fluid"; Modelica.SIunits.NusseltNumber Nu; Modelica.SIunits.ReynoldsNumber Re; - + equation - dT = 20 ; + dT = 20; Re = 5 * 10 ^ (time + 5); Nu = Functions.ForcedConvection.internal_pipe_ASHRAE(Pr = 1, Re = Re, dT = dT); - - annotation( + + annotation ( experiment(StartTime = 0, StopTime = 6, Tolerance = 1e-06, Interval = 0.06)); + end internal_pipe_ASHRAE; diff --git a/HeatTransfer/Functions/ForcedConvection/Tests/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/package.mo similarity index 98% rename from HeatTransfer/Functions/ForcedConvection/Tests/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/package.mo index f19950f..8b767ea 100644 --- a/HeatTransfer/Functions/ForcedConvection/Tests/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/package.mo @@ -1,4 +1,5 @@ within TAeZoSysPro.HeatTransfer.Functions.ForcedConvection; package Tests + end Tests; diff --git a/HeatTransfer/Functions/ForcedConvection/Tests/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/package.order similarity index 100% rename from HeatTransfer/Functions/ForcedConvection/Tests/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/Tests/package.order diff --git a/HeatTransfer/Functions/ForcedConvection/crossFlow_cylinder_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/crossFlow_cylinder_ASHRAE.mo similarity index 87% rename from HeatTransfer/Functions/ForcedConvection/crossFlow_cylinder_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/crossFlow_cylinder_ASHRAE.mo index e3b4763..902e0cf 100644 --- a/HeatTransfer/Functions/ForcedConvection/crossFlow_cylinder_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/crossFlow_cylinder_ASHRAE.mo @@ -1,19 +1,21 @@ within TAeZoSysPro.HeatTransfer.Functions.ForcedConvection; function crossFlow_cylinder_ASHRAE + extends Modelica.Icons.Function; input Modelica.SIunits.PrandtlNumber Pr; input Modelica.SIunits.ReynoldsNumber Re; - output Modelica.SIunits.NusseltNumber Nu; + output Modelica.SIunits.NusseltNumber Nu; algorithm Nu := 0.3 + 0.62 * Re ^ (1 / 2) * Pr ^ (1 / 3) / (1 + (0.4 / Pr) ^ (2 / 3)) ^ (1 / 4) * (1 + (Re / 282000) ^ (5 / 8)) ^ (4 / 5); - annotation( + annotation ( Diagram(coordinateSystem(grid = {1, 1})), - Documentation(info = " + Documentation( + info = " crossFlow_cylinder_ASHRAE diff --git a/HeatTransfer/Functions/ForcedConvection/flat_plate_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/flat_plate_ASHRAE.mo similarity index 79% rename from HeatTransfer/Functions/ForcedConvection/flat_plate_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/flat_plate_ASHRAE.mo index eb85e3f..23ca896 100644 --- a/HeatTransfer/Functions/ForcedConvection/flat_plate_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/flat_plate_ASHRAE.mo @@ -1,21 +1,23 @@ within TAeZoSysPro.HeatTransfer.Functions.ForcedConvection; function flat_plate_ASHRAE + extends Modelica.Icons.Function; input Modelica.SIunits.PrandtlNumber Pr; input Modelica.SIunits.ReynoldsNumber Re; - output Modelica.SIunits.NusseltNumber Nu; + output Modelica.SIunits.NusseltNumber Nu; algorithm Nu := 0.037 * Re ^ (4 / 5) * Pr ^ (1 / 3); - assert(not(Re < 5*10^5), "The Reynolds number < 5x10^5 is out of the range of the correlation", level = AssertionLevel.warning) ; + assert(not (Re < 5 * 10 ^ 5), "The Reynolds number < 5x10^5 is out of the range of the correlation", level = AssertionLevel.warning); - annotation( + annotation ( Diagram(coordinateSystem(grid = {1, 1})), - Documentation(info = " + Documentation( + info = " flat_plate_ASHRAE diff --git a/HeatTransfer/Functions/ForcedConvection/internal_pipe_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/internal_pipe_ASHRAE.mo similarity index 82% rename from HeatTransfer/Functions/ForcedConvection/internal_pipe_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/internal_pipe_ASHRAE.mo index 6ee234a..799119b 100644 --- a/HeatTransfer/Functions/ForcedConvection/internal_pipe_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/internal_pipe_ASHRAE.mo @@ -3,19 +3,22 @@ within TAeZoSysPro.HeatTransfer.Functions.ForcedConvection; function internal_pipe_ASHRAE extends Modelica.Icons.Function; - + input Modelica.SIunits.PrandtlNumber Pr; input Modelica.SIunits.ReynoldsNumber Re; - input Modelica.SIunits.TemperatureDifference dT; + input Modelica.SIunits.TemperatureDifference dT; output Modelica.SIunits.NusseltNumber Nu; - + protected - Real n "reynolds exponent" ; - + + Real n + "reynolds exponent"; + algorithm -// non declarative algorithmic -//cooling or heating mode selection -/* + + // non declarative algorithmic + //cooling or heating mode selection + /* - Twall > T mean fluid => heating mode - Twall < T mean fluid => cooling mode */ @@ -31,11 +34,12 @@ algorithm end if; Nu := 0.023 * Re ^ (4 / 5) * Pr ^ n; - - assert(not(Re < 10^4), "The Reynolds number < 10^4 is out of the range of the correlation", level = AssertionLevel.warning) ; - annotation( - Documentation(info = " + assert(not (Re < 10 ^ 4), "The Reynolds number < 10^4 is out of the range of the correlation", level = AssertionLevel.warning); + + annotation ( + Documentation( + info = " internal_flow_pipe_ASHRAE @@ -72,4 +76,4 @@ algorithm "), Diagram(coordinateSystem(grid = {1, 1}))); -end internal_pipe_ASHRAE ; +end internal_pipe_ASHRAE; diff --git a/HeatTransfer/Functions/ForcedConvection/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/package.mo similarity index 67% rename from HeatTransfer/Functions/ForcedConvection/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/package.mo index 7982ce7..3d75a5f 100644 --- a/HeatTransfer/Functions/ForcedConvection/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/package.mo @@ -2,6 +2,6 @@ within TAeZoSysPro.HeatTransfer.Functions; package ForcedConvection - extends Modelica.Icons.FunctionsPackage ; + extends Modelica.Icons.FunctionsPackage; end ForcedConvection; diff --git a/HeatTransfer/Functions/ForcedConvection/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/package.order similarity index 100% rename from HeatTransfer/Functions/ForcedConvection/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/ForcedConvection/package.order diff --git a/HeatTransfer/Functions/FreeConvection/Tests/ceiling_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/ceiling_ASHRAE.mo similarity index 75% rename from HeatTransfer/Functions/FreeConvection/Tests/ceiling_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/ceiling_ASHRAE.mo index 342b5b2..6374486 100644 --- a/HeatTransfer/Functions/FreeConvection/Tests/ceiling_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/ceiling_ASHRAE.mo @@ -4,14 +4,15 @@ model ceiling_ASHRAE Modelica.SIunits.NusseltNumber Nu; Modelica.SIunits.RayleighNumber Ra; - parameter Modelica.SIunits.TemperatureDifference dT = -20 "Difference of Temperature plate - fluid"; - + parameter Modelica.SIunits.TemperatureDifference dT = -20 + "Difference of Temperature plate - fluid"; + equation Ra = min(10 ^ time, 10 ^ 11); Nu = Functions.FreeConvection.ceiling_ASHRAE(Ra = Ra, dT = dT); - - annotation( + + annotation ( experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.1)); end ceiling_ASHRAE; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/ground_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/ground_ASHRAE.mo new file mode 100644 index 0000000..8d8148a --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/ground_ASHRAE.mo @@ -0,0 +1,20 @@ +within TAeZoSysPro.HeatTransfer.Functions.FreeConvection.Tests; + +model ground_ASHRAE + + Modelica.SIunits.NusseltNumber Nu; + Modelica.SIunits.RayleighNumber Ra; + Modelica.SIunits.TemperatureDifference dT + "Difference of Temperature plate - fluid"; + +equation + + Ra = min(10 ^ time, 10 ^ 11); + dT = 20; + + Nu = Functions.FreeConvection.ground_ASHRAE(Ra = Ra, dT = dT); + + annotation ( + experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-6, Interval = 0.1)); + +end ground_ASHRAE; diff --git a/HeatTransfer/Functions/FreeConvection/Tests/horizontal_cylinder_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/horizontal_cylinder_ASHRAE.mo similarity index 95% rename from HeatTransfer/Functions/FreeConvection/Tests/horizontal_cylinder_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/horizontal_cylinder_ASHRAE.mo index 7aee9b1..e27a575 100644 --- a/HeatTransfer/Functions/FreeConvection/Tests/horizontal_cylinder_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/horizontal_cylinder_ASHRAE.mo @@ -4,12 +4,13 @@ model horizontal_cylinder_ASHRAE Modelica.SIunits.NusseltNumber Nu; Modelica.SIunits.RayleighNumber Ra; - + equation Ra = 10 ^ time; Nu = Functions.FreeConvection.horizontal_cylinder_ASHRAE(Pr = 1, Ra = Ra); - annotation( + + annotation ( experiment(StartTime = 1, StopTime = 12, Tolerance = 1e-06, Interval = 0.11)); end horizontal_cylinder_ASHRAE; diff --git a/HeatTransfer/Functions/FreeConvection/Tests/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/package.mo similarity index 98% rename from HeatTransfer/Functions/FreeConvection/Tests/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/package.mo index a6ff294..5467336 100644 --- a/HeatTransfer/Functions/FreeConvection/Tests/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/package.mo @@ -1,4 +1,5 @@ within TAeZoSysPro.HeatTransfer.Functions.FreeConvection; package Tests + end Tests; diff --git a/HeatTransfer/Functions/FreeConvection/Tests/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/package.order similarity index 100% rename from HeatTransfer/Functions/FreeConvection/Tests/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/package.order diff --git a/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_ASHRAE.mo similarity index 68% rename from HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_ASHRAE.mo index 5719cdc..b1dc117 100644 --- a/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_ASHRAE.mo @@ -2,15 +2,16 @@ within TAeZoSysPro.HeatTransfer.Functions.FreeConvection.Tests; model vertical_plate_ASHRAE - Modelica.SIunits.NusseltNumber Nu ; - Modelica.SIunits.RayleighNumber Ra ; + Modelica.SIunits.NusseltNumber Nu; + Modelica.SIunits.RayleighNumber Ra; equation - Ra = min(10^time, 10^11); - - Nu = Functions.FreeConvection.vertical_plate_ASHRAE(Pr = 1, Ra = Ra) ; -annotation( + Ra = min(10 ^ time, 10 ^ 11); + + Nu = Functions.FreeConvection.vertical_plate_ASHRAE(Pr = 1, Ra = Ra); + + annotation ( experiment(StartTime = 1, StopTime = 10, Tolerance = 1e-6, Interval = 0.0045)); end vertical_plate_ASHRAE; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_Recknagel.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_Recknagel.mo new file mode 100644 index 0000000..b87fee1 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/Tests/vertical_plate_Recknagel.mo @@ -0,0 +1,23 @@ +within TAeZoSysPro.HeatTransfer.Functions.FreeConvection.Tests; + +model vertical_plate_Recknagel + + parameter Modelica.SIunits.Temperature T_ref = 283.15 + "Reference temperature"; + Modelica.SIunits.Temperature T_mean + "Mean temperature between plate and fluid"; + Modelica.SIunits.TemperatureDifference dT + "Difference temperature between plate and fluid"; + Modelica.SIunits.CoefficientOfHeatTransfer h_cv + "Convective heat transfer coefficient"; + +equation + + dT = time; + T_mean = T_ref + dT / 2; + h_cv = Functions.FreeConvection.vertical_plate_Recknagel(dT = dT, T_mean = T_mean); + + annotation ( + experiment(StartTime = 0, StopTime = 20, Tolerance = 1e-06, Interval = 0.2)); + +end vertical_plate_Recknagel; diff --git a/HeatTransfer/Functions/FreeConvection/ceiling_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/ceiling_ASHRAE.mo similarity index 54% rename from HeatTransfer/Functions/FreeConvection/ceiling_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/ceiling_ASHRAE.mo index 5aea841..fdad127 100644 --- a/HeatTransfer/Functions/FreeConvection/ceiling_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/ceiling_ASHRAE.mo @@ -4,59 +4,65 @@ function ceiling_ASHRAE extends Modelica.Icons.Function; - input Modelica.SIunits.TemperatureDifference dT "Temperature difference plate - fluid"; + input Modelica.SIunits.TemperatureDifference dT + "Temperature difference plate - fluid"; input Modelica.SIunits.RayleighNumber Ra; output Modelica.SIunits.NusseltNumber Nu; protected + //boundary Rayleigh number - constant Real Ra_1 = 200, Ra_2 = 10 ^ 4, Ra_3 = 8 * 10 ^ 6 ; - Modelica.SIunits.NusseltNumber Nu_up, Nu_buffer ; - Real x_small "shift value to enter in the polynomial fitting to remove discontinuities"; - + constant Real Ra_1 = 200, Ra_2 = 10 ^ 4, Ra_3 = 8 * 10 ^ 6; + Modelica.SIunits.NusseltNumber Nu_up, Nu_buffer; + Real x_small + "shift value to enter in the polynomial fitting to remove discontinuities"; + algorithm + // initialization - x_small := 0 ; - Nu_up := 0 ; - Nu_buffer := 0 ; + x_small := 0; + Nu_up := 0; + Nu_buffer := 0; if dT < 0 then if Ra < Ra_1 then - x_small:= Ra_1/100 ; + x_small := Ra_1 / 100; Nu_buffer := 0.96 * Ra ^ (1 / 6); Nu_up := 0.59 * Ra ^ (1 / 4); - Nu := Modelica.Fluid.Utilities.regStep(x = Ra_1-Ra-x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up) ; - + Nu := Modelica.Fluid.Utilities.regStep(x = Ra_1 - Ra - x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up); + elseif Ra >= Ra_1 and Ra < Ra_2 then - x_small:= Ra_2/100 ; + x_small := Ra_2 / 100; Nu_buffer := 0.59 * Ra ^ (1 / 4); Nu_up := 0.54 * Ra ^ (1 / 4); - Nu := Modelica.Fluid.Utilities.regStep(x = Ra_2-Ra-x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up) ; - + Nu := Modelica.Fluid.Utilities.regStep(x = Ra_2 - Ra - x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up); + elseif Ra >= Ra_2 and Ra < Ra_3 then - x_small:= Ra_3/100 ; + x_small := Ra_3 / 100; Nu_buffer := 0.54 * Ra ^ (1 / 4); Nu_up := 0.15 * Ra ^ (1 / 3); - Nu := Modelica.Fluid.Utilities.regStep(x = Ra_3-Ra-x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up) ; - - elseif Ra >= Ra_3 then + Nu := Modelica.Fluid.Utilities.regStep(x = Ra_3 - Ra - x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up); + + elseif Ra >= Ra_3 then Nu := 0.15 * Ra ^ (1 / 3); - - end if ; - - assert(not(Ra < 1), "the Rayleigh number <1 is out of the range of the correlation", level = AssertionLevel.warning) ; - assert(not(Ra > 1.5*10^9), "the Rayleigh number >1.5*10^9 is out of the range of the correlation", level = AssertionLevel.warning) ; - + + end if; + + assert(not (Ra < 1), "the Rayleigh number <1 is out of the range of the correlation", level = AssertionLevel.warning); + assert(not (Ra > 1.5 * 10 ^ 9), "the Rayleigh number >1.5*10^9 is out of the range of the correlation", level = AssertionLevel.warning); + else - + Nu := 0.27 * Ra ^ (1 / 4); - assert(not(Ra < 10^5), "the Rayleigh number <10^5 is out of the range of the correlation", level = AssertionLevel.warning) ; - assert(not(Ra > 10^10), "the Rayleigh number >10^9 is out of the range of the correlation", level = AssertionLevel.warning) ; + assert(not (Ra < 10 ^ 5), "the Rayleigh number <10^5 is out of the range of the correlation", level = AssertionLevel.warning); + assert(not (Ra > 10 ^ 10), "the Rayleigh number >10^9 is out of the range of the correlation", level = AssertionLevel.warning); end if; - -annotation(Documentation(info = " + + annotation ( + Documentation( + info = " ceiling_ASHRAE diff --git a/HeatTransfer/Functions/FreeConvection/ground_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/ground_ASHRAE.mo similarity index 57% rename from HeatTransfer/Functions/FreeConvection/ground_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/ground_ASHRAE.mo index 597343c..65f5597 100644 --- a/HeatTransfer/Functions/FreeConvection/ground_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/ground_ASHRAE.mo @@ -1,6 +1,7 @@ within TAeZoSysPro.HeatTransfer.Functions.FreeConvection; function ground_ASHRAE + extends Modelica.Icons.Function; input Modelica.SIunits.TemperatureDifference dT; @@ -8,54 +9,59 @@ function ground_ASHRAE output Modelica.SIunits.NusseltNumber Nu; protected + //boundary Rayleigh number - constant Real Ra_1 = 200, Ra_2 = 10 ^ 4, Ra_3 = 8 * 10 ^ 6 ; - Modelica.SIunits.NusseltNumber Nu_up, Nu_buffer ; - Real x_small "shift value to enter in the polynomial fitting to remove discontinuities"; - + constant Real Ra_1 = 200, Ra_2 = 10 ^ 4, Ra_3 = 8 * 10 ^ 6; + Modelica.SIunits.NusseltNumber Nu_up, Nu_buffer; + Real x_small + "shift value to enter in the polynomial fitting to remove discontinuities"; + algorithm + // initialization - x_small := 0 ; - Nu_up := 0 ; - Nu_buffer := 0 ; + x_small := 0; + Nu_up := 0; + Nu_buffer := 0; if dT > 0 then if Ra < Ra_1 then - x_small:= Ra_1/100 ; + x_small := Ra_1 / 100; Nu_buffer := 0.96 * Ra ^ (1 / 6); Nu_up := 0.59 * Ra ^ (1 / 4); - Nu := Modelica.Fluid.Utilities.regStep(x = Ra_1-Ra-x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up) ; - + Nu := Modelica.Fluid.Utilities.regStep(x = Ra_1 - Ra - x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up); + elseif Ra >= Ra_1 and Ra < Ra_2 then - x_small:= Ra_2/100 ; + x_small := Ra_2 / 100; Nu_buffer := 0.59 * Ra ^ (1 / 4); Nu_up := 0.54 * Ra ^ (1 / 4); - Nu := Modelica.Fluid.Utilities.regStep(x = Ra_2-Ra-x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up) ; - + Nu := Modelica.Fluid.Utilities.regStep(x = Ra_2 - Ra - x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up); + elseif Ra >= Ra_2 and Ra < Ra_3 then - x_small:= Ra_3/100 ; + x_small := Ra_3 / 100; Nu_buffer := 0.54 * Ra ^ (1 / 4); Nu_up := 0.15 * Ra ^ (1 / 3); - Nu := Modelica.Fluid.Utilities.regStep(x = Ra_3-Ra-x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up) ; - - elseif Ra >= Ra_3 then + Nu := Modelica.Fluid.Utilities.regStep(x = Ra_3 - Ra - x_small, x_small = x_small, y1 = Nu_buffer, y2 = Nu_up); + + elseif Ra >= Ra_3 then Nu := 0.15 * Ra ^ (1 / 3); - - end if ; - - assert(not(Ra < 1), "the Rayleigh number <1 is out of the range of the correlation", level = AssertionLevel.warning) ; - assert(not(Ra > 1.5*10^9), "the Rayleigh number >1.5*10^9 is out of the range of the correlation", level = AssertionLevel.warning) ; - + + end if; + + assert(not (Ra < 1), "the Rayleigh number <1 is out of the range of the correlation", level = AssertionLevel.warning); + assert(not (Ra > 1.5 * 10 ^ 9), "the Rayleigh number >1.5*10^9 is out of the range of the correlation", level = AssertionLevel.warning); + else - + Nu := 0.27 * Ra ^ (1 / 4); - assert(not(Ra < 10^5), "the Rayleigh number <10^5 is out of the range of the correlation", level = AssertionLevel.warning) ; - assert(not(Ra > 10^10), "the Rayleigh number >10^9 is out of the range of the correlation", level = AssertionLevel.warning) ; + assert(not (Ra < 10 ^ 5), "the Rayleigh number <10^5 is out of the range of the correlation", level = AssertionLevel.warning); + assert(not (Ra > 10 ^ 10), "the Rayleigh number >10^9 is out of the range of the correlation", level = AssertionLevel.warning); end if; - annotation(Documentation(info = " + annotation ( + Documentation( + info = " ground_ASHRAE diff --git a/HeatTransfer/Functions/FreeConvection/horizontal_cylinder_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/horizontal_cylinder_ASHRAE.mo similarity index 76% rename from HeatTransfer/Functions/FreeConvection/horizontal_cylinder_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/horizontal_cylinder_ASHRAE.mo index 353ccfb..55c0136 100644 --- a/HeatTransfer/Functions/FreeConvection/horizontal_cylinder_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/horizontal_cylinder_ASHRAE.mo @@ -5,17 +5,19 @@ function horizontal_cylinder_ASHRAE extends Modelica.Icons.Function; input Modelica.SIunits.PrandtlNumber Pr; - input Modelica.SIunits.RayleighNumber Ra; + input Modelica.SIunits.RayleighNumber Ra; output Modelica.SIunits.NusseltNumber Nu; algorithm Nu := (0.6 + 0.387 * Ra ^ (1 / 6) / (1 + (0.559 / Pr) ^ (9 / 16)) ^ (8 / 27)) ^ 2; - - assert(not(Ra < 10^9), "the Rayleigh number <10^9 is out of the range of the correlation", level = AssertionLevel.warning) ; - assert(not(Ra > 10^13), "the Rayleigh number >10^13 is out of the range of the correlation", level = AssertionLevel.warning) ; - - annotation(Documentation(info = " + + assert(not (Ra < 10 ^ 9), "the Rayleigh number <10^9 is out of the range of the correlation", level = AssertionLevel.warning); + assert(not (Ra > 10 ^ 13), "the Rayleigh number >10^13 is out of the range of the correlation", level = AssertionLevel.warning); + + annotation ( + Documentation( + info = " horizontal_cylinder_ASHRAE diff --git a/HeatTransfer/Functions/FreeConvection/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/package.mo similarity index 66% rename from HeatTransfer/Functions/FreeConvection/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/package.mo index 2052c11..30ab802 100644 --- a/HeatTransfer/Functions/FreeConvection/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/package.mo @@ -2,6 +2,6 @@ within TAeZoSysPro.HeatTransfer.Functions; package FreeConvection - extends Modelica.Icons.FunctionsPackage ; + extends Modelica.Icons.FunctionsPackage; end FreeConvection; diff --git a/HeatTransfer/Functions/FreeConvection/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/package.order similarity index 100% rename from HeatTransfer/Functions/FreeConvection/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/package.order diff --git a/HeatTransfer/Functions/FreeConvection/vertical_plate_ASHRAE.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/vertical_plate_ASHRAE.mo similarity index 78% rename from HeatTransfer/Functions/FreeConvection/vertical_plate_ASHRAE.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/vertical_plate_ASHRAE.mo index 84f3937..13eb090 100644 --- a/HeatTransfer/Functions/FreeConvection/vertical_plate_ASHRAE.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/vertical_plate_ASHRAE.mo @@ -1,26 +1,28 @@ within TAeZoSysPro.HeatTransfer.Functions.FreeConvection; function vertical_plate_ASHRAE + extends Modelica.Icons.Function; input Modelica.SIunits.PrandtlNumber Pr; - input Modelica.SIunits.RayleighNumber Ra; + input Modelica.SIunits.RayleighNumber Ra; output Modelica.SIunits.NusseltNumber Nu; algorithm -// the following code were used for avoiding the extrapolation of correlation + // the following code were used for avoiding the extrapolation of correlation //Nu_down := 0.68 + 0.67 * Ra^(1 / 4) / ( 1 + (0.492/Pr)^(9/16) )^(4/9) ; //Nu_up := (0.825 + 0.387 * Ra ^ (1 / 6) / (1 + (0.492 / Pr) ^ (9 / 16)) ^ (8 / 27)) ^ 2; //Nu := Modelica.Fluid.Utilities.regStep(x = Ra_1-Ra, x_small = x_small, y1 = Nu_down, y2 = Nu_up) ; - + Nu := (0.825 + 0.387 * Ra ^ (1 / 6) / (1 + (0.492 / Pr) ^ (9 / 16)) ^ (8 / 27)) ^ 2; - - assert(not(Ra < 10^9), "the Rayleigh number < 10^9 is out of the range of the correlation. => Correlation extrapolated ", level = AssertionLevel.warning) ; - assert(not(Ra > 10^13), "the Rayleigh number > 10^12 is out of the range of the correlation", level = AssertionLevel.warning) ; - - annotation(Documentation(info = " + assert(not (Ra < 10 ^ 9), "the Rayleigh number < 10^9 is out of the range of the correlation. => Correlation extrapolated ", level = AssertionLevel.warning); + assert(not (Ra > 10 ^ 13), "the Rayleigh number > 10^12 is out of the range of the correlation", level = AssertionLevel.warning); + + annotation ( + Documentation( + info = " vertical_plate_ASHRAE diff --git a/HeatTransfer/Functions/FreeConvection/vertical_plate_Recknagel.mo b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/vertical_plate_Recknagel.mo similarity index 76% rename from HeatTransfer/Functions/FreeConvection/vertical_plate_Recknagel.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/vertical_plate_Recknagel.mo index 2221a49..60bbae9 100644 --- a/HeatTransfer/Functions/FreeConvection/vertical_plate_Recknagel.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/FreeConvection/vertical_plate_Recknagel.mo @@ -1,17 +1,23 @@ within TAeZoSysPro.HeatTransfer.Functions.FreeConvection; function vertical_plate_Recknagel + extends Modelica.Icons.Function; - input Modelica.SIunits.TemperatureDifference dT "Difference temperature between plate and fluid" ; - input Modelica.SIunits.Temperature T_mean "Mean temperature between plate and fluid" ; - output Modelica.SIunits.CoefficientOfHeatTransfer h_cv "Convective heat transfer coefficient"; + input Modelica.SIunits.TemperatureDifference dT + "Difference temperature between plate and fluid"; + input Modelica.SIunits.Temperature T_mean + "Mean temperature between plate and fluid"; + output Modelica.SIunits.CoefficientOfHeatTransfer h_cv + "Convective heat transfer coefficient"; algorithm h_cv := 9.7 * (abs(dT) / T_mean) ^ (1 / 3); - annotation(Documentation(info = " + annotation ( + Documentation( + info = " vertical_plate_Recknagel diff --git a/HeatTransfer/Functions/MeshGrid/Tests/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/package.mo similarity index 98% rename from HeatTransfer/Functions/MeshGrid/Tests/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/package.mo index 78a1c57..e2f7609 100644 --- a/HeatTransfer/Functions/MeshGrid/Tests/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/package.mo @@ -1,4 +1,5 @@ within TAeZoSysPro.HeatTransfer.Functions.MeshGrid; package Tests + end Tests; diff --git a/HeatTransfer/Functions/MeshGrid/Tests/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/package.order similarity index 100% rename from HeatTransfer/Functions/MeshGrid/Tests/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/package.order diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndGeometricalGrowthGrid.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndGeometricalGrowthGrid.mo new file mode 100644 index 0000000..92ad967 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndGeometricalGrowthGrid.mo @@ -0,0 +1,28 @@ +within TAeZoSysPro.HeatTransfer.Functions.MeshGrid.Tests; + +model test_biotAndGeometricalGrowthGrid + + parameter Modelica.SIunits.Length L = 1 + "Length of the domain to mesh"; + parameter Integer N = 8 + "number of segments"; + parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10; + parameter Modelica.SIunits.ThermalConductivity k = 1; + parameter Modelica.SIunits.Position x[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.biotAndGeometricalGrowthGrid( + L = L, + N = N, + q = 1.2, + h = h, + k = k, + symmetricalMesh = false); + parameter Modelica.SIunits.Position x2[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.biotAndGeometricalGrowthGrid( + L = L, + N = N, + q = 2, + h = h, + k = k, + symmetricalMesh = true); + +equation + +end test_biotAndGeometricalGrowthGrid; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndUniformGrid.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndUniformGrid.mo new file mode 100644 index 0000000..d6fe921 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_biotAndUniformGrid.mo @@ -0,0 +1,26 @@ +within TAeZoSysPro.HeatTransfer.Functions.MeshGrid.Tests; + +model test_biotAndUniformGrid + + parameter Modelica.SIunits.Length L = 1 + "Length of the domain to mesh"; + parameter Integer N = 5 + "number of segments"; + parameter Modelica.SIunits.CoefficientOfHeatTransfer h = 10; + parameter Modelica.SIunits.ThermalConductivity k = 1; + parameter Modelica.SIunits.Position x[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.biotAndUniformGrid( + L = L, + N = N, + h = h, + k = k, + symmetricalMesh = false); + parameter Modelica.SIunits.Position x2[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.biotAndUniformGrid( + L = L, + N = N, + h = h, + k = k, + symmetricalMesh = true); + +equation + +end test_biotAndUniformGrid; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_geometricalGrowthGrid.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_geometricalGrowthGrid.mo new file mode 100644 index 0000000..5356fc4 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_geometricalGrowthGrid.mo @@ -0,0 +1,30 @@ +within TAeZoSysPro.HeatTransfer.Functions.MeshGrid.Tests; + +model test_geometricalGrowthGrid + + parameter Modelica.SIunits.Length L = 1 + "Length of the domain to mesh"; + parameter Integer N_odd = 5 + "Odd number of segments"; + parameter Integer N_even = 6 + "Even number of segments"; + parameter Modelica.SIunits.Position x[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.geometricalGrowthGrid( + L = L, + N = N_odd, + q = 1.2, + symmetricalMesh = false); + parameter Modelica.SIunits.Position x_sym_odd[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.geometricalGrowthGrid( + L = L, + N = N_odd, + q = 1.2, + symmetricalMesh = true); + + parameter Modelica.SIunits.Position x_sym_even[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.geometricalGrowthGrid( + L = L, + N = N_even, + q = 1.2, + symmetricalMesh = true); + +equation + +end test_geometricalGrowthGrid; diff --git a/HeatTransfer/Functions/MeshGrid/Tests/test_uniformGrid.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_uniformGrid.mo similarity index 64% rename from HeatTransfer/Functions/MeshGrid/Tests/test_uniformGrid.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_uniformGrid.mo index 3ad0653..d7b43c2 100644 --- a/HeatTransfer/Functions/MeshGrid/Tests/test_uniformGrid.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/Tests/test_uniformGrid.mo @@ -2,8 +2,10 @@ within TAeZoSysPro.HeatTransfer.Functions.MeshGrid.Tests; model test_uniformGrid - parameter Modelica.SIunits.Length L = 1 "Length of the domain to mesh" ; - parameter Integer N = 5 "number of segments" ; + parameter Modelica.SIunits.Length L = 1 + "Length of the domain to mesh"; + parameter Integer N = 5 + "number of segments"; parameter Modelica.SIunits.Position x[:] = TAeZoSysPro.HeatTransfer.Functions.MeshGrid.uniformGrid(L = L, N = N); equation diff --git a/HeatTransfer/Functions/MeshGrid/biotAndGeometricalGrowthGrid.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/biotAndGeometricalGrowthGrid.mo similarity index 65% rename from HeatTransfer/Functions/MeshGrid/biotAndGeometricalGrowthGrid.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/biotAndGeometricalGrowthGrid.mo index 2e6d5a6..162090d 100644 --- a/HeatTransfer/Functions/MeshGrid/biotAndGeometricalGrowthGrid.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/biotAndGeometricalGrowthGrid.mo @@ -2,69 +2,83 @@ within TAeZoSysPro.HeatTransfer.Functions.MeshGrid; function biotAndGeometricalGrowthGrid - input Modelica.SIunits.Length L "Length of the domain to mesh" ; - input Integer N "number of segments" ; - input Real q "Growth rate" ; - input Modelica.SIunits.CoefficientOfHeatTransfer h "Decoupled value of the heat transfer coefficient" ; - input Modelica.SIunits.ThermalConductivity k "Decoupled value of thermal conductivity" ; - input Boolean symmetricalMesh = true "Axial symmetry mesh where the axis is the middle of the domain"; - output Modelica.SIunits.Position x[N+1] "Vector of vertice position" ; + input Modelica.SIunits.Length L + "Length of the domain to mesh"; + input Integer N + "number of segments"; + input Real q + "Growth rate"; + input Modelica.SIunits.CoefficientOfHeatTransfer h + "Decoupled value of the heat transfer coefficient"; + input Modelica.SIunits.ThermalConductivity k + "Decoupled value of thermal conductivity"; + input Boolean symmetricalMesh = true + "Axial symmetry mesh where the axis is the middle of the domain"; + output Modelica.SIunits.Position x[N + 1] + "Vector of vertice position"; protected - constant Modelica.SIunits.BiotNumber Bi = 0.1 ; - Modelica.SIunits.Distance dx_biot "length of the first segment according to the biot number" ; - Modelica.SIunits.Distance dx "size of the first element" ; - Integer N_2 "number of segments - 2 for biot segment" ; + + constant Modelica.SIunits.BiotNumber Bi = 0.1; + Modelica.SIunits.Distance dx_biot + "length of the first segment according to the biot number"; + Modelica.SIunits.Distance dx + "size of the first element"; + Integer N_2 + "number of segments - 2 for biot segment"; algorithm - N_2 := N - 2 ; - dx_biot := Bi * k / h ; - - if N > 2 then - x[1] := 0.0 ; - x[2] := dx_biot ; - + + N_2 := N - 2; + dx_biot := Bi * k / h; + + if N > 2 then + x[1] := 0.0; + x[2] := dx_biot; + if symmetricalMesh then - if rem(N,2) == 0 then // even number of segment - dx := (L-2*dx_biot)/2 / ( (1-q^(N_2/2))/(1-q) ) ; - - for i in 2:integer(N/2) loop - x[i+1] := x[i] + dx * q^(i-2) ; - end for ; - - for i in integer(N/2)+2:N+1 loop - x[i] := L - x[N+1-i+1] ; - end for ; - + if rem(N, 2) == 0 then // even number of segment + dx := (L - 2 * dx_biot) / 2 / ((1 - q ^ (N_2 / 2)) / (1 - q)); + + for i in 2 : integer(N / 2) loop + x[i + 1] := x[i] + dx * q ^ (i - 2); + end for; + + for i in integer(N / 2) + 2 : N + 1 loop + x[i] := L - x[N + 1 - i + 1]; + end for; + else - dx := (L-2*dx_biot) / ( 2 * (1-q^(floor(N_2/2)))/(1-q) + q^(floor(N_2/2))) ; - - for i in 2:integer( ceil(N/2) ) loop - x[i+1] := x[i] + dx * q^(i-2) ; - end for ; - - for i in integer(ceil(N/2))+1:N+1 loop - x[i] := L - x[N+1-i+1] ; - end for ; - + dx := (L - 2 * dx_biot) / (2 * (1 - q ^ (floor(N_2 / 2))) / (1 - q) + q ^ (floor(N_2 / 2))); + + for i in 2 : integer(ceil(N / 2)) loop + x[i + 1] := x[i] + dx * q ^ (i - 2); + end for; + + for i in integer(ceil(N / 2)) + 1 : N + 1 loop + x[i] := L - x[N + 1 - i + 1]; + end for; + end if; - + else - dx := (L-dx_biot) / ( (1-q^(N-1))/(1-q) ) ; - - for i in 2:N loop - x[i+1] := x[i] + dx * q^(i-2) ; - end for ; - - end if ; + dx := (L - dx_biot) / ((1 - q ^ (N - 1)) / (1 - q)); + + for i in 2 : N loop + x[i + 1] := x[i] + dx * q ^ (i - 2); + end for; + + end if; else - x[1] := 0.0 ; - x[2] := L/2 ; - x[3] := L ; + x[1] := 0.0; + x[2] := L / 2; + x[3] := L; end if; - annotation(Documentation(info = " + annotation ( + Documentation( + info = " uniformGrid @@ -143,6 +157,6 @@ algorithm

        -")) ; +")); end biotAndGeometricalGrowthGrid; diff --git a/HeatTransfer/Functions/MeshGrid/biotAndUniformGrid.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/biotAndUniformGrid.mo similarity index 67% rename from HeatTransfer/Functions/MeshGrid/biotAndUniformGrid.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/biotAndUniformGrid.mo index 8e4d1f4..49acd6e 100644 --- a/HeatTransfer/Functions/MeshGrid/biotAndUniformGrid.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/biotAndUniformGrid.mo @@ -2,40 +2,51 @@ within TAeZoSysPro.HeatTransfer.Functions.MeshGrid; function biotAndUniformGrid - input Modelica.SIunits.Length L "Length of the domain to mesh" ; - input Integer N "number of segments" ; - input Modelica.SIunits.CoefficientOfHeatTransfer h "Decoupled value of the heat transfer coefficient" ; - input Modelica.SIunits.ThermalConductivity k "Decoupled value of thermal conductivity" ; - input Boolean symmetricalMesh = true "Axial symmetry mesh where the axis is the middle of the domain"; - output Modelica.SIunits.Position x[N+1] "Vector of vertice position" ; + input Modelica.SIunits.Length L + "Length of the domain to mesh"; + input Integer N + "number of segments"; + input Modelica.SIunits.CoefficientOfHeatTransfer h + "Decoupled value of the heat transfer coefficient"; + input Modelica.SIunits.ThermalConductivity k + "Decoupled value of thermal conductivity"; + input Boolean symmetricalMesh = true + "Axial symmetry mesh where the axis is the middle of the domain"; + output Modelica.SIunits.Position x[N + 1] + "Vector of vertice position"; protected - constant Modelica.SIunits.BiotNumber Bi = 0.1 ; - Modelica.SIunits.Distance dx "length of the first segment according to the biot number" ; - + + constant Modelica.SIunits.BiotNumber Bi = 0.1; + Modelica.SIunits.Distance dx + "length of the first segment according to the biot number"; + algorithm + if N > 2 then - dx := Bi * k / h ; - x[1] := 0 ; - + dx := Bi * k / h; + x[1] := 0; + if symmetricalMesh then - x[2:N] := linspace(dx, L-dx, N-1); - x[N+1] := L; - + x[2 : N] := linspace(dx, L - dx, N - 1); + x[N + 1] := L; + else - x[2:end] := linspace(dx, L, N); - - end if ; - + x[2 : end] := linspace(dx, L, N); + + end if; + else - dx := 0.0 ; - x[1] := 0 ; - x[2] := L/2 ; - x[3] := L ; - - end if ; + dx := 0.0; + x[1] := 0; + x[2] := L / 2; + x[3] := L; + + end if; - annotation(Documentation(info = " + annotation ( + Documentation( + info = " biotAndUniformGrid @@ -81,6 +92,6 @@ algorithm

        -")) ; +")); end biotAndUniformGrid; diff --git a/HeatTransfer/Functions/MeshGrid/geometricalGrowthGrid.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/geometricalGrowthGrid.mo similarity index 64% rename from HeatTransfer/Functions/MeshGrid/geometricalGrowthGrid.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/geometricalGrowthGrid.mo index 25b2022..55a1a36 100644 --- a/HeatTransfer/Functions/MeshGrid/geometricalGrowthGrid.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/geometricalGrowthGrid.mo @@ -2,49 +2,58 @@ within TAeZoSysPro.HeatTransfer.Functions.MeshGrid; function geometricalGrowthGrid - input Modelica.SIunits.Length L "Length of the domain to mesh" ; - input Integer N "number of segments" ; - input Real q "Growth rate" ; - input Boolean symmetricalMesh = true "Axial symmetry mesh where the axis is the middle of the domain"; - output Modelica.SIunits.Position x[N+1] "Vector of vertice position" ; + input Modelica.SIunits.Length L + "Length of the domain to mesh"; + input Integer N + "number of segments"; + input Real q + "Growth rate"; + input Boolean symmetricalMesh = true + "Axial symmetry mesh where the axis is the middle of the domain"; + output Modelica.SIunits.Position x[N + 1] + "Vector of vertice position"; protected - Modelica.SIunits.Length dx "size of the first element" ; + + Modelica.SIunits.Length dx + "size of the first element"; algorithm if symmetricalMesh then - if rem(N,2) == 0 then // even number of segment - dx := (L/2) / ( (1-q^(N/2))/(1-q) ) ; - x[1] := 0.0 ; - for i in 1:integer(N/2) loop - x[i+1] := x[i] + dx * q^(i-1) ; - end for ; - - for i in integer(N/2)+1:N+1 loop - x[i] := L - x[N+1-i+1] ; - end for ; - + if rem(N, 2) == 0 then // even number of segment + dx := (L / 2) / ((1 - q ^ (N / 2)) / (1 - q)); + x[1] := 0.0; + for i in 1 : integer(N / 2) loop + x[i + 1] := x[i] + dx * q ^ (i - 1); + end for; + + for i in integer(N / 2) + 1 : N + 1 loop + x[i] := L - x[N + 1 - i + 1]; + end for; + else - dx := L / ( 2 * (1-q^(floor(N/2)))/(1-q) + q^(floor(N/2))) ; - x[1] := 0.0 ; - for i in 1:integer( ceil(N/2) ) loop - x[i+1] := x[i] + dx * q^(i-1) ; - end for ; - for i in integer(ceil(N/2))+1:N+1 loop - x[i] := L - x[N+1-i+1] ; - end for ; - + dx := L / (2 * (1 - q ^ (floor(N / 2))) / (1 - q) + q ^ (floor(N / 2))); + x[1] := 0.0; + for i in 1 : integer(ceil(N / 2)) loop + x[i + 1] := x[i] + dx * q ^ (i - 1); + end for; + for i in integer(ceil(N / 2)) + 1 : N + 1 loop + x[i] := L - x[N + 1 - i + 1]; + end for; + end if; else - dx := L / ( (1-q^(N))/(1-q) ) ; - x[1] := 0.0 ; - for i in 1:N loop - x[i+1] := x[i] + dx * q^(i-1) ; - end for ; - end if ; + dx := L / ((1 - q ^ (N)) / (1 - q)); + x[1] := 0.0; + for i in 1 : N loop + x[i + 1] := x[i] + dx * q ^ (i - 1); + end for; + end if; - annotation(Documentation(info = " + annotation ( + Documentation( + info = " geometricalGrowthGrid @@ -101,6 +110,6 @@ algorithm

        -")) ; +")); end geometricalGrowthGrid; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/package.mo new file mode 100644 index 0000000..8d8097a --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/package.mo @@ -0,0 +1,8 @@ +within TAeZoSysPro.HeatTransfer.Functions; + +package MeshGrid + "Package of functions to set the shape and the size of a mesh" + + extends Modelica.Icons.FunctionsPackage; + +end MeshGrid; diff --git a/HeatTransfer/Functions/MeshGrid/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/package.order similarity index 100% rename from HeatTransfer/Functions/MeshGrid/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/package.order diff --git a/HeatTransfer/Functions/MeshGrid/uniformGrid.mo b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/uniformGrid.mo similarity index 77% rename from HeatTransfer/Functions/MeshGrid/uniformGrid.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/uniformGrid.mo index 8feb39f..fd550a6 100644 --- a/HeatTransfer/Functions/MeshGrid/uniformGrid.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/MeshGrid/uniformGrid.mo @@ -1,15 +1,21 @@ within TAeZoSysPro.HeatTransfer.Functions.MeshGrid; function uniformGrid - input Modelica.SIunits.Length L "Length of the domain to mesh" ; - input Integer N "number of segments" ; - output Modelica.SIunits.Position x[N+1] "Vector of vertice position" ; + + input Modelica.SIunits.Length L + "Length of the domain to mesh"; + input Integer N + "number of segments"; + output Modelica.SIunits.Position x[N + 1] + "Vector of vertice position"; algorithm - x := linspace(0, L, N+1) ; + x := linspace(0, L, N + 1); - annotation(Documentation(info = " + annotation ( + Documentation( + info = " uniformGrid @@ -40,6 +46,6 @@ algorithm

        -")) ; +")); end uniformGrid; diff --git a/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/Tests/h_rad.mo b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/Tests/h_rad.mo new file mode 100644 index 0000000..d55621e --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/Tests/h_rad.mo @@ -0,0 +1,18 @@ +within TAeZoSysPro.HeatTransfer.Functions.Radiation.Tests; + +model h_rad + + parameter Modelica.SIunits.Temperature T_A = 303.15; + parameter Modelica.SIunits.Temperature T_B = 283.15; + constant Modelica.SIunits.Emissivity eps = 1; + Modelica.SIunits.CoefficientOfHeatTransfer h_rad, h_rad_check; + +equation + + h_rad = Radiation.h_rad(T_A = T_A, T_B = T_B, R_th = 1 / eps); + h_rad_check = eps * Modelica.Constants.sigma * (T_A ^ 4 - T_B ^ 4) / (T_A - T_B); + + annotation ( + experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.002)); + +end h_rad; diff --git a/HeatTransfer/Functions/Radiation/Tests/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/Tests/package.mo similarity index 98% rename from HeatTransfer/Functions/Radiation/Tests/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/Radiation/Tests/package.mo index fee0a7d..0e963e8 100644 --- a/HeatTransfer/Functions/Radiation/Tests/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/Tests/package.mo @@ -1,4 +1,5 @@ within TAeZoSysPro.HeatTransfer.Functions.Radiation; package Tests + end Tests; diff --git a/HeatTransfer/Functions/Radiation/Tests/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/Tests/package.order similarity index 100% rename from HeatTransfer/Functions/Radiation/Tests/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/Radiation/Tests/package.order diff --git a/HeatTransfer/Functions/Radiation/h_rad.mo b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/h_rad.mo similarity index 84% rename from HeatTransfer/Functions/Radiation/h_rad.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/Radiation/h_rad.mo index 7e944bd..21e58f2 100644 --- a/HeatTransfer/Functions/Radiation/h_rad.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/h_rad.mo @@ -2,22 +2,25 @@ within TAeZoSysPro.HeatTransfer.Functions.Radiation; function h_rad - input Modelica.SIunits.Temperature T_A ; - input Modelica.SIunits.Temperature T_B ; - input Real R_th "Thermal resistance between solid A and B (emissivity and view factor)" ; - output Modelica.SIunits.CoefficientOfHeatTransfer h_rad ; - + input Modelica.SIunits.Temperature T_A; + input Modelica.SIunits.Temperature T_B; + input Real R_th + "Thermal resistance between solid A and B (emissivity and view factor)"; + output Modelica.SIunits.CoefficientOfHeatTransfer h_rad; + algorithm - + // with the expression bellow rise a zero division when T_A = T_B //h_rad := 1 / R_th * Modelica.Constants.sigma * (T_A^4 - T_B^4) / (T_A - T_B) ; - + // the expression bellow is non recursive //h_rad := 1 / R_th * Modelica.Constants.sigma * (T_A^3 + T_A * T_B^2 + T_B * T_A^2 + T_B^3) ; - - h_rad := abs(Modelica.Constants.sigma * (T_A + T_B) * (T_A^2 + T_B^2) / R_th) ; - - annotation(Documentation( info = " + + h_rad := abs(Modelica.Constants.sigma * (T_A + T_B) * (T_A ^ 2 + T_B ^ 2) / R_th); + + annotation ( + Documentation( + info = " HeatTransfer package @@ -62,6 +65,6 @@ algorithm - ") ) ; + ")); end h_rad; diff --git a/HeatTransfer/Functions/Radiation/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/package.mo similarity index 64% rename from HeatTransfer/Functions/Radiation/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/Radiation/package.mo index 6ae5de3..ed2a700 100644 --- a/HeatTransfer/Functions/Radiation/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/package.mo @@ -2,6 +2,6 @@ within TAeZoSysPro.HeatTransfer.Functions; package Radiation - extends Modelica.Icons.FunctionsPackage ; + extends Modelica.Icons.FunctionsPackage; end Radiation; diff --git a/HeatTransfer/Functions/Radiation/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/Radiation/package.order similarity index 100% rename from HeatTransfer/Functions/Radiation/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/Radiation/package.order diff --git a/HeatTransfer/Functions/fviewFunction.mo b/src/TAeZoSysPro/HeatTransfer/Functions/fviewFunction.mo similarity index 63% rename from HeatTransfer/Functions/fviewFunction.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/fviewFunction.mo index e96fdd5..b2aa1e9 100644 --- a/HeatTransfer/Functions/fviewFunction.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/fviewFunction.mo @@ -2,51 +2,62 @@ within TAeZoSysPro.HeatTransfer.Functions; function fviewFunction input Real[:] Awall; - output Real[size(Awall,1)] Fview; + output Real[size(Awall, 1)] Fview; protected - Real tolerance=1e-5 "convergence criteria of residual that stops the iteration process"; - Real Fview_pre[:] "Fview at iteration N-1"; - Real AwallFviewSum "sum of the product Sk*Fk"; - Real residual "norm 2 of vector of the difference (Fview-Fview_pre)"; - Integer iter "number of iterations"; + + Real tolerance = 1e-5 + "convergence criteria of residual that stops the iteration process"; + Real Fview_pre[:] + "Fview at iteration N-1"; + Real AwallFviewSum + "sum of the product Sk*Fk"; + Real residual + "norm 2 of vector of the difference (Fview-Fview_pre)"; + Integer iter + "number of iterations"; algorithm - for i in 1:size(Awall,1) loop - if Awall[i] > sum(Awall)*0.499 then - assert(false,"The surface with the index "+String(i)+" is greater than 49.9 percent of total surface, Fview factor not calculated\n", AssertionLevel.error); + for i in 1 : size(Awall, 1) loop + if Awall[i] > sum(Awall) * 0.499 then + assert(false, "The surface with the index " + String(i) + " is greater than 49.9 percent of total surface, Fview factor not calculated\n", AssertionLevel.error); end if; end for; -// initialisation + // initialisation iter := 0; - Fview := ones(size(Awall,1)); - residual := 10*tolerance; + Fview := ones(size(Awall, 1)); + residual := 10 * tolerance; -// loop - while (residual > tolerance and iter <=1000) loop + // loop + while (residual > tolerance and iter <= 1000) loop AwallFviewSum := 0.0; residual := 0.0; Fview_pre := Fview; - AwallFviewSum := Awall*Fview; + AwallFviewSum := Awall * Fview; - for j in 1:size(Awall,1) loop - Fview[j] := 1/(1-Fview[j]*Awall[j]/AwallFviewSum); + for j in 1 : size(Awall, 1) loop + Fview[j] := 1 / (1 - Fview[j] * Awall[j] / AwallFviewSum); end for; - residual := Modelica.Math.Vectors.norm(v=(Fview-Fview_pre), p=2); + residual := Modelica.Math.Vectors.norm(v = (Fview - Fview_pre), p = 2); - iter := iter+1; + iter := iter + 1; end while; - Modelica.Utilities.Streams.print("iteration to converge on Fview: "+String(iter)); + Modelica.Utilities.Streams.print("iteration to converge on Fview: " + String(iter)); - assert(not - (iter>=1000),"The convergence criteria on view factors is not achieved\n", AssertionLevel.warning); + assert( + not (iter >= 1000), + "The convergence criteria on view factors is not achieved\n", + AssertionLevel.warning); -annotation(Inline = true, Documentation(info = " + annotation ( + Inline = true, + Documentation( + info = " FviewFunction @@ -92,4 +103,5 @@ annotation(Inline = true, Documentation(info = " ")); + end fviewFunction; diff --git a/HeatTransfer/Functions/package.mo b/src/TAeZoSysPro/HeatTransfer/Functions/package.mo similarity index 79% rename from HeatTransfer/Functions/package.mo rename to src/TAeZoSysPro/HeatTransfer/Functions/package.mo index 5e1d94b..4b85c93 100644 --- a/HeatTransfer/Functions/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Functions/package.mo @@ -2,9 +2,9 @@ within TAeZoSysPro.HeatTransfer; package Functions - extends Modelica.Icons.Package ; + extends Modelica.Icons.Package; - annotation( + annotation ( Icon(graphics = {Bitmap(extent = {{-80, -80}, {80, 80}}, fileName = "modelica://TAeZoSysPro/Information/HeatTransfer/Functions/image_package.png")}, coordinateSystem(initialScale = 0.1))); -end Functions; \ No newline at end of file +end Functions; diff --git a/HeatTransfer/Functions/package.order b/src/TAeZoSysPro/HeatTransfer/Functions/package.order similarity index 100% rename from HeatTransfer/Functions/package.order rename to src/TAeZoSysPro/HeatTransfer/Functions/package.order diff --git a/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort.mo b/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort.mo new file mode 100644 index 0000000..cffd0f8 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort.mo @@ -0,0 +1,17 @@ +within TAeZoSysPro.HeatTransfer.Interfaces; + +partial connector HeatPort + "Thermal port for 1-dim. heat transfer" + + Modelica.SIunits.Temperature T + "Port temperature"; + flow Modelica.SIunits.HeatFlowRate Q_flow + "Heat flow rate (positive if flowing from outside into the component)"; + + annotation ( + Documentation( + info = " + +")); + +end HeatPort; diff --git a/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort_a.mo b/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort_a.mo new file mode 100644 index 0000000..375f9ee --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort_a.mo @@ -0,0 +1,56 @@ +within TAeZoSysPro.HeatTransfer.Interfaces; + +connector HeatPort_a + "Thermal port for 1-dim. heat transfer (filled rectangular icon)" + + extends HeatPort; + + annotation ( + defaultComponentName = "port_a", + Documentation( + info = " +

        This connector is used for 1-dimensional heat flow between components. +The variables in the connector are:

        +
        +T       Temperature in [Kelvin].
        +Q_flow  Heat flow rate in [Watt].
        +
        +

        According to the Modelica sign convention, a positive heat flow +rate Q_flow is considered to flow into a component. This +convention has to be used whenever this connector is used in a model +class.

        +

        Note, that the two connector classes HeatPort_a and +HeatPort_b are identical with the only exception of the different +icon layout.

        "), + Icon( + coordinateSystem( + preserveAspectRatio = true, + extent = { + {-100, -100}, + { + 100, + 100}}), + graphics = { + Rectangle( + extent = {{-100, 100}, {100, -100}}, + lineColor = {191, 0, 0}, + fillColor = {191, 0, 0}, + fillPattern = FillPattern.Solid)}), + Diagram( + coordinateSystem( + preserveAspectRatio = true, + extent = { + {-100, -100}, + {100, 100}}), + graphics = { + Rectangle( + extent = {{-50, 50}, {50, -50}}, + lineColor = {191, 0, 0}, + fillColor = {191, 0, 0}, + fillPattern = FillPattern.Solid), + Text( + extent = {{-120, 120}, {100, 60}}, + lineColor = {191, 0, 0}, + textString = "%name")})); + +end HeatPort_a; diff --git a/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort_b.mo b/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort_b.mo new file mode 100644 index 0000000..b02cc47 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Interfaces/HeatPort_b.mo @@ -0,0 +1,56 @@ +within TAeZoSysPro.HeatTransfer.Interfaces; + +connector HeatPort_b + "Thermal port for 1-dim. heat transfer (unfilled rectangular icon)" + + extends HeatPort; + + annotation ( + defaultComponentName = "port_b", + Documentation( + info = " +

        This connector is used for 1-dimensional heat flow between components. +The variables in the connector are:

        +
        +T       Temperature in [Kelvin].
        +Q_flow  Heat flow rate in [Watt].
        +
        +

        According to the Modelica sign convention, a positive heat flow +rate Q_flow is considered to flow into a component. This +convention has to be used whenever this connector is used in a model +class.

        +

        Note, that the two connector classes HeatPort_a and +HeatPort_b are identical with the only exception of the different +icon layout.

        "), + Diagram( + coordinateSystem( + preserveAspectRatio = true, + extent = { + {-100, -100}, + {100, 100}}), + graphics = { + Rectangle( + extent = {{-50, 50}, {50, -50}}, + lineColor = {191, 0, 0}, + fillColor = {255, 255, 255}, + fillPattern = FillPattern.Solid), + Text( + extent = {{-100, 120}, {120, 60}}, + lineColor = {191, 0, 0}, + textString = "%name")}), + Icon( + coordinateSystem( + preserveAspectRatio = true, + extent = { + {-100, -100}, + { + 100, + 100}}), + graphics = { + Rectangle( + extent = {{-100, 100}, {100, -100}}, + lineColor = {191, 0, 0}, + fillColor = {255, 255, 255}, + fillPattern = FillPattern.Solid)})); + +end HeatPort_b; diff --git a/HeatTransfer/Interfaces/package.mo b/src/TAeZoSysPro/HeatTransfer/Interfaces/package.mo similarity index 67% rename from HeatTransfer/Interfaces/package.mo rename to src/TAeZoSysPro/HeatTransfer/Interfaces/package.mo index 34ea436..188fc11 100644 --- a/HeatTransfer/Interfaces/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Interfaces/package.mo @@ -2,9 +2,11 @@ within TAeZoSysPro.HeatTransfer; package Interfaces - extends Modelica.Icons.InterfacesPackage ; + extends Modelica.Icons.InterfacesPackage; -annotation(Documentation(info = " + annotation ( + Documentation( + info = "

        This package contains the definition of 'ports' to exchange data with others modules diff --git a/HeatTransfer/Interfaces/package.order b/src/TAeZoSysPro/HeatTransfer/Interfaces/package.order similarity index 100% rename from HeatTransfer/Interfaces/package.order rename to src/TAeZoSysPro/HeatTransfer/Interfaces/package.order diff --git a/src/TAeZoSysPro/HeatTransfer/Sensors/Density.mo b/src/TAeZoSysPro/HeatTransfer/Sensors/Density.mo new file mode 100644 index 0000000..9ce1240 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Sensors/Density.mo @@ -0,0 +1,42 @@ +within TAeZoSysPro.HeatTransfer.Sensors; + +model Density + "Ideal one port density sensor" + + replaceable package Medium = TAeZoSysPro.Media.MyMedia; + extends Modelica.Icons.RotationalSensor; + Modelica.Blocks.Interfaces.RealOutput d( + final quantity = "Density", + final unit = "kg/m3", + min = 0) + "Density in port medium" + annotation (Placement(transformation(extent = {{100, -10}, {120, 10}}))); + TAeZoSysPro.HeatTransfer.Interfaces.HeatPort_a port + annotation ( + Placement(visible = true, transformation(origin = {0, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0), iconTransformation(origin = {0, -100}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + Modelica.Blocks.Interfaces.RealInput p( + final quantity = "Absolute pressure", + final unit = "Pa", + min = 0) + "Absolute pressure in port medium" + annotation ( + Placement(visible = true, transformation(origin = {-100, -2}, extent = {{-20, -20}, {20, 20}}, rotation = 0), iconTransformation(origin = {-100, 0}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +equation + + d = Medium.density_pTX(p = p, T = port.T, X = Medium.X_default); + port.Q_flow = 0.0; + + annotation ( + Icon(coordinateSystem(initialScale = 0.1), graphics = {Line(points = {{0, -70}, {0, -100}}, color = {0, 0, 127}), Text(lineColor = {0, 0, 255}, extent = {{-150, 80}, {150, 120}}, textString = "%name"), Text(origin = {4, 2}, extent = {{156, -23}, {56, -61}}, textString = "d"), Line(points = {{70, 0}, {100, 0}}, color = {0, 0, 127}), Text(origin = {-216, 82}, extent = {{156, -23}, {56, -61}}, textString = "p")}), + Documentation( + info = " + +

        + This model outputs the density of the fluid from the port tempeature and the input of pressure. + The sensor is ideal, i.e. it does not influence the fluid. +

        +"), + Diagram(coordinateSystem(initialScale = 0.1))); + +end Density; diff --git a/HeatTransfer/Sensors/package.mo b/src/TAeZoSysPro/HeatTransfer/Sensors/package.mo similarity index 69% rename from HeatTransfer/Sensors/package.mo rename to src/TAeZoSysPro/HeatTransfer/Sensors/package.mo index 301db82..c9c907b 100644 --- a/HeatTransfer/Sensors/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Sensors/package.mo @@ -1,5 +1,8 @@ within TAeZoSysPro.HeatTransfer; -package Sensors "Thermal sensors" +package Sensors + "Thermal sensors" + extends Modelica.Icons.SensorsPackage; + end Sensors; diff --git a/HeatTransfer/Sensors/package.order b/src/TAeZoSysPro/HeatTransfer/Sensors/package.order similarity index 100% rename from HeatTransfer/Sensors/package.order rename to src/TAeZoSysPro/HeatTransfer/Sensors/package.order diff --git a/src/TAeZoSysPro/HeatTransfer/Types/CrossFlow_arrangement.mo b/src/TAeZoSysPro/HeatTransfer/Types/CrossFlow_arrangement.mo new file mode 100644 index 0000000..575eb96 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Types/CrossFlow_arrangement.mo @@ -0,0 +1,10 @@ +within TAeZoSysPro.HeatTransfer.Types; + +type CrossFlow_arrangement = enumeration( + both_unmixed + "Both fluids are unmixed", + fluidA_mixed_fluidB_unmixed + "Fluid A in mixed and B unmixed", + fluidB_mixed_fluidA_unmixed + "Fluid A in mixed and B unmixed") + "Enumeration defining the configuration of a cross flows exchanger"; diff --git a/HeatTransfer/Types/Dynamics.mo b/src/TAeZoSysPro/HeatTransfer/Types/Dynamics.mo similarity index 90% rename from HeatTransfer/Types/Dynamics.mo rename to src/TAeZoSysPro/HeatTransfer/Types/Dynamics.mo index 9a22d31..eac89a3 100644 --- a/HeatTransfer/Types/Dynamics.mo +++ b/src/TAeZoSysPro/HeatTransfer/Types/Dynamics.mo @@ -1,15 +1,18 @@ within TAeZoSysPro.HeatTransfer.Types; type Dynamics = enumeration( - DynamicFreeInitial - "DynamicFreeInitial -- Dynamic balance, Initial guess value", - FixedInitial "FixedInitial -- Dynamic balance, Initial value fixed", - SteadyStateInitial - "SteadyStateInitial -- Dynamic balance, Steady state initial with guess value", - - SteadyState "SteadyState -- Steady state balance, Initial guess value") + DynamicFreeInitial + "DynamicFreeInitial -- Dynamic balance, Initial guess value", + FixedInitial + "FixedInitial -- Dynamic balance, Initial value fixed", + SteadyStateInitial + "SteadyStateInitial -- Dynamic balance, Steady state initial with guess value", + SteadyState + "SteadyState -- Steady state balance, Initial guess value") "Enumeration to define definition of balance equations" -annotation (Documentation(info=" + annotation ( + Documentation( + info = "

        Enumeration to define the formulation of balance equations (to be selected via choices menu): diff --git a/src/TAeZoSysPro/HeatTransfer/Types/ForcedConvectionCorrelation.mo b/src/TAeZoSysPro/HeatTransfer/Types/ForcedConvectionCorrelation.mo new file mode 100644 index 0000000..b28ab74 --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Types/ForcedConvectionCorrelation.mo @@ -0,0 +1,12 @@ +within TAeZoSysPro.HeatTransfer.Types; + +type ForcedConvectionCorrelation = enumeration( + internal_pipe_ASHRAE + "Dittus and Boelter correlation for the internal flow inside a cylinder", + crossFlow_cylinder_ASHRAE + "Churchill and Bernstein correlation for the external flow for cross flow over cylinder", + flat_plate_ASHRAE + "ASHRAE correlation for the external flow over a flat plate", + Constant + "Constant convection heat transfer ") + "Enumeration defining the correlation of table"; diff --git a/src/TAeZoSysPro/HeatTransfer/Types/FreeConvectionCorrelation.mo b/src/TAeZoSysPro/HeatTransfer/Types/FreeConvectionCorrelation.mo new file mode 100644 index 0000000..ddfc58c --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Types/FreeConvectionCorrelation.mo @@ -0,0 +1,16 @@ +within TAeZoSysPro.HeatTransfer.Types; + +type FreeConvectionCorrelation = enumeration( + vertical_plate_ASHRAE + "Churchill & Chu correlation for a flat vertical plate", + vertical_plate_Recknagel + "Recknagel correlation for a flat vertical plate", + ground_ASHRAE + "Lloyd and Moran correlation for a horizontal ground plate", + ceiling_ASHRAE + "Lloyd and Moran correlation for a horizontal ceiling plate", + horizontal_cylinder_ASHRAE + "Churchill & Chu correlation for the external flow around an horizontal cylinder", + Constant + "Constant convective heat transfer coefficient") + "Enumeration defining the correlation of table"; diff --git a/src/TAeZoSysPro/HeatTransfer/Types/MeshGrid.mo b/src/TAeZoSysPro/HeatTransfer/Types/MeshGrid.mo new file mode 100644 index 0000000..39e26ca --- /dev/null +++ b/src/TAeZoSysPro/HeatTransfer/Types/MeshGrid.mo @@ -0,0 +1,12 @@ +within TAeZoSysPro.HeatTransfer.Types; + +type MeshGrid = enumeration( + uniform + "Uniform grid with equal spacing between vertices", + biotAndUniform + "Uniform grid with equal spacing between vertices execpted for boundary segments with a specing from biot number", + geometricalGrowth + "Grid with geometrical growth spacing between vertices", + biotAndGeometricalGrowth + "Grid with geometrical growth spacing between vertices execpted for boundary segments with a specing from biot number") + "Enumeration to define the function used to mesh the domain"; diff --git a/HeatTransfer/Types/package.mo b/src/TAeZoSysPro/HeatTransfer/Types/package.mo similarity index 60% rename from HeatTransfer/Types/package.mo rename to src/TAeZoSysPro/HeatTransfer/Types/package.mo index a2e4c75..d7abaaf 100644 --- a/HeatTransfer/Types/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/Types/package.mo @@ -2,6 +2,6 @@ within TAeZoSysPro.HeatTransfer; package Types - extends Modelica.Icons.TypesPackage ; + extends Modelica.Icons.TypesPackage; end Types; diff --git a/HeatTransfer/Types/package.order b/src/TAeZoSysPro/HeatTransfer/Types/package.order similarity index 100% rename from HeatTransfer/Types/package.order rename to src/TAeZoSysPro/HeatTransfer/Types/package.order diff --git a/HeatTransfer/package.mo b/src/TAeZoSysPro/HeatTransfer/package.mo similarity index 99% rename from HeatTransfer/package.mo rename to src/TAeZoSysPro/HeatTransfer/package.mo index 8823f6a..2df9064 100644 --- a/HeatTransfer/package.mo +++ b/src/TAeZoSysPro/HeatTransfer/package.mo @@ -2,8 +2,9 @@ within TAeZoSysPro; package HeatTransfer -annotation( - Documentation(info = " + annotation ( + Documentation( + info = " HeatTransfer package diff --git a/HeatTransfer/package.order b/src/TAeZoSysPro/HeatTransfer/package.order similarity index 100% rename from HeatTransfer/package.order rename to src/TAeZoSysPro/HeatTransfer/package.order diff --git a/Information/FluidDynamics/BasesClasses/EQ_Condensation.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Condensation.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_Condensation.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Condensation.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_FogModel1.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FogModel1.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_FogModel1.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FogModel1.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_FogModel2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FogModel2.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_FogModel2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FogModel2.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_FogModel3.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FogModel3.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_FogModel3.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FogModel3.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_FogModel4.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FogModel4.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_FogModel4.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FogModel4.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_FreeConvection.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FreeConvection.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_FreeConvection.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FreeConvection.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_FreeConvection2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FreeConvection2.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_FreeConvection2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_FreeConvection2.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_GasNode1.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_GasNode1.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_GasNode1.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_GasNode1.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_GasNode2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_GasNode2.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_GasNode2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_GasNode2.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_GasNode3.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_GasNode3.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_GasNode3.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_GasNode3.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas1.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas1.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas1.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas1.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas2.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas2.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas3.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas3.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas3.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas3.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas4.PNG b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas4.PNG similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas4.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_Interface_liq_gas4.PNG diff --git a/Information/FluidDynamics/BasesClasses/EQ_MolecularDiffusion.png b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_MolecularDiffusion.png similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_MolecularDiffusion.png rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_MolecularDiffusion.png diff --git a/Information/FluidDynamics/BasesClasses/EQ_MolecularDiffusion2.png b/src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_MolecularDiffusion2.png similarity index 100% rename from Information/FluidDynamics/BasesClasses/EQ_MolecularDiffusion2.png rename to src/TAeZoSysPro/Information/FluidDynamics/BasesClasses/EQ_MolecularDiffusion2.png diff --git a/Information/FluidDynamics/Components/Buildings/EQ_WallLeak.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Buildings/EQ_WallLeak.PNG similarity index 100% rename from Information/FluidDynamics/Components/Buildings/EQ_WallLeak.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Buildings/EQ_WallLeak.PNG diff --git a/Information/FluidDynamics/Components/Buildings/EQ_WallLeak2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Buildings/EQ_WallLeak2.PNG similarity index 100% rename from Information/FluidDynamics/Components/Buildings/EQ_WallLeak2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Buildings/EQ_WallLeak2.PNG diff --git a/Information/FluidDynamics/Components/Filters/EQ_Filter.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Filters/EQ_Filter.PNG similarity index 100% rename from Information/FluidDynamics/Components/Filters/EQ_Filter.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Filters/EQ_Filter.PNG diff --git a/Information/FluidDynamics/Components/Filters/EQ_Filter2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Filters/EQ_Filter2.PNG similarity index 100% rename from Information/FluidDynamics/Components/Filters/EQ_Filter2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Filters/EQ_Filter2.PNG diff --git a/Information/FluidDynamics/Components/Machines/EQ_PartialPump.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Machines/EQ_PartialPump.PNG similarity index 100% rename from Information/FluidDynamics/Components/Machines/EQ_PartialPump.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Machines/EQ_PartialPump.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger10.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger10.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger10.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger10.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger11.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger11.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger11.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger11.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger12.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger12.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger12.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger12.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger2.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger2.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger3.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger3.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger3.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger3.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger4.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger4.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger4.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger4.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger5.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger5.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger5.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger5.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger6.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger6.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger6.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger6.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger7.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger7.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger7.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger7.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger8.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger8.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger8.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger8.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger9.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger9.PNG similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger9.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/EQ_AnalyticWetExchanger9.PNG diff --git a/Information/FluidDynamics/Components/MassExchangers/Module Batterie froide humide BEG_V2_0.pdf b/src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/Module Batterie froide humide BEG_V2_0.pdf similarity index 100% rename from Information/FluidDynamics/Components/MassExchangers/Module Batterie froide humide BEG_V2_0.pdf rename to src/TAeZoSysPro/Information/FluidDynamics/Components/MassExchangers/Module Batterie froide humide BEG_V2_0.pdf diff --git a/Information/FluidDynamics/Components/Orifices/Demo_opening_aerodynamic.tex b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/Demo_opening_aerodynamic.tex similarity index 100% rename from Information/FluidDynamics/Components/Orifices/Demo_opening_aerodynamic.tex rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/Demo_opening_aerodynamic.tex diff --git a/Information/FluidDynamics/Components/Orifices/EQ_HorizontalOpening1.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_HorizontalOpening1.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_HorizontalOpening1.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_HorizontalOpening1.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_Opening1.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening1.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_Opening1.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening1.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_Opening2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening2.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_Opening2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening2.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_Opening3.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening3.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_Opening3.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening3.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_Opening4.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening4.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_Opening4.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening4.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_Opening5_Cc.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening5_Cc.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_Opening5_Cc.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening5_Cc.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_Opening6_Cv.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening6_Cv.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_Opening6_Cv.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening6_Cv.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_Opening7_Cd.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening7_Cd.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_Opening7_Cd.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening7_Cd.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_Opening8.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening8.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_Opening8.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_Opening8.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp1.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp1.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp1.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp1.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp2.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp2.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp3.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp3.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp3.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp3.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp4.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp4.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp4.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp4.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp5.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp5.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp5.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp5.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp6.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp6.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp6.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp6.PNG diff --git a/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp7.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp7.PNG similarity index 100% rename from Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp7.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Orifices/EQ_SimpleOpeningComp7.PNG diff --git a/Information/FluidDynamics/Components/Pipes/EQ_StaticPipe_ksi.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Pipes/EQ_StaticPipe_ksi.PNG similarity index 100% rename from Information/FluidDynamics/Components/Pipes/EQ_StaticPipe_ksi.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Pipes/EQ_StaticPipe_ksi.PNG diff --git a/Information/FluidDynamics/Components/Pipes/EQ_StaticPipe_m_flow.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Pipes/EQ_StaticPipe_m_flow.PNG similarity index 100% rename from Information/FluidDynamics/Components/Pipes/EQ_StaticPipe_m_flow.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Pipes/EQ_StaticPipe_m_flow.PNG diff --git a/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper1.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper1.PNG similarity index 100% rename from Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper1.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper1.PNG diff --git a/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper2.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper2.PNG similarity index 100% rename from Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper2.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper2.PNG diff --git a/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper3.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper3.PNG similarity index 100% rename from Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper3.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper3.PNG diff --git a/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper4.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper4.PNG similarity index 100% rename from Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper4.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/EQ_PartialDamper4.PNG diff --git a/Information/FluidDynamics/Components/Valves/BaseClasses/FIG_PartialDamper.png b/src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/FIG_PartialDamper.png similarity index 100% rename from Information/FluidDynamics/Components/Valves/BaseClasses/FIG_PartialDamper.png rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/BaseClasses/FIG_PartialDamper.png diff --git a/Information/FluidDynamics/Components/Valves/FIG_Damper_opposedBlades.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/FIG_Damper_opposedBlades.PNG similarity index 100% rename from Information/FluidDynamics/Components/Valves/FIG_Damper_opposedBlades.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/FIG_Damper_opposedBlades.PNG diff --git a/Information/FluidDynamics/Components/Valves/FIG_Damper_parallelBlades.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/FIG_Damper_parallelBlades.PNG similarity index 100% rename from Information/FluidDynamics/Components/Valves/FIG_Damper_parallelBlades.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Components/Valves/FIG_Damper_parallelBlades.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_changeVar.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_changeVar.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_changeVar.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_changeVar.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr2Nul.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr2Nul.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr2Nul.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr2Nul.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr2Pos.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr2Pos.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr2Pos.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discr2Pos.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrNeg.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrNeg.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrNeg.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrNeg.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrNul.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrNul.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrNul.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrNul.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrPos.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrPos.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrPos.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_discrPos.PNG diff --git a/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_firstOrder.PNG b/src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_firstOrder.PNG similarity index 100% rename from Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_firstOrder.PNG rename to src/TAeZoSysPro/Information/FluidDynamics/Functions/EQ_rootsPolyOrder3_firstOrder.PNG diff --git a/Information/Graphs.pptx b/src/TAeZoSysPro/Information/Graphs.pptx similarity index 100% rename from Information/Graphs.pptx rename to src/TAeZoSysPro/Information/Graphs.pptx diff --git a/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation.PNG diff --git a/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation1.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation1.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation1.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation1.PNG diff --git a/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation2.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation2.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation2.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation2.PNG diff --git a/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation3.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation3.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation3.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_CarrollRadiation3.PNG diff --git a/Information/HeatTransfer/BasesClasses/EQ_FreeConvection.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_FreeConvection.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/EQ_FreeConvection.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_FreeConvection.PNG diff --git a/Information/HeatTransfer/BasesClasses/EQ_LumpVolume.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_LumpVolume.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/EQ_LumpVolume.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_LumpVolume.PNG diff --git a/Information/HeatTransfer/BasesClasses/EQ_PartialHeatExchanger.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_PartialHeatExchanger.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/EQ_PartialHeatExchanger.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_PartialHeatExchanger.PNG diff --git a/Information/HeatTransfer/BasesClasses/EQ_PartialWall.png b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_PartialWall.png similarity index 100% rename from Information/HeatTransfer/BasesClasses/EQ_PartialWall.png rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/EQ_PartialWall.png diff --git a/Information/HeatTransfer/BasesClasses/Eq_Conduction_cylindric.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/Eq_Conduction_cylindric.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/Eq_Conduction_cylindric.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/Eq_Conduction_cylindric.PNG diff --git a/Information/HeatTransfer/BasesClasses/Eq_Conduction_linear.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/Eq_Conduction_linear.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/Eq_Conduction_linear.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/Eq_Conduction_linear.PNG diff --git a/Information/HeatTransfer/BasesClasses/Eq_HeatCapacitor.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/Eq_HeatCapacitor.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/Eq_HeatCapacitor.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/Eq_HeatCapacitor.PNG diff --git a/Information/HeatTransfer/BasesClasses/FIG_FreeConvection_dT_decoupled.png b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/FIG_FreeConvection_dT_decoupled.png similarity index 100% rename from Information/HeatTransfer/BasesClasses/FIG_FreeConvection_dT_decoupled.png rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/FIG_FreeConvection_dT_decoupled.png diff --git a/Information/HeatTransfer/BasesClasses/FIG_FviewCalculator.PNG b/src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/FIG_FviewCalculator.PNG similarity index 100% rename from Information/HeatTransfer/BasesClasses/FIG_FviewCalculator.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/BasesClasses/FIG_FviewCalculator.PNG diff --git a/Information/HeatTransfer/Components/Demo_vertical_opening_thermal_mode.tex b/src/TAeZoSysPro/Information/HeatTransfer/Components/Demo_vertical_opening_thermal_mode.tex similarity index 100% rename from Information/HeatTransfer/Components/Demo_vertical_opening_thermal_mode.tex rename to src/TAeZoSysPro/Information/HeatTransfer/Components/Demo_vertical_opening_thermal_mode.tex diff --git a/Information/HeatTransfer/Components/EQ_FanVentilation.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_FanVentilation.PNG similarity index 100% rename from Information/HeatTransfer/Components/EQ_FanVentilation.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_FanVentilation.PNG diff --git a/Information/HeatTransfer/Components/EQ_FanVentilation_aero.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_FanVentilation_aero.PNG similarity index 100% rename from Information/HeatTransfer/Components/EQ_FanVentilation_aero.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_FanVentilation_aero.PNG diff --git a/Information/HeatTransfer/Components/EQ_FviewCalculator.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_FviewCalculator.PNG similarity index 100% rename from Information/HeatTransfer/Components/EQ_FviewCalculator.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_FviewCalculator.PNG diff --git a/Information/HeatTransfer/Components/EQ_FviewCalculator2.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_FviewCalculator2.PNG similarity index 100% rename from Information/HeatTransfer/Components/EQ_FviewCalculator2.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_FviewCalculator2.PNG diff --git a/Information/HeatTransfer/Components/EQ_Ventilation.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_Ventilation.PNG similarity index 100% rename from Information/HeatTransfer/Components/EQ_Ventilation.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Components/EQ_Ventilation.PNG diff --git a/Information/HeatTransfer/Components/FIG_CabinetPower.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Components/FIG_CabinetPower.PNG similarity index 100% rename from Information/HeatTransfer/Components/FIG_CabinetPower.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Components/FIG_CabinetPower.PNG diff --git a/Information/HeatTransfer/Components/FIG_CabinetPower2.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Components/FIG_CabinetPower2.PNG similarity index 100% rename from Information/HeatTransfer/Components/FIG_CabinetPower2.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Components/FIG_CabinetPower2.PNG diff --git a/Information/HeatTransfer/Components/FIG_FviewCalculator.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Components/FIG_FviewCalculator.PNG similarity index 100% rename from Information/HeatTransfer/Components/FIG_FviewCalculator.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Components/FIG_FviewCalculator.PNG diff --git a/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_coCurrent.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_coCurrent.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_coCurrent.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_coCurrent.PNG diff --git a/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_counterCurrent.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_counterCurrent.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_counterCurrent.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_counterCurrent.PNG diff --git a/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Cr=0.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Cr=0.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Cr=0.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Cr=0.PNG diff --git a/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Qc_max_mixed.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Qc_max_mixed.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Qc_max_mixed.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Qc_max_mixed.PNG diff --git a/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Qc_max_unmixed.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Qc_max_unmixed.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Qc_max_unmixed.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_Qc_max_unmixed.PNG diff --git a/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_both_unmixed.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_both_unmixed.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_both_unmixed.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/EQ_crossCurrent_both_unmixed.PNG diff --git a/Information/HeatTransfer/Functions/ExchangerEffectiveness/inverse/EQ_NTU_coCurrent.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/inverse/EQ_NTU_coCurrent.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ExchangerEffectiveness/inverse/EQ_NTU_coCurrent.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/inverse/EQ_NTU_coCurrent.PNG diff --git a/Information/HeatTransfer/Functions/ExchangerEffectiveness/inverse/EQ_NTU_counterCurrent.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/inverse/EQ_NTU_counterCurrent.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ExchangerEffectiveness/inverse/EQ_NTU_counterCurrent.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ExchangerEffectiveness/inverse/EQ_NTU_counterCurrent.PNG diff --git a/Information/HeatTransfer/Functions/ForcedConvection/EQ_crossFlow_cylinder_ASHRAE.png b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ForcedConvection/EQ_crossFlow_cylinder_ASHRAE.png similarity index 100% rename from Information/HeatTransfer/Functions/ForcedConvection/EQ_crossFlow_cylinder_ASHRAE.png rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ForcedConvection/EQ_crossFlow_cylinder_ASHRAE.png diff --git a/Information/HeatTransfer/Functions/ForcedConvection/EQ_flat_plate_ASHRAE.png b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ForcedConvection/EQ_flat_plate_ASHRAE.png similarity index 100% rename from Information/HeatTransfer/Functions/ForcedConvection/EQ_flat_plate_ASHRAE.png rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ForcedConvection/EQ_flat_plate_ASHRAE.png diff --git a/Information/HeatTransfer/Functions/ForcedConvection/EQ_internal_pipe_ASHRAE.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/ForcedConvection/EQ_internal_pipe_ASHRAE.PNG similarity index 100% rename from Information/HeatTransfer/Functions/ForcedConvection/EQ_internal_pipe_ASHRAE.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/ForcedConvection/EQ_internal_pipe_ASHRAE.PNG diff --git a/Information/HeatTransfer/Functions/FreeConvection/EQ_ground_ASHRAE.png b/src/TAeZoSysPro/Information/HeatTransfer/Functions/FreeConvection/EQ_ground_ASHRAE.png similarity index 100% rename from Information/HeatTransfer/Functions/FreeConvection/EQ_ground_ASHRAE.png rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/FreeConvection/EQ_ground_ASHRAE.png diff --git a/Information/HeatTransfer/Functions/FreeConvection/EQ_horizontal_cylinder_ASHRAE.png b/src/TAeZoSysPro/Information/HeatTransfer/Functions/FreeConvection/EQ_horizontal_cylinder_ASHRAE.png similarity index 100% rename from Information/HeatTransfer/Functions/FreeConvection/EQ_horizontal_cylinder_ASHRAE.png rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/FreeConvection/EQ_horizontal_cylinder_ASHRAE.png diff --git a/Information/HeatTransfer/Functions/FreeConvection/EQ_vertical_plate_ASHRAE.png b/src/TAeZoSysPro/Information/HeatTransfer/Functions/FreeConvection/EQ_vertical_plate_ASHRAE.png similarity index 100% rename from Information/HeatTransfer/Functions/FreeConvection/EQ_vertical_plate_ASHRAE.png rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/FreeConvection/EQ_vertical_plate_ASHRAE.png diff --git a/Information/HeatTransfer/Functions/FreeConvection/EQ_vertical_plate_Recknagel.png b/src/TAeZoSysPro/Information/HeatTransfer/Functions/FreeConvection/EQ_vertical_plate_Recknagel.png similarity index 100% rename from Information/HeatTransfer/Functions/FreeConvection/EQ_vertical_plate_Recknagel.png rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/FreeConvection/EQ_vertical_plate_Recknagel.png diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid.PNG diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_asymmetric.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_asymmetric.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_asymmetric.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_asymmetric.PNG diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_even.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_even.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_even.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_even.PNG diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_odd.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_odd.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_odd.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndGeometricalGrowthGrid_odd.PNG diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndUniformGrid.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndUniformGrid.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndUniformGrid.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_biotAndUniformGrid.PNG diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_asymetric.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_asymetric.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_asymetric.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_asymetric.PNG diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_even.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_even.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_even.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_even.PNG diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_odd.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_odd.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_odd.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_geometricalGrowthGrid_odd.PNG diff --git a/Information/HeatTransfer/Functions/MeshGrid/EQ_uniformGrid.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_uniformGrid.PNG similarity index 100% rename from Information/HeatTransfer/Functions/MeshGrid/EQ_uniformGrid.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/MeshGrid/EQ_uniformGrid.PNG diff --git a/Information/HeatTransfer/Functions/Radiation/EQ_h_rad.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/Radiation/EQ_h_rad.PNG similarity index 100% rename from Information/HeatTransfer/Functions/Radiation/EQ_h_rad.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/Radiation/EQ_h_rad.PNG diff --git a/Information/HeatTransfer/Functions/Radiation/EQ_h_rad2.PNG b/src/TAeZoSysPro/Information/HeatTransfer/Functions/Radiation/EQ_h_rad2.PNG similarity index 100% rename from Information/HeatTransfer/Functions/Radiation/EQ_h_rad2.PNG rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/Radiation/EQ_h_rad2.PNG diff --git a/Information/HeatTransfer/Functions/image_package.png b/src/TAeZoSysPro/Information/HeatTransfer/Functions/image_package.png similarity index 100% rename from Information/HeatTransfer/Functions/image_package.png rename to src/TAeZoSysPro/Information/HeatTransfer/Functions/image_package.png diff --git a/Information/PDE/Delta_uc_lc.svg b/src/TAeZoSysPro/Information/PDE/Delta_uc_lc.svg similarity index 100% rename from Information/PDE/Delta_uc_lc.svg rename to src/TAeZoSysPro/Information/PDE/Delta_uc_lc.svg diff --git a/Information/PDE/ThermalDiffusion/Discrete_scheme.png b/src/TAeZoSysPro/Information/PDE/ThermalDiffusion/Discrete_scheme.png similarity index 100% rename from Information/PDE/ThermalDiffusion/Discrete_scheme.png rename to src/TAeZoSysPro/Information/PDE/ThermalDiffusion/Discrete_scheme.png diff --git a/Information/PDE/ThermalDiffusion/EQ_central.png b/src/TAeZoSysPro/Information/PDE/ThermalDiffusion/EQ_central.png similarity index 100% rename from Information/PDE/ThermalDiffusion/EQ_central.png rename to src/TAeZoSysPro/Information/PDE/ThermalDiffusion/EQ_central.png diff --git a/Information/PDE/ThermalDiffusion/EQ_spaceDerivative.png b/src/TAeZoSysPro/Information/PDE/ThermalDiffusion/EQ_spaceDerivative.png similarity index 100% rename from Information/PDE/ThermalDiffusion/EQ_spaceDerivative.png rename to src/TAeZoSysPro/Information/PDE/ThermalDiffusion/EQ_spaceDerivative.png diff --git a/Information/PDE/Transport/EQ_UpwindFirstOrder1.PNG b/src/TAeZoSysPro/Information/PDE/Transport/EQ_UpwindFirstOrder1.PNG similarity index 100% rename from Information/PDE/Transport/EQ_UpwindFirstOrder1.PNG rename to src/TAeZoSysPro/Information/PDE/Transport/EQ_UpwindFirstOrder1.PNG diff --git a/Information/PDE/Transport/EQ_UpwindFirstOrder2.PNG b/src/TAeZoSysPro/Information/PDE/Transport/EQ_UpwindFirstOrder2.PNG similarity index 100% rename from Information/PDE/Transport/EQ_UpwindFirstOrder2.PNG rename to src/TAeZoSysPro/Information/PDE/Transport/EQ_UpwindFirstOrder2.PNG diff --git a/Information/PDE/Transport/FIG_UpwindFirstOrder.png b/src/TAeZoSysPro/Information/PDE/Transport/FIG_UpwindFirstOrder.png similarity index 100% rename from Information/PDE/Transport/FIG_UpwindFirstOrder.png rename to src/TAeZoSysPro/Information/PDE/Transport/FIG_UpwindFirstOrder.png diff --git a/Information/PDE/img_package.png b/src/TAeZoSysPro/Information/PDE/img_package.png similarity index 100% rename from Information/PDE/img_package.png rename to src/TAeZoSysPro/Information/PDE/img_package.png diff --git a/Information/script for equations.docx b/src/TAeZoSysPro/Information/script for equations.docx similarity index 100% rename from Information/script for equations.docx rename to src/TAeZoSysPro/Information/script for equations.docx diff --git a/Media/Air/Air_H2.mo b/src/TAeZoSysPro/Media/Air/Air_H2.mo similarity index 50% rename from Media/Air/Air_H2.mo rename to src/TAeZoSysPro/Media/Air/Air_H2.mo index defafec..6a2a82f 100644 --- a/Media/Air/Air_H2.mo +++ b/src/TAeZoSysPro/Media/Air/Air_H2.mo @@ -1,230 +1,339 @@ within TAeZoSysPro.Media.Air; package Air_H2 + extends Modelica.Media.Interfaces.PartialMixtureMedium( - mediumName="Air_H2", - substanceNames={"dihydrogen","air"}, - final reducedX=true, - final singleState=false, - reference_X={0.001,0.999}, + mediumName = "Air_H2", + substanceNames = {"dihydrogen", "air"}, + final reducedX = true, + final singleState = false, + reference_X = {0.001, 0.999}, reference_T = 293.15, - Temperature(min=190, max=647), - ThermoStates=Modelica.Media.Interfaces.Choices.IndependentVariables.pTX); + Temperature(min = 190, max = 647), + ThermoStates = Modelica.Media.Interfaces.Choices.IndependentVariables.pTX); - constant Integer H2=1 + constant Integer H2 = 1 "Index of dihydrogen (in substanceNames, massFractions X, etc.)"; - constant Integer Air=2 + constant Integer Air = 2 "Index of air (in substanceNames, massFractions X, etc.)"; - constant Real k_mair=dihydrogen.MM/dryair.MM "Ratio of molar weights"; + constant Real k_mair = dihydrogen.MM / dryair.MM + "Ratio of molar weights"; record dryair - constant Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp = 1005 "cp(p_ref, T_ref)"; + + constant Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp = 1005 + "cp(p_ref, T_ref)"; constant Modelica.SIunits.MolarMass MM = Modelica.Media.IdealGases.Common.SingleGasesData.Air; - constant Real R(final unit="J/(kg.K)") = Modelica.Constants.R / MM; - constant Modelica.SIunits.DynamicViscosity eta = 1.8e-5 "eta(p_ref, T_ref)"; + constant Real R(final unit = "J/(kg.K)") = Modelica.Constants.R / MM; + constant Modelica.SIunits.DynamicViscosity eta = 1.8e-5 + "eta(p_ref, T_ref)"; + end dryair; record dihydrogen - constant Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp = 14287 "cp(p_ref, T_ref)"; - constant Modelica.SIunits.MolarMass MM = Modelica.Media.IdealGases.Common.SingleGasesData.H2; - constant Real R(final unit="J/(kg.K)") = Modelica.Constants.R / MM; - constant Modelica.SIunits.DynamicViscosity eta = 8.8e-5 "eta(p_ref, T_ref)"; - constant Modelica.SIunits.ThermalConductivity lambda = 1.8248 "lambda(p_ref, T_ref)"; + + constant Modelica.SIunits.SpecificHeatCapacityAtConstantPressure cp = 14287 + "cp(p_ref, T_ref)"; + constant Modelica.SIunits.MolarMass MM = Modelica.Media.IdealGases.Common.SingleGasesData.H2; + constant Real R(final unit = "J/(kg.K)") = Modelica.Constants.R / MM; + constant Modelica.SIunits.DynamicViscosity eta = 8.8e-5 + "eta(p_ref, T_ref)"; + constant Modelica.SIunits.ThermalConductivity lambda = 1.8248 + "lambda(p_ref, T_ref)"; + end dihydrogen; - + redeclare replaceable model extends BaseProperties( - preferredMediumStates=true, - T(stateSelect=if preferredMediumStates then StateSelect.prefer else + preferredMediumStates = true, + T( + stateSelect = + if preferredMediumStates then + StateSelect.prefer + else StateSelect.default), - p(stateSelect=if preferredMediumStates then StateSelect.prefer else + p( + stateSelect = + if preferredMediumStates then + StateSelect.prefer + else StateSelect.default), - Xi(each stateSelect=if preferredMediumStates then StateSelect.prefer - else StateSelect.default), - final standardOrderComponents=true) "Moist air base properties record" + Xi( + each stateSelect = + if preferredMediumStates then + StateSelect.prefer + else + StateSelect.default), + final standardOrderComponents = true) + "Moist air base properties record" - /* p, T, X = X[Water] are used as preferred states, since only then all + /* p, T, X = X[Water] are used as preferred states, since only then all other quantities can be computed in a recursive sequence. If other variables are selected as states, static state selection is no longer possible and non-linear algebraic equations occur. */ equation + h = specificEnthalpy_pTX( p, T, X); - u = h - R*T; - R = H2.R*Xi[H2] + dryair.R*(1-Xi[H2]); - d = p/(R*T); - MM = Modelica.Constants.R/R; + u = h - R * T; + R = H2.R * Xi[H2] + dryair.R * (1 - Xi[H2]); + d = p / (R * T); + MM = Modelica.Constants.R / R; state.p = p; state.T = T; state.X = X; + end BaseProperties; - + redeclare function extends gasConstant + algorithm - R := dihydrogen.R*state.X[H2] + dryair.R*(1-state.X[H2]); - end gasConstant ; - + + R := dihydrogen.R * state.X[H2] + dryair.R * (1 - state.X[H2]); + + end gasConstant; + function gasConstant_X + extends Modelica.Icons.Function; input Modelica.SIunits.MassFraction X[:]; - output Real R(final unit="J/(kg.K)"); + output Real R(final unit = "J/(kg.K)"); + algorithm - R := dihydrogen.R*X[H2] + dryair.R*(1-state.X[H2]); - end gasConstant_X ; - + + R := dihydrogen.R * X[H2] + dryair.R * (1 - state.X[H2]); + + end gasConstant_X; + redeclare function extends setState_pTX + algorithm - state.p := p; - state.T := T; + + state.p := p; + state.T := T; if size(X, 1) == nX then state.X := X; else - state.X := cat(1, X, {1.0-sum(X)}); - end if ; + state.X := cat(1, X, {1.0 - sum(X)}); + end if; + end setState_pTX; - + redeclare function extends setState_phX + algorithm + state.p := p; - state.T := Temperature_hX(h=h, X=X); + state.T := Temperature_hX(h = h, X = X); if size(X, 1) == nX then state.X := X; else - state.X := cat(1, X, {1.0-sum(X)}); - end if ; + state.X := cat(1, X, {1.0 - sum(X)}); + end if; + end setState_phX; - + redeclare function extends setState_dTX + algorithm - state.p := pressure_dTX(d=d, T=T, X=X); - state.T := T; + + state.p := pressure_dTX(d = d, T = T, X = X); + state.T := T; if size(X, 1) == nX then state.X := X; else - state.X := cat(1, X, {1.0-sum(X)}); - end if ; + state.X := cat(1, X, {1.0 - sum(X)}); + end if; + end setState_dTX; - + redeclare function extends dynamicViscosity + protected + Modelica.SIunits.MoleFraction Y[nX]; + algorithm - Y := massToMoleFractions(X=state.X, MMX={dihydrogen.MM, dryair.MM}); - eta := dihydrogen.eta * Y[H2] + dryair.eta * (1-Y[H2]); - end dynamicViscosity ; + + Y := massToMoleFractions(X = state.X, MMX = {dihydrogen.MM, dryair.MM}); + eta := dihydrogen.eta * Y[H2] + dryair.eta * (1 - Y[H2]); + + end dynamicViscosity; redeclare function extends thermalConductivity + protected + Modelica.SIunits.MoleFraction Y[nX]; + algorithm - Y := massToMoleFractions(X=state.X, MMX={dihydrogen.MM, dryair.MM}); - lambda := dihydrogen.lambda * Y[H2] + dryair.lambda * (1-Y[H2]); + + Y := massToMoleFractions(X = state.X, MMX = {dihydrogen.MM, dryair.MM}); + lambda := dihydrogen.lambda * Y[H2] + dryair.lambda * (1 - Y[H2]); + end thermalConductivity; - + redeclare function extends pressure + algorithm + p := state.p; + end pressure; - + redeclare function extends temperature + algorithm + T := state.T; + end temperature; - + redeclare function extends density + algorithm - d := pressure(state) / (gasConstant(state.X)*temperature(state)); + + d := pressure(state) / (gasConstant(state.X) * temperature(state)); + end density; - + redeclare function extends specificEnthalpy + algorithm - h := (state.X[H2]*dihydrogen.cp+(1-state.X[H2])*dryair.cp) * (temperature(state)-reference_T) ; + + h := (state.X[H2] * dihydrogen.cp + (1 - state.X[H2]) * dryair.cp) * (temperature(state) - reference_T); + end specificEnthalpy; - + redeclare function extends specificInternalEnergy + algorithm - u := specificEnthalpy(state) - gasConstant(state)*temperature(state) ; + + u := specificEnthalpy(state) - gasConstant(state) * temperature(state); + end specificInternalEnergy; - + redeclare function extends specificHeatCapacityCp + algorithm - cp := state.X[H2]*dihydrogen.cp + (1.0-state.X[H2])*dryair.cp ; + + cp := state.X[H2] * dihydrogen.cp + (1.0 - state.X[H2]) * dryair.cp; + end specificHeatCapacityCp; - + redeclare function extends specificHeatCapacityCv + algorithm - cv := state.X[H2]*(dihydrogen.cp-dihydrogen.R) + (1.0-state.X[H2])*(dryair.cp-dryair.R) ; + + cv := state.X[H2] * (dihydrogen.cp - dihydrogen.R) + (1.0 - state.X[H2]) * (dryair.cp - dryair.R); + end specificHeatCapacityCv; redeclare function extends isentropicExponent + algorithm - gamma := specificHeatCapacityCp(state) / specificHeatCapacityCv(state) ; + + gamma := specificHeatCapacityCp(state) / specificHeatCapacityCv(state); + end isentropicExponent; - + redeclare function extends VelocityOfSound + algorithm - a := sqrt(isentropicExponent(state)*gasConstant(state)*temperature(state)) ; + + a := sqrt(isentropicExponent(state) * gasConstant(state) * temperature(state)); + end VelocityOfSound; - + redeclare function extends isobaricExpansionCoefficient + algorithm - beta := 1/temperature(state); + + beta := 1 / temperature(state); + end isobaricExpansionCoefficient; - + redeclare function extends isothermalCompressibility + algorithm - beta := 1/pressure(state); - end isothermalCompressibility; - + + beta := 1 / pressure(state); + + end isothermalCompressibility; + redeclare function extends density_derp_T + algorithm - ddpT := 1/(gasConstant(state)*temperature(state)); + + ddpT := 1 / (gasConstant(state) * temperature(state)); + end density_derp_T; - + redeclare function extends density_derT_p + algorithm - ddpT := -density(state)/temperature(state); - end density_derT_p; + + ddpT := -density(state) / temperature(state); + + end density_derT_p; redeclare function extends density_derX + algorithm - dddX[Water] := - pressure(state)/temperature(state) * (dihydrogen.R - dryair.R)/(((dihydrogen.R - dryair.R) - *state.X[Water] + dryair.R)^2); - dddX[Air] := - pressure(state)/temperature(state) * (dryair.R - dihydrogen.R)/((dihydrogen.R + (dryair.R - dihydrogen.R)* - state.X[Air])^2); + + dddX[Water] := -pressure(state) / temperature(state) * (dihydrogen.R - dryair.R) / (((dihydrogen.R - dryair.R) + * state.X[Water] + dryair.R) ^ 2); + dddX[Air] := -pressure(state) / temperature(state) * (dryair.R - dihydrogen.R) / ((dihydrogen.R + (dryair.R - dihydrogen.R) + * state.X[Air]) ^ 2); + end density_derX; - + redeclare function extends MolarMass + algorithm - MM := Modelica.Constants.R/gasConstant(state); + + MM := Modelica.Constants.R / gasConstant(state); + end MolarMass; - + function temperature_hX + input Modelica.SIunits.SpecificEnthalpy h; input Modelica.SIunits.MassFraction X[:]; output Modelica.SIunits.Temperature T; + algorithm - T := h / (X[H2] * dihydrogen.cp + (1-X[H2])*dryair.cp) + reference_T ; + + T := h / (X[H2] * dihydrogen.cp + (1 - X[H2]) * dryair.cp) + reference_T; + end temperature_hX; - + function pressure_dTX + input Modelica.SIunits.Density d; input Modelica.SIunits.Temperature T; input Modelica.SIunits.MassFraction X[:]; output Modelica.SIunits.Pressure p; + algorithm - p := d * gasConstant_X(X) * T ; + + p := d * gasConstant_X(X) * T; + end pressure_dTX; - + redeclare function extends specificEnthalpy_pTX + input Modelica.SIunits.Pressure p = reference_p; input Modelica.SIunits.Temperature T; input Modelica.SIunits.MassFraction X[:]; output Modelica.SIunits.SpecificEnthalpy h; + algorithm - h := (dihydrogen.cp*X[H2] + dryair.cp*(1-X[H2]))*(T-reference_T); - end specificEnthalpy_pTX; - + + h := (dihydrogen.cp * X[H2] + dryair.cp * (1 - X[H2])) * (T - reference_T); + + end specificEnthalpy_pTX; + end Air_H2; diff --git a/src/TAeZoSysPro/Media/Air/MoistAir.mo b/src/TAeZoSysPro/Media/Air/MoistAir.mo new file mode 100644 index 0000000..14f89b1 --- /dev/null +++ b/src/TAeZoSysPro/Media/Air/MoistAir.mo @@ -0,0 +1,2068 @@ +within TAeZoSysPro.Media.Air; + +package MoistAir + + extends Modelica.Media.Interfaces.PartialMedium(redeclare replaceable record FluidConstants = Modelica.Media.Interfaces.Types.IdealGas.FluidConstants, mediumName = "Moist air", substanceNames = {"water", "air"}, final reducedX = true, final singleState = false, reference_X = {0.01, 0.99}, reference_T = 293.15, Temperature(min = 190, max = 647), ThermoStates = Modelica.Media.Interfaces.Choices.IndependentVariables.dTX); + import Modelica.Media.Interfaces.Types.ExtraProperty; + constant Integer Water = 1 + "Index of water (in substanceNames, massFractions X, etc.)"; + constant Integer Air = 2 + "Index of air (in substanceNames, massFractions X, etc.)"; + constant Real k_mair = steam.MM / dryair.MM + "Ratio of molar weights"; + + record dryair + + constant SI.SpecificHeatCapacity R = Modelica.Media.IdealGases.Common.SingleGasesData.Air.R; + constant SI.MolarMass MM = Modelica.Media.IdealGases.Common.SingleGasesData.Air.MM; + constant SI.SpecificHeatCapacityAtConstantPressure cp = 1006.4 + "Specific heat capacity of dry air at 293.15K (20°C)"; + + end dryair; + + record steam + + constant SI.SpecificHeatCapacity R = Modelica.Media.IdealGases.Common.SingleGasesData.H2O.R; + constant SI.MolarMass MM = Modelica.Media.IdealGases.Common.SingleGasesData.H2O.MM; + constant SI.SpecificEnergy h_lv = 2453.55e3 + "Enthalpy of vaporization of water at 293.15K (20°C)"; + constant SI.SpecificHeatCapacityAtConstantPressure cp = 1886.0 + "Specific heat capacity of steam at 293.15K (20°C)"; + + end steam; + + record water + + constant SI.SpecificHeatCapacityAtConstantPressure cp = 4181 + "Specific heat capacity of liquid water at 293.15K (20°C)"; + + end water; + + record ice + + constant SI.SpecificHeatCapacityAtConstantPressure cp = 2060 + "Specific heat capacity of solid water at 273.15K (0°C)"; + constant SI.SpecificEnergy h_sl = 333e3 + "Enthalpy of fusion of water at 273.15K (0°C)"; + + end ice; + + constant SI.MolarMass[2] MMX = {steam.MM, dryair.MM} + "Molar masses of components"; + constant FluidConstants[nS] fluidConstants = {Modelica.Media.IdealGases.Common.FluidData.H2O, Modelica.Media.IdealGases.Common.FluidData.N2} + "Constant data for the fluid"; + import SI = Modelica.SIunits; + import Modelica.SIunits; + + redeclare record extends ThermodynamicState + "Thermodynamic state variables of moist air" + + Density d + "density of medium"; + Temperature T + "Temperature of medium"; + MassFraction[nX] X(start = reference_X) + "Mass fractions (= (component mass)/total mass m_i/m)"; + + end ThermodynamicState; + + redeclare replaceable model extends BaseProperties(T(stateSelect = if preferredMediumStates then StateSelect.prefer else StateSelect.default), d(stateSelect = if preferredMediumStates then StateSelect.prefer else StateSelect.default), Xi(each stateSelect = if preferredMediumStates then StateSelect.prefer else StateSelect.default), final standardOrderComponents = true) + "Moist air base properties record" + + /* d, T, X = X[Water] are used as preferred states, since only then all + other quantities can be computed in a recursive sequence. + If other variables are selected as states, static state selection + is no longer possible and non-linear algebraic equations occur. + */ + Real phi + "Relative humidity"; + MassFraction X_liquid + "Mass fraction of liquid or solid water"; + MassFraction X_steam + "Mass fraction of steam water"; + MassFraction X_air + "Mass fraction of air"; + Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + + equation + + assert( + T >= 190 and T <= 647, + " +Temperature T is not in the allowed range +190.0 K <= (T =" + String(T) + " K) <= 647.0 K +required from medium model \"" + mediumName + "\"."); + MM = 1 / (Xi[Water] / MMX[Water] + (1.0 - Xi[Water]) / MMX[Air]); + d_sat = saturationDensity(T); + X_liquid = max(d * X[Water] - d_sat, 0) / d; + X_steam = Xi[Water] - X_liquid; + X_air = 1 - Xi[Water]; + h = h_dTX(d, T, Xi); + // R = dryair.R * (X_air / (1 - X_liquid)) + steam.R * X_steam / (1 - X_liquid); + R = r_dTX(d, T, Xi); + // + u = h - R * T; + // u = X_air*720*(T-reference_T) + X_steam*(1000*(T-reference_T)+steam.h_lv) + X_liquid*4185*(T-reference_T); + // u = h - p/d; + p = d * (1 - X_liquid) * R * T; + /* Note, is computed under the assumption that the volume of the liquid + water is negligible with respect to the volume of air and of steam + */ + state.d = d; + state.T = T; + state.X = X; + phi = min(d * X[Water], d_sat) / d_sat; + + annotation ( + Documentation( + info = " +

        + This model computes thermodynamic properties of moist air from three independent (thermodynamic or/and numerical) state variables. + Preferred numerical states are temperature T, density d and the reduced composition vector Xi, which contains the water mass fraction only. + As an EOS the ideal gas law is used and associated restrictions apply. + The model can also be used in the fog region, when moisture is present in its liquid state. + However, it is assumed that the liquid water volume is negligible compared to that of the gas phase. + Computation of thermal properties is based on property data of dry air and water (source: VDI-Wärmeatlas), respectively. + Besides the standard thermodynamic variables absolute and relative humidity, x_water and phi, respectively, are given by the model. + Upper case X denotes absolute humidity with respect to mass of moist air while absolute humidity with respect to mass of dry air only is denoted by a lower case x throughout the model. + See package description for further information. +

        +")); + + end BaseProperties; + + redeclare function extends setState_pTX + + protected + + SI.MassFraction X_sat + "Absolute humidity per unit mass of moist air at saturation"; + MassFraction X_liquid + "Mass fraction of liquid or solid water"; + MassFraction X_air; + SI.Pressure p_sat + "water saturation pressure"; + SI.SpecificHeatCapacity R + "Mixture gas constant"; + SI.Density d_sat; + SI.Density d_air_sat; + SI.Pressure p_air_sat; + + algorithm + + assert(if size(X, 1) == nX then X[Air] > 1e-4 else 1 - X[Water] > 1e-4, "Too little dry air in the mixture to compute the density", AssertionLevel.error); + X_air := 1.0 - X[Water]; + p_sat := saturationPressure(T); + d_sat := p_sat / (steam.R * T); + p_air_sat := max(p - p_sat, 0); /*Manage the case with high gas temperature where psat > p */ + d_air_sat := p_air_sat / (dryair.R * T); + + X_sat := min(d_sat / (d_sat + d_air_sat), 0.99); /*Manage the case with high gas temperature where psat > p */ + + /* X_sat +X_air/(1-X_l)=1 : balance for gas part */ + X_liquid := max(-X_air / (1 - X_sat) + 1.0, 0.0); + R := dryair.R * (1 - X[Water]) / (1 - X_liquid) + steam.R * (X[Water] - X_liquid) / (1 - X_liquid); + state := if size(X, 1) == nX then ThermodynamicState(d = p / ((1 - X_liquid) * R * T), T = T, X = X) else ThermodynamicState(d = p / ((1 - X_liquid) * R * T), T = T, X = cat(1, X, {1 - sum(X)})); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + The thermodynamic state record is computed from pressure p, temperature T and composition X.
        + If X[Air]<1e-4, the density cannot be computed in case of diphasique water since p and T remain contant. + + + ")); + + end setState_pTX; + + redeclare function extends setState_phX + + protected + + SI.MassFraction X_sat + "Absolute humidity per unit mass of moist air at saturation"; + SI.MassFraction X_steam + "Mass fraction of gaseous water (kg gas water / kg moist air)"; + SI.Temperature T + "Temperature"; + + algorithm + + state := if size(X, 1) == nX then ThermodynamicState(d = d_phX(p = p, h = h, X = X), T = T_phX(p = p, h = h, X = X), X = X) else ThermodynamicState(d = d_phX(p = p, h = h, X = X), T = T_phX(p = p, h = h, X = X), X = cat(1, X, {1 - sum(X)})); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + The thermodynamic state record is computed from pressure p, specific enthalpy h and composition X. + ")); + + end setState_phX; + + redeclare function extends setState_dTX + + algorithm + + state := if size(X, 1) == nX then ThermodynamicState(d = d, T = T, X = X) else ThermodynamicState(d = d, T = T, X = cat(1, X, {1 - sum(X)})); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + The thermodynamic state record is computed from density d, temperature T and composition X. + ")); + + end setState_dTX; + + redeclare function extends setSmoothState + "Return thermodynamic state so that it smoothly approximates: if x > 0 then state_a else state_b" + + algorithm + + state := ThermodynamicState(d = Modelica.Media.Common.smoothStep(x, state_a.d, state_b.d, x_small), T = Modelica.Media.Common.smoothStep(x, state_a.T, state_b.T, x_small), X = Modelica.Media.Common.smoothStep(x, state_a.X, state_b.X, x_small)); + + end setSmoothState; + + function Xsaturation + "Return absolute humidity per unit mass of moist air at saturation as a function of the thermodynamic state record" + + extends Modelica.Icons.Function; + input ThermodynamicState state + "Thermodynamic state record"; + output MassFraction X_sat + "Steam mass fraction of sat. boundary"; + + algorithm + + X_sat := saturationDensity(state.T) / (saturationDensity(state.T) + state.d * state.X[Air]); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Absolute humidity per unit mass of moist air at saturation is computed from density and temperature in the state record. Note, that this mass fraction refers to mass of moist air at saturation. + ")); + + end Xsaturation; + + function xsaturation + "Return absolute humidity per unit mass of dry air at saturation as a function of the thermodynamic state record" + + extends Modelica.Icons.Function; + input ThermodynamicState state + "Thermodynamic state record"; + output MassFraction x_sat + "Absolute humidity per unit mass of dry air"; + + algorithm + + x_sat := saturationDensity(state.T) / (state.d * state.X[Air]); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Absolute humidity per unit mass of dry air at saturation is computed from density and temperature in the thermodynamic state record. + ")); + + end xsaturation; + + function xsaturation_pT + "Return absolute humidity per unit mass of dry air at saturation as a function of pressure p and temperature T" + + extends Modelica.Icons.Function; + input AbsolutePressure p + "Pressure"; + input SI.Temperature T + "Temperature"; + output MassFraction x_sat + "Absolute humidity per unit mass of dry air"; + + algorithm + + assert(p - saturationPressure(T) >= 1e-4, "p_sat(T) is too close to p", AssertionLevel.error); + x_sat := k_mair * saturationPressure(T) / max(100 * Modelica.Constants.eps, p - saturationPressure(T)); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Absolute humidity per unit mass of dry air at saturation is computed from pressure and temperature. The function is valid for p-p_sat(T)≥ 1e-4 + ")); + + end xsaturation_pT; + + function massFraction_pTphi + "Return steam mass fraction as a function of relative humidity phi and temperature T" + + extends Modelica.Icons.Function; + input AbsolutePressure p + "Pressure"; + input Temperature T + "Temperature"; + input Real phi + "Relative humidity (0 ... 1.0)"; + output MassFraction X_steam + "Absolute humidity, steam mass fraction"; + + protected + + AbsolutePressure psat = saturationPressure(T) + "Saturation pressure"; + + algorithm + + X_steam := phi * k_mair / (k_mair * phi + p / psat - phi); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Absolute humidity per unit mass of moist air is computed from temperature, pressure and relative humidity. + ")); + + end massFraction_pTphi; + + function relativeHumidity_pTX + "Return relative humidity as a function of pressure p, temperature T and composition X" + + extends Modelica.Icons.Function; + input SI.Pressure p + "Pressure"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction[:] X + "Composition"; + output Real phi + "Relative humidity"; + + protected + + SI.Pressure p_steam_sat + "Saturation pressure"; + SI.MassFraction X_air + "Dry air mass fraction"; + + algorithm + + p_steam_sat := min(saturationPressure(T), 0.999 * p); + X_air := 1 - X[Water]; + phi := max(0.0, min(1.0, p / p_steam_sat * X[Water] / (X[Water] + k_mair * X_air))); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Relative humidity is computed from pressure, temperature and composition with 1.0 as the upper limit at saturation. Water mass fraction is the first entry in the composition vector. + ")); + + end relativeHumidity_pTX; + + function relativeHumidity + "Return relative humidity as a function of the thermodynamic state record" + + extends Modelica.Icons.Function; + input ThermodynamicState state + "Thermodynamic state"; + output Real phi + "Relative humidity"; + + protected + + SI.Density d_sat + "Saturation density of water in mosit air"; + + algorithm + + d_sat := saturationDensity(state.T); + phi := min(state.d * state.X[Water] - d_sat) / d_sat; + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Relative humidity is computed from the thermodynamic state record with 1.0 as the upper limit at saturation. + ")); + + end relativeHumidity; + + function gasConstant + "Return ideal gas constant as a function from thermodynamic state, remains valid with liquid water in the mixture" + + extends Modelica.Icons.Function; + input ThermodynamicState state + "Thermodynamic state"; + output SI.SpecificHeatCapacity R + "Mixture gas constant"; + + protected + + MassFraction X_liquid + "Mass fraction of liquid or solid water"; + Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + + algorithm + + d_sat := saturationDensity(state.T); + X_liquid := max(state.d * state.X[Water] - d_sat, 0) / state.d; + R := dryair.R * (1 - state.X[Water]) / (1 - X_liquid) + steam.R * (state.X[Water] - X_liquid) / (1 - X_liquid); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + The ideal gas constant for moist air is computed from thermodynamic state where the mass fractions of dry air and steam are corrected of the mass fraction of liquid that does not count for the gas contant calculation. +")); + + end gasConstant; + + function r_dTX + "Return ideal gas constant as a function from thermodynamic d, T and X, remains valid with liquid water in the mixture" + + input SI.Density d + "Density"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + output SI.SpecificHeatCapacity R + "Mixture gas constant"; + + protected + + MassFraction X_liquid + "Mass fraction of liquid or solid water"; + Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + + algorithm + + d_sat := saturationDensity(T); + X_liquid := max(d * X[Water] - d_sat, 0) / d; + R := dryair.R * (1 - X[Water]) / (1 - X_liquid) + steam.R * (X[Water] - X_liquid) / (1 - X_liquid); + + annotation ( + derivative = r_dTX_der, + Documentation( + info = " + The ideal gas constant for moist air is computed from the density d, temperature T and composition X where the mass fractions of dry air and steam are corrected of the mass fraction of liquid that does not count for the gas contant calculation. +")); + + end r_dTX; + + function r_dTX_der + "Return ideal gas constant derivative as a function from thermodynamic d, T and X, remains valid with liquid water in the mixture" + + input SI.Density d + "Density"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + input Real dd(unit = "kg/(m3.s)") + "Density derivative"; + input Real dT(unit = "K/s") + "Temperature derivative"; + input Real dX[:](each unit = "1/s") + "Composition derivative"; + output Real R_der(unit = "J/(kg.s.K)") + "Time derivative of specific enthalpy"; + + protected + + SI.MassFraction X_liquid + "Mass fraction of liquid or solid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + Real dX_steam(unit = "1/s") + "Time derivative of steam mass fraction"; + Real dX_air(unit = "1/s") + "Time derivative of dry air mass fraction"; + Real dX_liq(unit = "1/s") + "Time derivative of liquid/solid water mass fraction"; + Real dd_sat(unit = "kg/(m3.s)") + "Time derivative of saturation density"; + + algorithm + + d_sat := saturationDensity(T); + X_liquid := Utilities.smoothMax(X[Water] - d_sat / d, 0.0, 1e-5); + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + + dd_sat := saturationDensity_der(T, dT); + dX_liq := Utilities.smoothMax_der( + X[Water] - d_sat / d, + 0.0, + 1e-5, + dX[Water] - dd_sat / d + d_sat * dd / d ^ 2, + 0, + 0); + dX_steam := dX[Water] - dX_liq; + dX_air := -dX[Water]; + + R_der := (dryair.R * dX_air + steam.R * dX_steam) / (1 - X_liquid) + dX_liq / (1 - X_liquid) ^ 2 * (dryair.R * X_air + steam.R * X_steam) + annotation ( + Documentation( + info = " + The ideal gas constant derivative for moist air is computed from the density d, temperature T and composition X where the mass fractions of dry air and steam are corrected of the mass fraction of liquid that does not count for the gas contant calculation. +")); + + end r_dTX_der; + + function gasConstant_X + "Return ideal gas constant as a function from composition X (only valid for phi<1)" + + extends Modelica.Icons.Function; + input SI.MassFraction X[:] + "Gas phase composition"; + output SI.SpecificHeatCapacity R + "Ideal gas constant"; + + algorithm + + R := dryair.R * (1 - X[Water]) + steam.R * X[Water]; + + annotation ( + smoothOrder = 2, + Documentation( + info = " + The ideal gas constant for moist air is computed from the gas phase composition. + The first entry in composition vector X is the steam mass fraction of the gas phase. + This function assumed a fully gas mixture thus remains valid for a relative humidity bellow or equal to 1. + ")); + + end gasConstant_X; + + function moleToMassFractions + "Return mass fractions X from mole fractions" + + extends Modelica.Icons.Function; + input SI.MoleFraction moleFractions[:] + "Mole fractions of mixture"; + input MolarMass[:] MMX + "Molar masses of components"; + output SI.MassFraction X[size(moleFractions, 1)] + "Mass fractions of gas mixture"; + + protected + + MolarMass Mmix = moleFractions * MMX + "Molar mass of mixture"; + + algorithm + + for i in 1 : size(moleFractions, 1) loop + X[i] := moleFractions[i] * MMX[i] / Mmix; + end for; + + annotation ( + smoothOrder = 5); + + end moleToMassFractions; + + function massToMoleFractions + "Return mole fractions from mass fractions X" + + extends Modelica.Icons.Function; + input SI.MassFraction X[:] + "Mass fractions of mixture"; + input SI.MolarMass[:] MMX + "Molar masses of components"; + output SI.MoleFraction moleFractions[size(X, 1)] + "Mole fractions of gas mixture"; + + protected + + Real invMMX[size(X, 1)] + "Inverses of molar weights"; + SI.MolarMass Mmix + "Molar mass of mixture"; + + algorithm + + for i in 1 : size(X, 1) loop + invMMX[i] := 1 / MMX[i]; + end for; + Mmix := 1 / (X * invMMX); + for i in 1 : size(X, 1) loop + moleFractions[i] := Mmix * X[i] / MMX[i]; + end for; + + annotation ( + smoothOrder = 5); + + end massToMoleFractions; + + replaceable function saturationDensity + "Return saturation density of steam as a function of temperature T" + + extends Modelica.Icons.Function; + input Temperature T + "Saturation temperature"; + output Density dsat + "Saturation density"; + + algorithm + + dsat := saturationPressure(T) / (steam.R * T); + + annotation ( + derivative = saturationDensity_der, + Inline = true, + Documentation( + info = " + Saturation density of steam is computed as function of the Temperature using the saturation pressure function psat and the perfect gas law. +")); + + end saturationDensity; + + replaceable function saturationDensity_der + "Derivative function for 'saturationDensity'" + + extends Modelica.Icons.Function; + input Temperature T + "Saturation temperature"; + input Real dTsat(unit = "K/s") + "Time derivative of saturation temperature"; + output Real dsat_der(unit = "kg/(m3.s)") + "Saturation pressure"; + + algorithm + + // dsat_der := 1 / steam.R * saturationPressure_der(T, dTsat) * (Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.dptofT(T) / T - Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T) / T ^ 2) * dTsat; + dsat_der := 1 / steam.R * (saturationPressure_der(T, dTsat) / T - saturationPressure(T) / T ^ 2 * dTsat) + annotation ( + Inline = false, + smoothOrder = 5, + Documentation( + info = " + Derivative function of saturationDensity + ")); + + end saturationDensity_der; + + replaceable function saturationPressure + "Return saturation pressure of water as a function of temperature T between 190 and 647.096 K" + + extends Modelica.Icons.Function; + input Temperature Tsat + "Saturation temperature"; + output AbsolutePressure psat + "Saturation pressure"; + + algorithm + + psat := Utilities.spliceFunction(saturationPressureLiquid(Tsat), sublimationPressureIce(Tsat), Tsat - 273.16, 1.0); + + annotation ( + Inline = false, + smoothOrder = 5, + derivative = saturationPressure_der, + Documentation( + info = " +Saturation pressure of water in the liquid and the solid region is computed using correlations. Functions for the +solid and the liquid region, respectively, are combined using the first derivative continuous spliceFunction. This functions range of validity is from 190 to 647.096 K. For more information on the type of correlation used, see the documentation of the linked functions. +")); + + end saturationPressure; + + replaceable function saturationPressure_der + "Derivative function for 'saturationPressure'" + + extends Modelica.Icons.Function; + input Temperature Tsat + "Saturation temperature"; + input Real dTsat(unit = "K/s") + "Time derivative of saturation temperature"; + output Real psat_der(unit = "Pa/s") + "Saturation pressure"; + + algorithm + + /*psat := Utilities.spliceFunction(saturationPressureLiquid(Tsat),sublimationPressureIce(Tsat),Tsat-273.16,1.0);*/ + psat_der := Utilities.spliceFunction_der(saturationPressureLiquid(Tsat), sublimationPressureIce(Tsat), Tsat - 273.16, 1.0, saturationPressureLiquid_der(Tsat = Tsat, dTsat = dTsat), sublimationPressureIce_der(Tsat = Tsat, dTsat = dTsat), dTsat, 0); + + annotation ( + Inline = false, + smoothOrder = 5, + Documentation( + info = " + Derivative function of saturationPressure + ")); + + end saturationPressure_der; + + replaceable function saturationPressureLiquid + "Return saturation pressure of water as a function of temperature T in the range of 273.15K to 647.096K (region 4 from the IF97 definition)" + + extends Modelica.Icons.Function; + input SI.Temperature Tsat + "Saturation temperature"; + output SI.AbsolutePressure psat + "Saturation pressure"; + + protected + + // SI.Temperature Tcritical = 647.096 "Critical temperature"; + // SI.AbsolutePressure pcritical = 22.064e6 "Critical pressure"; + // Real r1 = 1 - Tsat / Tcritical "Common subexpression"; + // Real a[:] = {-7.85951783, 1.84408259, -11.7866497, 22.6807411, -15.9618719, 1.80122502} "Coefficients a[:]"; + // Real n[:] = {1.0, 1.5, 3.0, 3.5, 4.0, 7.5} "Coefficients n[:]"; + constant SI.Temperature T_limit_low = 273.16; + constant SI.Temperature T_limit_high = 679.096; + SI.Temperature T + "Temperature in definition range"; + + algorithm + + // psat := exp(((a[1]*r1^n[1] + a[2]*r1^n[2] + a[3]*r1^n[3] + a[4]*r1^n[4] + // + a[5]*r1^n[5] + a[6]*r1^n[6])*Tcritical)/Tsat)*pcritical; + T := max(Tsat, T_limit_low); + psat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T); + + annotation ( + derivative = saturationPressureLiquid_der, + Inline = false, + smoothOrder = 5, + Documentation( + info = " +

        Saturation pressure of water above the triple point temperature is computed from temperature.

        +

        Source: A Saul, W Wagner: "International equations for the saturation properties of ordinary water substance", equation 2.1

        + ")); + + end saturationPressureLiquid; + + replaceable function saturationPressureLiquid_der + "Derivative function for 'saturationPressureLiquid'" + + extends Modelica.Icons.Function; + input SI.Temperature Tsat + "Saturation temperature"; + input Real dTsat(unit = "K/s") + "Saturation temperature derivative"; + output Real psat_der(unit = "Pa/s") + "Saturation pressure derivative"; + + protected + + SI.Temperature Tcritical = 647.096 + "Critical temperature"; + SI.AbsolutePressure pcritical = 22.064e6 + "Critical pressure"; + Real r1 = 1 - Tsat / Tcritical + "Common subexpression 1"; + Real r1_der = -1 / Tcritical * dTsat + "Derivative of common subexpression 1"; + Real a[:] = {-7.85951783, 1.84408259, -11.7866497, 22.6807411, -15.9618719, 1.80122502} + "Coefficients a[:]"; + Real n[:] = {1.0, 1.5, 3.0, 3.5, 4.0, 7.5} + "Coefficients n[:]"; + Real r2 = a[1] * r1 ^ n[1] + a[2] * r1 ^ n[2] + a[3] * r1 ^ n[3] + a[4] * r1 ^ n[4] + a[5] * r1 ^ n[5] + a[6] * r1 ^ n[6] + "Common subexpression 2"; + + algorithm + + // Approach used here is based on Baehr: "Thermodynamik", 12th edition p.204ff, "Method of Wagner" + //psat := exp(((a[1]*r1^n[1] + a[2]*r1^n[2] + a[3]*r1^n[3] + a[4]*r1^n[4] + a[5]*r1^n[5] + a[6]*r1^n[6])*Tcritical)/Tsat) * pcritical; + psat_der := exp(r2 * Tcritical / Tsat) * pcritical * ((a[1] * (r1 ^ (n[1] - 1) * n[1] * r1_der) + a[2] * (r1 ^ (n[2] - 1) * n[2] * r1_der) + a[3] * (r1 ^ (n[3] - 1) * n[3] * r1_der) + a[4] * (r1 ^ (n[4] - 1) * n[4] * r1_der) + a[5] * (r1 ^ (n[5] - 1) * n[5] * r1_der) + a[6] * (r1 ^ (n[6] - 1) * n[6] * r1_der)) * Tcritical / Tsat - r2 * Tcritical * dTsat / Tsat ^ 2); + + annotation ( + Inline = false, + smoothOrder = 5, + Documentation( + info = " +

        Saturation pressure of water above the triple point temperature is computed from temperature.

        +

        Source: A Saul, W Wagner: "International equations for the saturation properties of ordinary water substance", equation 2.1

        + ")); + + end saturationPressureLiquid_der; + + replaceable function sublimationPressureIce + "Return sublimation pressure of water as a function of temperature T between 190 and 273.16 K" + + extends Modelica.Icons.Function; + input SI.Temperature Tsat + "Sublimation temperature"; + output SI.AbsolutePressure psat + "Sublimation pressure"; + + protected + + SI.Temperature Ttriple = 273.16 + "Triple point temperature"; + SI.AbsolutePressure ptriple = 611.657 + "Triple point pressure"; + Real r1 = Tsat / Ttriple + "Common subexpression"; + Real a[:] = {-13.9281690, 34.7078238} + "Coefficients a[:]"; + Real n[:] = {-1.5, -1.25} + "Coefficients n[:]"; + + algorithm + + psat := exp(a[1] - a[1] * r1 ^ n[1] + a[2] - a[2] * r1 ^ n[2]) * ptriple; + + annotation ( + Inline = false, + smoothOrder = 5, + derivative = sublimationPressureIce_der, + Documentation( + info = " +

        Sublimation pressure of water below the triple point temperature is computed from temperature.

        +

        Source: W Wagner, A Saul, A Pruss: "International equations for the pressure along the melting and along the sublimation curve of ordinary water substance", equation 3.5

        + ")); + + end sublimationPressureIce; + + replaceable function sublimationPressureIce_der + "Derivative function for 'sublimationPressureIce'" + + extends Modelica.Icons.Function; + input SI.Temperature Tsat + "Sublimation temperature"; + input Real dTsat(unit = "K/s") + "Sublimation temperature derivative"; + output Real psat_der(unit = "Pa/s") + "Sublimation pressure derivative"; + + protected + + SI.Temperature Ttriple = 273.16 + "Triple point temperature"; + SI.AbsolutePressure ptriple = 611.657 + "Triple point pressure"; + Real r1 = Tsat / Ttriple + "Common subexpression 1"; + Real r1_der = dTsat / Ttriple + "Derivative of common subexpression 1"; + Real a[:] = {-13.9281690, 34.7078238} + "Coefficients a[:]"; + Real n[:] = {-1.5, -1.25} + "Coefficients n[:]"; + + algorithm + + //psat := exp(a[1] - a[1]*r1^n[1] + a[2] - a[2]*r1^n[2]) * ptriple; + psat_der := exp(a[1] - a[1] * r1 ^ n[1] + a[2] - a[2] * r1 ^ n[2]) * ptriple * ((-a[1] * (r1 ^ (n[1] - 1) * n[1] * r1_der)) - a[2] * (r1 ^ (n[2] - 1) * n[2] * r1_der)); + + annotation ( + Inline = false, + smoothOrder = 5, + Documentation( + info = " +

        Sublimation pressure of water below the triple point temperature is computed from temperature.

        +

        Source: W Wagner, A Saul, A Pruss: "International equations for the pressure along the melting and along the sublimation curve of ordinary water substance", equation 3.5

        + ")); + + end sublimationPressureIce_der; + + replaceable function enthalpyOfVaporization + "Return vaporization enthalpy of condensing fluid" + + extends Modelica.Icons.Function; + input Temperature T + "Temperature"; + output SpecificEnthalpy r0 + "Vaporization enthalpy"; + + algorithm + + r0 := water.cp * (reference_T - T) + steam.h_lv + steam.cp * (T - reference_T); + + annotation ( + Inline = true, + smoothOrder = 5, + Documentation( + info = " +

        Enthalpy of vaporization of water is computed from temperature.

        +

        As the enthalpy is a state function, it does not depend on the transformation path. + Therefore, the enthalpy of vaporisation at a given temperature is computed from the enthalpy of vaporisation at 2°C corrected by the sensible enthalpy diffence between the temperature T and 0°C

        + ")); + + end enthalpyOfVaporization; + + replaceable function enthalpyOfLiquid + "Return enthalpy of liquid water as a function of temperature T(use enthalpyOfWater instead)" + + extends Modelica.Icons.Function; + input Temperature T + "Temperature"; + output SpecificEnthalpy h + "Liquid enthalpy"; + + algorithm + + h := water.cp * (T - reference_T); + + annotation ( + Inline = true, + smoothOrder = 5, + Documentation( + info = " +

        Specific enthalpy of water is computed from temperature and constant specific heat capacity.

        + ")); + + end enthalpyOfLiquid; + + replaceable function enthalpyOfGas + "Return specific enthalpy of gas (air and steam) as a function of temperature T and composition X (only valide for phi<1)" + + extends Modelica.Icons.Function; + input Temperature T + "Temperature"; + input MassFraction[:] X + "Vector of mass fractions"; + output SpecificEnthalpy h + "Specific enthalpy"; + + algorithm + + h := (steam.cp * (T - reference_T) + steam.h_lv) * X[Water] + dryair.cp * (T - reference_T) * (1.0 - X[Water]); + + annotation ( + Inline = true, + smoothOrder = 5, + Documentation( + info = " + Specific enthalpy of moist air is computed from temperature and constant specific heat capacity, provided all water is in the gaseous state. The first entry in the composition vector X must be the mass fraction of steam. For a function that also covers the fog region please refer to h_dTX. +")); + + end enthalpyOfGas; + + replaceable function enthalpyOfCondensingGas + "Return specific enthalpy of steam as a function of temperature T" + + extends Modelica.Icons.Function; + input Temperature T + "Temperature"; + output SpecificEnthalpy h + "Specific enthalpy"; + + algorithm + + h := steam.cp * (T - reference_T) + steam.h_lv; + + annotation ( + Inline = true, + smoothOrder = 5, + Documentation( + info = " + Specific enthalpy of steam is computed from temperature and constant specific heat capacity. +")); + + end enthalpyOfCondensingGas; + + replaceable function enthalpyOfNonCondensingGas + "Return specific enthalpy of dry air as a function of temperature T" + + extends Modelica.Icons.Function; + input Temperature T + "Temperature"; + output SpecificEnthalpy h + "Specific enthalpy"; + + algorithm + + h := dryair.cp * (T - reference_T); + + annotation ( + Inline = true, + smoothOrder = 5, + Documentation( + info = " + Specific enthalpy of dry air is computed from temperature and constant specific heat capacity. +")); + + end enthalpyOfNonCondensingGas; + + function enthalpyOfWater + "Computes specific enthalpy of water (solid/liquid) near atmospheric pressure from temperature T" + + extends Modelica.Icons.Function; + input SIunits.Temperature T + "Temperature"; + output SIunits.SpecificEnthalpy h + "Specific enthalpy of water"; + + algorithm + + /*simple model assuming constant properties: + heat capacity of solid water: 2050 J/kg + enthalpy of fusion (liquid=>solid): 333000 J/kg*/ + h := Utilities.spliceFunction(water.cp * (T - reference_T), ice.cp * (T - reference_T) - ice.h_sl, T - 273.16, 0.1); + + annotation ( + derivative = enthalpyOfWater_der, + Documentation( + info = " + Specific enthalpy of water (liquid and solid) is computed from temperature using constant properties as follows:
        +
          +
        • heat capacity of liquid water:water(record).cp J/kg
        • +
        • heat capacity of solid water: 2050 J/kg
        • +
        • enthalpy of fusion (liquid=>solid): 333000 J/kg
        • +
        + Pressure is assumed to be around 1 bar. This function is usually used to determine the specific enthalpy of the liquid or solid fraction of moist air. + ")); + + end enthalpyOfWater; + + function enthalpyOfWater_der + "Derivative function of enthalpyOfWater" + + extends Modelica.Icons.Function; + input SIunits.Temperature T + "Temperature"; + input Real dT(unit = "K/s") + "Time derivative of temperature"; + output Real dh(unit = "J/(kg.s)") + "Time derivative of specific enthalpy"; + + algorithm + + /*simple model assuming constant properties: + heat capacity of solid water: 2050 J/kg + enthalpy of fusion (liquid=>solid): 333000 J/kg*/ + //h:=Utilities.spliceFunction(water.cp*(T-273.15),2050*(T-273.15)-333000,T-273.16,0.1); + dh := Utilities.spliceFunction_der(water.cp * (T - reference_T), ice.cp * (T - reference_T) - ice.h_sl, T - 273.16, 0.1, water.cp * dT, ice.cp * dT, dT, 0); + + annotation ( + Documentation( + info = " + Derivative function for enthalpyOfWater. + + ")); + + end enthalpyOfWater_der; + + redeclare function extends pressure + "Returns pressure of ideal gas as a function of the thermodynamic state record" + + protected + + SI.MassFraction X_liquid + "Mass fraction of liquid or solid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + + algorithm + + d_sat := saturationDensity(state.T); + X_liquid := max(state.d * state.X[Water] - d_sat, 0) / state.d; + X_steam := state.X[Water] - X_liquid; + X_air := 1 - state.X[Water]; + p := state.d * (dryair.R * X_air + steam.R * X_steam) * state.T; + + annotation ( + smoothOrder = 5, + Documentation( + info = " +

        Pressure is returned from the thermodynamic state record input from the density and the temparture applying the ideal gas law.

        + ")); + + end pressure; + + redeclare function extends temperature + "Return temperature of ideal gas as a function of the thermodynamic state record" + + algorithm + + T := state.T; + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Temperature is returned from the thermodynamic state record input as a simple assignment. + ")); + + end temperature; + + function T_phX + "Return temperature as a function of pressure p, specific enthalpy h and composition X" + + input AbsolutePressure p + "Pressure"; + input SpecificEnthalpy h + "Specific enthalpy"; + input MassFraction[:] X + "Mass fractions of composition"; + output Temperature T + "Temperature"; + + protected + + SI.MoleFraction Y[2] + "Mole fraction of species in the medium"; + SI.MassFraction X_liq + "Mass fraction of liquid"; + SI.Temperature T_sat + "Steam saturation temperature at given steam pressure"; + SI.MassFraction X_steam + "Mass fraction of steam in medium"; + Integer i; + + algorithm + + i := 0; + /* specific enthalpy formula is assumed to be + h = X_air*dryair.cp*(T_sat-T_ref)+X_steam*(steam.cp*(T_sat-T_ref)+h_lv)+(1-X_air-X_steam)*water.cp*(T_sat-T_ref) */ + T := (h - X[Water] * steam.h_lv) / (X[Air] * dryair.cp + X[Water] * steam.cp) + reference_T; + Y := massToMoleFractions(X = X, MMX = MMX); + T_sat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p * Y[Water]); + if T < T_sat then + while abs((T - T_sat) / T_sat) > 1e-5 loop + T := T_sat; + X_steam := (h - (T - reference_T) * (X[Water] * water.cp + X[Air] * dryair.cp)) / (steam.h_lv + (steam.cp - water.cp) * (T - reference_T)); + X_liq := X[Water] - X_steam; + Y := massToMoleFractions(X = {X_steam / (1 - X_liq), 1 - X_steam / (1 - X_liq)}, MMX = MMX); + T_sat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.tsat(p * Y[Water]); + i := i + 1; + end while; + T := T_sat; + else + X_steam := X[Water]; + X_liq := 0.0; + end if; + + //The region of solid water is not allowed + assert(T > 273.16, "The solid region for water in the T_phX function is not allowed", level = AssertionLevel.error); + + //Modelica.Utilities.Streams.print("i = "+String(i)) ; + annotation ( + Documentation( + info = " +

        + Temperature is computed from pressure, specific enthalpy and composition. + Loop over the saturation temperature is performed for the fog region and for dry mixture, + the temperature is computed from analytic inversion of the enthalpy relation with respect to the temperature. +

        + + ")); + + end T_phX; + + redeclare function extends density + "Returns density as a function of the thermodynamic state record" + + algorithm + + d := state.d; + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Density is returned from the thermodynamic state record input as a simple assignment. + ")); + + end density; + + function d_phX + "Returns density as a function of pressure p, enthalpy h and composition X" + + extends Modelica.Icons.Function; + input AbsolutePressure p + "Pressure"; + input SpecificEnthalpy h + "Specific enthalpy"; + input MassFraction X[:] = reference_X + "Mass fractions"; + output Density d + "Density"; + + protected + + SI.Temperature T; + SI.MassFraction X_steam + "Steam mass fraction in the medium"; + SI.MassFraction X_liquid + "Liquid water mass fraction in the medium"; + SI.MolarMass MMmix + "Molar mass of gas mixture"; + + algorithm + + T := T_phX(p = p, h = h, X = X); + X_steam := (h - (X[Air] * (dryair.cp - water.cp) + water.cp) * (T - reference_T)) / ((steam.cp - water.cp) * (T - reference_T) + steam.h_lv); + X_steam := min(X_steam, X[Water]); + X_liquid := max(X[Water] - X_steam, 0.0); + MMmix := (X_steam / (1 - X_liquid) / steam.MM + X[Air] / (1 - X_liquid) / dryair.MM) ^ (-1); + d := p / (Modelica.Constants.R / MMmix * T); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Density is returned from the pressure p, specific enthalpy h and composition X. + ")); + + end d_phX; + + redeclare function extends specificEnthalpy + "Return specific enthalpy of moist air as a function of the thermodynamic state record" + + algorithm + + h := h_dTX(state.d, state.T, state.X); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Specific enthalpy of moist air is computed from the thermodynamic state record. The fog region is included for both, ice and liquid fog. + ")); + + end specificEnthalpy; + + function h_dTX + "Return specific enthalpy of moist air as a function of density d, temperature T and composition X" + + extends Modelica.Icons.Function; + input SI.Density d + "Density"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + output SI.SpecificEnthalpy h + "Specific enthalpy at p, T, X"; + + protected + + SI.MassFraction X_liquid + "Mass fraction of liquid or solid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + + algorithm + + d_sat := saturationDensity(T); + X_liquid := max(d * X[Water] - d_sat, 0) / d; + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + //h := X_air*dryair.cp*(T-273.15) + X_steam*(steam.cp*(T-273.15)+steam.h_lv) + enthalpyOfWater(T)*X_liquid; + h := X_air * dryair.cp * (T - reference_T) + X_steam * (steam.cp * (T - reference_T) + steam.h_lv) + X_liquid * water.cp * (T - reference_T); + + annotation ( + Inline = false, + derivative = h_dTX_der, + Documentation( + info = " + Specific enthalpy of moist air is computed from density, temperature and composition with X[1] as the total water mass fraction. The fog region is included for both, ice and liquid fog. + ")); + + end h_dTX; + + function h_dTX_der + "Derivative function of h_dTX" + + extends Modelica.Icons.Function; + input SI.Density d + "Density"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + input Real dd(unit = "kg/(m3.s)") + "Density derivative"; + input Real dT(unit = "K/s") + "Temperature derivative"; + input Real dX[:](each unit = "1/s") + "Composition derivative"; + output Real h_der(unit = "J/(kg.s)") + "Time derivative of specific enthalpy"; + + protected + + SI.MassFraction X_liquid + "Mass fraction of liquid or solid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + Real dX_steam(unit = "1/s") + "Time derivative of steam mass fraction"; + Real dX_air(unit = "1/s") + "Time derivative of dry air mass fraction"; + Real dX_liq(unit = "1/s") + "Time derivative of liquid/solid water mass fraction"; + Real dd_sat(unit = "kg/(m3.s)") + "Time derivative of saturation density"; + + algorithm + + d_sat := saturationDensity(T); + X_liquid := Utilities.smoothMax(X[Water] - d_sat / d, 0.0, 1e-6); + //X_liquid := max(X[Water] - d_sat/d, 0); + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + dX_air := -dX[Water]; + dd_sat := saturationDensity_der(T, dT); + dX_liq := Utilities.smoothMax_der(X[Water] - d_sat / d, 0.0, 1e-5, (d * dX[Water] + dd * X[Water] - dd_sat) / d - (d * X[Water] - d_sat) / (d * d) * dd, 0, 0); + //dX_liq := if X_liquid > 0.0 then dX[Water] - dd_sat / d + dd*d_sat / (d*d) else 0.0; + dX_steam := dX[Water] - dX_liq; + h_der := X_air * dryair.cp * dT + dX_air * dryair.cp * (T - reference_T) + X_steam * steam.cp * dT + dX_steam * (steam.h_lv + steam.cp * (T - reference_T)) + X_liquid * water.cp * dT + dX_liq * water.cp * (T - reference_T); + + annotation ( + Inline = false, + smoothOrder = 1, + Documentation( + info = " + Derivative function for h_dTX. + ")); + + end h_dTX_der; + + function h_pTX + "Return specific enthalpy of moist air as a function of pressure p, temperature T and composition X" + + extends Modelica.Icons.Function; + input SI.Pressure p + "Pressure"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + output SI.SpecificEnthalpy h + "Specific enthalpy at p, T, X"; + + protected + + SI.AbsolutePressure p_steam_sat + "partial saturation pressure of steam"; + SI.MassFraction X_sat + "Absolute humidity per unit mass of moist air"; + SI.MassFraction X_liquid + "Mass fraction of liquid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + + algorithm + + p_steam_sat := saturationPressure(T); + X_sat := min(p_steam_sat * k_mair / max(100 * Modelica.Constants.eps, p - p_steam_sat) * (1 - X[Water]), 1.0); + X_liquid := max(X[Water] - X_sat, 0.0); + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + h := (X_steam * steam.cp + X_air * dryair.cp) * (T - reference_T) + X_steam * steam.h_lv + enthalpyOfWater(T) * X_liquid; + + annotation ( + derivative = h_pTX_der, + Inline = false, + Documentation( + info = " +

        + Specific enthalpy of moist air is computed from pressure, temperature and composition with X[1] as the total water mass fraction. + The fog region is included for both, ice and liquid fog. +

        +

        + This function is only valid for a mass fraction of air X[Air] > 1e-4. + Otherwise, when the mixture is fully composed of water, the ratio between steam and liquid water cannot be determine since the pressure p and the temperature T remains constant whatever the ratio. +

        + ")); + + end h_pTX; + + function h_pTX_der + "Derivative function of h_pTX" + + extends Modelica.Icons.Function; + input SI.Pressure p + "Pressure"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + input Real dp(unit = "Pa/s") + "Pressure derivative"; + input Real dT(unit = "K/s") + "Temperature derivative"; + input Real dX[:](each unit = "1/s") + "Composition derivative"; + output Real h_der(unit = "J/(kg.s)") + "Time derivative of specific enthalpy"; + + protected + + SI.AbsolutePressure p_steam_sat + "partial saturation pressure of steam"; + SI.MassFraction X_sat + "Absolute humidity per unit mass of moist air"; + SI.MassFraction X_liquid + "Mass fraction of liquid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.MassFraction x_sat + "Absolute humidity per unit mass of dry air at saturation"; + Real dX_steam(unit = "1/s") + "Time derivative of steam mass fraction"; + Real dX_air(unit = "1/s") + "Time derivative of dry air mass fraction"; + Real dX_liq(unit = "1/s") + "Time derivative of liquid/solid water mass fraction"; + Real dps(unit = "Pa/s") + "Time derivative of saturation pressure"; + Real dx_sat(unit = "1/s") + "Time derivative of absolute humidity per unit mass of dry air"; + + algorithm + + p_steam_sat := saturationPressure(T); + x_sat := p_steam_sat * k_mair / max(100 * Modelica.Constants.eps, p - p_steam_sat); + X_sat := min(x_sat * (1 - X[Water]), 1.0); + X_liquid := Utilities.smoothMax(X[Water] - X_sat, 0.0, 1e-5); + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + dX_air := -dX[Water]; + dps := saturationPressure_der(Tsat = T, dTsat = dT); + dx_sat := k_mair * (dps * (p - p_steam_sat) - p_steam_sat * (dp - dps)) / (p - p_steam_sat) / (p - p_steam_sat); + dX_liq := Utilities.smoothMax_der(X[Water] - X_sat, 0.0, 1e-5, (1 + x_sat) * dX[Water] - (1 - X[Water]) * dx_sat, 0, 0); + dX_steam := dX[Water] - dX_liq; + h_der := X_air * dryair.cp * dT + dX_air * dryair.cp * (T - reference_T) + X_steam * steam.cp * dT + dX_steam * (steam.h_lv + steam.cp * (T - reference_T)) + X_liquid * enthalpyOfWater_der(T = T, dT = dT) + dX_liq * enthalpyOfWater(T); + + annotation ( + Inline = false, + smoothOrder = 1, + Documentation( + info = " + Derivative function for h_pTX. + ")); + + end h_pTX_der; + + redeclare function extends isentropicExponent + "Return isentropic exponent (only for gas fraction!)" + + algorithm + + gamma := specificHeatCapacityCp(state) / specificHeatCapacityCv(state); + + end isentropicExponent; + + function isentropicEnthalpyApproximation + "Approximate calculation of h_is from upstream properties, downstream pressure, gas part only" + + extends Modelica.Icons.Function; + input AbsolutePressure p2 + "Downstream pressure"; + input ThermodynamicState state + "Thermodynamic state at upstream location"; + output SpecificEnthalpy h_is + "Isentropic enthalpy"; + + protected + + SpecificEnthalpy h + "Specific enthalpy at upstream location"; + IsentropicExponent gamma = isentropicExponent(state) + "Isentropic exponent"; + + protected + + AbsolutePressure p1 + "Upstream pressure"; + + algorithm + + h := {steam.cp * (state.T - reference_T), dryair.cp * (state.T - reference_T)} * state.X; + p1 := state.d * (state.X[Water] * steam.R + (1 - state.X[Water]) * dryair.R) * state.T; + h_is := h + gamma / (gamma - 1.0) * (state.T * gasConstant_X(state.X)) * ((p2 / p1) ^ ((gamma - 1) / gamma) - 1.0); + + end isentropicEnthalpyApproximation; + + redeclare function extends specificInternalEnergy + "Return specific internal energy of moist air as a function of the thermodynamic state record" + + extends Modelica.Icons.Function; + + algorithm + + u := specificInternalEnergy_dTX(state.d, state.T, state.X); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + Specific internal energy is determined from the thermodynamic state record, assuming that the liquid or solid water volume is negligible. + ")); + + end specificInternalEnergy; + + function specificInternalEnergy_dTX + "Return specific internal energy of moist air as a function of density d, temperature T and composition X" + + extends Modelica.Icons.Function; + input SI.Density d + "Density"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + output SI.SpecificInternalEnergy u + "Specific internal energy"; + + protected + + SI.MassFraction X_liquid + "Mass fraction of liquid or solid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.MassFraction d_sat + "Steam water density of saturation boundary in kg_water/m3"; + Real R_gas + "Ideal gas constant"; + + algorithm + + d_sat := saturationDensity(T); + X_liquid := max(d * X[Water] - d_sat, 0) / d; + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + R_gas := dryair.R * X_air / (1 - X_liquid) + steam.R * X_steam / (1 - X_liquid); + u := X_steam * steam.cp * (T - reference_T) + X_air * dryair.cp * (T - reference_T) + enthalpyOfWater(T) * X_liquid - R_gas * T; + + annotation ( + derivative = specificInternalEnergy_dTX_der, + Documentation( + info = " + Specific internal energy is determined from density d, temperature T and composition X, assuming that the liquid or solid water volume is negligible. + ")); + + end specificInternalEnergy_dTX; + + function specificInternalEnergy_dTX_der + "Derivative function for specificInternalEnergy_dTX" + + extends Modelica.Icons.Function; + input SI.Density d + "Density"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + input Real dd(unit = "kg/(m3.s)") + "Density derivative"; + input Real dT(unit = "K/s") + "Temperature derivative"; + input Real dX[:](each unit = "1/s") + "Mass fraction derivatives"; + output Real u_der(unit = "J/(kg.s)") + "Specific internal energy derivative"; + + protected + + SI.MassFraction X_liquid + "Mass fraction of liquid or solid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + SI.SpecificHeatCapacity R_gas + "Ideal gas constant"; + Real dX_steam(unit = "1/s") + "Time derivative of steam mass fraction"; + Real dX_air(unit = "1/s") + "Time derivative of dry air mass fraction"; + Real dX_liq(unit = "1/s") + "Time derivative of liquid/solid water mass fraction"; + Real dd_sat(unit = "kg/(m3.s)") + "Time derivative of saturation density"; + Real dR_gas(unit = "J/(kg.K.s)") + "Time derivative of ideal gas constant"; + + algorithm + + d_sat := saturationDensity(T); + X_liquid := Utilities.spliceFunction(max(d * X[Water] - d_sat, 0) / d, 0.0, max(d * X[Water] - d_sat, 0) / d, 1e-6); + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + R_gas := steam.R * X_steam / (1 - X_liquid) + dryair.R * X_air / (1 - X_liquid); + dd_sat := saturationDensity_der(T, dT); + dX_liq := Utilities.spliceFunction_der((d * X[Water] - d_sat) / d, 0.0, (d * X[Water] - d_sat) / d, 1e-6, (d * dX[Water] + dd * X[Water] - dd_sat) / d - (d * X[Water] - d_sat) / (d * d) * dd, 0.0, (d * dX[Water] + dd * X[Water] - dd_sat) / d - (d * X[Water] - d_sat) / (d * d) * dd, 0.0); + dX_air := -dX[Water]; + dX_steam := dX[Water] - dX_liq; + dR_gas := (steam.R * (dX_steam * (1 - X_liquid) + dX_liq * X_steam) + dryair.R * (dX_air * (1 - X_liquid) + dX_liq * X_air)) / (1 - X_liquid) / (1 - X_liquid); + u_der := h_dTX_der(d, T, X, dd, dT, dX) - R_gas * dT - dR_gas * T + annotation ( + Documentation( + info = " + Derivative function for specificInternalEnergy_dTX. + ")); + + end specificInternalEnergy_dTX_der; + + redeclare function extends specificEntropy + "Return specific entropy from thermodynamic state record" + + algorithm + + s := s_dTX(state.d, state.T, state.X); + + annotation ( + Inline = false, + smoothOrder = 2, + Documentation( + info = " + Specific entropy is calculated from the thermodynamic state record, assuming ideal gas behavior and including entropy of mixing. Liquid but not solid water is taken into account. + ")); + + end specificEntropy; + + function s_dTX + "Return specific entropy of moist air as a function of density d, temperature T and composition X" + + extends Modelica.Icons.Function; + input SI.Density d + "Density"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + output SI.SpecificEntropy s + "Specific entropy at p, T, X"; + + protected + + SI.Pressure p[2] + "Vector of partial pressure of water and dry air"; + SI.MassFraction X_liquid + "Mass fraction of liquid or solid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.MassFraction d_sat + "Steam water density of saturation boundary in kg_water/m3"; + + algorithm + + d_sat := saturationDensity(T); + X_liquid := max(d * X[Water] - d_sat, 0) / d; + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + p[Water] := d * X_steam * steam.R * T; + p[Air] := d * X_air * dryair.R * T; + s := X_air * dryair.cp * Modelica.Math.log(T / reference_T) + X_steam * steam.cp * Modelica.Math.log(T / reference_T) - Modelica.Constants.R * (Utilities.smoothMax(X_steam / MMX[Water], 0.0, 1e-9) * Modelica.Math.log(max(p[Water], Modelica.Constants.eps) / reference_p) + Utilities.smoothMax(X_air / MMX[Air], 0.0, 1e-9) * Modelica.Math.log(max(p[Air], Modelica.Constants.eps) / reference_p)) + X_liquid * water.cp * Modelica.Math.log(T / reference_T) + X_liquid * enthalpyOfVaporization(T) / T; + + annotation ( + derivative = s_dTX_der, + Inline = false, + Documentation( + info = " + Specific entropy of moist air is computed from density, temperature and composition with X[1] as the total water mass fraction. + ")); + + end s_dTX; + + function s_dTX_der + "Derivative function of h_dTX" + + extends Modelica.Icons.UnderConstruction; + input SI.Density d + "Density"; + input SI.Temperature T + "Temperature"; + input SI.MassFraction X[:] + "Mass fractions of moist air"; + input Real dd(unit = "kg/(m3.s)") + "Derivative of density"; + input Real dT(unit = "K/s") + "Derivative of temperature"; + input Real dX[nX](each unit = "1/s") + "Derivative of mass fractions"; + output Real ds(unit = "J/(kg.K.s)") + "Specific entropy at p, T, X"; + + protected + + SI.Pressure p[2] + "Vector of partial pressure of water and dry air"; + SI.MassFraction X_liquid + "Mass fraction of liquid or solid water"; + SI.MassFraction X_steam + "Mass fraction of steam water"; + SI.MassFraction X_air + "Mass fraction of air"; + SI.MassFraction d_sat + "Steam water density of saturation boundary in kg_water/m3"; + Real dp[2](unit = "Pa/s") + "Time derivative of vector of partial pressure of water and dry air"; + Real dX_steam(unit = "1/s") + "Time derivative of steam mass fraction"; + Real dX_air(unit = "1/s") + "Time derivative of dry air mass fraction"; + Real dX_liq(unit = "1/s") + "Time derivative of liquid/solid water mass fraction"; + Real dd_sat(unit = "kg/(m3.s)") + "Time derivative of saturation density"; + + algorithm + + d_sat := saturationDensity(T); + X_liquid := Utilities.smoothMax(max(d * X[Water] - d_sat, 0) / d, 0.0, 1e-5); + X_steam := X[Water] - X_liquid; + X_air := 1 - X[Water]; + p[Water] := d * X_steam * steam.R * T; + p[Air] := d * X_air * dryair.R * T; + dX_air := -dX[Water]; + //dd_sat = dd_sat/dp*dp/dT*dT + dd_sat := Modelica.Media.Water.IF97_Utilities.BaseIF97.Regions.drhov_dp(Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat(T)) * Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.psat_der(T, dT); + dX_liq := Utilities.smoothMax_der(max(d * X[Water] - d_sat, 0) / d, 0.0, 1e-5, d * dX[Water] + dd * X[Water] - dd_sat, 0, 0); + dX_steam := dX[Water] - dX_liq; + dp[Water] := dd * X_steam * steam.R * T + d * (dX_steam * steam.R * T + X_steam * steam.R * dT); + dp[Air] := dd * X_air * dryair.R * T + d * (dX_air * dryair.R * T + X_air * dryair.R * dT); + ds := (1 - X[Water]) * dryair.cp * dT / T + dX_air * dryair.cp * Modelica.Math.log(T / reference_T) + X[Water] * steam.cp * dT / T + dX[Water] * Modelica.Math.log(T / reference_T) - Modelica.Constants.R * (1 / MMX[Water] * (Utilities.smoothMax_der(X[Water], 0.0, 1e-9, dX[Water], 0.0, 0.0) * Modelica.Math.log(max(dp[Water], Modelica.Constants.eps) / reference_p) + dp[Water] / p[Water] * Utilities.smoothMax(X[Water], 0.0, 1e-9)) + 1 / MMX[Air] * (Utilities.smoothMax_der(X[Air], 0.0, 1e-9, dX[Air], 0.0, 0.0) * Modelica.Math.log(max(p[Air], Modelica.Constants.eps) / reference_p) + dp[Air] / p[Air] * Utilities.smoothMax(X[Air], 0.0, 1e-9))) + dX_liq * water.cp * Modelica.Math.log(T / reference_T) + X_liquid * water.cp * dT / T; + + annotation ( + Inline = false, + smoothOrder = 1, + Documentation( + info = " + Specific entropy of moist air is computed from density, temperature and composition with X[1] as the total water mass fraction. + ")); + + end s_dTX_der; + + redeclare function extends specificGibbsEnergy + "Return specific Gibbs energy as a function of the thermodynamic state record, only valid for phi<1" + + extends Modelica.Icons.Function; + + algorithm + + g := h_dTX(state.d, state.T, state.X) - state.T * specificEntropy(state); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + The Gibbs Energy is computed from the thermodynamic state record for moist air with a water content below saturation. + ")); + + end specificGibbsEnergy; + + redeclare function extends specificHelmholtzEnergy + "Return specific Helmholtz energy as a function of the thermodynamic state record, only valid for phi<1" + + extends Modelica.Icons.Function; + + algorithm + + f := h_dTX(state.d, state.T, state.X) - gasConstant(state) * state.T - state.T * specificEntropy(state); + + annotation ( + smoothOrder = 2, + Documentation( + info = " + The Specific Helmholtz Energy is computed from the thermodynamic state record for moist air with a water content below saturation. + ")); + + end specificHelmholtzEnergy; + + redeclare function extends specificHeatCapacityCp + "Return specific heat capacity at constant pressure as a function of the thermodynamic state record" + + protected + + SI.Density d_sat + "Steam water density of saturation boundary in kg_water/m3"; + SI.MassFraction X_liquid; + SI.MassFraction X_steam; + SI.MassFraction X_air; + + algorithm + + d_sat := saturationDensity(state.T); + X_liquid := max(state.d * state.X[Water] - d_sat, 0) / state.d; + X_steam := state.X[Water] - X_liquid; + X_air := 1 - state.X[Water]; + cp := steam.cp * X_steam + dryair.cp * X_air + water.cp * X_liquid; + + // cp := steam.cp*state.X[Water] + dryair.cp*(1-state.X[Water]); + annotation ( + Inline = false, + smoothOrder = 2, + Documentation( + info = " + The specific heat capacity at constant pressure cp is computed from temperature and composition for a mixture of steam (X[1]) and dry air. Solid water region is excluded. + ")); + + end specificHeatCapacityCp; + + redeclare function extends specificHeatCapacityCv + "Return specific heat capacity at constant volume as a function of the thermodynamic state record, only valide for phi<1" + + algorithm + + cv := (steam.cp - steam.R) * state.X[Water] + (dryair.cp - dryair.R) * (1 - state.X[Water]); + + annotation ( + Inline = true, + smoothOrder = 2, + Documentation( + info = " + The specific heat capacity at constant density cv is computed from temperature and composition for a mixture of steam (X[1]) and dry air. All water is assumed to be in the vapor state. + ")); + + end specificHeatCapacityCv; + + redeclare function extends dynamicViscosity + "Return dynamic viscosity as a function of the thermodynamic state record, valid from 123.15 K to 1273.15 K" + + import Modelica.Media.Incompressible.TableBased.Polynomials_Temp; + + algorithm + + eta := 1.81063e-5; + + annotation ( + smoothOrder = 5, + Documentation( + info = " +

        Dynamic viscosity is constant and the value is computed from the NIST at the reference temperature and pressure and for dry air

        + ")); + + end dynamicViscosity; + + redeclare function extends thermalConductivity + "Return thermal conductivity as a function of the thermodynamic state record, valid from 123.15 K to 1273.15 K" + + import Modelica.Media.Incompressible.TableBased.Polynomials_Temp; + import Cv = Modelica.SIunits.Conversions; + + algorithm + + lambda := 0.0258738; + + annotation ( + smoothOrder = 2, + Documentation( + info = " +

        Thermal conductivity is constant and the value is computed from the NIST at the reference temperature and pressure and for dry air

        + ")); + + end thermalConductivity; + + redeclare function extends velocityOfSound + + algorithm + + a := sqrt(isentropicExponent(state) * gasConstant(state) * temperature(state)); + + annotation ( + Documentation( + revisions = " +

        2012-01-12 Stefan Wischhusen: Initial Release.

        + ")); + + end velocityOfSound; + + redeclare function extends isobaricExpansionCoefficient + + algorithm + + beta := 1 / temperature(state); + + annotation ( + Documentation( + revisions = " +

        2012-01-12 Stefan Wischhusen: Initial Release.

        + ")); + + end isobaricExpansionCoefficient; + + redeclare function extends isothermalCompressibility + + algorithm + + kappa := 1 / pressure(state); + + annotation ( + Documentation( + revisions = " +

        2012-01-12 Stefan Wischhusen: Initial Release.

        + ")); + + end isothermalCompressibility; + + redeclare function extends isentropicEnthalpy + "Isentropic enthalpy (only valid for phi<1)" + + extends Modelica.Icons.Function; + + algorithm + + h_is := isentropicEnthalpyApproximation(p2 = p_downstream, state = refState); + + annotation (); + + end isentropicEnthalpy; + + package Utilities + "Utility functions" + + extends Modelica.Icons.UtilitiesPackage; + + function spliceFunction + "Spline interpolation of two functions" + + extends Modelica.Icons.Function; + input Real pos + "Returned value for x-deltax >= 0"; + input Real neg + "Returned value for x+deltax <= 0"; + input Real x + "Function argument"; + input Real deltax = 1 + "Region around x with spline interpolation"; + output Real out; + + protected + + Real scaledX; + Real scaledX1; + Real y; + + algorithm + + scaledX1 := x / deltax; + scaledX := scaledX1 * Modelica.Math.asin(1); + if scaledX1 <= (-0.999999999) then + y := 0; + elseif scaledX1 >= 0.999999999 then + y := 1; + else + y := (Modelica.Math.tanh(Modelica.Math.tan(scaledX)) + 1) / 2; + end if; + out := pos * y + (1 - y) * neg; + + annotation ( + derivative = spliceFunction_der); + + end spliceFunction; + + function spliceFunction_der + "Derivative of spliceFunction" + + extends Modelica.Icons.Function; + input Real pos; + input Real neg; + input Real x; + input Real deltax = 1; + input Real dpos; + input Real dneg; + input Real dx; + input Real ddeltax = 0; + output Real out; + + protected + + Real scaledX; + Real scaledX1; + Real dscaledX1; + Real y; + + algorithm + + scaledX1 := x / deltax; + scaledX := scaledX1 * Modelica.Math.asin(1); + dscaledX1 := (dx - scaledX1 * ddeltax) / deltax; + if scaledX1 <= (-0.99999999999) then + y := 0; + elseif scaledX1 >= 0.9999999999 then + y := 1; + else + y := (Modelica.Math.tanh(Modelica.Math.tan(scaledX)) + 1) / 2; + end if; + out := dpos * y + (1 - y) * dneg; + if abs(scaledX1) < 1 then + out := out + (pos - neg) * dscaledX1 * Modelica.Math.asin(1) / 2 / (Modelica.Math.cosh(Modelica.Math.tan(scaledX)) * Modelica.Math.cos(scaledX)) ^ 2; + end if; + + end spliceFunction_der; + + function smoothMax + + extends Modelica.Icons.Function; + import Modelica.Math; + input Real x1 + "First argument of smooth max operator"; + input Real x2 + "Second argument of smooth max operator"; + input Real dx + "Approximate difference between x1 and x2, below which regularization starts"; + output Real y + "Result of smooth max operator"; + + algorithm + + y := max(x1, x2) + Math.log(exp(4 / dx * (x1 - max(x1, x2))) + exp(4 / dx * (x2 - max(x1, x2)))) / (4 / dx); + + annotation ( + smoothOrder = 2, + Documentation( + info = " +

        An implementation of Kreisselmeier Steinhauser smooth maximum

        + ")); + + end smoothMax; + + function smoothMax_der + + extends Modelica.Icons.Function; + import Modelica.Math.exp; + import Modelica.Math.log; + input Real x1 + "First argument of smooth max operator"; + input Real x2 + "Second argument of smooth max operator"; + input Real dx + "Approximate difference between x1 and x2, below which regularization starts"; + input Real dx1; + input Real dx2; + input Real ddx; + output Real dy + "Derivative of smooth max operator"; + + algorithm + + dy := (if x1 > x2 then dx1 else dx2) + 0.25 * (((4 * (dx1 - (if x1 > x2 then dx1 else dx2)) / dx - 4 * (x1 - max(x1, x2)) * ddx / dx ^ 2) * exp(4 * (x1 - max(x1, x2)) / dx) + (4 * (dx2 - (if x1 > x2 then dx1 else dx2)) / dx - 4 * (x2 - max(x1, x2)) * ddx / dx ^ 2) * exp(4 * (x2 - max(x1, x2)) / dx)) * dx / (exp(4 * (x1 - max(x1, x2)) / dx) + exp(4 * (x2 - max(x1, x2)) / dx)) + log(exp(4 * (x1 - max(x1, x2)) / dx) + exp(4 * (x2 - max(x1, x2)) / dx)) * ddx); + + annotation ( + Documentation( + info = " +

        An implementation of Kreisselmeier Steinhauser smooth maximum

        + ")); + + end smoothMax_der; + + end Utilities; + +end MoistAir; diff --git a/Media/Air/MoistAir2.bak-mo b/src/TAeZoSysPro/Media/Air/MoistAir2.bak-mo similarity index 100% rename from Media/Air/MoistAir2.bak-mo rename to src/TAeZoSysPro/Media/Air/MoistAir2.bak-mo diff --git a/Media/Air/package.mo b/src/TAeZoSysPro/Media/Air/package.mo similarity index 97% rename from Media/Air/package.mo rename to src/TAeZoSysPro/Media/Air/package.mo index 13d3e26..7aa60ff 100644 --- a/Media/Air/package.mo +++ b/src/TAeZoSysPro/Media/Air/package.mo @@ -1,4 +1,6 @@ within TAeZoSysPro.Media; package Air + extends Modelica.Icons.VariantsPackage; + end Air; diff --git a/Media/Air/package.order b/src/TAeZoSysPro/Media/Air/package.order similarity index 100% rename from Media/Air/package.order rename to src/TAeZoSysPro/Media/Air/package.order diff --git a/src/TAeZoSysPro/Media/MyMedia/package.mo b/src/TAeZoSysPro/Media/MyMedia/package.mo new file mode 100644 index 0000000..0cbbc3b --- /dev/null +++ b/src/TAeZoSysPro/Media/MyMedia/package.mo @@ -0,0 +1,64 @@ +within TAeZoSysPro.Media; + +package MyMedia + + extends Modelica.Icons.Package; + + // inherite extend the package of the media to propagate it to all components using MyMedia as default media + //extends Modelica.Media.Air.ReferenceAir.Air_pT ; + extends Modelica.Media.Air.SimpleAir; + + //extends TAeZoSysPro.Media.Air.MoistAir ; + //extends Modelica.Media.Air.MoistAir ; + + annotation ( + Icon( + coordinateSystem(preserveAspectRatio = false, extent = {{-100, -100}, {100, 100}}), + graphics = { + Line( + points = {{-76, -80}, {-62, -30}, {-32, 40}, {4, 66}, {48, 66}, {73, 45}, {62, -8}, {48, -50}, {38, -80}}, + color = {64, 64, 64}, + smooth = Smooth.Bezier), + Line( + points = {{-40, 20}, {68, 20}}, + color = {175, 175, 175}), + Line( + points = {{-40, 20}, {-44, 88}, {-44, 88}}, + color = {175, 175, 175}), + Line( + points = {{68, 20}, {86, -58}}, + color = {175, 175, 175}), + Line( + points = {{-60, -28}, {56, -28}}, + color = {175, 175, 175}), + Line( + points = {{-60, -28}, {-74, 84}, {-74, 84}}, + color = {175, 175, 175}), + Line( + points = {{56, -28}, {70, -80}}, + color = {175, 175, 175}), + Line( + points = {{-76, -80}, {38, -80}}, + color = {175, 175, 175}), + Line( + points = {{-76, -80}, {-94, -16}, {-94, -16}}, + color = {175, 175, 175})}), + Documentation( + info = " + + MyMedia + + + +

        + The objective of this class is to be used as the default Medium in each module required the definition of a Medium . + This class is inherited of a Media (ReferenceAir, MoistAir, Air_H2 or any Media from the Modelica Standard Library or from TAeZoSysPro. +

        +

        + If the user want to change the media used, it can just change the inherited media and it is propagated to all components. +

        + + +")); + +end MyMedia; diff --git a/Media/MyMedia/package.order b/src/TAeZoSysPro/Media/MyMedia/package.order similarity index 100% rename from Media/MyMedia/package.order rename to src/TAeZoSysPro/Media/MyMedia/package.order diff --git a/Media/package.mo b/src/TAeZoSysPro/Media/package.mo similarity index 58% rename from Media/package.mo rename to src/TAeZoSysPro/Media/package.mo index b739e5c..1b66bac 100644 --- a/Media/package.mo +++ b/src/TAeZoSysPro/Media/package.mo @@ -2,11 +2,12 @@ within TAeZoSysPro; package Media -extends Modelica.Icons.Package; + extends Modelica.Icons.Package; -annotation (preferredView="info", - Documentation( - info=" + annotation ( + preferredView = "info", + Documentation( + info = "

        This library contains interface @@ -39,38 +40,40 @@ annotation (preferredView="info",

        Copyright © 1998-2019, Modelica Association and contributors

        -", - revisions=" +", + revisions = " "), - Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100,100}}), - graphics={ + Icon( + coordinateSystem(preserveAspectRatio = false, extent = {{-100, -100}, {100, 100}}), + graphics = { Line( - points = {{-76,-80},{-62,-30},{-32,40},{4,66},{48,66},{73,45},{62,-8},{48,-50},{38,-80}}, - color={64,64,64}, - smooth=Smooth.Bezier), + points = {{-76, -80}, {-62, -30}, {-32, 40}, {4, 66}, {48, 66}, {73, 45}, {62, -8}, {48, -50}, {38, -80}}, + color = {64, 64, 64}, + smooth = Smooth.Bezier), Line( - points={{-40,20},{68,20}}, - color={175,175,175}), + points = {{-40, 20}, {68, 20}}, + color = {175, 175, 175}), Line( - points={{-40,20},{-44,88},{-44,88}}, - color={175,175,175}), + points = {{-40, 20}, {-44, 88}, {-44, 88}}, + color = {175, 175, 175}), Line( - points={{68,20},{86,-58}}, - color={175,175,175}), + points = {{68, 20}, {86, -58}}, + color = {175, 175, 175}), Line( - points={{-60,-28},{56,-28}}, - color={175,175,175}), + points = {{-60, -28}, {56, -28}}, + color = {175, 175, 175}), Line( - points={{-60,-28},{-74,84},{-74,84}}, - color={175,175,175}), + points = {{-60, -28}, {-74, 84}, {-74, 84}}, + color = {175, 175, 175}), Line( - points={{56,-28},{70,-80}}, - color={175,175,175}), + points = {{56, -28}, {70, -80}}, + color = {175, 175, 175}), Line( - points={{-76,-80},{38,-80}}, - color={175,175,175}), + points = {{-76, -80}, {38, -80}}, + color = {175, 175, 175}), Line( - points={{-76,-80},{-94,-16},{-94,-16}}, - color={175,175,175})})); + points = {{-76, -80}, {-94, -16}, {-94, -16}}, + color = {175, 175, 175})})); + end Media; diff --git a/Media/package.order b/src/TAeZoSysPro/Media/package.order similarity index 100% rename from Media/package.order rename to src/TAeZoSysPro/Media/package.order diff --git a/ModelicaLicense2.mo b/src/TAeZoSysPro/ModelicaLicense2.mo similarity index 99% rename from ModelicaLicense2.mo rename to src/TAeZoSysPro/ModelicaLicense2.mo index 2156b42..ee9c612 100644 --- a/ModelicaLicense2.mo +++ b/src/TAeZoSysPro/ModelicaLicense2.mo @@ -3,8 +3,10 @@ within TAeZoSysPro; class ModelicaLicense2 extends Modelica.Icons.Information; - annotation( - Documentation(info = " + + annotation ( + Documentation( + info = " The Modelica License 2 + + + + + +

        + 1. What is PDE ?
        + 2. Package structure
        + 3. Use examples
        +

        + +
        + +

        1. What is PDE ?

        + +

        + The PDE package for Partial Derivative Equation is used to provide numerical schemes for the resolution of partial derivative equations such as transport equation or diffusion equation.
        + The time resolution scheme and its implicit or explicit character is taken in charge by the open modelica solver selected by the user before simulating. + The approach in this package is to proposed different numerical discrete schemes (central, upwind ... and first order, second order...) to model partial derivative other than temporal.
        + The PDE currently modelled are : +

        + +
          +
        • Transport equation with the Transport subpackage
        • + +
        • Thermal Diffusion equation with the ThermalDiffusion subpackage
        • +
        + +

        2. Package structure

        + +

        + The package is decomposed in subpackages for each kind of PDE. Each subpackage contains multiple models either having different spatial discrete scheme or simply that makes different assumptions. For example, the mathematical model for uncompressible or compressible transport is different.
        +

        + +
          +
        • Transport
        • +
            +
          • UpwindFirstOrder
          • +
          +
          +
        • ThermalDiffusion
        • +
            +
          • CentralSecondOrder
          • +
          +
        + + +

        3. Use examples

        + +

        +

          +
        • Transport: advection of the enthalpy through a pipe with incompressible water
        • + +
        • ThermalDiffusion: Thermal diffusion through a wall
        • +
        + +

        + + + +"), + Icon(coordinateSystem(initialScale = 0.1), graphics = {Bitmap(origin = {40.5, 22.5}, extent = {{-112.5, -112.5}, {67.5, 67.5}}, fileName = "modelica://TAeZoSysPro/Information/PDE/img_package.png")})); + +end PDE; diff --git a/src/TAeZoSysPro_testsuite/PDE/package.order b/src/TAeZoSysPro_testsuite/PDE/package.order new file mode 100644 index 0000000..251e4d4 --- /dev/null +++ b/src/TAeZoSysPro_testsuite/PDE/package.order @@ -0,0 +1,2 @@ +test_UpwindFirstOrder +test_CentralSecondOrder diff --git a/src/TAeZoSysPro_testsuite/PDE/test_CentralSecondOrder.mo b/src/TAeZoSysPro_testsuite/PDE/test_CentralSecondOrder.mo new file mode 100644 index 0000000..f41f184 --- /dev/null +++ b/src/TAeZoSysPro_testsuite/PDE/test_CentralSecondOrder.mo @@ -0,0 +1,62 @@ +within TAeZoSysPro_testsuite.PDE; +model test_CentralSecondOrder + "Boundary step diffusion" + + import Modelica.Constants.pi; + + constant Real std_dev = 0.05; + constant Real u_init = 0; + constant Real u_left = 20; + + parameter Integer N(quantity = "number of discrete layer", min = 11) = 11 + "Number of layer"; + parameter Modelica.SIunits.Length L = 1 + "length of the domain"; + parameter Real dx = L / N; + parameter Real x[N + 2] = cat(1, {0.0}, linspace(dx / 2, L - dx / 2, N), {L}); + parameter Real xbis[N + 2] = cat(1, {0.0}, linspace(dx / 2, L - dx / 2, N), {L}); + parameter Modelica.SIunits.DiffusionCoefficient Dth = 0.001; + Real[N + 2] u_1order; + Real[N + 2] u_analytic; + + TAeZoSysPro.PDE.ThermalDiffusion.CentralSecondOrder centralSecondOrder( + N = N, + x = linspace(0, L, N + 1), + CoeffTimeDer = 1, + CoeffSpaceDer = -Dth, + SourceTerm = zeros(N)) + annotation ( + Placement(visible = true, transformation(origin = {0, -2}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); + +initial equation + + // for i in 2:N+2-1 loop + // u_1order[i] = exp(-( (x[i] - L/2) / (2*std_dev) ) ^2) "Initial Condition" ; + // end for ; + + centralSecondOrder.u[2 : end - 1] = fill(u_init, N) + "Initial Condition"; + +equation + + // Analytical solution + for compt in 1 : N + 2 loop + u_analytic[compt] = u_left * (1 - x[compt] / L) - 2 * u_left / pi * sum(1 / i * exp(-(i * Dth ^ 0.5 * pi / L) ^ 2 * time) * sin(i * pi / L * x[compt]) for i in 1 : 30); + end for; + + // Boundary conditions + centralSecondOrder.u[1] = if initial() then u_init else u_left + "Left boundary condition"; + centralSecondOrder.u[end] = u_init + "Right boundary condition"; + + // PDE domain + //centralSecondOrder.SourceTerm = zeros(N); + u_1order = centralSecondOrder.u + annotation ( + experiment(StartTime = 0, StopTime = 300, Tolerance = 1e-06, Interval = 0.3)); + + annotation ( + experiment(StartTime = 0, StopTime = 300, Tolerance = 1e-6, Interval = 0.5)); + +end test_CentralSecondOrder; diff --git a/src/TAeZoSysPro_testsuite/PDE/test_UpwindFirstOrder.mo b/src/TAeZoSysPro_testsuite/PDE/test_UpwindFirstOrder.mo new file mode 100644 index 0000000..b944a16 --- /dev/null +++ b/src/TAeZoSysPro_testsuite/PDE/test_UpwindFirstOrder.mo @@ -0,0 +1,33 @@ +within TAeZoSysPro_testsuite.PDE; + +model test_UpwindFirstOrder + + parameter Modelica.SIunits.Length L = 1 + "Length of the domain"; + parameter Integer N = 5 + "Number of discrete layer"; + Modelica.SIunits.Velocity Vel; + TAeZoSysPro.PDE.Transport.UpwindFirstOrder transport(CoeffTimeDer = 1, CoeffSpaceDer = Vel, N = N, N_quantity = 2, x = linspace(0, L, N + 1), SourceTerm = fill(0.0, N)) + annotation ( + Placement(visible = true, transformation(origin = {0, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); + Modelica.Blocks.Sources.Pulse pulse(amplitude = -2, offset = 1, period = 4, startTime = 2) + annotation ( + Placement(visible = true, transformation(origin = {-60, 0}, extent = {{-20, -20}, {20, 20}}, rotation = 0))); + +initial equation + + transport.u[:, 1] = fill(0.0, N); + transport.u[:, 2] = fill(0.0, N); + +equation + + // + Vel = pulse.y; + // Boundary conditions + transport.u_ghost_left[:] = fill(1.0, 2); + transport.u_ghost_right[:] = fill(2.0, 2); + + annotation ( + experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-06, Interval = 0.002)); + +end test_UpwindFirstOrder; diff --git a/src/TAeZoSysPro_testsuite/package.mo b/src/TAeZoSysPro_testsuite/package.mo new file mode 100644 index 0000000..4838f38 --- /dev/null +++ b/src/TAeZoSysPro_testsuite/package.mo @@ -0,0 +1,3 @@ +package TAeZoSysPro_testsuite + +end TAeZoSysPro_testsuite; diff --git a/src/TAeZoSysPro_testsuite/package.order b/src/TAeZoSysPro_testsuite/package.order new file mode 100644 index 0000000..c364cae --- /dev/null +++ b/src/TAeZoSysPro_testsuite/package.order @@ -0,0 +1,4 @@ +HeatTransfer +FluidDynamics +Media +PDE