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

Issue 1500 - Print parameter info by submodel #3628

Closed
wants to merge 34 commits into from
Closed

Issue 1500 - Print parameter info by submodel #3628

wants to merge 34 commits into from

Conversation

cringeyburger
Copy link
Contributor

Description

Further improved on "print_parameter_info" by implementing "by_submodel" feature which allow users to print parameters sub-model wise.

Fixes #1500

Type of change

Please add a line in the relevant section of CHANGELOG.md to document the change (include PR #) - note reverse order of PR #s. If necessary, also add to the list of breaking changes.

  • New feature (non-breaking change which adds functionality)
  • Optimization (back-end change that speeds up the code)
  • Bug fix (non-breaking change which fixes an issue)

Key checklist:

  • No style issues: $ pre-commit run (or $ nox -s pre-commit) (see CONTRIBUTING.md for how to set this up to run automatically when committing locally, in just two lines of code)
  • All tests pass: $ python run-tests.py --all (or $ nox -s tests)
  • The documentation builds: $ python run-tests.py --doctest (or $ nox -s doctests)

You can run integration tests, unit tests, and doctests together at once, using $ python run-tests.py --quick (or $ nox -s quick).

Further checks:

  • Code is commented, particularly in hard-to-understand areas
  • Tests added that prove fix is effective or that feature works

@cringeyburger
Copy link
Contributor Author

Hello! This PR allows users to print parameters submodel-wise. The following is an example of it's working:

CODE:

import pybamm

model = pybamm.lithium_ion.SPM()
submodel = model.submodels["positive primary particle"]
model.print_parameter_info(by_submodel=True)

OUTPUT:

'external circuit' submodel parameters:
| Parameter            | Type of parameter                          |
| ==================== | ========================================== |
| Current function [A] | FunctionParameter with inputs(s) 'Time[s]' |

'porosity' submodel parameters: 
No parameters

'Negative interface utilisation' submodel parameters: 
No parameters

'Positive interface utilisation' submodel parameters: 
No parameters

'negative particle mechanics' submodel parameters: 
No parameters

'positive particle mechanics' submodel parameters: 
No parameters

'negative primary active material' submodel parameters: 
No parameters

'positive primary active material' submodel parameters: 
No parameters

'electrolyte transport efficiency' submodel parameters: 
No parameters

'electrode transport efficiency' submodel parameters: 
No parameters

'transverse convection' submodel parameters: 
No parameters

'through-cell convection' submodel parameters: 
No parameters

'negative primary open-circuit potential' submodel parameters: 
No parameters

'positive primary open-circuit potential' submodel parameters: 
No parameters

'negative interface' submodel parameters: 
No parameters

'negative interface current' submodel parameters: 
No parameters

'positive interface' submodel parameters: 
No parameters

'positive interface current' submodel parameters: 
No parameters

'negative primary particle' submodel parameters:
| Parameter                                                 | Type of parameter                                                                           |
| ========================================================= | =========================================================================================== |
| Faraday constant [C.mol-1]                                | Parameter                                                                                   |
| Electrode height [m]                                      | Parameter                                                                                   |
| Negative electrode thickness [m]                          | Parameter                                                                                   |
| Maximum concentration in negative electrode [mol.m-3]     | Parameter                                                                                   |
| Number of electrodes connected in parallel to make a cell | Parameter                                                                                   |
| Electrode width [m]                                       | Parameter                                                                                   |
| Initial concentration in negative electrode [mol.m-3]     | FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]' |
| Negative electrode active material volume fraction        | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                            |
| Current function [A]                                      | FunctionParameter with inputs(s) 'Time[s]'                                                  |
| Negative electrode diffusivity [m2.s-1]                   | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Temperature [K]'       |
| Negative particle radius [m]                              | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                            |

'negative primary total particle concentration' submodel parameters: 
No parameters

'positive primary particle' submodel parameters:
| Parameter                                                 | Type of parameter                                                                           |
| ========================================================= | =========================================================================================== |
| Maximum concentration in positive electrode [mol.m-3]     | Parameter                                                                                   |
| Faraday constant [C.mol-1]                                | Parameter                                                                                   |
| Electrode height [m]                                      | Parameter                                                                                   |
| Positive electrode thickness [m]                          | Parameter                                                                                   |
| Number of electrodes connected in parallel to make a cell | Parameter                                                                                   |
| Electrode width [m]                                       | Parameter                                                                                   |
| Positive electrode diffusivity [m2.s-1]                   | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Temperature [K]'       |
| Positive particle radius [m]                              | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                            |
| Initial concentration in positive electrode [mol.m-3]     | FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]' |
| Current function [A]                                      | FunctionParameter with inputs(s) 'Time[s]'                                                  |
| Positive electrode active material volume fraction        | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                            |

'positive primary total particle concentration' submodel parameters: 
No parameters

'negative electrode potential' submodel parameters: 
No parameters

'positive electrode potential' submodel parameters: 
No parameters

'electrolyte diffusion' submodel parameters: 
No parameters

'leading-order electrolyte conductivity' submodel parameters: 
No parameters

'negative surface potential difference' submodel parameters: 
No parameters

'positive surface potential difference' submodel parameters: 
No parameters

'thermal' submodel parameters: 
No parameters

'current collector' submodel parameters: 
No parameters

'negative primary sei' submodel parameters: 
No parameters

'positive primary sei' submodel parameters: 
No parameters

'negative primary sei on cracks' submodel parameters: 
No parameters

'positive primary sei on cracks' submodel parameters: 
No parameters

'negative lithium plating' submodel parameters: 
No parameters

'positive lithium plating' submodel parameters: 
No parameters

'total interface' submodel parameters: 
No parameters

I would appreciate it if we could review this PR and merge it. Thank you!

Copy link

codecov bot commented Dec 17, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.60%. Comparing base (4df6a87) to head (70aef8f).
Report is 5 commits behind head on develop.

❗ Current head 70aef8f differs from pull request most recent head ae0737b. Consider uploading reports for the commit ae0737b to get more accurate results

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #3628   +/-   ##
========================================
  Coverage    99.60%   99.60%           
========================================
  Files          259      259           
  Lines        21287    21333   +46     
========================================
+ Hits         21203    21249   +46     
  Misses          84       84           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@agriyakhetarpal agriyakhetarpal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, just needs a test or two to check to check the output for by_submodel=True. To exclude specific lines from coverage for any reason if it is necessary, you may add # pragma: no cover to them

Copy link
Member

@arjxn-py arjxn-py left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @cringeyburger, changes looks good. Although to fix coverage you might first want to add some favorable test cases in test_read_input_parameters() in test_base_model. Please correct me if needed @agriyakhetarpal

@rtimms
Copy link
Contributor

rtimms commented Dec 18, 2023

Thanks @cringeyburger . This has revealed an issue with trying to print by submodel. At the moment _find_symbols looks through rhs, algebraic, initial_conditions, boudnary_conditions and variables, but submodels don't have a variables attribute. Instead, they have two methods for setting variables: get_fundamental_variables returns a dictionary of variables that can be defined by that submodel independent of any other submodels; and get_coupled_variables that defines variables that depend on "fundamental variables" defined in other submodels. To get the correct parameter info you need to call these methods and see which parameters appear in the new variables.

However, the way this has been set up, get_coupled_variables takes in the current model.variables and updates it with new variables and returns the updated dict. This is frustrating, since now you can't tell which new "coupled variables" were defined from outside the submodel very easily.

Something like the below doesn't work since it just returns all the model variables. You don't know from outside of the submodel which fundamental variables it already expects to be defined. Using a default dict doesn't work since the variables need to be PyBaMM symbols with the correct domain etc.

import pybamm

model = pybamm.lithium_ion.SPM()
submodel = model.submodels["negative primary open-circuit potential"]
submodel.print_parameter_info()

sumbodel_vars = submodel.get_fundamental_variables()
submodel.get_coupled_variables(model.variables)

Maybe we should just make get_coupled_variables return the new dict, and wrap calls to it in variables.update(get_coupled_variables(variables)). This is a reasonably fundamental change to how you set up models, but I don't think it would be that disruptive (many users would never even notice, unless they are defining their own submodels). Thoughts @tinosulzer , @martinjrobins ?

@cringeyburger
Copy link
Contributor Author

So, we need to change all instances of get_coupled_variables in all submodels to return new variables instead of the updated dict?

Can you check the code below and tell me if I am doing it right or not
CHECK FOR # NEW CHANGE^^^^

    def get_coupled_variables(self, variables):
        domain, Domain = self.domain_Domain
        phase_name = self.phase_name

        new_variables = {}  # NEW CHANGE^^^^

        if self.reaction == "lithium-ion main":
            T = variables[f"{Domain} electrode temperature [K]"]
            # For "particle-size distribution" models, take distribution version
            # of c_s_surf that depends on particle size.
            domain_options = getattr(self.options, domain)
            if domain_options["particle size"] == "distribution":
                sto_surf = variables[
                    f"{Domain} {phase_name}particle surface stoichiometry distribution"
                ]
                # If variable was broadcast, take only the orphan
                if isinstance(sto_surf, pybamm.Broadcast) and isinstance(
                    T, pybamm.Broadcast
                ):
                    sto_surf = sto_surf.orphans[0]
                    T = T.orphans[0]
                T = pybamm.PrimaryBroadcast(T, [f"{domain} particle size"])
            else:
                sto_surf = variables[
                    f"{Domain} {phase_name}particle surface stoichiometry"
                ]
                # If variable was broadcast, take only the orphan
                if isinstance(sto_surf, pybamm.Broadcast) and isinstance(
                    T, pybamm.Broadcast
                ):
                    sto_surf = sto_surf.orphans[0]
                    T = T.orphans[0]

            ocp_surf = self.phase_param.U(sto_surf, T)
            dUdT = self.phase_param.dUdT(sto_surf)

            # Bulk OCP is from the average SOC and temperature
            sto_bulk = variables[f"{Domain} electrode {phase_name}stoichiometry"]
            T_bulk = pybamm.xyz_average(pybamm.size_average(T))
            ocp_bulk = self.phase_param.U(sto_bulk, T_bulk)
        elif self.reaction == "lithium metal plating":
            T = variables[f"{Domain} electrode temperature [K]"]
            ocp_surf = 0 * T
            ocp_bulk = pybamm.Scalar(0)
            dUdT = 0 * T
        elif self.reaction == "lead-acid main":
            c_e = variables[f"{Domain} electrolyte concentration [mol.m-3]"]
            # If c_e was broadcast, take only the orphan
            if isinstance(c_e, pybamm.Broadcast):
                c_e = c_e.orphans[0]
            ocp_surf = self.phase_param.U(c_e, self.param.T_init)
            dUdT = pybamm.Scalar(0)

            # Bulk OCP is from the average concentration and temperature
            c_e_av = variables["X-averaged electrolyte concentration [mol.m-3]"]
            ocp_bulk = self.phase_param.U(c_e_av, self.param.T_init)

        elif self.reaction == "lead-acid oxygen":
            ocp_surf = self.param.U_Ox
            ocp_bulk = self.param.U_Ox
            dUdT = pybamm.Scalar(0)


        # NEW CHANGE^^^
        new_variables.update(
            self._get_standard_ocp_variables(ocp_surf, ocp_bulk, dUdT)
        )
        
        # NEW CHANGE^^^^
        return new_variables

Later, I think we can access it like this?
CODE:

import pybamm

model = pybamm.lithium_ion.SPM()
submodel = model.submodels["negative primary open-circuit potential"]
new_variables = submodel.get_coupled_variables(model.variables)
model.variables.update(new_variables)
print("New variables introduced by the submodel:", new_variables)

@valentinsulzer
Copy link
Member

Changing get_coupled_variables might work, but wouldn't it be easier to compare keys before and after the call to get_coupled_variables to see which variables have been added?

@valentinsulzer
Copy link
Member

Also, it might be nice to have an option where only the parameters that are unique to that submodel are printed. Otherwise, a lot of submodels are going to have a lot of common parameters that appear everywhere (e.g. electrode height). But it might be difficult to decide how "unique" a parameter has to be - e.g. what if it only appears in two submodels?

@cringeyburger
Copy link
Contributor Author

Changing get_coupled_variables might work, but wouldn't it be easier to compare keys before and after the call to get_coupled_variables to see which variables have been added?

True, I will give this a try.

Also, it might be nice to have an option where only the parameters that are unique to that submodel are printed. Otherwise, a lot of submodels are going to have a lot of common parameters that appear everywhere (e.g. electrode height). But it might be difficult to decide how "unique" a parameter has to be - e.g. what if it only appears in two submodels?

Hmm.. we may need to parse through and keep a track of all parameters in such a case. I will get to you shortly.

@rtimms
Copy link
Contributor

rtimms commented Dec 20, 2023

Changing get_coupled_variables might work, but wouldn't it be easier to compare keys before and after the call to get_coupled_variables to see which variables have been added?

Yes, but then you need to figure out which variables to pass to get_coupled_variables first. Sometimes submodels need coupled variables from other submodels, so something like

model = pybamm.lithium_ion.SPM()
all_fundamental_vars = {}
for submodel in model.submodels.values():
    all_fundamental_vars.update(submodel.get_fundamental_variables())
sumbodel_fundamental_vars = submodel.get_fundamental_variables()
updated_vars = submodel.get_coupled_variables(all_fundamental_vars)

also fails. If the behaviour to get_coupled_variables was changed to just return the new variables, then you can just pass all model variables to get_coupled_variables and see what's returned.

The solution that avoids changing get_coupled_variables is to get all this information using the same logic as in build_coupled_variables and comparing keys as suggested by @tinosulzer. Let's do that for now.

In any case, we should also throw an error if users try to use get_parameter_info directly on a submodel, as it only works properly in the context of a full model.

@cringeyburger
Copy link
Contributor Author

Does this solve it?
check for # ----------NEW
CODE:

    def build_coupled_variables(self):
        # Note: pybamm will try to get the coupled variables for the submodels in the
        # order they are set by the user. If this fails for a particular submodel,
        # return to it later and try again. If setting coupled variables fails and
        # there are no more submodels to try, raise an error.
        submodels = list(self.submodels.keys())
        count = 0
        # For this part the FuzzyDict of variables is briefly converted back into a
        # normal dictionary for speed with KeyErrors
        self._variables = dict(self._variables)
        while len(submodels) > 0:
            count += 1
            for submodel_name, submodel in self.submodels.items():
                if submodel_name in submodels:
                    pybamm.logger.debug(
                        "Getting coupled variables for {} submodel ({})".format(
                            submodel_name, self.name
                        )
                    )
                    try:
                        # ----------NEW
                        submodel_coupled_vars = submodel.get_coupled_variables(self.variables)
                        # ----------NEW
                        self.variables[submodel_name] = submodel_coupled_vars
                        submodels.remove(submodel_name)
                    except KeyError as key:
                        if len(submodels) == 1 or count == 100:
                            # no more submodels to try
                            raise pybamm.ModelError(
                                "Missing variable for submodel '{}': {}.\n".format(
                                    submodel_name, key
                                )
                                + "Check the selected "
                                "submodels provide all of the required variables."
                            )
                        else:
                            # try setting coupled variables on next loop through
                            pybamm.logger.debug(
                                f"Can't find {key}, trying other submodels first"
                            )
        # Convert variables back into FuzzyDict
        self.variables = pybamm.FuzzyDict(self._variables)

I think we will end up with a dict, self.variables like this:

{
    'submodel1': {'coupled_var1': value1, 'coupled_var2': value2, ...},
    'submodel2': {'coupled_var3': value3, 'coupled_var4': value4, ...},
    ...
}

I am a bit confused as what to do now.

@agriyakhetarpal
Copy link
Member

It would be great if you could commit and push this change, @cringeyburger – doing that allows us to see the diff and track what lines were added or removed.

… added by get_coupled_variables in model.variables
@cringeyburger
Copy link
Contributor Author

I think I understand where I did the mistake. I didn't account for this:

However, the way this has been set up, get_coupled_variables takes in the current model.variables and updates it with new variables and returns the updated dict. This is frustrating, since now you can't tell which new "coupled variables" were defined from outside the submodel very easily.

So I think what I should do, is keep a copy of model.variables before updating it with get_coupled_variables, then after updating, I should add the difference in model.variables[submodel].

What I did was simply add the result of updating model.variables with get_coupled_variables for each submodel.

So in reality, model.variables looks like this:

{
    'submodel1': {'pre-existing model variables': model_value, 'coupled_var1': value1, 'coupled_var2': value2},
    'submodel2': {'pre-existing model variables': model_value, 'coupled_var1': value1, 'coupled_var2': value2, 'coupled_var3': value3, 'coupled_var4': value4},
    ...
}

where I need something like this:

{
    'submodel1': {'coupled_var1': value1, 'coupled_var2': value2, ...},
    'submodel2': {'coupled_var3': value3, 'coupled_var4': value4, ...},
    ...
}

Am I right regarding this?

… added by get_coupled_variables in model.variables V2
@cringeyburger
Copy link
Contributor Author

cringeyburger commented Dec 21, 2023

I think this should work now.
But, when I ran this code:

import pybamm

model = pybamm.lithium_ion.SPM()
model.print_parameter_info()

This is the output I got:

Traceback (most recent call last):
  File "/home/yukinatsu/code/PyBaMM/pybamm/models/base_model.py", line 584, in build_coupled_variables
    submodel_coupled_result = submodel.get_coupled_variables(self.variables)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/yukinatsu/code/PyBaMM/pybamm/models/submodels/interface/kinetics/inverse_kinetics/inverse_butler_volmer.py", line 39, in get_coupled_variables
    j_tot_av, a_j_tot_av = self._get_average_total_interfacial_current_density(
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/yukinatsu/code/PyBaMM/pybamm/models/submodels/interface/base_interface.py", line 185, in _get_average_total_interfacial_current_density
    i_boundary_cc = variables["Current collector current density [A.m-2]"]
                    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyError: 'Current collector current density [A.m-2]'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/yukinatsu/code/PyBaMM/mydir/test.py", line 3, in <module>
    model = pybamm.lithium_ion.SPM()
            ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/yukinatsu/code/PyBaMM/pybamm/models/full_battery_models/lithium_ion/spm.py", line 44, in __init__
    self.set_submodels(build)
  File "/home/yukinatsu/code/PyBaMM/pybamm/models/full_battery_models/lithium_ion/base_lithium_ion_model.py", line 59, in set_submodels
    self.build_model()
  File "/home/yukinatsu/code/PyBaMM/pybamm/models/full_battery_models/base_battery_model.py", line 1082, in build_model
    self._build_model()
  File "/home/yukinatsu/code/PyBaMM/pybamm/models/base_model.py", line 655, in _build_model
    self.build_coupled_variables()
  File "/home/yukinatsu/code/PyBaMM/pybamm/models/base_model.py", line 591, in build_coupled_variables
    raise pybamm.ModelError(
pybamm.expression_tree.exceptions.ModelError: Missing variable for submodel 'negative interface': 'Current collector current density [A.m-2]'.
Check the selected submodels provide all of the required variables.
ERROR conda.cli.main_run:execute(49): `conda run python /home/yukinatsu/code/PyBaMM/mydir/test.py` failed. (See above for error)

Just to provide info, I ran the code without any changes from this PR except by_submodel=True and False, this is the output:

| Parameter                                                 | Type of parameter                                                                                                                                                                                           |
| ========================================================= | =========================================================================================================================================================================================================== |
| Positive electrode Bruggeman coefficient (electrode)      | Parameter                                                                                                                                                                                                   |
| Maximum concentration in negative electrode [mol.m-3]     | Parameter                                                                                                                                                                                                   |
| Maximum concentration in positive electrode [mol.m-3]     | Parameter                                                                                                                                                                                                   |
| Faraday constant [C.mol-1]                                | Parameter                                                                                                                                                                                                   |
| Electrode width [m]                                       | Parameter                                                                                                                                                                                                   |
| Initial concentration in electrolyte [mol.m-3]            | Parameter                                                                                                                                                                                                   |
| Number of electrodes connected in parallel to make a cell | Parameter                                                                                                                                                                                                   |
| Upper voltage cut-off [V]                                 | Parameter                                                                                                                                                                                                   |
| Nominal cell capacity [A.h]                               | Parameter                                                                                                                                                                                                   |
| Positive electrode Bruggeman coefficient (electrolyte)    | Parameter                                                                                                                                                                                                   |
| Electrode height [m]                                      | Parameter                                                                                                                                                                                                   |
| Negative electrode Bruggeman coefficient (electrode)      | Parameter                                                                                                                                                                                                   |
| Ideal gas constant [J.K-1.mol-1]                          | Parameter                                                                                                                                                                                                   |
| Negative electrode Bruggeman coefficient (electrolyte)    | Parameter                                                                                                                                                                                                   |
| Separator Bruggeman coefficient (electrolyte)             | Parameter                                                                                                                                                                                                   |
| Lower voltage cut-off [V]                                 | Parameter                                                                                                                                                                                                   |
| Positive electrode thickness [m]                          | Parameter                                                                                                                                                                                                   |
| Number of cells connected in series to make a battery     | Parameter                                                                                                                                                                                                   |
| Reference temperature [K]                                 | Parameter                                                                                                                                                                                                   |
| Separator thickness [m]                                   | Parameter                                                                                                                                                                                                   |
| Negative electrode thickness [m]                          | Parameter                                                                                                                                                                                                   |
| Negative electrode OCP [V]                                | FunctionParameter with inputs(s) 'Negative particle stoichiometry'                                                                                                                                          |
| Negative electrode active material volume fraction        | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                                                                                                                                            |
| Positive electrode active material volume fraction        | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                                                                                                                                            |
| Positive electrode porosity                               | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                                                                                                                                            |
| Negative electrode diffusivity [m2.s-1]                   | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Temperature [K]'                                                                                                                       |
| Positive electrode OCP [V]                                | FunctionParameter with inputs(s) 'Positive particle stoichiometry'                                                                                                                                          |
| Positive electrode exchange-current density [A.m-2]       | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Positive particle surface concentration [mol.m-3]', 'Maximum positive particle surface concentration [mol.m-3]', 'Temperature [K]' |
| Separator porosity                                        | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                                                                                                                                            |
| Negative electrode OCP entropic change [V.K-1]            | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Maximum negative particle surface concentration [mol.m-3]'                                                                             |
| Positive particle radius [m]                              | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                                                                                                                                            |
| Positive electrode OCP entropic change [V.K-1]            | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Maximum positive particle surface concentration [mol.m-3]'                                                                             |
| Initial concentration in positive electrode [mol.m-3]     | FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]'                                                                                                                 |
| Negative particle radius [m]                              | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                                                                                                                                            |
| Initial concentration in negative electrode [mol.m-3]     | FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]'                                                                                                                 |
| Ambient temperature [K]                                   | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]'                                                                                  |
| Negative electrode exchange-current density [A.m-2]       | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Negative particle surface concentration [mol.m-3]', 'Maximum negative particle surface concentration [mol.m-3]', 'Temperature [K]' |
| Positive electrode diffusivity [m2.s-1]                   | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Temperature [K]'                                                                                                                       |
| Negative electrode porosity                               | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                                                                                                                                            |
| Current function [A]                                      | FunctionParameter with inputs(s) 'Time[s]'                                                                                                                                                                  |

'external circuit' submodel parameters:
| Parameter            | Type of parameter                          |
| ==================== | ========================================== |
| Current function [A] | FunctionParameter with inputs(s) 'Time[s]' |

'porosity' submodel parameters: 
No parameters

'Negative interface utilisation' submodel parameters: 
No parameters

'Positive interface utilisation' submodel parameters: 
No parameters

'negative particle mechanics' submodel parameters: 
No parameters

'positive particle mechanics' submodel parameters: 
No parameters

'negative primary active material' submodel parameters: 
No parameters

'positive primary active material' submodel parameters: 
No parameters

'electrolyte transport efficiency' submodel parameters: 
No parameters

'electrode transport efficiency' submodel parameters: 
No parameters

'transverse convection' submodel parameters: 
No parameters

'through-cell convection' submodel parameters: 
No parameters

'negative primary open-circuit potential' submodel parameters: 
No parameters

'positive primary open-circuit potential' submodel parameters: 
No parameters

'negative interface' submodel parameters: 
No parameters

'negative interface current' submodel parameters: 
No parameters

'positive interface' submodel parameters: 
No parameters

'positive interface current' submodel parameters: 
No parameters

'negative primary particle' submodel parameters:
| Parameter                                                 | Type of parameter                                                                           |
| ========================================================= | =========================================================================================== |
| Faraday constant [C.mol-1]                                | Parameter                                                                                   |
| Negative electrode thickness [m]                          | Parameter                                                                                   |
| Electrode height [m]                                      | Parameter                                                                                   |
| Number of electrodes connected in parallel to make a cell | Parameter                                                                                   |
| Electrode width [m]                                       | Parameter                                                                                   |
| Maximum concentration in negative electrode [mol.m-3]     | Parameter                                                                                   |
| Negative electrode active material volume fraction        | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                            |
| Negative electrode diffusivity [m2.s-1]                   | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Temperature [K]'       |
| Current function [A]                                      | FunctionParameter with inputs(s) 'Time[s]'                                                  |
| Negative particle radius [m]                              | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                            |
| Initial concentration in negative electrode [mol.m-3]     | FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]' |

'negative primary total particle concentration' submodel parameters: 
No parameters

'positive primary particle' submodel parameters:
| Parameter                                                 | Type of parameter                                                                           |
| ========================================================= | =========================================================================================== |
| Faraday constant [C.mol-1]                                | Parameter                                                                                   |
| Maximum concentration in positive electrode [mol.m-3]     | Parameter                                                                                   |
| Electrode height [m]                                      | Parameter                                                                                   |
| Number of electrodes connected in parallel to make a cell | Parameter                                                                                   |
| Electrode width [m]                                       | Parameter                                                                                   |
| Positive electrode thickness [m]                          | Parameter                                                                                   |
| Positive electrode diffusivity [m2.s-1]                   | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Temperature [K]'       |
| Initial concentration in positive electrode [mol.m-3]     | FunctionParameter with inputs(s) 'Radial distance (r) [m]', 'Through-cell distance (x) [m]' |
| Current function [A]                                      | FunctionParameter with inputs(s) 'Time[s]'                                                  |
| Positive particle radius [m]                              | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                            |
| Positive electrode active material volume fraction        | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]'                            |

'positive primary total particle concentration' submodel parameters: 
No parameters

'negative electrode potential' submodel parameters: 
No parameters

'positive electrode potential' submodel parameters: 
No parameters

'electrolyte diffusion' submodel parameters: 
No parameters

'leading-order electrolyte conductivity' submodel parameters: 
No parameters

'negative surface potential difference' submodel parameters: 
No parameters

'positive surface potential difference' submodel parameters: 
No parameters

'thermal' submodel parameters: 
No parameters

'current collector' submodel parameters: 
No parameters

'negative primary sei' submodel parameters: 
No parameters

'positive primary sei' submodel parameters: 
No parameters

'negative primary sei on cracks' submodel parameters: 
No parameters

'positive primary sei on cracks' submodel parameters: 
No parameters

'negative lithium plating' submodel parameters: 
No parameters

'positive lithium plating' submodel parameters: 
No parameters

'total interface' submodel parameters: 
No parameters

Any idea why this is happening?

submodel.get_coupled_variables(self.variables)
)
submodel_coupled_vars = submodel.get_coupled_variables(self.variables)
self.variables[submodel_name] = submodel_coupled_vars
Copy link
Contributor

@rtimms rtimms Dec 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

variables is already a dict with keys corresponding to variable names and values corresponding to their symbols. you'll need to store the coupled variables that each submodel defines in a new object.

i don't know if it makes sense to do this when building the model, or if it should be done separately when getting the parameter info. does it make a difference if we store e.g. self.variables and self.variables_by_submodel where the latter is a dict of dicts (e.g. {"submodel 1": {"var1": x, ...}, ...}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I know, there isn't much benefit to make a separate dict. other from keeping info clean and sorted + avoid searching a large dictionary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't know if it makes sense to do this when building the model, or if it should be done separately when getting the parameter info

I think the latter is better. Accessing elements from a dictionary is usually very fast – even if a dict of dicts is used to print out the information, then it can be "normalised" with the name of a submodel as the key (i.e., print the values of the sub-dictionary, similar to how pandas can normalise JSON) to account for by_submodel=True.

If by_submodel is False, it can pretty-print the whole dict in a table like it currently does. This method might be better, but would also be harder.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay.. so what should be done now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I add an object in build_coupled_variables, e.g. self.variables_by_submodel which has a structure:

{
    'submodel1': {'coupled_var1': value1, 'coupled_var2': value2, ...},
    'submodel2': {'coupled_var3': value3, 'coupled_var4': value4, ...},
    ...
}

The code for this would be the same as before:

                    try:
                        model_var_copy = self.variables.copy()
                        submodel_coupled_result = submodel.get_coupled_variables(self.variables)
                        self.variables_by_submodel[submodel_name] = {
                            key: submodel_coupled_result[key]
                            for key in submodel_coupled_result
                            if key not in model_var_copy
                        }
                        self.variables.update(
                            submodel.get_coupled_variables(self.variables)
                        )
                        submodels.remove(submodel_name)

This stores both self.variables and self.variables_by_submodel.

Next, We can modify get_parameter_info to include by_submodel=False too.
In this way, if we set print_paramter_info(by_submodel=False), then get_parameter_info will print the usual way.
If we set print_paramter_info(by_submodel=True), then we change the parameter_info returned by get_parameter_info by submodel wise.

NOTE: I have been coding something for this. I was successful in getting the coupled variables. Now I am experimenting with parameter processing and trying to make the links between get_parameter_info and print_parameter_info better. Also trying to make the code efficient and cleaner to look at... Will commit soon

@cringeyburger
Copy link
Contributor Author

I have a question.

Consider the code:

import pybamm

def write_info_to_file(file_path, info):
    with open(file_path, 'w') as file:
        for key, value in info.items():
            file.write(f"{key}: {value}\n")

model = pybamm.lithium_ion.SPM()
info = model.get_parameter_info(by_submodel=True)

output_file_path = 'output.py'
write_info_to_file(output_file_path, model.variables_by_submodel)

This basically prints the output in another file, you only need to concern with what output is printed.

NOTE: I have modified build_fundamental and build_coupled_variables to additionally update their variables in self.variables_by_submodel

Consider this submodel variables (fundamental + coupled):

Negative interface utilisation: {'Negative electrode interface utilisation variable': FullBroadcast(-0xab1acf4eed3711a, broadcast, children=['1.0'], domains={'primary': ['negative electrode'], 'secondary': ['current collector']}), 'X-averaged negative electrode interface utilisation variable': PrimaryBroadcast(-0x20fa506d607e19bd, broadcast, children=['1.0'], domains={'primary': ['current collector']}), 'Negative electrode interface utilisation': FullBroadcast(-0xab1acf4eed3711a, broadcast, children=['1.0'], domains={'primary': ['negative electrode'], 'secondary': ['current collector']}), 'X-averaged negative electrode interface utilisation': PrimaryBroadcast(-0x20fa506d607e19bd, broadcast, children=['1.0'], domains={'primary': ['current collector']})}

As you can notice, there is no FunctionParameter, Parameter or InputParameter mentioned.

So when I run the code, but output-ing the parameter_info (basically filtering the submodels variables for those three categories)

OUTPUT:

Negative interface utilisation: {}

So the question is, Is this what is required? I mean, are we targeting only those three categories, i.e. FunctionParameter, Parameter or InputParameter, OR are we missing any other category?

NOTE: I will commit the version where we only filter for these three categories of parameters. If there is any change required, I will modify it quickly afterwards.

… name as key and its variables as value.

Modified `get_parameter_info` to parse through the submodels' variables and give out `parameter_info` in `by_submodel=True` condition
Modified `print_parameter_info` to print `parameter_info` of a model with an option to print submodel wise using `by_submodel=True`
@cringeyburger
Copy link
Contributor Author

cringeyburger commented Dec 24, 2023

I have worked out a solution to this problem. The method below works.
I created an object self.variables_by_submodel, which contains both fundamental and coupled variables of each submodel.

Then I modified build_fundamental and build_coupled_variables to incorporate the variables into the object.

It has a structure as follows:

{
    "submodel1": {
        'Variable1': (SymbolType1, 'TypeDescription1'),
        'Variable2': (SymbolType2, 'TypeDescription2'),
        # ... other variables
    },
    "submodel2": {
        'VariableA': (SymbolTypeA, 'TypeDescriptionA'),
        'VariableB': (SymbolTypeB, 'TypeDescriptionB'),
        # ... other variables
    },
    # ... other submodels
}

I then modified get_parameter_info to parse through self.variables_by_submodel to filter out unnecessary parameters (only considered Parameter, InputParameter, FunctionParameter) while given that by_submodel=True, otherwise it returns the parameters of the model like before.

Then I modified print_parameter_info to print submodel-wise using the data from the newly built get_parameter_info(by_submodel=True)

NOTE:

In any case, we should also throw an error if users try to use get_parameter_info directly on a submodel, as it only works properly in the context of a full model.

I have to work on this. Also, I still need to create test cases for the PR. I will do it soon (actually, it is my first time creating tests)
EDIT:

I have a question.

It would be great if this is cleared so we can move further.
Please let me know of any problems or any other ideas that would be better. Thank youu

@cringeyburger
Copy link
Contributor Author

Here is an example of the output:
CODE:

import pybamm

model = pybamm.lithium_ion.SPM()
model.print_parameter_info(by_submodel=True)

OUTPUT:

'external circuit' submodel parameters:
| Parameter            | Type of parameter                          |
| ==================== | ========================================== |
| Current function [A] | FunctionParameter with inputs(s) 'Time[s]' |
| Current function [A] | FunctionParameter with inputs(s) 'Time[s]' |

'porosity' submodel parameters:
| Parameter                   | Type of parameter                                                |
| =========================== | ================================================================ |
| Negative electrode porosity | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |
| Separator porosity          | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |
| Positive electrode porosity | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |

'Negative interface utilisation' submodel parameters: 
No parameters

'Positive interface utilisation' submodel parameters: 
No parameters

'negative particle mechanics' submodel parameters: 
No parameters

'positive particle mechanics' submodel parameters: 
No parameters

'negative primary active material' submodel parameters:
| Parameter                                          | Type of parameter                                                |
| ================================================== | ================================================================ |
| Negative electrode active material volume fraction | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |
| Negative particle radius [m]                       | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |

'positive primary active material' submodel parameters:
| Parameter                                          | Type of parameter                                                |
| ================================================== | ================================================================ |
| Positive electrode active material volume fraction | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |
| Positive particle radius [m]                       | FunctionParameter with inputs(s) 'Through-cell distance (x) [m]' |

'electrolyte transport efficiency' submodel parameters: 
No parameters

'electrode transport efficiency' submodel parameters: 
No parameters

'transverse convection' submodel parameters: 
No parameters

'through-cell convection' submodel parameters: 
No parameters

'negative primary open-circuit potential' submodel parameters:
| Parameter                                      | Type of parameter                                                                                                               |
| ============================================== | =============================================================================================================================== |
| Negative electrode OCP entropic change [V.K-1] | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Maximum negative particle surface concentration [mol.m-3]' |
| Negative electrode OCP entropic change [V.K-1] | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Maximum negative particle surface concentration [mol.m-3]' |

'positive primary open-circuit potential' submodel parameters:
| Parameter                                      | Type of parameter                                                                                                               |
| ============================================== | =============================================================================================================================== |
| Positive electrode OCP entropic change [V.K-1] | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Maximum positive particle surface concentration [mol.m-3]' |
| Positive electrode OCP entropic change [V.K-1] | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Maximum positive particle surface concentration [mol.m-3]' |

'negative interface' submodel parameters:
| Parameter                                           | Type of parameter                                                                                                                                                                                           |
| =================================================== | =========================================================================================================================================================================================================== |
| Negative electrode exchange-current density [A.m-2] | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Negative particle surface concentration [mol.m-3]', 'Maximum negative particle surface concentration [mol.m-3]', 'Temperature [K]' |

'negative interface current' submodel parameters: 
No parameters

'positive interface' submodel parameters:
| Parameter                                           | Type of parameter                                                                                                                                                                                           |
| =================================================== | =========================================================================================================================================================================================================== |
| Positive electrode exchange-current density [A.m-2] | FunctionParameter with inputs(s) 'Electrolyte concentration [mol.m-3]', 'Positive particle surface concentration [mol.m-3]', 'Maximum positive particle surface concentration [mol.m-3]', 'Temperature [K]' |

'positive interface current' submodel parameters: 
No parameters

'negative primary particle' submodel parameters:
| Parameter                               | Type of parameter                                                                     |
| ======================================= | ===================================================================================== |
| Negative electrode diffusivity [m2.s-1] | FunctionParameter with inputs(s) 'Negative particle stoichiometry', 'Temperature [K]' |

'negative primary total particle concentration' submodel parameters: 
No parameters

'positive primary particle' submodel parameters:
| Parameter                               | Type of parameter                                                                     |
| ======================================= | ===================================================================================== |
| Positive electrode diffusivity [m2.s-1] | FunctionParameter with inputs(s) 'Positive particle stoichiometry', 'Temperature [K]' |

'positive primary total particle concentration' submodel parameters: 
No parameters

'negative electrode potential' submodel parameters: 
No parameters

'positive electrode potential' submodel parameters: 
No parameters

'electrolyte diffusion' submodel parameters: 
No parameters

'leading-order electrolyte conductivity' submodel parameters: 
No parameters

'negative surface potential difference' submodel parameters: 
No parameters

'positive surface potential difference' submodel parameters: 
No parameters

'thermal' submodel parameters:
| Parameter               | Type of parameter                                                                                                          |
| ======================= | ========================================================================================================================== |
| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |
| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |
| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |
| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |
| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |
| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |
| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |
| Ambient temperature [K] | FunctionParameter with inputs(s) 'Distance across electrode width [m]', 'Distance across electrode height [m]', 'Time [s]' |

'current collector' submodel parameters: 
No parameters

'negative primary sei' submodel parameters: 
No parameters

'positive primary sei' submodel parameters: 
No parameters

'negative primary sei on cracks' submodel parameters: 
No parameters

'positive primary sei on cracks' submodel parameters: 
No parameters

'negative lithium plating' submodel parameters: 
No parameters

'positive lithium plating' submodel parameters: 
No parameters

'total interface' submodel parameters: 
No parameters

New parameters are being printed, so this is a good attempt towards our desired solution.
PS: Happy New Year in advance to everyone!

@cringeyburger
Copy link
Contributor Author

Hi! I have been trying to code the test for get_parameter_info(by_submodel=True) but failed to write a successful test. Here is what I tried till now:

  1. Find a model whose submodels have at least one InputParameter --> There are no models whose submodels have InputParameter
  2. Try to create a dummy model and insert submodels with all three types of parameters --> I tried this numerous times. I successfully created a BaseModel and gave it a BaseSubModel. I gave parameters to that submodel using pybamm.InputParamters and others, but when I ran get_parameter_info(by_submodel=True), the output was an empty dict. Maybe I am doing this one wrong, so I request a little help on what is the right way to create a system of models and submodels which have parameters

@brosaplanella
Copy link
Sponsor Member

Input parameters are just a placeholder for the other types of parameters, which basically allows you to plug them in at the solving stage. Hence, there would be none appearing in the models so don't worry about them. Does this sort the issue?

@cringeyburger
Copy link
Contributor Author

get_parameter_info(by_submodel=True) basically filters Parameters, InputParameters and FunctionalParameters from a model's submodels' and returns them with their info. I am writing a test to check if the method gives out the parameters from the submodels.

Since you said that no InputParameters would appear in the submodels, would making a dummy model with dummy submodels and giving them params be a good way to test the method?

@rtimms
Copy link
Contributor

rtimms commented Jan 24, 2024

For testing you can make a model from submodels like this

model = pybamm.BaseModel()

a = pybamm.InputParameter("a")
b = pybamm.InputParameter("b", "test")
c = pybamm.InputParameter("c")
d = pybamm.InputParameter("d")
e = pybamm.InputParameter("e")
f = pybamm.InputParameter("f")
g = pybamm.Parameter("g")
h = pybamm.Parameter("h")
i = pybamm.Parameter("i")

u = pybamm.Variable("u")
v = pybamm.Variable("v")

sub1 = pybamm.BaseSubModel(None)
sub1.rhs = {u: -u * a}
sub1.initial_conditions = {u: c}
sub1.variables = {"u": u}
sub1.boundary_conditions = {
    u: {"left": (g, "Dirichlet"), "right": (0, "Neumann")},
}
sub2 = pybamm.BaseSubModel(None)
sub2.algebraic = {v: v - b}
sub2.variables = {"v":v, "v+f+i": v + f + i}
sub2.initial_conditions = {v: d}
sub2.boundary_conditions = {
    v: {"left": (0, "Dirichlet"), "right": (h, "Neumann")},
}
model.submodels = {"sub1": sub1, "sub2": sub2}
model.events = [pybamm.Event("u=e", u - e)]
model.build_model()

@cringeyburger
Copy link
Contributor Author

With this commit, most of the code is covered by tests. The only thing left is

                for var_name, var_symbol in submodel_vars.items():
                    if isinstance(var_symbol, pybamm.Parameter):
                        submodel_info[var_name] = (var_symbol, "Parameter")
                    elif isinstance(var_symbol, pybamm.InputParameter):
                        if not var_symbol.domain:
                            submodel_info[var_name] = (var_symbol, "InputParameter")
                        else:
                            submodel_info[var_name] = (
                                var_symbol,
                                f"InputParameter in {var_symbol.domain}",
                            )
                    elif isinstance(var_symbol, pybamm.FunctionParameter):
                        input_names = "', '".join(var_symbol.input_names)
                        submodel_info[var_name] = (
                            var_symbol,
                            f"FunctionParameter with inputs(s) '{input_names}'",
                        )

in get_parameter_info(by_submodel=True) in base_model.py

I figured out the issue. The submodels do not have fundamental nor coupled variables with the BaseModel. Hence, we are unable to test the above lines.

I have been trying to extend the code given by @rtimms by adding fundamental and coupled variables, but I need help.

I would be grateful if someone could guide me on how to add fundamental and coupled variables to sub1 and sub2.

Thank youu

@rtimms
Copy link
Contributor

rtimms commented Feb 15, 2024

@cringeyburger you could make the submodels into classes so they use the fundamental and coupled variables, e.g.

class SubModel1(pybamm.BaseSubModel):

    def get_fundamental_variables(self):
        u = pybamm.Variable("u")

        variables = {"u": u}
        return variables

    def get_coupled_variables(self, variables):
        u = variables["u"]
        v = variables["v"]
        w = u * v
        variables.update({"w": w})
        return variables

    def set_rhs(self, variables):
        a = pybamm.InputParameter("a")
        u = variables["u"]
        self.rhs = {u: -u * a}

    def set_boundary_conditions(self, variables):
        g = pybamm.Parameter("g")
        self.boundary_conditions = {
            u: {"left": (g, "Dirichlet"), "right": (0, "Neumann")},
        }

    def set_initial_conditions(self, variables):
        c = pybamm.InputParameter("c")
        u = variables["u"]
        self.initial_conditions = {u: c}

    def set_events(self, variables):
        e = pybamm.InputParameter("e")
        u = variables["u"]
        self.events = [pybamm.Event("u=e", u - e)]


class SubModel2(pybamm.BaseSubModel):
    def get_fundamental_variables(self):
        v = pybamm.Variable("v")
        f = pybamm.InputParameter("f")
        i = pybamm.Parameter("i")
        variables = {"v": v, "v+f+i": v + f + i}
        return variables

    def set_rhs(self, variables):
        b = pybamm.InputParameter("b", "test")
        v = variables["v"]
        self.rhs = {v: v - b}

    def set_boundary_conditions(self, variables):
        h = pybamm.Parameter("h")
        v = variables["v"]
        self.boundary_conditions = {
            v: {"left": (0, "Dirichlet"), "right": (h, "Neumann")},
        }

    def set_initial_conditions(self, variables):
        c = pybamm.InputParameter("c")
        v = variables["v"]
        self.initial_conditions = {v: c}


sub1 = SubModel1(None)
sub2 = SubModel2(None)
model = pybamm.BaseModel()
model.submodels = {"sub1": sub1, "sub2": sub2}
model.build_model()

@cringeyburger
Copy link
Contributor Author

cringeyburger commented Feb 17, 2024

With the latest commit, I am getting 100% coverage on my code. I especially give thanks to everyone who helped me on this issue. I learned a lot during this issue.

@cringeyburger
Copy link
Contributor Author

I noticed the Lychee check has failed for the past few runs. Is there an issue, and can I help resolve it?

@agriyakhetarpal
Copy link
Member

It's not a big issue and we have been considering reducing how much Lychee runs or reducing the number of links across the codebase if necessary, since a lot of them are unneeded and can contribute to link rot. From the job summary it looks like Stack Overflow is hitting back against automated link checkers, so if you want to help out – maybe you can add a user agent to bypass this and test the changes on your fork, or replace those links with non-SO alternatives that explain the same thing (wherever it's possible, and if there are any – I don't expect there will be many). I wouldn't recommend removing the links because they were added as notes for certain functionality, for both accreditation and further reference.

@cringeyburger
Copy link
Contributor Author

Unfortunately, I don't think I can fix this issue. I had set up a fake User-Agent in the lychee_url_checker.yml, Docker and Act, a program that locally runs the GitHub Actions using Docker.

But the way my university's ethernet and wifi are set up (basically highly restricted, blocked ports and more), all of the links are repeatedly failed by Act, either by connection reset or unexpected EOF.

@agriyakhetarpal
Copy link
Member

I don't usually use act because of hardware concerns (emulation), but it should be fine to test this out on GitHub Actions itself on your fork. The workflow takes ~20 seconds to run, and this way you should be able to circumvent your university's ISP's restrictions.

@cringeyburger cringeyburger closed this by deleting the head repository Feb 28, 2024
@agriyakhetarpal
Copy link
Member

@cringeyburger, was this in error?

@cringeyburger
Copy link
Contributor Author

Yes! I don't know what how or what happened. I am so sorry!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Print parameter info by submodel
7 participants