From fa420d92c08ce1f18fd561611b262a0df3713f76 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Fri, 18 Sep 2026 10:28:44 -0700 Subject: [PATCH 1/3] add PR and issue templates --- .github/ISSUE_TEMPLATE/bug-report.md | 31 ++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++++ .github/PULL_REQUEST_TEMPLATE.md | 92 +++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug-report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 0000000..b9268a9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve +title: 'Bug: Helpful but short description' +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Python and WOMBAT Version** + - Python 3.x + - Result of `wombat.__version__` + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..e1dda9d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: 'Feature: Short description of the request' +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..14af615 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,92 @@ + + + +# Add meaningful title here + + + + +## PR Checklist + + +- [ ] `CHANGELOG.md` has been updated to describe the changes made in this PR +- [ ] Documentation + - [ ] Docstrings are up-to-date + - [ ] Related `docs/` files are up-to-date, or added when necessary + - [ ] Documentation has been rebuilt successfully + - [ ] Examples have been updated +- [ ] Tests pass (If not, and this is expected, please elaborate in the tests section) +- [ ] PR description thoroughly describes the new feature, bug fix, etc. + + + +### New Model Checklist + + +- [ ] `parameter_map` has been updated to reflect the required variables for each calculation +- [ ] New tests created + - [ ] Unit tests + - [ ] Regression tests +- [ ] Model docstrings + - [ ] New default values are listed + - [ ] New and deprecated scaling models are highlighted in the description + - [ ] New scaling model methods adhere to the existing format for model equations and required inputs +- [ ] Model documentation + - [ ] New documentation page has been added to `docs/api/models/` + - [ ] `autoclass` is setup similar to existing models to control displayed elements + - [ ] Updated scaling relationships have a dedicated subsection + - [ ] All calculations are correctly referenced in the reference tables + (these can be copied and modified from an existing model or from `_base_calculations.md` + or `_shared_functionality.md`) + - [ ] The new documentation page is indexed appropriately in `docs/api/index.md` + +## Related issues + + + + +## Impacted areas of the software + + +- `path/to/file.extension` + - `method1`: What and why something was changed in one sentence or less. + +## Additional supporting information + + +Python version: 3.x +CSM version (`CSM.__version__`): 0.x + + From 3ab2552f35275af37a0110e2d369c16efb3afcde Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Fri, 18 Sep 2026 15:43:08 -0700 Subject: [PATCH 2/3] add new model contribution guide --- docs/api/models/base.md | 1 + docs/intro/contributing.md | 129 ++++++++++++++++++++++++++++++++++ docs/user_guide/new_models.md | 17 ++++- 3 files changed, 145 insertions(+), 2 deletions(-) diff --git a/docs/api/models/base.md b/docs/api/models/base.md index f045e5a..0fe6b00 100644 --- a/docs/api/models/base.md +++ b/docs/api/models/base.md @@ -132,6 +132,7 @@ .. automethod:: csm.models.CSMBase.total_domestic_content ``` +(api:base-model:helpers)= ## Model Helpers ```{eval-rst} diff --git a/docs/intro/contributing.md b/docs/intro/contributing.md index 38cd2b2..737aa6c 100644 --- a/docs/intro/contributing.md +++ b/docs/intro/contributing.md @@ -123,6 +123,16 @@ be built using the following two procedures. ### Generate the Local Documentation Site for Inspection +To prepare the documentation and ensure it builds successfully prior to submission, run the +following command within the `docs/` folder. + +```bash +sh build_book.sh +``` + +For simple updates to formatting, or for a first build, users can simply run the following at the +project's top-level folder. Alternatively if inside the `docs/` folder, substitute "docs/" with ".". + ```bash jupyter-book build docs/ ``` @@ -196,3 +206,122 @@ below: [semantic versioning guidelines](https://semver.org/). 2. Follow steps 2 through 8 above. 3. Merge the NLRWindSystems main branch back into the `develop` branch and push the changes. + +(contributor-guide:new-model)= +## New Models + +New model submissions will have the following checklist to complete prior to a PR being merged. +Models seeking feedback or help may be submitted as a draft PR with clear communication about +where help is needed and an action plan. + +The `Land2020NLR` and `Land2021NLR` both offer good entry points for the kinds of changes needed +to models and their documentation to be successfully integrated. This section will cover more +details about the requirements for each over item in the checklist below. + +- [ ] `parameter_map` has been updated to reflect the required variables for each calculation +- [ ] New tests created + - [ ] Unit tests + - [ ] Regression tests +- [ ] Model docstrings + - [ ] New default values are listed + - [ ] New and deprecated scaling models are highlighted in the description + - [ ] New scaling model methods adhere to the existing format for model equations and required inputs +- [ ] Model documentation + - [ ] New documentation page has been added to `docs/api/models/` + - [ ] `autoclass` is setup similar to existing models to control displayed elements + - [ ] Updated scaling relationships have a dedicated subsection + - [ ] All calculations are correctly referenced in the reference tables + (these can be copied and modified from an existing model or from `_base_calculations.md` + or `_shared_functionality.md`) + - [ ] The new documentation page is indexed appropriately in `docs/api/index.md` + +### Model Changes + +The [new model creation guide](#new-models) provides a good overview of the requirements to create +a well-validated model, and this guide will fill in some of the gaps to ensure it consistently +works for all users. + +#### `parameter_map` + +The [parameter mapping guide](#new-models:parameter-map) provides a good overview of how to modify +an existing component calculation (e.g., `blade_mass` in the guide), so it should be referred to +as a starting point. + +For components that will no longer be modeled, there are two options to update `parameter_map`, and +both will have the same effect of not relying on any other values for their now deprecated +calculation. + +1. Set the dictionary value to an empty tuple: `self.parameter_map["blade_mass"] = ()`. +2. Set the dictionary value equal to length-1 tuple of dictionary key: + `self.parameter_map["blade_mass"] = ("blade_mass", )`. + +#### Component calculations and aggregations + +Prior to calculating a value for any scaling relationship, the model must first verify the required +values to calculate that value exist, or attempt to calculate them. Please see the +[defining a new scaling relationship section of the new model guide](#new-models:new-scaling) +for further details. + +Once completed, any upstream results calculations should be updated to account for any necessary +changes. In most cases this should not be necessary, however if it is, please see the +[new model results calculation documentation](#new-models:results) for more details. + +### Testing + +At minimum, new models should replicate the testing format of the `test/test_Land2020NLR.py`, +which checks that the default values exist as expected when the model is initialized with no inputs, +and that minimum required inputs produces a set of expected results when `run()` is called. + +### Model Documentation + +text + +#### Docstrings + +A model class should have have a thorough docstring providing the following: + +* A brief description of the model (1-2 sentences). +* A more detailed description of the model (paragraph), if applicable. +* Changes from the base and parent models (See `Land2021NLR` for an example of this). +* `Args` section describing the required inputs to run the whole model +* `Parameters` section describing all the attributes of the model with their existing or updated + default values. These may be copied from an existing model for simplicity, but updated with + relevant information as needed. + * Unused parameters can be described as such at the bottom of this section. + +Individual component calculations should have the following information: + +* A basic, 1 sentence description of the method (can be copied from parent class(es)). +* Detailed description, if needed or desired. +* New formula in math-type with a mapping from the mathematical symbols or variables to the model's + attributes +* `Args` to describe the required attributes to perform the calculation. Attribute descriptions + may be copied from the class docstring for ease and consistency. +* `Raises` section copied from any other docstring. + +#### Documentation Site + +A new Markdown file in `docs/api/models` should be created that is similar to existing model files +and then referenced in the table of contents section of `docs/api/index.md`. In the new Markdown +file, the following information should be present. Most of the information can be copied over from +the base model or the parent class' documentation with edits for any updated information. + +For an example of how this should look, please review any of `land_2015.md`, `land_2020.md`, or +`land_2021.md`. + +* Under the first level heading, any relevant information that does not already exist in the model's + docstring should be placed here. +* Using the `eval-rst` directive, generate an `autoclass` summary for the new model, updating the + `inherited-memebers` field with any parent classes, and the `exclude-members` with any newly added + attributes or methods. +* Under a second-level heading, generate the method documentation for add any updated scaling + relationships. +* Include the `_shared_functionality.md` file (directly copy this from an existing document). +* Copy over the subsystem calculations and subsystem aggregations sections from an existing file + and update the model references for any new scaling relationships, e.g., for a new + `calculate_blade_mass` for a new `NLR2027Distributed` whose parent class is `CSMBase`, change + "#csm.models.CSMBase.calculate_blade_mass" to + "#csm.models.NLR2027Distributed.calculate_blade_mass". If a calculation has been removed, simply + remove the hyperlink, so + "[`calculate_blade_mass`](#csm.models.Land2021NLR.calculate_blade_mass)()" becomes + "`calculate_blade_mass`" and indicate the calculation is now unused. diff --git a/docs/user_guide/new_models.md b/docs/user_guide/new_models.md index 80caa33..ee2bfe0 100644 --- a/docs/user_guide/new_models.md +++ b/docs/user_guide/new_models.md @@ -1,9 +1,15 @@ +(new-models)= # Creating a New Model This guide will walk through the process and considerations for creating a new model by focusing on creating a new blade mass formulation with new mass relationships, mirroring the [`Land2020NLR`](#api:land-2020) model. +## Submitting a model to the repository + +Please see the new [model contributor's guide](#contributor-guide:new-model) for more details about +the expectations for models that will be included in the repository. + ## Imports and setup Aside from the base model, we also need to be able to access the actual attribute data provided by @@ -63,6 +69,7 @@ class CustomModel(CSMBase): blade_mass_exp = create_field(obj=float, units="unitless", io_type="input", default=9.2157) ``` +(new-models:parameter-map)= #### Updating the parameter mapping and post initialization hook The `parameter_map` defines what each attribute's dependent attributes are, enabling the @@ -82,6 +89,7 @@ dependency graph based on these relationships. super().__attrs_post_init__() ``` +(new-models:new-scaling)= #### Defining a new scaling relationship For the new `calculate_blade_mass` method, the first three lines are used to determine if the focal @@ -95,13 +103,18 @@ value. It is important to adhere to the existing attribute naming conventions to runtime. Please note, the docstring has not been created in this example, but please follow the examples set forth in `CSMBase` or any custom models for the information that should be provided. +Note that `rotor_radius` is used in the calculation, but `rotor_diameter` is listed in the +`parameter_map` because `rotor_diameter` is the user input and `rotor_radius` is a property +of `CSMBase` that is calculated from `rotor_diameter`. See the +[base model's helper documentation](#api:base-model:helpers) for other such properties. + ```python def calculate_blade_mass(self): exists = self._prepare_calculation("blade_mass") if exists: return - self.blade_mass = self.blade_mass_coeff * (self.rotor_diameter / 2) ** self.blade_mass_exp + self.blade_mass = self.blade_mass_coeff * (self.rotor_radius / 2) ** self.blade_mass_exp ``` #### Updating results calculations @@ -169,6 +182,6 @@ class CustomModel(CSMBase): return self.blade_mass = ( - self.blade_mass_coeff * (self.rotor_diameter / 2) ** self.blade_mass_exp + self.blade_mass_coeff * (self.rotor_radius / 2) ** self.blade_mass_exp ) ``` From d3d7a18106b7e920aa427f237a4ca7e326527046 Mon Sep 17 00:00:00 2001 From: "Hammond, Rob" <13874373+RHammond2@users.noreply.github.com> Date: Fri, 18 Sep 2026 16:20:48 -0700 Subject: [PATCH 3/3] udpate pr template for missing docs links --- .github/PULL_REQUEST_TEMPLATE.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 14af615..e576418 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -48,7 +48,10 @@ IMPORTANT NOTES