Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

correcting tests #178

Merged
merged 6 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/CI_Tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,16 @@ jobs:
cache: 'pip'

- name: Install dependencies
run: python -m pip install --upgrade pip
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Install this package
run: pip install -e .

- name: Run pytest
run: cd tests && pytest

- name: Run the smoke tests
run: |
music_box configFile=tests/configs/analytical_config/my_config.json outputDir=tests/configs/analytical_config
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ classifiers = ["License :: OSI Approved :: Apache Software License"]
dynamic = ["version", "description"]

dependencies = [
"musica==0.7.0"
"musica==0.7.3"
]

[project.urls]
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
musica==0.7.0
pandas
pipx
pytest
Expand Down
19 changes: 6 additions & 13 deletions src/acom_music_box/music_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def generateReactionConfig(self):

return json.dumps(reactionsJson, indent=4)

def create_solver(self, path_to_config):
def create_solver(self, path_to_config, solver_type = musica.micmsolver.rosenbrock, number_of_grid_cells = 1):
"""
Creates a micm solver object using the CAMP configuration files.

Expand All @@ -417,10 +417,10 @@ def create_solver(self, path_to_config):
None
"""
# Create a solver object using the configuration file
self.solver = musica.create_solver(path_to_config)
self.solver = musica.create_solver(path_to_config, musica.micmsolver.rosenbrock, number_of_grid_cells)


def solve(self, path_to_output = None):
def solve(self, output_path = None):
"""
Solves the box model simulation and optionally writes the output to a file.

Expand All @@ -440,9 +440,6 @@ def solve(self, path_to_output = None):
#sets up initial conditions to be current conditions
curr_conditions = self.initial_conditions

#sets up initial concentraion values
curr_concentrations = self.initial_conditions.get_concentration_array()

#sets up next condition if evolving conditions is not empty
next_conditions = None
next_conditions_time = 0
Expand Down Expand Up @@ -528,10 +525,6 @@ def solve(self, path_to_output = None):
GAS_CONSTANT = BOLTZMANN_CONSTANT * AVOGADRO_CONSTANT
air_density = curr_conditions.pressure / (GAS_CONSTANT * curr_conditions.temperature)

#updates M accordingly
if 'M' in species_constant_ordering:
ordered_concentrations[species_constant_ordering['M']] = air_density

#solves and updates concentration values in concentration array
if (not ordered_concentrations):
logger.info("Warning: ordered_concentrations list is empty.")
Expand All @@ -544,9 +537,9 @@ def solve(self, path_to_output = None):
curr_time += self.box_model_options.chem_step_time

#outputs to file if output is present
if(path_to_output != None):
logger.info("path_to_output = {}".format(path_to_output))
with open(path_to_output, 'w', newline='') as output:
if(output_path != None):
logger.info("path_to_output = {}".format(output_path))
with open(output_path, 'w', newline='') as output:
writer = csv.writer(output)
writer.writerows(output_array)

Expand Down
8 changes: 8 additions & 0 deletions src/acom_music_box/music_box_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ def __init__(self, pressure=None, temperature=None, species_concentrations=None,
self.temperature = temperature
self.species_concentrations = species_concentrations if species_concentrations is not None else []
self.reaction_rates = reaction_rates if reaction_rates is not None else []

def __repr__(self):
return f"Conditions(pressure={self.pressure}, temperature={self.temperature}, species_concentrations={self.species_concentrations}, reaction_rates={self.reaction_rates})"

def __str__(self):
return f"Pressure: {self.pressure}, Temperature: {self.temperature}, Species Concentrations: {self.species_concentrations}, Reaction Rates: {self.reaction_rates}"

@classmethod
def from_UI_JSON(cls, UI_JSON, species_list, reaction_list):
Expand Down Expand Up @@ -125,6 +131,8 @@ def from_config_JSON(cls, path_to_json, config_JSON, species_list, reaction_list
species_concentrations.append(SpeciesConcentration(species, concentration))

for species in species_list.species:
if species.tracer_type == 'THIRD_BODY':
continue
if not any(conc.species.name == species.name for conc in species_concentrations):
species_concentrations.append(SpeciesConcentration(species, 0))

Expand Down
6 changes: 6 additions & 0 deletions src/acom_music_box/music_box_reaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ def __init__(self, name=None, reaction_type=None, reactants=None, products=None,
self.products = products if products is not None else []
self.scaling_factor = scaling_factor

def __str__(self):
return f"{self.name}: {self.reaction_type}"

def __repr__(self):
return f"{self.name}: {self.reaction_type}"

def add_reactant(self, reactant):
"""
Add a Reactant instance to the list of reactants.
Expand Down
6 changes: 6 additions & 0 deletions src/acom_music_box/music_box_reaction_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ def __init__(self, reaction, rate):
"""
self.reaction = reaction
self.rate = rate

def __str__(self):
return f"{self.reaction.name}: {self.rate}"

def __repr__(self):
return f"{self.reaction.name}: {self.rate}"
23 changes: 18 additions & 5 deletions src/acom_music_box/music_box_species.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
class Species:
"""
Represents a species with various attributes such as name, absolute tolerance, phase, molecular weight, and density.
Represents a species with various attributes such as name, absolute tolerance, phase, molecular weight

Attributes:
name (str): The name of the species.
absolute_tolerance (float): The absolute tolerance of the species.
phase (str): The phase of the species.
molecular_weight (float): The molecular weight of the species in kg mol^-1.
density (float): The density of the species in kg m^-3.
"""

def __init__(self, name=None, absolute_tolerance=None, phase=None, molecular_weight=None, density=None):
def __init__(self, name=None, absolute_tolerance=None, phase=None, molecular_weight=None, tracer_type=None, diffusion_coefficient=None):
"""
Initializes a new instance of the Species class.

Expand All @@ -19,10 +18,24 @@ def __init__(self, name=None, absolute_tolerance=None, phase=None, molecular_wei
absolute_tolerance (float): The absolute tolerance of the species.
phase (str): The phase of the species.
molecular_weight (float): The molecular weight of the species in kg mol^-1.
density (float): The density of the species in kg m^-3.
tracer_type (str): The type of the tracer. Default is None. Other options are THIRD_BODY or CONSTANT
diffusion_coefficient (float): The diffusion coefficient of the species in m^2 s^-1. Default is None.
"""
self.name = name
self.absolute_tolerance = absolute_tolerance
self.phase = phase
self.molecular_weight = molecular_weight
self.density = density
self.tracer_type = tracer_type
self.diffusion_coefficient = diffusion_coefficient

def __repr__(self):
return (f"Species(name={self.name!r}, absolute_tolerance={self.absolute_tolerance!r}, "
f"phase={self.phase!r}, molecular_weight={self.molecular_weight!r}, "
f"tracer_type={self.tracer_type!r}, diffusion_coefficient={self.diffusion_coefficient!r})")

def __str__(self):
return (f"Species: {self.name}, Phase: {self.phase}, "
f"Molecular Weight: {self.molecular_weight} kg/mol, "
f"Tolerance: {self.absolute_tolerance}, "
f"Tracer Type: {self.tracer_type}, "
f"Diffusion Coefficient: {self.diffusion_coefficient} m^2/s")
7 changes: 7 additions & 0 deletions src/acom_music_box/music_box_species_concentration.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@ def __init__(self, species, concentration):
"""
self.species = species
self.concentration = concentration

def __str__(self):
return f"{self.species.name}: {self.concentration}"

def __repr__(self):
return f"{self.species.name}: {self.concentration}"

33 changes: 11 additions & 22 deletions src/acom_music_box/music_box_species_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def __init__(self, species=None, relative_tolerance=1.0e-4):
"""
self.species = species if species is not None else []
self.relative_tolerance = relative_tolerance
self.tracer_type = None

@classmethod
def from_UI_JSON(cls, UI_JSON):
Expand Down Expand Up @@ -62,7 +63,7 @@ def from_config_JSON(cls, path_to_json, config_JSON):
species_from_json = []

#gets config file path
config_file_path = os.path.dirname(path_to_json) + "/" + config_JSON['model components'][0]['configuration file']
config_file_path = os.path.join(os.path.dirname(path_to_json), config_JSON['model components'][0]['configuration file'])

#opnens config path to read species file
with open(config_file_path, 'r') as json_file:
Expand All @@ -74,28 +75,16 @@ def from_config_JSON(cls, path_to_json, config_JSON):
with open(species_file_path, 'r') as species_file:
species_data = json.load(species_file)
#loads species by names from camp files
for properties in species_data['camp-data']:
if properties.get('name') is not None:
name = properties.get('name')
species_from_json.append(Species(name, None, None, None, None))


#chceks if species are in the config file and updates attributes accordingly
for chem_spec in config_JSON['chemical species']:
for species in species_from_json:
if species.name == chem_spec:
# Add attributes to species
if 'absolute tolerance' in chem_spec:
species.absolute_tolerance = chem_spec['absolute tolerance']
if 'molecular weight' in chem_spec:
species.molecular_weight = chem_spec['molecular weight']
if 'density' in chem_spec:
species.density = chem_spec['density']
if 'phase' in chem_spec:
species.phase = chem_spec['phase']
for species in species_data['camp-data']:
if species['type'] == 'CHEM_SPEC':
tolerance = species.get('absolute tolerance', None)
molecular_weight = species.get('molecular weight [kg mol-1]', None)
phase = species.get('phase', None)
diffusion_coefficient = species.get('diffusion coefficient [m2 s-1]', None)
tracer_type = species.get('tracer type', None)
name = species.get('name')
species_from_json.append(Species(name=name, absolute_tolerance=tolerance, molecular_weight=molecular_weight, phase=phase, diffusion_coefficient=diffusion_coefficient, tracer_type=tracer_type))



return cls(species_from_json)


Expand Down
2 changes: 1 addition & 1 deletion tests/configs/chapman_config/camp_data/species.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"name": "M",
"type": "CHEM_SPEC",
"tracer type": "CONSTANT"
"tracer type": "THIRD_BODY"
},
{
"name": "Ar",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
{
"camp-files": [
"species.json",
"reactions.json"
]
}
{"camp-files": ["species.json", "reactions.json"]}
Loading