musica 0.12.1__cp310-cp310-win_arm64.whl → 0.12.2__cp310-cp310-win_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of musica might be problematic. Click here for more details.

Binary file
musica/_version.py CHANGED
@@ -1 +1 @@
1
- version = "0.12.1"
1
+ version = "0.12.2"
@@ -1 +1 @@
1
- from .examples import Examples
1
+ from .examples import Examples
@@ -11,6 +11,7 @@ import ussa1976
11
11
 
12
12
  available = musica.backend.carma_available()
13
13
 
14
+
14
15
  def run_carma_aluminum_example():
15
16
  group = musica.carma.CARMAGroupConfig(
16
17
  name="aluminum",
@@ -14,6 +14,7 @@ import musica
14
14
 
15
15
  available = musica.backend.carma_available()
16
16
 
17
+
17
18
  def run_carma_sulfate_example():
18
19
  """Test CARMA sulfate growth from gas condensation in a simple single grid box."""
19
20
 
@@ -272,8 +272,8 @@ def run_box_model():
272
272
  state.set_concentrations(initial_concentrations)
273
273
  state.set_user_defined_rate_parameters({"EMIS.SO2": np.full(NUMBER_OF_GRID_CELLS, 1.0e-8, dtype=np.float64)})
274
274
 
275
- # Run the simulation for 6 hours with a timestep of 30 seconds
276
- time_hours = 2.0
275
+ # Run the simulation for 30 minutes with a timestep of 30 seconds
276
+ time_hours = 0.5
277
277
  time_seconds = time_hours * np.float64(3600.0)
278
278
  dt = np.float64(30.0)
279
279
  num_steps = int(time_seconds / dt)
@@ -242,4 +242,4 @@ ax[2].set_ylabel('Air Density [kg m-3]')
242
242
  ax[2].set_xlabel('Grid Cell')
243
243
 
244
244
  fig.tight_layout()
245
- fig.savefig('ts1_latin_hypercube_conditions.png', dpi=300)
245
+ fig.savefig('ts1_latin_hypercube_conditions.png', dpi=300)
@@ -5,7 +5,8 @@ available = musica.backend.carma_available()
5
5
  pytestmark = pytest.mark.skipif(
6
6
  not available, reason="CARMA backend is not available")
7
7
 
8
+
8
9
  def test_carma_aluminum():
9
10
  from musica.examples import carma_aluminum
10
11
  state = carma_aluminum.run_carma_aluminum_example()
11
- assert state is not None, "State should not be None"
12
+ assert state is not None, "State should not be None"
@@ -5,6 +5,7 @@ available = musica.backend.carma_available()
5
5
  pytestmark = pytest.mark.skipif(
6
6
  not available, reason="CARMA backend is not available")
7
7
 
8
+
8
9
  def test_carma_sulfate():
9
10
  from musica.examples import carma_sulfate
10
11
  env_state, gas_state, bin_state = carma_sulfate.run_carma_sulfate_example()
@@ -13,4 +14,4 @@ def test_carma_sulfate():
13
14
  assert gas_state is not None, "Gas state should not be None"
14
15
  assert bin_state is not None, "Bin state should not be None"
15
16
  # Optionally, check expected dimensions or variables
16
- assert hasattr(bin_state, "mass_mixing_ratio"), "Bin state should have mass_mixing_ratio"
17
+ assert hasattr(bin_state, "mass_mixing_ratio"), "Bin state should have mass_mixing_ratio"
@@ -5,6 +5,7 @@ available = musica.backend.carma_available()
5
5
  pytestmark = pytest.mark.skipif(
6
6
  not available, reason="CARMA backend is not available")
7
7
 
8
+
8
9
  def test_sulfate_box_model():
9
10
  """Test the sulfate box model implementation."""
10
11
  from musica.examples import sulfate_box_model
@@ -31,4 +32,3 @@ def test_sulfate_box_model():
31
32
  print(f" Chemical species tracked: {list(concentrations.columns)}")
32
33
  print(f" CARMA bins: {len(sulfate_data.bin)}")
33
34
  print(f" Vertical levels: {len(sulfate_data.vertical_center)}")
34
-
@@ -0,0 +1,325 @@
1
+ """Tests for the State class."""
2
+ from __future__ import annotations
3
+ import pytest # type: ignore # pylint: disable=import-error
4
+ import numpy as np # type: ignore # pylint: disable=import-error
5
+ from musica.types import State, MICM
6
+ import musica.mechanism_configuration as mc
7
+ from musica.mechanism_configuration import Mechanism
8
+
9
+
10
+ def create_test_mechanism() -> Mechanism:
11
+ """Helper function to create a test mechanism."""
12
+ # Chemical species
13
+ A = mc.Species(
14
+ name="A",
15
+ diffusion_coefficient_m2_s=20.3,
16
+ molecular_weight_kg_mol=13.2,
17
+ other_properties={
18
+ "__absolute tolerance": "1.0e-30"})
19
+ B = mc.Species(name="B")
20
+ C = mc.Species(name="C")
21
+ M = mc.Species(name="M", is_third_body=True)
22
+
23
+ # Chemical phases
24
+ gas = mc.Phase(name="gas", species=[A, B, C, M])
25
+
26
+ # Reactions
27
+ my_arrhenius = mc.Arrhenius(
28
+ name="my arrhenius",
29
+ A=32.1, B=-2.3, C=102.3, D=63.4, E=-1.3,
30
+ gas_phase=gas,
31
+ reactants=[B],
32
+ products=[C],
33
+ other_properties={"__irrelevant": "2"},
34
+ )
35
+
36
+ my_other_arrhenius = mc.Arrhenius(
37
+ name="my other arrhenius",
38
+ A=29.3, B=-1.5, Ea=101.2, D=82.6, E=-0.98,
39
+ gas_phase=gas,
40
+ reactants=[A],
41
+ products=[(1.2, B)]
42
+ )
43
+
44
+ my_troe = mc.Troe(
45
+ name="my troe",
46
+ gas_phase=gas,
47
+ k0_A=1.2e-12,
48
+ k0_B=167,
49
+ k0_C=3,
50
+ kinf_A=136,
51
+ kinf_B=5,
52
+ kinf_C=24,
53
+ Fc=0.9,
54
+ N=0.8,
55
+ reactants=[B, A],
56
+ products=[C],
57
+ other_properties={"__irrelevant": "2"},
58
+ )
59
+
60
+ my_ternary = mc.TernaryChemicalActivation(
61
+ name="my ternary chemical activation",
62
+ gas_phase=gas,
63
+ k0_A=32.1,
64
+ k0_B=-2.3,
65
+ k0_C=102.3,
66
+ kinf_A=63.4,
67
+ kinf_B=-1.3,
68
+ kinf_C=908.5,
69
+ Fc=1.3,
70
+ N=32.1,
71
+ reactants=[B, A],
72
+ products=[C],
73
+ other_properties={"__irrelevant": "2"},
74
+ )
75
+
76
+ my_branched = mc.Branched(
77
+ name="my branched",
78
+ gas_phase=gas,
79
+ reactants=[A],
80
+ alkoxy_products=[B],
81
+ nitrate_products=[C],
82
+ X=1.2e-4,
83
+ Y=167,
84
+ a0=0.15,
85
+ n=9,
86
+ other_properties={"__irrelevant": "2"},
87
+ )
88
+
89
+ my_tunneling = mc.Tunneling(
90
+ name="my tunneling",
91
+ gas_phase=gas,
92
+ reactants=[B],
93
+ products=[C],
94
+ A=123.45,
95
+ B=1200.0,
96
+ C=1.0e8,
97
+ other_properties={"__irrelevant": "2"},
98
+ )
99
+
100
+ my_surface = mc.Surface(
101
+ name="my surface",
102
+ gas_phase=gas,
103
+ gas_phase_species=A,
104
+ reaction_probability=2.0e-2,
105
+ gas_phase_products=[B, C],
106
+ other_properties={"__irrelevant": "2"},
107
+ )
108
+
109
+ photo_b = mc.Photolysis(
110
+ name="photo B",
111
+ gas_phase=gas,
112
+ reactants=[B],
113
+ products=[C],
114
+ scaling_factor=12.3,
115
+ other_properties={"__irrelevant": "2"},
116
+ )
117
+
118
+ my_emission = mc.Emission(
119
+ name="my emission",
120
+ gas_phase=gas,
121
+ products=[B],
122
+ scaling_factor=12.3,
123
+ other_properties={"__irrelevant": "2"},
124
+ )
125
+
126
+ my_first_order_loss = mc.FirstOrderLoss(
127
+ name="my first order loss",
128
+ gas_phase=gas,
129
+ reactants=[C],
130
+ scaling_factor=12.3,
131
+ other_properties={"__irrelevant": "2"},
132
+ )
133
+
134
+ user_defined = mc.UserDefined(
135
+ name="my user defined",
136
+ gas_phase=gas,
137
+ reactants=[A, B],
138
+ products=[(1.3, C)],
139
+ scaling_factor=12.3,
140
+ other_properties={"__irrelevant": "2"}
141
+ )
142
+
143
+ # Mechanism
144
+ return mc.Mechanism(
145
+ name="Full Configuration",
146
+ species=[A, B, C, M],
147
+ phases=[gas],
148
+ reactions=[my_arrhenius, my_other_arrhenius, my_troe, my_ternary,
149
+ my_branched, my_tunneling, my_surface, photo_b,
150
+ my_emission, my_first_order_loss, user_defined],
151
+ version=mc.Version(1, 0, 0),
152
+ )
153
+
154
+
155
+ def get_test_solver(mech: Mechanism) -> MICM:
156
+ """Helper function to create a test solver."""
157
+ return MICM(mechanism=mech)
158
+
159
+
160
+ def test_state_initialization():
161
+ """Test State initialization with various grid cell configurations."""
162
+ # Use the test mechanism
163
+ mech = create_test_mechanism()
164
+
165
+ # Create MICM instance
166
+ solver = get_test_solver(mech)
167
+
168
+ # Test with valid input
169
+ state = solver.create_state(number_of_grid_cells=1)
170
+ assert isinstance(state, State)
171
+
172
+ # Test with multiple grid cells
173
+ state_multi = solver.create_state(number_of_grid_cells=3)
174
+ assert isinstance(state_multi, State)
175
+
176
+ # Test with invalid input
177
+ with pytest.raises(ValueError, match="number_of_grid_cells must be greater than 0"):
178
+ solver.create_state(number_of_grid_cells=0)
179
+
180
+
181
+ def test_set_get_concentrations():
182
+ """Test setting and getting concentrations."""
183
+ # Use the test mechanism
184
+ mech = create_test_mechanism()
185
+ solver = get_test_solver(mech)
186
+
187
+ # Test single grid cell
188
+ state = solver.create_state(number_of_grid_cells=1)
189
+ concentrations = {"A": 1.0, "B": 2.0, "C": 3.0}
190
+ state.set_concentrations(concentrations)
191
+ result = state.get_concentrations()
192
+ assert result["A"][0] == 1.0
193
+ assert result["B"][0] == 2.0
194
+ assert result["C"][0] == 3.0
195
+
196
+ # Test multiple grid cells
197
+ state_multi = solver.create_state(number_of_grid_cells=2)
198
+ concentrations_multi = {"A": [1.0, 2.0], "B": [3.0, 4.0], "C": [5.0, 6.0]}
199
+ state_multi.set_concentrations(concentrations_multi)
200
+ result_multi = state_multi.get_concentrations()
201
+ assert result_multi["A"] == [1.0, 2.0]
202
+ assert result_multi["B"] == [3.0, 4.0]
203
+ assert result_multi["C"] == [5.0, 6.0]
204
+
205
+ # Test invalid species
206
+ with pytest.raises(ValueError, match="Species D not found in the mechanism"):
207
+ state.set_concentrations({"D": 1.0})
208
+
209
+ # Test invalid length
210
+ with pytest.raises(ValueError, match="must have length"):
211
+ state_multi.set_concentrations({"A": [1.0]})
212
+
213
+ # Test cannot set third-body species
214
+ with pytest.raises(ValueError, match="Species M not found in the mechanism"):
215
+ state.set_concentrations({"M": 1.0})
216
+
217
+
218
+ def test_set_get_conditions():
219
+ """Test setting and getting environmental conditions."""
220
+ # Use the test mechanism
221
+ mech = create_test_mechanism()
222
+ solver = get_test_solver(mech)
223
+
224
+ # Test single grid cell
225
+ state = solver.create_state(number_of_grid_cells=1)
226
+ state.set_conditions(temperatures=300.0, pressures=101325.0)
227
+ conditions = state.get_conditions()
228
+ assert conditions["temperature"][0] == 300.0
229
+ assert conditions["pressure"][0] == 101325.0
230
+ assert np.isclose(conditions["air_density"][0], 40.9, rtol=0.1) # Approximate value from ideal gas law
231
+
232
+ # Test multiple grid cells
233
+ state_multi = solver.create_state(number_of_grid_cells=2)
234
+ state_multi.set_conditions(
235
+ temperatures=[300.0, 310.0],
236
+ pressures=[101325.0, 101325.0],
237
+ air_densities=[40.9, 39.5]
238
+ )
239
+ conditions_multi = state_multi.get_conditions()
240
+ assert conditions_multi["temperature"] == [300.0, 310.0]
241
+ assert conditions_multi["pressure"] == [101325.0, 101325.0]
242
+ assert conditions_multi["air_density"] == [40.9, 39.5]
243
+
244
+ # Test invalid input length
245
+ with pytest.raises(ValueError, match="must be a list of length"):
246
+ state_multi.set_conditions(temperatures=[300.0])
247
+
248
+
249
+ def test_set_get_user_defined_rate_parameters():
250
+ """Test setting and getting user-defined rate parameters."""
251
+ # Use the test mechanism which includes a user-defined reaction
252
+ mech = create_test_mechanism()
253
+ solver = get_test_solver(mech)
254
+
255
+ # Test single grid cell
256
+ state = solver.create_state(number_of_grid_cells=1)
257
+ params = {"EMIS.my emission": 1.0}
258
+ state.set_user_defined_rate_parameters(params)
259
+ result = state.get_user_defined_rate_parameters()
260
+ assert result["EMIS.my emission"][0] == 1.0
261
+
262
+ # Test multiple grid cells
263
+ state_multi = solver.create_state(number_of_grid_cells=2)
264
+ params_multi = {"PHOTO.photo B": [1.0, 2.0]}
265
+ state_multi.set_user_defined_rate_parameters(params_multi)
266
+ result_multi = state_multi.get_user_defined_rate_parameters()
267
+ assert result_multi["PHOTO.photo B"] == [1.0, 2.0]
268
+
269
+ # Test invalid parameter
270
+ with pytest.raises(ValueError, match="User-defined rate parameter invalid_param not found"):
271
+ state.set_user_defined_rate_parameters({"invalid_param": 1.0})
272
+
273
+ solver = get_test_solver(mech)
274
+
275
+ state = solver.create_state(number_of_grid_cells=1)
276
+
277
+ # Test species ordering
278
+ species_ordering = state.get_species_ordering()
279
+ assert isinstance(species_ordering, dict)
280
+ assert len(species_ordering) == 3 # A, B, C (M is third-body and not included)
281
+
282
+ # Dictionary style access
283
+ assert species_ordering["A"] >= 0
284
+ assert species_ordering["B"] >= 0
285
+ assert species_ordering["C"] >= 0
286
+
287
+ # Using get() method with default value
288
+ assert species_ordering.get("A", -1) >= 0 # returns value if key exists
289
+ assert species_ordering.get("Z", -1) == -1 # returns -1 since Z doesn't exist
290
+
291
+ # Test key membership
292
+ assert "A" in species_ordering
293
+ assert "B" in species_ordering
294
+ assert "C" in species_ordering
295
+ assert "M" not in species_ordering # third-body not included
296
+
297
+ # Test parameter ordering
298
+ param_ordering = state.get_user_defined_rate_parameters_ordering()
299
+ assert isinstance(param_ordering, dict)
300
+ assert len(param_ordering) == 6
301
+
302
+ # Convert dict keys to list using list() function
303
+ param_names = list(param_ordering.keys())
304
+ assert len(param_names) == 6
305
+ assert isinstance(param_names[0], str)
306
+
307
+ # Alternative way using list comprehension
308
+ param_names_alt = [key for key in param_ordering]
309
+ assert param_names_alt == param_names
310
+
311
+ # Sort the keys if needed - useful for consistent ordering in tests
312
+ sorted_param_names = sorted(param_ordering.keys())
313
+ assert len(sorted_param_names) == 6
314
+ assert all(isinstance(name, str) for name in sorted_param_names)
315
+
316
+ # Verify all expected keys are present
317
+ expected_params = [
318
+ "PHOTO.photo B",
319
+ "EMIS.my emission",
320
+ "LOSS.my first order loss",
321
+ "SURF.my surface.effective radius [m]",
322
+ "SURF.my surface.particle number concentration [# m-3]",
323
+ "USER.my user defined"
324
+ ]
325
+ assert sorted(expected_params) == sorted(param_names)
@@ -5,32 +5,17 @@ set -x
5
5
  target_arch="$(uname -m)"
6
6
  echo "Detected target_arch: $target_arch"
7
7
 
8
- # Set package manager based on architecture
9
- # x86_64 and aarch64 use manylinux_2_28 (AlmaLinux 8) with dnf
10
- # i686 uses manylinux2014 (CentOS 7) with yum
11
- if [ "$target_arch" = "i686" ]; then
12
- PKG_MGR="yum"
13
-
14
- # CentOS 7 is EOL, so we need to use vault.centos.org for i686 builds
15
- # Replace the repo files to point to vault.centos.org
16
- sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo
17
- sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*.repo
18
- else
19
- PKG_MGR="dnf"
20
- fi
21
-
22
- echo "Using package manager: $PKG_MGR"
23
-
24
- $PKG_MGR -y update
8
+ dnf -y update
25
9
 
26
- if [ "$target_arch" = "x86_64" ] || [ "$target_arch" = "aarch64" ]; then
27
- # For manylinux_2_28 (AlmaLinux 8), epel-release is required to get netcdf, for some reason
28
- $PKG_MGR install -y epel-release
29
- $PKG_MGR install -y netcdf-devel netcdf-fortran-devel
10
+ # For 64 bit systems can enable our fortran components, but we require netcdf
11
+ if [[ "$target_arch" == "x86_64" || "$target_arch" == "aarch64" ]]; then
12
+ dnf install -y epel-release
13
+ dnf install -y netcdf-devel netcdf-fortran-devel
30
14
  fi
31
15
 
32
- $PKG_MGR install -y tree wget zip lapack-devel
16
+ dnf install -y tree wget zip lapack-devel
33
17
 
18
+ # 64 bit intel and amd systems support building cuda
34
19
  if [ "$target_arch" = "x86_64" ]; then
35
20
  # Install CUDA 12.8 for x86_64 on AlmaLinux 8 (manylinux_2_28) - supports GCC 14
36
21
  dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo
@@ -44,7 +29,4 @@ if [ "$target_arch" = "x86_64" ]; then
44
29
  # Verify CUDA installation
45
30
  echo "=== CUDA Installation Verification ==="
46
31
  /usr/local/cuda/bin/nvcc --version
47
-
48
- # list the installed CUDA packages
49
- # tree -L 4 /usr/local/cuda
50
32
  fi
musica/types.py CHANGED
@@ -165,30 +165,31 @@ class State():
165
165
  k += 1
166
166
 
167
167
  def set_conditions(self,
168
- temperatures: Union[Union[float, int], List[Union[float, int]]],
169
- pressures: Union[Union[float, int], List[Union[float, int]]],
168
+ temperatures: Optional[Union[Union[float, int], List[Union[float, int]]]] = None,
169
+ pressures: Optional[Union[Union[float, int], List[Union[float, int]]]] = None,
170
170
  air_densities: Optional[Union[Union[float, int], List[Union[float, int]]]] = None):
171
171
  """
172
172
  Set the conditions for the state. The individual conditions can be a single value
173
173
  when solving for a single grid cell, or a list of values when solving for multiple grid cells.
174
174
  If air density is not provided, it will be calculated from the Ideal Gas Law using the provided
175
- temperature and pressure.
175
+ temperature and pressure. If temperature or pressure are not provided, their values will remain
176
+ unchanged.
176
177
 
177
178
  Parameters
178
179
  ----------
179
- temperatures : Union[float, List[float]]
180
+ temperatures : Optional[Union[float, List[float]]]
180
181
  Temperature in Kelvin.
181
- pressures : Union[float, List[float]]
182
+ pressures : Optional[Union[float, List[float]]]
182
183
  Pressure in Pascals.
183
184
  air_densities : Optional[Union[float, List[float]]]
184
185
  Air density in mol m-3. If not provided, it will be calculated from the Ideal Gas Law.
185
186
  """
186
- if isinstance(temperatures, float) or isinstance(temperatures, int):
187
+ if temperatures is not None and (isinstance(temperatures, float) or isinstance(temperatures, int)):
187
188
  if self.__number_of_grid_cells > 1:
188
189
  raise ValueError(
189
190
  f"temperatures must be a list of length {self.__number_of_grid_cells}.")
190
191
  temperatures = [temperatures]
191
- if isinstance(pressures, float) or isinstance(pressures, int):
192
+ if pressures is not None and (isinstance(pressures, float) or isinstance(pressures, int)):
192
193
  if self.__number_of_grid_cells > 1:
193
194
  raise ValueError(
194
195
  f"pressures must be a list of length {self.__number_of_grid_cells}.")
@@ -198,10 +199,10 @@ class State():
198
199
  raise ValueError(
199
200
  f"air_densities must be a list of length {self.__number_of_grid_cells}.")
200
201
  air_densities = [air_densities]
201
- if len(temperatures) != self.__number_of_grid_cells:
202
+ if temperatures is not None and len(temperatures) != self.__number_of_grid_cells:
202
203
  raise ValueError(
203
204
  f"temperatures must be a list of length {self.__number_of_grid_cells}.")
204
- if len(pressures) != self.__number_of_grid_cells:
205
+ if pressures is not None and len(pressures) != self.__number_of_grid_cells:
205
206
  raise ValueError(
206
207
  f"pressures must be a list of length {self.__number_of_grid_cells}.")
207
208
  if air_densities is not None and len(air_densities) != self.__number_of_grid_cells:
@@ -210,10 +211,10 @@ class State():
210
211
  k = 0
211
212
  for state in self.__states:
212
213
  for condition in state.conditions:
213
- condition.temperature = temperatures[k]
214
- condition.pressure = pressures[k]
215
- condition.air_density = air_densities[k] if air_densities is not None else pressures[k] / (
216
- GAS_CONSTANT * temperatures[k])
214
+ condition.temperature = temperatures[k] if temperatures is not None else condition.temperature
215
+ condition.pressure = pressures[k] if pressures is not None else condition.pressure
216
+ condition.air_density = air_densities[k] if air_densities is not None else condition.pressure / (
217
+ GAS_CONSTANT * condition.temperature)
217
218
  k += 1
218
219
 
219
220
  def get_concentrations(self) -> Dict[str, List[float]]:
@@ -334,11 +335,13 @@ class MICM():
334
335
  Mechanism object which specifies the chemical mechanism to use. If provided, this will be used
335
336
  to create the solver.
336
337
  solver_type : SolverType, optional
337
- Type of solver to use. If not provided, the default solver type will be used.
338
+ Type of solver to use. If not provided, the default Rosenbrock (with standard-ordered matrices) solver type will be used.
338
339
  ignore_non_gas_phases : bool, optional
339
340
  If True, non-gas phases will be ignored when configuring micm with the mechanism. This is only needed
340
341
  until micm properly supports non-gas phases. This option is only supported when passing in a mechanism.
341
342
  """
343
+ if solver_type is None:
344
+ solver_type = SolverType.rosenbrock_standard_order
342
345
  self.__solver_type = solver_type
343
346
  self.__vector_size = _vector_size(solver_type)
344
347
  if config_path is None and mechanism is None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: musica
3
- Version: 0.12.1
3
+ Version: 0.12.2
4
4
  Summary: MUSICA is a Python library for performing computational simulations in atmospheric chemistry.
5
5
  Author-Email: Matthew Dawsom <mattdawson@ucar.edu>, Jiwon Gim <jiwongim@ucar.edu>, David Fillmore <fillmore@ucar.edu>, Kyle Shores <kshores@ucar.edu>, Montek Thind <mthind@ucar.edu>
6
6
  Maintainer-Email: ACOM MUSICA Developers <musica-support@ucar.edu>
@@ -207,6 +207,7 @@ License: Apache License
207
207
  limitations under the License.
208
208
 
209
209
  Project-URL: homepage, https://wiki.ucar.edu/display/MUSICA/MUSICA+Home
210
+ Requires-Python: >=3.9
210
211
  Requires-Dist: pyyaml>=6.0.2
211
212
  Requires-Dist: xarray>=2022.3.0
212
213
  Requires-Dist: ussa1976>=v0.3.4
@@ -1,6 +1,6 @@
1
1
  musica/__init__.py,sha256=pSZ-H2IJ4EEYIbQDygjGwjhGySXdeifB1DzQBMJzz2g,403
2
- musica/_musica.cp310-win_amd64.pyd,sha256=thVujIHODau8317jEA113jURuckUBjqGY6kSxw4FCxQ,1667072
3
- musica/_version.py,sha256=RtCQ8kIuMhcZYVMe49ceaEtTSjdzpfPWuCJXoyjaKg0,20
2
+ musica/_musica.cp310-win_amd64.pyd,sha256=Qrd44IbVXubp2cowwL8wS8f1AMeLcB9-05P53QOrnFw,1671680
3
+ musica/_version.py,sha256=4bzF9LMIExRVigCODQ4A-chBc4NdBm0Fk_FjBxMRo9Q,20
4
4
  musica/backend.py,sha256=Fw3-HECqsifQmvRonDTGeEZqS-KXYD09BCwBue_HwfM,1081
5
5
  musica/binding_common.cpp,sha256=qrJCfdePt-ZoIgCTrPJqSUF1Ie8Mq7b7S2_pEdpi4CE,1013
6
6
  musica/binding_common.hpp,sha256=YAcb9WnfXL7Ps-rR-iMBSwUgBQZfZZdCQQod5CTMEZA,108
@@ -11,12 +11,12 @@ musica/constants.py,sha256=sQqh1UVu2HRvl25qWPW0ACT8NrHe_r4Ugy-v_BiTGG4,126
11
11
  musica/cpu_binding.cpp,sha256=Cy06zLErMV0g7Ol9Fg-q2cpG-g5fb8hcBl-M-ihHLyk,236
12
12
  musica/cuda.cpp,sha256=oTG2ZnL-SiW2kx9eL4XJOQGJeIiGuy8tJ5BEoLRWL4M,358
13
13
  musica/cuda.py,sha256=ClHKnSNiU8SX0BANh5KybismYHH6mFUyC-3r8S9qARo,271
14
- musica/examples/__init__.py,sha256=y9FNR3NhT9OYCk7S_kktyOSpkRqwQb-VLNiaMp0rbz0,30
15
- musica/examples/carma_aluminum.py,sha256=QTdJpcpvoyR4HbliFqfuEIwRHGT0v3NUjC9tiTv1mnc,3806
16
- musica/examples/carma_sulfate.py,sha256=_LgXOupxsLD6UkziRw40nDsDXPFbmKH-8VyPXaqnUD0,8363
14
+ musica/examples/__init__.py,sha256=hR0kZhoHfL9dcup7gg64HDJyIyAQqHAsip8LpuRNnI8,32
15
+ musica/examples/carma_aluminum.py,sha256=Q2IRvU9jxuKAUZvhQkTawVfZV0UADiMvXP-R6uzjemo,3808
16
+ musica/examples/carma_sulfate.py,sha256=MbV1oBrB6rc7yWMxbnYVr_SHlTMqd6uV21kwVhlUymY,8365
17
17
  musica/examples/examples.py,sha256=xWnFSNMYPpUhz04YtSSNsr6DoxmQoOdUtTT9GSUm3ps,5901
18
- musica/examples/sulfate_box_model.py,sha256=AlQ_30dMLf4wbs9pGWw6y9bxNUHLVIsdJlx9fbC-LKk,17107
19
- musica/examples/ts1_latin_hypercube.py,sha256=yQIUZJiNnJx5yF_pW9RWq9uZNECQagKDFJdEvl9-17w,9866
18
+ musica/examples/sulfate_box_model.py,sha256=LU1kJYtCZNV_4Mi8kJl2V7YQwQuP1dv8Ba4-2vhPFbE,17110
19
+ musica/examples/ts1_latin_hypercube.py,sha256=tLH9swPT4pvDnd7a86-xnt8PqXl4Y7bAXowsA0J7PV8,9868
20
20
  musica/gpu_binding.cpp,sha256=X0qISrKYz7Ldjn5UnqNw8oLzOY4VgyF3fUUszm-QSJI,240
21
21
  musica/main.py,sha256=gVCfeh44VL4EH7eFRR2wU_I_kANB94furojDi-0LhoE,2797
22
22
  musica/mechanism_configuration/__init__.py,sha256=odlwrCvBBnqUBi951RysExLDYqK_AfqP4nRY90MQpcc,40
@@ -47,23 +47,24 @@ musica/test/examples/v1/full_configuration/full_configuration.json,sha256=zBC3EV
47
47
  musica/test/examples/v1/full_configuration/full_configuration.yaml,sha256=XY6TW78rus0DyrI70NR3yvTeUIPff8_I9ErOXy2m3KE,5911
48
48
  musica/test/integration/test_analytical.py,sha256=eOPb3DtjQEodTZCpjelw1LQZM_VyhFi2TOlx1bmEtkk,14129
49
49
  musica/test/integration/test_carma.py,sha256=itPJNxSRp7FHJokYSicZFgqzBBrZ9dr1TDxawDPT9BM,7092
50
- musica/test/integration/test_carma_aluminum.py,sha256=qDbFtD7b1q7zW8I_8Fky9tQLevVrQ5DBLxeVyD5OEGY,364
51
- musica/test/integration/test_carma_sulfate.py,sha256=-xChTCI0eLFOWKNQx6KHq8RJ_KgU4cP1nP92_qHn0-M,755
50
+ musica/test/integration/test_carma_aluminum.py,sha256=F7_8xwZnKjSxgnZKdZR1tDwzwfVUiD7ZT1b_9cseE3M,368
51
+ musica/test/integration/test_carma_sulfate.py,sha256=OWQDLQNao5vU2FAMpWDVqs8xrFhpxvRfhx8HrP6GTCs,759
52
52
  musica/test/integration/test_chapman.py,sha256=t6p0CadUy-B4OP7A-EZ9Wz52diuYs5yc9LKiFUS9T6A,3651
53
- musica/test/integration/test_sulfate_box_model.py,sha256=3hb63Tij05VX__CIRT-njNkGgZp57Vo0ieUI7_DC1Fo,1638
53
+ musica/test/integration/test_sulfate_box_model.py,sha256=umqG0PAaCu27J3s5W_cnWJt9T_9EFox9z_JMHKNz5GI,1638
54
54
  musica/test/integration/test_tuvx.py,sha256=6MU5RrbNpX_I5VHTDUTreCGdL9c9y3voy68QurVazNI,1980
55
55
  musica/test/unit/test_parser.py,sha256=PF7GPddM4-Mbz0qjzqRvl_YSISj-VQR49MGXLfe8dDg,2667
56
56
  musica/test/unit/test_serializer.py,sha256=y6u_e2uJm9TGpn7B3x8_LobVGxIFyuKzF-WrIfP1Ewo,2527
57
+ musica/test/unit/test_state.py,sha256=he0cEVOS7fnWRP7cOzift5abSAwEWUC-eQ6V5deTgdM,10694
57
58
  musica/test/unit/test_util_full_mechanism.py,sha256=O7nJjpIt1k-pxUNj4zBiLdSXruyhj8qfbp8Me75kPJg,25915
58
- musica/tools/prepare_build_environment_linux.sh,sha256=IPNqU0d9cNJQkIU4L7bTO7kqBSUSq69wwPoLE-dU0AE,1671
59
+ musica/tools/prepare_build_environment_linux.sh,sha256=i69LuyY25KE-jFIFNuYC4_33_DGTngentBvt2Tbed9g,1017
59
60
  musica/tools/prepare_build_environment_macos.sh,sha256=Yhhd-8W6YvR79NabEqixexU6BsClNf7DH_EYYlsmeMo,41
60
61
  musica/tools/repair_wheel_gpu.sh,sha256=nQueyGNC2qWcBAicjVdAfB6JH4m_51dFOG83vVxke54,1525
61
62
  musica/tuvx.cpp,sha256=vvRi7T8TLZ-U8H7R-jrWIEmHBexXlms-0abhPGibnC8,3108
62
63
  musica/tuvx.py,sha256=6EDOULrBc2cojLgK-lNKH68YVHQyOFpBC-jkGYuaraY,6587
63
- musica/types.py,sha256=R7Iv3iNdp5V3sLABdsnKJm8ShEjY1LbSrjhPY-qe8mE,17029
64
- musica-0.12.1.dist-info/METADATA,sha256=IShAL_zZWoCFHuV_iXTdW9V9lcjy1QF_ADT_o1EGaIE,26322
65
- musica-0.12.1.dist-info/WHEEL,sha256=Luasc2BiJxWiaiM0E1hbP6g3pT0Vc_mN1IBvklTrOUk,106
66
- musica-0.12.1.dist-info/entry_points.txt,sha256=t9qRU9Ya63_yYMKJkTiVS5kCaW6dDDr0wuQ26lgXTH8,49
67
- musica-0.12.1.dist-info/licenses/AUTHORS.md,sha256=1ssAXR4WOMdfl5Or1raPu_2nxHbkwCpxfwJwzpF_cJM,2691
68
- musica-0.12.1.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
69
- musica-0.12.1.dist-info/RECORD,,
64
+ musica/types.py,sha256=zTqzaflhrwQqVMtwN_5eNxkvMis_QWAo3XwcNSpWEqs,17544
65
+ musica-0.12.2.dist-info/METADATA,sha256=FlXiev8ZTGt1gS9XbB3IKm4X5_jaDHB8dmMnUD29alg,26345
66
+ musica-0.12.2.dist-info/WHEEL,sha256=uMkeI2tSowhqEWYht1a0NP9-jXbaWqlBzws5ttgQOes,106
67
+ musica-0.12.2.dist-info/entry_points.txt,sha256=t9qRU9Ya63_yYMKJkTiVS5kCaW6dDDr0wuQ26lgXTH8,49
68
+ musica-0.12.2.dist-info/licenses/AUTHORS.md,sha256=1ssAXR4WOMdfl5Or1raPu_2nxHbkwCpxfwJwzpF_cJM,2691
69
+ musica-0.12.2.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
70
+ musica-0.12.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: scikit-build-core 0.11.5
2
+ Generator: scikit-build-core 0.11.6
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp310-cp310-win_arm64
5
5