praiteri commited on
Commit
cee3d25
·
1 Parent(s): 6935076
marimo/docs/LabManualCHEM2000-1.pdf CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:f48be468f7985a539350b9bfdf596b3741b6282672e6377a53a09161e14d28eb
3
- size 4004997
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f364d817342f54021293b252d540252f283f25a0c17223106b23a1152192bf1d
3
+ size 4005337
src/pycek_public/bomb_calorimetry.py CHANGED
@@ -2,17 +2,17 @@ import pycek_public as cek
2
  import numpy as np
3
  import pprint as pp
4
 
 
5
  class bomb_calorimetry(cek.cek_labs):
6
  def setup_lab(self):
7
  """
8
  Define base information for the lab
9
  """
10
- self.add_metadata(
11
- laboratory = 'Bomb Calorimetry',
12
- columns = ["Time (s)","Temperature (K)"]
13
- )
14
 
15
- self.available_samples = ['benzoic', 'sucrose', 'naphthalene']
16
 
17
  self.ignition_time = 20
18
  self.relaxation_time = 3
@@ -20,45 +20,45 @@ class bomb_calorimetry(cek.cek_labs):
20
  self.noise_level = 0.1
21
  self.precision = 2
22
 
23
- self.slope_before = np.random.uniform(0., self.noise_level) / 3
24
- self.slope_after = np.random.uniform(0., self.noise_level) / 3
25
-
26
  self.RT = self.R * self.temperature
27
-
28
  # calorimeter constant (J/K)
29
- self.calorimeter_constant = {'value':10135,'std_error':0.0}
30
  self.sample_parameters["co2"] = {
31
- "mM" : 44.01,
32
- "dH" : -393.51e3, # co2 enthapy of formation (J/mol/K)
33
  }
34
  self.sample_parameters["h2o"] = {
35
- "mM" : 18.015,
36
- "dH" : -285.83e3,# h2o enthapy of formation (J/mol/K)
37
- }
38
-
39
  self.sample_parameters["benzoic"] = {
40
- "mM" : 122.123,
41
- "n1" : 7,
42
- "n2" : 3,
43
- "dn" : 7-15/2,
44
- "dHf" : {'value':-384.8e3,'std_error':0.5e3},
45
- "dHc" : {'value':-3227.26e3,'std_error':0.2e3},
46
  }
47
  self.sample_parameters["sucrose"] = {
48
- "mM" : 342.3,
49
- "n1" : 12,
50
- "n2" : 11,
51
- "dn" : 0,
52
- "dHf" : {'value':-2221.2e3,'std_error':0.2e3},
53
- "dHc" : {'value':-5643.4e3,'std_error':1.8e3},
54
  }
55
  self.sample_parameters["naphthalene"] = {
56
- "mM" : 128.17,
57
- "n1" : 10,
58
- "n2" : 4,
59
- "dn" : 10 - 12,
60
- "dHf" : {'value':77e3,'std_error':10.0e3},
61
- "dHc" : {'value':-5160e3,'std_error':20.0e3},
62
  }
63
 
64
  def create_data(self):
@@ -68,50 +68,56 @@ class bomb_calorimetry(cek.cek_labs):
68
  if self.sample is None:
69
  raise Exception("Sample not defined")
70
 
71
- prm = self.sample_parameters[ self.sample ]
72
 
73
- self.set_parameters(
74
- sample = self.sample,
75
- number_of_values = self.number_of_values,
76
- )
77
 
78
  self.mass = np.random.normal(1000, 100)
79
- self.add_metadata(**{
80
- 'Tablet mass (mg)': self.mass,
81
- "Ignition time (s)" : self.ignition_time,
82
- "Sample" : self.sample,
83
- })
 
 
84
 
85
  moles = self.mass / 1000 / prm["mM"]
86
 
87
  # combustion enthalpy
88
  # nH{co2} + mH{h2o} - H = DcH
89
- DcH = prm["n1"] * self.sample_parameters["co2"]["dH"] + \
90
- prm["n2"] * self.sample_parameters["h2o"]["dH"] - prm["dHf"]["value"]
 
 
 
91
 
92
  dH = DcH * moles
93
  dnrt = moles * self.RT * prm["dn"]
94
  dU = dH - dnrt
95
-
96
- deltaT = -dU / self.calorimeter_constant['value']
97
 
98
  x = np.linspace(0, self.number_of_values, self.number_of_values)
99
  y = np.random.normal(0, self.noise_level, self.number_of_values)
100
 
101
- x = self._round_values(x,precision=0)
102
 
103
- dd = 0.
104
  T = self.temperature
105
  for i in range(self.number_of_values):
106
  if i < self.ignition_time:
107
- T += self.slope_before
108
- else:
109
  T += self.slope_after
110
- dd = deltaT * (1 - np.exp( - (i - self.ignition_time) / self.relaxation_time) )
111
- y[i] += T + dd
 
 
112
 
113
  y = self._round_values(y)
114
- self.data = np.column_stack((x,y))
115
 
116
  return self.data
117
-
 
2
  import numpy as np
3
  import pprint as pp
4
 
5
+
6
  class bomb_calorimetry(cek.cek_labs):
7
  def setup_lab(self):
8
  """
9
  Define base information for the lab
10
  """
11
+ self.add_metadata(
12
+ laboratory="Bomb Calorimetry", columns=["Time (s)", "Temperature (K)"]
13
+ )
 
14
 
15
+ self.available_samples = ["benzoic", "sucrose", "naphthalene"]
16
 
17
  self.ignition_time = 20
18
  self.relaxation_time = 3
 
20
  self.noise_level = 0.1
21
  self.precision = 2
22
 
23
+ self.slope_before = np.random.uniform(0.0, self.noise_level) / 3
24
+ self.slope_after = np.random.uniform(0.0, self.noise_level) / 3
25
+
26
  self.RT = self.R * self.temperature
27
+
28
  # calorimeter constant (J/K)
29
+ self.calorimeter_constant = {"value": 10135, "std_error": 0.0}
30
  self.sample_parameters["co2"] = {
31
+ "mM": 44.01,
32
+ "dH": -393.51e3, # co2 enthapy of formation (J/mol/K)
33
  }
34
  self.sample_parameters["h2o"] = {
35
+ "mM": 18.015,
36
+ "dH": -285.83e3, # h2o enthapy of formation (J/mol/K)
37
+ }
38
+
39
  self.sample_parameters["benzoic"] = {
40
+ "mM": 122.123,
41
+ "n1": 7,
42
+ "n2": 3,
43
+ "dn": 7 - 15 / 2,
44
+ "dHf": {"value": -384.8e3, "std_error": 0.5e3},
45
+ "dHc": {"value": -3227.26e3, "std_error": 0.2e3},
46
  }
47
  self.sample_parameters["sucrose"] = {
48
+ "mM": 342.3,
49
+ "n1": 12,
50
+ "n2": 11,
51
+ "dn": 0,
52
+ "dHf": {"value": -2221.2e3, "std_error": 0.2e3},
53
+ "dHc": {"value": -5643.4e3, "std_error": 1.8e3},
54
  }
55
  self.sample_parameters["naphthalene"] = {
56
+ "mM": 128.17,
57
+ "n1": 10,
58
+ "n2": 4,
59
+ "dn": 10 - 12,
60
+ "dHf": {"value": 77e3, "std_error": 10.0e3},
61
+ "dHc": {"value": -5160e3, "std_error": 20.0e3},
62
  }
63
 
64
  def create_data(self):
 
68
  if self.sample is None:
69
  raise Exception("Sample not defined")
70
 
71
+ prm = self.sample_parameters[self.sample]
72
 
73
+ self.set_parameters(
74
+ sample=self.sample,
75
+ number_of_values=self.number_of_values,
76
+ )
77
 
78
  self.mass = np.random.normal(1000, 100)
79
+ self.add_metadata(
80
+ **{
81
+ "Tablet mass (mg)": f"{self.mass:.1f}",
82
+ "Ignition time (s)": self.ignition_time,
83
+ "Sample": self.sample,
84
+ }
85
+ )
86
 
87
  moles = self.mass / 1000 / prm["mM"]
88
 
89
  # combustion enthalpy
90
  # nH{co2} + mH{h2o} - H = DcH
91
+ DcH = (
92
+ prm["n1"] * self.sample_parameters["co2"]["dH"]
93
+ + prm["n2"] * self.sample_parameters["h2o"]["dH"]
94
+ - prm["dHf"]["value"]
95
+ )
96
 
97
  dH = DcH * moles
98
  dnrt = moles * self.RT * prm["dn"]
99
  dU = dH - dnrt
100
+
101
+ deltaT = -dU / self.calorimeter_constant["value"]
102
 
103
  x = np.linspace(0, self.number_of_values, self.number_of_values)
104
  y = np.random.normal(0, self.noise_level, self.number_of_values)
105
 
106
+ x = self._round_values(x, precision=0)
107
 
108
+ dd = 0.0
109
  T = self.temperature
110
  for i in range(self.number_of_values):
111
  if i < self.ignition_time:
112
+ T += self.slope_before
113
+ else:
114
  T += self.slope_after
115
+ dd = deltaT * (
116
+ 1 - np.exp(-(i - self.ignition_time) / self.relaxation_time)
117
+ )
118
+ y[i] += T + dd
119
 
120
  y = self._round_values(y)
121
+ self.data = np.column_stack((x, y))
122
 
123
  return self.data