Skip to content
TemperatureOfTwoMassesTest.md

TemperatureOfTwoMassesTest

This model connects 2 masses at different temperature. And, compares and tests initial and final temperatures of these masses. This components tests RelativeTemperatureSensor and TemperatureSensor.

Usage

TemperatureOfTwoMassesTest()

Variables

NameDescriptionUnits
final_TProjected final temperatureK

Behavior

[final_T(t)=mass1.Cmass1.T0+mass2.Cmass2.T0mass1.C+mass2.Cconnect(mass1+node,conduction+nodea)connect(conduction+nodeb,mass2+node)connect(mass1+node,relativetemperature_sensor+node_a)connect(mass2+node,relativetemperature_sensor+node_b)connect(mass1+node,temperaturesensor1+node)connect(mass2+node,temperaturesensor2+node)mass1.T(t)=mass1.node.T(t)dmass1.T(t)dt=mass1.dT(t)mass1.dT(t)=mass1.node.Q(t)mass1.Cmass2.T(t)=mass2.node.T(t)dmass2.T(t)dt=mass2.dT(t)mass2.dT(t)=mass2.node.Q(t)mass2.Cconduction.ΔT(t)=conduction.node_b.T(t)+conduction.node_a.T(t)conduction.node_a.Q(t)=conduction.Q(t)conduction.node_a.Q(t)+conduction.node_b.Q(t)=0conduction.Q(t)=conduction.Gconduction.ΔT(t)relative_temperature_sensor.T_rel(t)=relative_temperature_sensor.node_b.T(t)+relative_temperature_sensor.node_a.T(t)0=relative_temperature_sensor.node_a.Q(t)0=relative_temperature_sensor.node_b.Q(t)temperature_sensor1.T(t)=temperature_sensor1.node.T(t)temperature_sensor1.node.Q(t)=0temperature_sensor2.T(t)=temperature_sensor2.node.T(t)temperature_sensor2.node.Q(t)=0]

Source

dyad
# This model connects 2 masses at different temperature. And, compares and tests
# initial and final temperatures of these masses. This components tests
# `RelativeTemperatureSensor` and `TemperatureSensor`.
component TemperatureOfTwoMassesTest
  mass1 = HeatCapacitor(C=15, T0=373.15)
  mass2 = HeatCapacitor(C=15, T0=273.15)
  conduction = ThermalConductor(G=10)
  relative_temperature_sensor = RelativeTemperatureSensor()
  temperature_sensor1 = TemperatureSensor()
  temperature_sensor2 = TemperatureSensor()
  # Projected final temperature
  variable final_T::Temperature
relations
  final_T = (mass1.T0*mass1.C+mass2.T0*mass2.C)/(mass1.C+mass2.C)
  connect(mass1.node, conduction.node_a)
  connect(conduction.node_b, mass2.node)
  connect(mass1.node, relative_temperature_sensor.node_a)
  connect(mass2.node, relative_temperature_sensor.node_b)
  connect(mass1.node, temperature_sensor1.node)
  connect(mass2.node, temperature_sensor2.node)
metadata {
  "Dyad": {
    "tests": {
      "case1": {
        "stop": 10,
        "atol": {
          "mass1.T": 0.001,
          "mass2.T": 0.001,
          "temperature_sensor1.T": 0.001,
          "temperature_sensor2.T": 0.001,
          "relative_temperature_sensor.T_rel": 0.001
        },
        "expect": {
          "initial": {
            "temperature_sensor1.T": 373.15,
            "temperature_sensor2.T": 273.15,
            "relative_temperature_sensor.T_rel": 100
          },
          "signals": [
            "mass1.node.T",
            "mass2.node.T",
            "temperature_sensor1.T",
            "temperature_sensor2.T",
            "relative_temperature_sensor.T_rel"
          ]
        }
      }
    }
  }
}
end
Flattened Source
dyad
# This model connects 2 masses at different temperature. And, compares and tests
# initial and final temperatures of these masses. This components tests
# `RelativeTemperatureSensor` and `TemperatureSensor`.
component TemperatureOfTwoMassesTest
  mass1 = HeatCapacitor(C=15, T0=373.15)
  mass2 = HeatCapacitor(C=15, T0=273.15)
  conduction = ThermalConductor(G=10)
  relative_temperature_sensor = RelativeTemperatureSensor()
  temperature_sensor1 = TemperatureSensor()
  temperature_sensor2 = TemperatureSensor()
  # Projected final temperature
  variable final_T::Temperature
relations
  final_T = (mass1.T0*mass1.C+mass2.T0*mass2.C)/(mass1.C+mass2.C)
  connect(mass1.node, conduction.node_a)
  connect(conduction.node_b, mass2.node)
  connect(mass1.node, relative_temperature_sensor.node_a)
  connect(mass2.node, relative_temperature_sensor.node_b)
  connect(mass1.node, temperature_sensor1.node)
  connect(mass2.node, temperature_sensor2.node)
metadata {
  "Dyad": {
    "tests": {
      "case1": {
        "stop": 10,
        "atol": {
          "mass1.T": 0.001,
          "mass2.T": 0.001,
          "temperature_sensor1.T": 0.001,
          "temperature_sensor2.T": 0.001,
          "relative_temperature_sensor.T_rel": 0.001
        },
        "expect": {
          "initial": {
            "temperature_sensor1.T": 373.15,
            "temperature_sensor2.T": 273.15,
            "relative_temperature_sensor.T_rel": 100
          },
          "signals": [
            "mass1.node.T",
            "mass2.node.T",
            "temperature_sensor1.T",
            "temperature_sensor2.T",
            "relative_temperature_sensor.T_rel"
          ]
        }
      }
    }
  }
}
end


Test Cases

This is setup code, that must be run before each test case.

julia
using ThermalComponents
using ModelingToolkit, OrdinaryDiffEqDefault
using Plots
using CSV, DataFrames

snapshotsdir = joinpath(dirname(dirname(pathof(ThermalComponents))), "test", "snapshots")
"/home/actions-runner-10/.julia/packages/ThermalComponents/uOuoD/test/snapshots"

Test Case case1

julia
@mtkbuild model_case1 = TemperatureOfTwoMassesTest()
u0_case1 = []
prob_case1 = ODEProblem(model_case1, u0_case1, (0, 10))
sol_case1 = solve(prob_case1)
retcode: Success
Interpolation: 3rd order Hermite
t: 13-element Vector{Float64}:
  0.0
  0.12852257621377688
  0.40388073519675033
  0.7558959151874505
  1.2017065290241797
  1.7472127954612833
  2.41175526467351
  3.2154719304092416
  4.194626799120885
  5.400956628278131
  6.920461137209956
  8.891523440959105
 10.0
u: 13-element Vector{Vector{Float64}}:
 [373.15, 273.15]
 [365.27576601244925, 281.0242339875507]
 [352.3309401096164, 293.96905989038356]
 [341.3999881466141, 304.9000118533859]
 [333.22203237264114, 313.0779676273588]
 [328.01698475213857, 318.2830152478614]
 [325.1570266683663, 321.14297333163364]
 [323.8380120480997, 322.46198795190026]
 [323.3373737769399, 322.96262622306006]
 [323.18851196092044, 323.1114880390795]
 [323.1560437453017, 323.14395625469825]
 [323.1512985261476, 323.1487014738523]
 [323.1503001213291, 323.14969987867084]
julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.mass1.node.T])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "TemperatureOfTwoMassesTest_case1_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.mass1.node.T], width=2, label="Actual value of mass1.node.T")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of mass1.node.T")
end

plt

julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.mass2.node.T])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "TemperatureOfTwoMassesTest_case1_sig1.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.mass2.node.T], width=2, label="Actual value of mass2.node.T")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of mass2.node.T")
end

plt

julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.temperature_sensor1.T])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "TemperatureOfTwoMassesTest_case1_sig2.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.temperature_sensor1.T], width=2, label="Actual value of temperature_sensor1.T")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of temperature_sensor1.T")
end
scatter!(plt, [df_case1.t[1]], [373.15], label="Initial Condition for `temperature_sensor1.T`")

plt

julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.temperature_sensor2.T])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "TemperatureOfTwoMassesTest_case1_sig3.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.temperature_sensor2.T], width=2, label="Actual value of temperature_sensor2.T")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of temperature_sensor2.T")
end
scatter!(plt, [df_case1.t[1]], [273.15], label="Initial Condition for `temperature_sensor2.T`")

plt

julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.relative_temperature_sensor.T_rel])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "TemperatureOfTwoMassesTest_case1_sig4.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.relative_temperature_sensor.T_rel], width=2, label="Actual value of relative_temperature_sensor.T_rel")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of relative_temperature_sensor.T_rel")
end
scatter!(plt, [df_case1.t[1]], [100], label="Initial Condition for `relative_temperature_sensor.T_rel`")

plt

  • Examples

  • Experiments

  • Analyses