musica 0.10.1__cp37-cp37m-win32.whl → 0.11.1__cp37-cp37m-win32.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.
- _musica.cp37-win32.pyd +0 -0
- lib/musica.lib +0 -0
- lib/yaml-cpp.lib +0 -0
- musica/CMakeLists.txt +41 -0
- musica/__init__.py +3 -0
- musica/_version.py +1 -1
- musica/binding.cpp +19 -0
- musica/mechanism_configuration.cpp +519 -0
- musica/mechanism_configuration.py +1291 -0
- musica/musica.cpp +211 -0
- musica/test/examples/v0/config.json +7 -0
- musica/test/examples/v0/config.yaml +3 -0
- musica/test/examples/v0/reactions.json +193 -0
- musica/test/examples/v0/reactions.yaml +142 -0
- musica/test/examples/v0/species.json +40 -0
- musica/test/examples/v0/species.yaml +19 -0
- musica/test/examples/v1/full_configuration.json +434 -0
- musica/test/examples/v1/full_configuration.yaml +271 -0
- musica/test/test_analytical.py +323 -0
- musica/test/test_chapman.py +123 -0
- musica/test/test_parser.py +693 -0
- musica/test/tuvx.py +10 -0
- musica/tools/prepare_build_environment_linux.sh +21 -0
- musica/tools/prepare_build_environment_windows.sh +22 -0
- musica/types.py +362 -0
- {musica-0.10.1.dist-info → musica-0.11.1.dist-info}/METADATA +19 -1
- musica-0.11.1.dist-info/RECORD +29 -0
- lib/mechanism_configuration.lib +0 -0
- musica-0.10.1.dist-info/RECORD +0 -9
- musica.cp37-win32.pyd +0 -0
- {musica-0.10.1.dist-info → musica-0.11.1.dist-info}/WHEEL +0 -0
- {musica-0.10.1.dist-info → musica-0.11.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#! /bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
set -x
|
|
5
|
+
|
|
6
|
+
# Cuda can only be installed on x86_64 architecture.
|
|
7
|
+
if [ "$(uname -m)" == "x86_64" ]; then
|
|
8
|
+
# Install CUDA 12.2:
|
|
9
|
+
yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo
|
|
10
|
+
# error mirrorlist.centos.org doesn't exists anymore.
|
|
11
|
+
sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
|
|
12
|
+
sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo
|
|
13
|
+
sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo
|
|
14
|
+
yum install --setopt=obsoletes=0 -y \
|
|
15
|
+
cuda-nvcc-12-2-12.2.140-1 \
|
|
16
|
+
cuda-cudart-devel-12-2-12.2.140-1 \
|
|
17
|
+
libcurand-devel-12-2-10.3.3.141-1 \
|
|
18
|
+
libcublas-devel-12-2-12.2.5.6-1 \
|
|
19
|
+
libnccl-devel-2.19.3-1+cuda12.2
|
|
20
|
+
ln -s cuda-12.2 /usr/local/cuda
|
|
21
|
+
fi
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#! /bin/bash
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
set -x
|
|
5
|
+
|
|
6
|
+
CUDA_ROOT="C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.8"
|
|
7
|
+
# curl --netrc-optional -L -nv -o cuda.exe https://developer.download.nvidia.com/compute/cuda/12.2.2/local_installers/cuda_12.2.2_537.13_windows.exe
|
|
8
|
+
curl --netrc-optional -L -nv -o cuda.exe https://developer.download.nvidia.com/compute/cuda/12.8.1/local_installers/cuda_12.8.1_572.61_windows.exe
|
|
9
|
+
./cuda.exe -s nvcc_12.8 cudart_12.8 cublas_dev_12.8 curand_dev_12.8
|
|
10
|
+
rm cuda.exe
|
|
11
|
+
|
|
12
|
+
export CUDA_PATH="/c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.8"
|
|
13
|
+
export PATH="$CUDA_PATH/bin:$PATH"
|
|
14
|
+
|
|
15
|
+
ls "c/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.8/extras/visual_studio_integration/MSBuildExtensions"
|
|
16
|
+
ls "c/Program Files (x86)/Microsoft Visual Studio/"
|
|
17
|
+
|
|
18
|
+
# choco install cuda
|
|
19
|
+
|
|
20
|
+
ls "$CUDA_PATH"
|
|
21
|
+
ls "$CUDA_PATH/bin"
|
|
22
|
+
which nvcc.exe
|
musica/types.py
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# Copyright (C) 2023-2025 University Corporation for Atmospheric Research
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# This file is part of the musica Python package.
|
|
5
|
+
# For more information, see the LICENSE file in the top-level directory of this distribution.
|
|
6
|
+
from typing import Optional, Any, Dict, List, Union, Tuple
|
|
7
|
+
from os import PathLike
|
|
8
|
+
import math
|
|
9
|
+
from _musica._core import (
|
|
10
|
+
_Conditions,
|
|
11
|
+
_SolverType,
|
|
12
|
+
_Solver,
|
|
13
|
+
_State,
|
|
14
|
+
_create_solver,
|
|
15
|
+
_create_solver_from_mechanism,
|
|
16
|
+
_create_state,
|
|
17
|
+
_micm_solve,
|
|
18
|
+
_vector_size,
|
|
19
|
+
_species_ordering,
|
|
20
|
+
_user_defined_rate_parameters_ordering,
|
|
21
|
+
)
|
|
22
|
+
import musica.mechanism_configuration as mc
|
|
23
|
+
|
|
24
|
+
AVOGADRO = 6.02214076e23 # mol^-1
|
|
25
|
+
BOLTZMANN = 1.380649e-23 # J K^-1
|
|
26
|
+
GAS_CONSTANT = AVOGADRO * BOLTZMANN # J K^-1 mol^-1
|
|
27
|
+
|
|
28
|
+
FilePath = Union[str, "PathLike[str]"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _get_vector_matrix_indices(row_index: int, column_index: int, vector_size: int) -> Tuple[int, int]:
|
|
32
|
+
"""
|
|
33
|
+
Get the row and column indices for a matrix given the row and column indices for a vector.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
row_index : int
|
|
38
|
+
Row index of the vector.
|
|
39
|
+
column_index : int
|
|
40
|
+
Column index of the vector.
|
|
41
|
+
vector_size : int
|
|
42
|
+
Size of the vector.
|
|
43
|
+
|
|
44
|
+
Returns
|
|
45
|
+
-------
|
|
46
|
+
tuple[int, int]
|
|
47
|
+
Index for which state matrix to use and the index in that matrix'x underlying data vector.
|
|
48
|
+
"""
|
|
49
|
+
return (row_index // vector_size, column_index * (vector_size - 1) + row_index % vector_size)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Conditions(_Conditions):
|
|
53
|
+
"""
|
|
54
|
+
Conditions class for the MICM solver. If air density is not provided,
|
|
55
|
+
it will be calculated from the Ideal Gas Law using the provided temperature and pressure.
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
temperature : float
|
|
60
|
+
Temperature in Kelvin.
|
|
61
|
+
pressure : float
|
|
62
|
+
Pressure in Pascals.
|
|
63
|
+
air_density : float
|
|
64
|
+
Air density in mol m-3
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
def __init__(
|
|
68
|
+
self,
|
|
69
|
+
temperature: Optional[Union[float, int]] = None,
|
|
70
|
+
pressure: Optional[Union[float, int]] = None,
|
|
71
|
+
air_density: Optional[Union[float, int]] = None,
|
|
72
|
+
):
|
|
73
|
+
super().__init__()
|
|
74
|
+
if temperature is not None:
|
|
75
|
+
self.temperature = temperature
|
|
76
|
+
if pressure is not None:
|
|
77
|
+
self.pressure = pressure
|
|
78
|
+
if air_density is not None:
|
|
79
|
+
self.air_density = air_density
|
|
80
|
+
elif temperature is not None and pressure is not None:
|
|
81
|
+
self.air_density = 1.0 / (GAS_CONSTANT * temperature / pressure)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class SolverType(_SolverType):
|
|
85
|
+
"""
|
|
86
|
+
Enum class for the type of solver to use.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class State():
|
|
91
|
+
"""
|
|
92
|
+
State class for the MICM solver. It contains the initial conditions and species concentrations.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
def __init__(self, solver: _Solver, number_of_grid_cells: int, vector_size: int = 0):
|
|
96
|
+
if number_of_grid_cells < 1:
|
|
97
|
+
raise ValueError("number_of_grid_cells must be greater than 0.")
|
|
98
|
+
super().__init__()
|
|
99
|
+
self.__states = [
|
|
100
|
+
_create_state(solver, min(vector_size, number_of_grid_cells - i * vector_size))
|
|
101
|
+
for i in range(math.ceil(number_of_grid_cells / vector_size))
|
|
102
|
+
] if vector_size > 0 else [_create_state(solver, number_of_grid_cells)]
|
|
103
|
+
self.__species_ordering = _species_ordering(self.__states[0])
|
|
104
|
+
self.__user_defined_rate_parameters_ordering = _user_defined_rate_parameters_ordering(self.__states[0])
|
|
105
|
+
self.__number_of_grid_cells = number_of_grid_cells
|
|
106
|
+
self.__vector_size = vector_size
|
|
107
|
+
|
|
108
|
+
def get_internal_states(self) -> List[_State]:
|
|
109
|
+
"""
|
|
110
|
+
Get the internal states of the MICM solver.
|
|
111
|
+
|
|
112
|
+
Returns
|
|
113
|
+
-------
|
|
114
|
+
List[_State]
|
|
115
|
+
List of internal states.
|
|
116
|
+
"""
|
|
117
|
+
return self.__states
|
|
118
|
+
|
|
119
|
+
def set_concentrations(self, concentrations: Dict[str, Union[Union[float, int], List[Union[float, int]]]]):
|
|
120
|
+
"""
|
|
121
|
+
Set the concentrations of the species in the state. Any species not in the
|
|
122
|
+
dictionary will be set to zero. The concentrations can be a single value when solving
|
|
123
|
+
for a single grid cell, or a list of values when solving for multiple grid cells.
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
concentrations : Dict[str, Union[Union[float, int], List[Union[float, int]]]]
|
|
128
|
+
Dictionary of species names and their concentrations.
|
|
129
|
+
"""
|
|
130
|
+
for name, value in concentrations.items():
|
|
131
|
+
if name not in self.__species_ordering:
|
|
132
|
+
raise ValueError(f"Species {name} not found in the mechanism.")
|
|
133
|
+
i_species = self.__species_ordering[name]
|
|
134
|
+
if isinstance(value, float) or isinstance(value, int):
|
|
135
|
+
value = [value]
|
|
136
|
+
if len(value) != self.__number_of_grid_cells:
|
|
137
|
+
raise ValueError(f"Concentration list for {name} must have length {self.__number_of_grid_cells}.")
|
|
138
|
+
# Counter 'k' is used to map grid cell indices across multiple state segments.
|
|
139
|
+
k = 0
|
|
140
|
+
for state in self.__states:
|
|
141
|
+
cell_stride, species_stride = state.concentration_strides()
|
|
142
|
+
for i_cell in range(state.number_of_grid_cells()):
|
|
143
|
+
state.concentrations[i_species * species_stride + i_cell * cell_stride] = value[k]
|
|
144
|
+
k += 1
|
|
145
|
+
|
|
146
|
+
def set_user_defined_rate_parameters(
|
|
147
|
+
self, user_defined_rate_parameters: Dict[str, Union[Union[float, int], List[Union[float, int]]]]):
|
|
148
|
+
"""
|
|
149
|
+
Set the user-defined rate parameters in the state. Any parameter not in the
|
|
150
|
+
dictionary will be set to zero. The parameters can be a single value when solving
|
|
151
|
+
for a single grid cell, or a list of values when solving for multiple grid cells.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
user_defined_rate_parameters : Dict[str, Union[Union[float, int], List[Union[float, int]]]]
|
|
156
|
+
Dictionary of user-defined rate parameter names and their values.
|
|
157
|
+
"""
|
|
158
|
+
for name, value in user_defined_rate_parameters.items():
|
|
159
|
+
if name not in self.__user_defined_rate_parameters_ordering:
|
|
160
|
+
raise ValueError(f"User-defined rate parameter {name} not found in the mechanism.")
|
|
161
|
+
i_param = self.__user_defined_rate_parameters_ordering[name]
|
|
162
|
+
if isinstance(value, float) or isinstance(value, int):
|
|
163
|
+
value = [value]
|
|
164
|
+
if len(value) != self.__number_of_grid_cells:
|
|
165
|
+
raise ValueError(
|
|
166
|
+
f"User-defined rate parameter list for {name} must have length {self.__number_of_grid_cells}.")
|
|
167
|
+
# Initialize `k` to index the grid cells when assigning user-defined rate parameters.
|
|
168
|
+
k = 0
|
|
169
|
+
for state in self.__states:
|
|
170
|
+
cell_stride, param_stride = state.user_defined_rate_parameter_strides()
|
|
171
|
+
for i_cell in range(state.number_of_grid_cells()):
|
|
172
|
+
state.user_defined_rate_parameters[i_param * param_stride + i_cell * cell_stride] = value[k]
|
|
173
|
+
k += 1
|
|
174
|
+
|
|
175
|
+
def set_conditions(self,
|
|
176
|
+
temperatures: Union[Union[float, int], List[Union[float, int]]],
|
|
177
|
+
pressures: Union[Union[float, int], List[Union[float, int]]],
|
|
178
|
+
air_densities: Optional[Union[Union[float, int], List[Union[float, int]]]] = None):
|
|
179
|
+
"""
|
|
180
|
+
Set the conditions for the state. The individual conditions can be a single value
|
|
181
|
+
when solving for a single grid cell, or a list of values when solving for multiple grid cells.
|
|
182
|
+
If air density is not provided, it will be calculated from the Ideal Gas Law using the provided
|
|
183
|
+
temperature and pressure.
|
|
184
|
+
|
|
185
|
+
Parameters
|
|
186
|
+
----------
|
|
187
|
+
temperatures : Union[float, List[float]]
|
|
188
|
+
Temperature in Kelvin.
|
|
189
|
+
pressures : Union[float, List[float]]
|
|
190
|
+
Pressure in Pascals.
|
|
191
|
+
air_densities : Optional[Union[float, List[float]]]
|
|
192
|
+
Air density in mol m-3. If not provided, it will be calculated from the Ideal Gas Law.
|
|
193
|
+
"""
|
|
194
|
+
if isinstance(temperatures, float) or isinstance(temperatures, int):
|
|
195
|
+
if self.__number_of_grid_cells > 1:
|
|
196
|
+
raise ValueError(f"temperatures must be a list of length {self.__number_of_grid_cells}.")
|
|
197
|
+
temperatures = [temperatures]
|
|
198
|
+
if isinstance(pressures, float) or isinstance(pressures, int):
|
|
199
|
+
if self.__number_of_grid_cells > 1:
|
|
200
|
+
raise ValueError(f"pressures must be a list of length {self.__number_of_grid_cells}.")
|
|
201
|
+
pressures = [pressures]
|
|
202
|
+
if air_densities is not None and (isinstance(air_densities, float) or isinstance(air_densities, int)):
|
|
203
|
+
if self.__number_of_grid_cells > 1:
|
|
204
|
+
raise ValueError(f"air_densities must be a list of length {self.__number_of_grid_cells}.")
|
|
205
|
+
air_densities = [air_densities]
|
|
206
|
+
if len(temperatures) != self.__number_of_grid_cells:
|
|
207
|
+
raise ValueError(f"temperatures must be a list of length {self.__number_of_grid_cells}.")
|
|
208
|
+
if len(pressures) != self.__number_of_grid_cells:
|
|
209
|
+
raise ValueError(f"pressures must be a list of length {self.__number_of_grid_cells}.")
|
|
210
|
+
if air_densities is not None and len(air_densities) != self.__number_of_grid_cells:
|
|
211
|
+
raise ValueError(f"air_densities must be a list of length {self.__number_of_grid_cells}.")
|
|
212
|
+
k = 0
|
|
213
|
+
for state in self.__states:
|
|
214
|
+
for condition in state.conditions:
|
|
215
|
+
condition.temperature = temperatures[k]
|
|
216
|
+
condition.pressure = pressures[k]
|
|
217
|
+
condition.air_density = air_densities[k] if air_densities is not None else pressures[k] / (
|
|
218
|
+
GAS_CONSTANT * temperatures[k])
|
|
219
|
+
k += 1
|
|
220
|
+
|
|
221
|
+
def get_concentrations(self) -> Dict[str, List[float]]:
|
|
222
|
+
"""
|
|
223
|
+
Get the concentrations of the species in the state.
|
|
224
|
+
|
|
225
|
+
Returns
|
|
226
|
+
-------
|
|
227
|
+
Dict[str, List[float]]
|
|
228
|
+
Dictionary of species names and their concentrations.
|
|
229
|
+
"""
|
|
230
|
+
concentrations = {}
|
|
231
|
+
for species, i_species in self.__species_ordering.items():
|
|
232
|
+
concentrations[species] = []
|
|
233
|
+
for state in self.__states:
|
|
234
|
+
cell_stride, species_stride = state.concentration_strides()
|
|
235
|
+
for i_cell in range(state.number_of_grid_cells()):
|
|
236
|
+
concentrations[species].append(
|
|
237
|
+
state.concentrations[i_species * species_stride + i_cell * cell_stride])
|
|
238
|
+
return concentrations
|
|
239
|
+
|
|
240
|
+
def get_user_defined_rate_parameters(self) -> Dict[str, List[float]]:
|
|
241
|
+
"""
|
|
242
|
+
Get the user-defined rate parameters in the state.
|
|
243
|
+
|
|
244
|
+
Returns
|
|
245
|
+
-------
|
|
246
|
+
Dict[str, List[float]]
|
|
247
|
+
Dictionary of user-defined rate parameter names and their values.
|
|
248
|
+
"""
|
|
249
|
+
user_defined_rate_parameters = {}
|
|
250
|
+
for param, i_param in self.__user_defined_rate_parameters_ordering.items():
|
|
251
|
+
user_defined_rate_parameters[param] = []
|
|
252
|
+
for state in self.__states:
|
|
253
|
+
cell_stride, param_stride = state.user_defined_rate_parameter_strides()
|
|
254
|
+
for i_cell in range(state.number_of_grid_cells()):
|
|
255
|
+
user_defined_rate_parameters[param].append(
|
|
256
|
+
state.user_defined_rate_parameters[i_param * param_stride + i_cell * cell_stride])
|
|
257
|
+
return user_defined_rate_parameters
|
|
258
|
+
|
|
259
|
+
def get_conditions(self) -> Dict[str, List[float]]:
|
|
260
|
+
"""
|
|
261
|
+
Get the conditions for the state.
|
|
262
|
+
|
|
263
|
+
Returns
|
|
264
|
+
-------
|
|
265
|
+
Dict[str, List[float]]
|
|
266
|
+
Dictionary of conditions names and their values.
|
|
267
|
+
"""
|
|
268
|
+
conditions = {}
|
|
269
|
+
conditions["temperature"] = []
|
|
270
|
+
conditions["pressure"] = []
|
|
271
|
+
conditions["air_density"] = []
|
|
272
|
+
for state in self.__states:
|
|
273
|
+
for i_cell in range(state.number_of_grid_cells()):
|
|
274
|
+
conditions["temperature"].append(state.conditions[i_cell].temperature)
|
|
275
|
+
conditions["pressure"].append(state.conditions[i_cell].pressure)
|
|
276
|
+
conditions["air_density"].append(state.conditions[i_cell].air_density)
|
|
277
|
+
return conditions
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
class MICM():
|
|
281
|
+
"""
|
|
282
|
+
The MICM class is a wrapper around the C++ MICM solver. It provides methods to create a solver,
|
|
283
|
+
create a state, and solve the system of equations.
|
|
284
|
+
|
|
285
|
+
Parameters
|
|
286
|
+
----------
|
|
287
|
+
config_path : FilePath
|
|
288
|
+
Path to the configuration file.
|
|
289
|
+
mechanism : mechanism_configuration.Mechanism
|
|
290
|
+
Mechanism object which specifies the chemical mechanism to use.
|
|
291
|
+
solver_type : SolverType
|
|
292
|
+
Type of solver to use.
|
|
293
|
+
number_of_grid_cells : int
|
|
294
|
+
Number of grid cells to use. The default is 1.
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
def __init__(
|
|
298
|
+
self,
|
|
299
|
+
config_path: FilePath = None,
|
|
300
|
+
mechanism: mc.Mechanism = None,
|
|
301
|
+
solver_type: _SolverType = None,
|
|
302
|
+
):
|
|
303
|
+
self.__solver_type = solver_type
|
|
304
|
+
self.__vector_size = _vector_size(solver_type)
|
|
305
|
+
if config_path is None and mechanism is None:
|
|
306
|
+
raise ValueError("Either config_path or mechanism must be provided.")
|
|
307
|
+
if config_path is not None and mechanism is not None:
|
|
308
|
+
raise ValueError("Only one of config_path or mechanism must be provided.")
|
|
309
|
+
if config_path is not None:
|
|
310
|
+
self.__solver = _create_solver(config_path, solver_type)
|
|
311
|
+
elif mechanism is not None:
|
|
312
|
+
self.__solver = _create_solver_from_mechanism(mechanism, solver_type)
|
|
313
|
+
|
|
314
|
+
def solver_type(self) -> SolverType:
|
|
315
|
+
"""
|
|
316
|
+
Get the type of solver used.
|
|
317
|
+
|
|
318
|
+
Returns
|
|
319
|
+
-------
|
|
320
|
+
SolverType
|
|
321
|
+
The type of solver used.
|
|
322
|
+
"""
|
|
323
|
+
return self.__solver_type
|
|
324
|
+
|
|
325
|
+
def create_state(self, number_of_grid_cells: int = 1) -> State:
|
|
326
|
+
"""
|
|
327
|
+
Create a new state object.
|
|
328
|
+
|
|
329
|
+
Returns
|
|
330
|
+
-------
|
|
331
|
+
State
|
|
332
|
+
A new state object.
|
|
333
|
+
"""
|
|
334
|
+
return State(self.__solver, number_of_grid_cells, self.__vector_size)
|
|
335
|
+
|
|
336
|
+
def solve(
|
|
337
|
+
self,
|
|
338
|
+
state: State,
|
|
339
|
+
time_step: float,
|
|
340
|
+
):
|
|
341
|
+
"""
|
|
342
|
+
Solve the system of equations for the given state and time step.
|
|
343
|
+
|
|
344
|
+
Parameters
|
|
345
|
+
----------
|
|
346
|
+
state : State
|
|
347
|
+
State object containing the initial conditions.
|
|
348
|
+
time_step : float
|
|
349
|
+
Time step in seconds.
|
|
350
|
+
|
|
351
|
+
Returns
|
|
352
|
+
-------
|
|
353
|
+
State
|
|
354
|
+
Updated state object after solving the system of equations.
|
|
355
|
+
"""
|
|
356
|
+
if not isinstance(state, State):
|
|
357
|
+
raise TypeError("state must be an instance of State.")
|
|
358
|
+
if not isinstance(time_step, (int, float)):
|
|
359
|
+
raise TypeError("time_step must be an int or float.")
|
|
360
|
+
states = state.get_internal_states()
|
|
361
|
+
for _, _state in enumerate(states):
|
|
362
|
+
_micm_solve(self.__solver, _state, time_step)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: musica
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: MUSICA is a Python library for performing computational simulations in atmospheric chemistry.
|
|
5
5
|
Home-page: https://wiki.ucar.edu/display/MUSICA/MUSICA+Home
|
|
6
6
|
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>
|
|
@@ -209,6 +209,7 @@ License: Apache License
|
|
|
209
209
|
Project-URL: Homepage, https://wiki.ucar.edu/display/MUSICA/MUSICA+Home
|
|
210
210
|
Provides-Extra: test
|
|
211
211
|
Requires-Dist: numpy; extra == "test"
|
|
212
|
+
Requires-Dist: pytest; extra == "test"
|
|
212
213
|
Description-Content-Type: text/markdown
|
|
213
214
|
|
|
214
215
|
# MUSICA
|
|
@@ -222,6 +223,7 @@ Description-Content-Type: text/markdown
|
|
|
222
223
|
[](https://zenodo.org/doi/10.5281/zenodo.7458559)
|
|
223
224
|
[](https://pypi.org/p/musica)
|
|
224
225
|
[](https://fairsoftwarechecklist.net/v0.2?f=31&a=32113&i=22322&r=123)
|
|
226
|
+
[](https://codecov.io/gh/NCAR/musica)
|
|
225
227
|
|
|
226
228
|
Multi-Scale Infrastructure for Chemistry and Aerosols
|
|
227
229
|
|
|
@@ -274,6 +276,22 @@ Specifying a specific version of `tuv-x` by has, but using the official reposito
|
|
|
274
276
|
-DTUVX_GIT_TAG=a6b2c4d8745
|
|
275
277
|
|
|
276
278
|
|
|
279
|
+
### Python build
|
|
280
|
+
Musica has python bindings. If you want to install the python package, you may `pip install musica`.
|
|
281
|
+
|
|
282
|
+
To build the package locally,
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
pip install -e .
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
If you have an NVIDIA GPU and cuda installed, you can enable a build of musica with GPU support by setting the environment
|
|
289
|
+
variable `BUILD_GPU`.
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
BUILD_GPU=1 pip install -e .
|
|
293
|
+
```
|
|
294
|
+
|
|
277
295
|
## Citing MUSICA
|
|
278
296
|
|
|
279
297
|
MUSICA can be cited in at least two ways. The first is to cite [the paper](https://doi.org/10.1175/BAMS-D-19-0331.1) that defines the vision
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
_musica.cp37-win32.pyd,sha256=QrOgwWywNu-c_WSEntx9Zppq6N9EeA-ZndgFDRSFb3E,1281024
|
|
2
|
+
lib/musica.lib,sha256=6GkqfVVMzpLdyN62CqFHbY1VzWxkCAgmHFz12x--nxg,3434448
|
|
3
|
+
lib/yaml-cpp.lib,sha256=1kXgiW-REqu2dloLReZbPd4FG7hMYkSArZTtOyxp2w8,1799180
|
|
4
|
+
musica/__init__.py,sha256=ZtW55jXUkE_2GFco1Q1GyGrpyNoVej6gfbpEWHzfpM0,85
|
|
5
|
+
musica/_version.py,sha256=TYiYsKySORMKTb6v-yyuXf6S-1keJ7xf0QxD5hFzCmg,20
|
|
6
|
+
musica/binding.cpp,sha256=rpc7Fn_GmR2Femli_gEvtgtiprRnForekUlMDoBo7PQ,674
|
|
7
|
+
musica/CMakeLists.txt,sha256=yDo8hzh5m44GUMoeTH3z1IC5zWJUYQeK8CrGFGfdJ8U,1010
|
|
8
|
+
musica/mechanism_configuration.cpp,sha256=JXGAO3j1EEKYdswjrtX8J3KcI_YlfS9WGRmlMxctaDw,27619
|
|
9
|
+
musica/mechanism_configuration.py,sha256=_0kS0fvGS-CbQ_YfJOeSM416u7WLPwq7GzDcPgGGBWA,59302
|
|
10
|
+
musica/musica.cpp,sha256=DH18hBFpJF9m68F1FaGgVBwxVxaeYr304dLF2DY4FOo,8579
|
|
11
|
+
musica/test/examples/v0/config.json,sha256=JDQdrDNRmRXGYlytX1uiSDV1lkYIAneLwlodHKFw-os,85
|
|
12
|
+
musica/test/examples/v0/config.yaml,sha256=r31QbiFE2YDudGxLGpTKnpyveTnlfXeLgJ2qSrQddDY,47
|
|
13
|
+
musica/test/examples/v0/reactions.json,sha256=SmRUE5XOAv0h3HOWg4Fb1swBiZvZ-1hsIrmMCJqEVIk,4380
|
|
14
|
+
musica/test/examples/v0/reactions.yaml,sha256=5QeEkhjeAL_rXxNYCLOuqDUudTmgwLW3NERDupKpj6s,2408
|
|
15
|
+
musica/test/examples/v0/species.json,sha256=klFuYb2vAtWdHfHJVYuIuPe_6LHRTuB0Aw29YhwfCFc,604
|
|
16
|
+
musica/test/examples/v0/species.yaml,sha256=ECT9DDa2GMwhSRaRLxjOiCATTKkTRTPwugRsUjHSytY,302
|
|
17
|
+
musica/test/examples/v1/full_configuration.json,sha256=1-kr2bZJvfuENfy6FMfc5ZEOtgs_NhzHYeGrEGLqLMw,9240
|
|
18
|
+
musica/test/examples/v1/full_configuration.yaml,sha256=9NSd8BUJnJ6CPjX9ZngqbFDEqUf1qG5ixbnQDO2m79k,5505
|
|
19
|
+
musica/test/test_analytical.py,sha256=UAM3YEx6OnxkQem0oidptY5mM1smDkcWIyIA0iG-f6w,14098
|
|
20
|
+
musica/test/test_chapman.py,sha256=_OHLNBWT5qcU8s3mQAisV16qOdyRq7gdaU4nFZtxTnY,3193
|
|
21
|
+
musica/test/test_parser.py,sha256=s8b55MntiDmUeW3GP_-JHucEhxi5RMSzPWQULM73rpg,24985
|
|
22
|
+
musica/test/tuvx.py,sha256=L8X7rJ09HiRlrhLK6fjircI8tGHnFCZJzVow8He5YOE,126
|
|
23
|
+
musica/tools/prepare_build_environment_linux.sh,sha256=qJeVEjYuWFYZuk9Q26gu0Ly4oKx06Sp5f-WVr3PmnYQ,822
|
|
24
|
+
musica/tools/prepare_build_environment_windows.sh,sha256=sBBWhJQaS2zWDVFLIDMNBMOMPw8auXwnwz7nhuB5Q_k,847
|
|
25
|
+
musica/types.py,sha256=GA04nbo-m7Jg_TQMvFMdMC35kzSDynUHvt7alBnM8FI,15257
|
|
26
|
+
musica-0.11.1.dist-info/METADATA,sha256=IlAF1TS5yurBr3aax-x1xM6svzQ2m3W8nP23j3Orsm4,20536
|
|
27
|
+
musica-0.11.1.dist-info/WHEEL,sha256=0jqwLq1QEQxAxQ8s6kub4lrGP70AxxK4kIUHpH0xAdM,101
|
|
28
|
+
musica-0.11.1.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
29
|
+
musica-0.11.1.dist-info/RECORD,,
|
lib/mechanism_configuration.lib
DELETED
|
Binary file
|
musica-0.10.1.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
lib/mechanism_configuration.lib,sha256=qkRxVS3983_ikvdP_WIybP7SQitZd7W2SOqWpeyVAdA,9070174
|
|
2
|
-
lib/musica.lib,sha256=3m8WCpfqEVLuRm8bgm15XMb16_ndnwNhbSqh8xcabcg,3051132
|
|
3
|
-
lib/yaml-cpp.lib,sha256=w0ndIiR-R1SZfEhaypcqzf0wS51D875R6MyTtFaFrIE,1765642
|
|
4
|
-
musica/_version.py,sha256=nv9a5tGlYCBP2HcJGV3ULwnsKWdjpZ47i8Es22y_BL4,20
|
|
5
|
-
musica.cp37-win32.pyd,sha256=1HZD4id6vdJ93FtNyVkLMlwCVc7kF8VuQe3dZkIWYMc,1023488
|
|
6
|
-
musica-0.10.1.dist-info/METADATA,sha256=DBMwh30xlAVKYFO-AY6l7iC03ebDbz7sOEX3S3bynkI,20025
|
|
7
|
-
musica-0.10.1.dist-info/WHEEL,sha256=0jqwLq1QEQxAxQ8s6kub4lrGP70AxxK4kIUHpH0xAdM,101
|
|
8
|
-
musica-0.10.1.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
9
|
-
musica-0.10.1.dist-info/RECORD,,
|
musica.cp37-win32.pyd
DELETED
|
Binary file
|
|
File without changes
|
|
File without changes
|