From 9d9c977b4af2c97a2582c7b23f77f2ad343debd1 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 3 Jun 2026 09:12:34 +0100 Subject: [PATCH 01/10] Remove Fortran references from docstrings and comments across multiple files --- process/core/caller.py | 3 +- process/core/input.py | 12 +----- process/core/io/data_structure_dicts.py | 1 - process/core/io/in_dat/base.py | 43 +--------------------- process/core/io/vary_run/tools.py | 1 - process/core/output.py | 1 - process/core/process_output.py | 1 - process/core/scan.py | 2 +- process/core/solver/iteration_variables.py | 5 +-- process/core/solver/solver_handler.py | 6 --- process/data_structure/numerics.py | 2 - process/main.py | 27 +++++--------- process/models/pfcoil.py | 6 +-- process/models/physics/physics.py | 2 +- process/models/tfcoil/base.py | 2 +- process/models/tfcoil/superconducting.py | 5 --- tests/integration/test_vmcon.py | 2 +- tests/unit/models/test_pfcoil.py | 5 +-- tracking/tracking_data.py | 2 - 19 files changed, 22 insertions(+), 106 deletions(-) diff --git a/process/core/caller.py b/process/core/caller.py index 041242c69b..ab4bb30ac3 100644 --- a/process/core/caller.py +++ b/process/core/caller.py @@ -248,8 +248,7 @@ def _call_models_once(self, xc: np.ndarray): """Call the physics and engineering models. This method is the principal caller of all the physics and - engineering models. Some are Fortran subroutines within modules, others - will be methods on Python model objects. + engineering models. Parameters ---------- diff --git a/process/core/input.py b/process/core/input.py index 644078ef83..0e630300c6 100644 --- a/process/core/input.py +++ b/process/core/input.py @@ -52,7 +52,7 @@ class InputVariable: """A variable to be parsed from the input file.""" module: Any - """The Fortran module that this variable should be set on.""" + """The module that this variable should be set on.""" type: type """The expected type of the variable""" range: tuple[NumberType, NumberType] | None = None @@ -1174,7 +1174,6 @@ def parse_input_file(data_structure_obj: DataStructure): continue # matches (variable name, array index, value) - # NOTE: array index is Fortran-based hence starts at 1. line_match = re.match( r"([a-zA-Z0-9_]+)(?:\(([0-9]+)\))?[ ]*=[ ]*([ +\-a-zA-Z0-9.,]+).*", stripped_line, @@ -1361,12 +1360,8 @@ def set_scalar_variable(name: str, value: ValidInputTypes, config: InputVariable """ current_value = getattr(config.module, name, ...) - # use ... sentinel because None is probably a valid return from Fortran - # and definately will be when moving to a Python data structure if current_value is ...: - error_msg = ( - f"Fortran module '{config.module}' does not have a variable '{name}'." - ) + error_msg = f"Module '{config.module}' does not have a variable '{name}'." raise ProcessValueError(error_msg) setattr(config.module, name, value) @@ -1375,9 +1370,6 @@ def set_scalar_variable(name: str, value: ValidInputTypes, config: InputVariable def set_array_variable(name: str, value: str, array_index: int, config: InputVariable): """Set an array variable in the `config.module`. - The way PROCESS input files are structured, each element of the array is provided on one line - so this function just needs to set the `value` at `array_index` (-1) because of Fortran-based indexing. - Parameters ---------- name : diff --git a/process/core/io/data_structure_dicts.py b/process/core/io/data_structure_dicts.py index 1a5d0e51bb..7f4f690fb3 100644 --- a/process/core/io/data_structure_dicts.py +++ b/process/core/io/data_structure_dicts.py @@ -59,7 +59,6 @@ def publish(self): class SourceDictionary(Dictionary): - # Dictionary created from Fortran source def __init__(self, name, dict_creator_func): Dictionary.__init__(self, name) # Function that creates the dict diff --git a/process/core/io/in_dat/base.py b/process/core/io/in_dat/base.py index 2ce9cb0cc8..aaf608b9f6 100644 --- a/process/core/io/in_dat/base.py +++ b/process/core/io/in_dat/base.py @@ -1152,11 +1152,6 @@ def process_line(self, line_type, line): line_commentless = line.split("*")[0] array_name = line_commentless.split("(")[0] empty_array = dicts["DICT_DEFAULT"][array_name] - # empty_array is what the array is initialised to when it is - # declared in the Fortran. If the array is declared but not - # initialised until later in a separate "init" subroutine, then - # empty_array will be None. This is a side-effect of the need to - # re-initialise Fortran arrays in a separate subroutine. if empty_array is None: # Array is declared but not initialised at the same time; @@ -1405,61 +1400,25 @@ def process_array(self, line, empty_array): empty_array: Default array for this array name """ - # TODO This is a mess after the Fortran module variable - # re-initialisation work. It is hard to see how this can be improved - # as the regex method of Fortran inspection (i.e. Python-Fortran - # dictionaries) is increasingly untenable. An attempt is made here, - # but with a view to the dictionaries method being dropped in future - # in light of increasing Python f2py conversion. - line_commentless = line.split("*")[0] if "*" in line else line name = line_commentless.split("(")[0] index = int(line_commentless.split("(")[1].split(")")[0]) - 1 - # The -1 assumes all Fortran arrays begin at 1: they don't in Process! - # This bug would cause a Fortran index of 0 to be interpreted as a - # Python index of -1 (last element). This didn't cause any exceptions, - # but would obviously set the wrong list index. This now throws - # exceptions when trying to access [-1] of an empty list []. Hence it - # must be guarded against with the following: + if index == -1: index = 0 - # This will cause Fortran index 0 and 1 to overwrite the same Python - # index of 0, which is clearly awful. However, it is equally bad to the - # previous case above, where Fortran [0] would overwrite Python [-1]. - # There isn't a way of reconciling this without knowing whether the - # Fortran array begins at 0 or 1. - # TODO Either enforce Fortran arrays that start at 1 throughout, or - # find a way of determining the starting index of the array value = line_commentless.split("=")[-1].replace(",", "") - # Many arrays are now declared but not initialised until the "init" - # subroutine is run in each Fortran module, to allow re-initialisation - # on demand for a new run etc. - # In Fortran, we have a declared but uninitialised array of a given - # length. This results in an empty list in the value attribute here. - # However, we need to set the value for a given index. Therefore - # make a list of Nones, so that we can set the value for a given - # index. We don't know the length of the Fortran array (its value is - # []), so we have to make the Python list as long as this Fortran index. - # This way, at least the list is long enough for this Fortran index. - # TODO Again, this requires a more robust solution - list_len = len(self.data[name].value) # Length of Python list in self.data max_list_index = list_len - 1 # The greatest index in that Python list array_len = index + 1 - # The Fortran array must be at least this long - # If the default array is an empty list, make a list of Nones of - # matching length to the Fortran array if len(empty_array) == 0: empty_array = [None] * array_len - # If the Pyhton list is an empty list, make a list of Nones of - # matching length to the Fortran array if list_len == 0: self.data[name].value = [None] * array_len # Check the Python list is long enough to store the new index diff --git a/process/core/io/vary_run/tools.py b/process/core/io/vary_run/tools.py index 9d871213a7..1f23ffabe3 100644 --- a/process/core/io/vary_run/tools.py +++ b/process/core/io/vary_run/tools.py @@ -354,7 +354,6 @@ def set_variable_in_indat(in_dat, varname, value): elif "(" in varname: name = varname.split("(")[0] - # Fortran numbering converted to Python numbering! identity = int((varname.split("("))[1].split(")")[0]) - 1 in_dat.change_array(name, identity, float(value)) diff --git a/process/core/output.py b/process/core/output.py index 1368eaae7f..54f1698777 100644 --- a/process/core/output.py +++ b/process/core/output.py @@ -16,7 +16,6 @@ def write(models, data, _outfile): models : process.main.Models physics and engineering model objects _outfile : int - Fortran output unit identifier """ # ensure we are capturing warnings that occur in the 'output' stage as these are warnings diff --git a/process/core/process_output.py b/process/core/process_output.py index 3faff8c0c2..dc03b3acbd 100644 --- a/process/core/process_output.py +++ b/process/core/process_output.py @@ -172,7 +172,6 @@ def ovarre(file, descr: str, varnam: str, value, output_flag: str = ""): if isinstance(value, np.ndarray): value = value.item() if isinstance(value, bytes): - # TODO: remove when Fortran is gone value = value.decode().strip() if isinstance(value, str): # try and convert the value to a float diff --git a/process/core/scan.py b/process/core/scan.py index b2da1471e0..2bbf2e9b31 100644 --- a/process/core/scan.py +++ b/process/core/scan.py @@ -185,7 +185,7 @@ def _missing_(cls, var): class Scan: - """Perform a parameter scan using the Fortran scan module.""" + """Perform a parameter scan using the scan module.""" def __init__(self, models: Model, solver: str, data: DataStructure): """Immediately run the run_scan() method. diff --git a/process/core/solver/iteration_variables.py b/process/core/solver/iteration_variables.py index 06a1e7ac34..8c037c2bed 100644 --- a/process/core/solver/iteration_variables.py +++ b/process/core/solver/iteration_variables.py @@ -14,7 +14,7 @@ class IterationVariable: name: str """The name of the variable""" module: str | Any - """The Fortran module that this variable should be set on.""" + """The module that this variable should be set on.""" lower_bound: float """The default lower bound of the iteration variable""" upper_bound: float @@ -27,7 +27,6 @@ class IterationVariable: """If `module.name` is an array, the iteration variable can only modify `array_index` of that array. - NOTE: The indexes start at 0 (despite indexing Fortran arrays). """ @@ -262,8 +261,6 @@ def load_iteration_variables(data): variable_index = data.numerics.ixc[i] iteration_variable = ITERATION_VARIABLES[variable_index] - # use ... as the default return value because None might be a valid return from Fortran? - module = ( getattr(data, iteration_variable.module) if isinstance(iteration_variable.module, str) diff --git a/process/core/solver/solver_handler.py b/process/core/solver/solver_handler.py index b457e25ca9..326407b6eb 100644 --- a/process/core/solver/solver_handler.py +++ b/process/core/solver/solver_handler.py @@ -29,13 +29,9 @@ def __init__(self, models, solver_name, data): def run(self): """Run solver and retry if it fails in certain ways.""" - # Initialise iteration variables and bounds in Fortran load_iteration_variables(self.data) load_scaled_bounds(self.data) - # Initialise iteration variables and bounds in Python: relies on Fortran - # iteration variables being defined above - # Trim maximum size arrays down to actually used size n = self.data.numerics.nvar x = self.data.numerics.xcm[:n] bndl = self.data.numerics.itv_scaled_lower_bounds[:n] @@ -100,7 +96,5 @@ def output(self): Objective function value, solution vector and constraints vector. """ self.data.numerics.norm_objf = self.solver.objf - # Slicing required due to Fortran arrays being maximum possible, rather - # than required, size self.data.numerics.xcm[: self.solver.x.shape[0]] = self.solver.x self.data.numerics.rcm[: self.solver.conf.shape[0]] = self.solver.conf diff --git a/process/data_structure/numerics.py b/process/data_structure/numerics.py index 427467d30e..c7f68cdb6b 100644 --- a/process/data_structure/numerics.py +++ b/process/data_structure/numerics.py @@ -155,8 +155,6 @@ class NumericsData: active_constraints: list[bool] = field(default_factory=lambda: [False] * IPEQNS) """Logical array showing which constraints are active""" - # TODO Do not change the comments for lablcc: they are used to create the - # Python-Fortran dictionaries. This must be improved on. lablcc: list[str] = field( default_factory=lambda: [ diff --git a/process/main.py b/process/main.py index 1fd681b9a0..7c3dcf0867 100644 --- a/process/main.py +++ b/process/main.py @@ -1,14 +1,10 @@ -"""Run Process by calling into the Fortran. +"""Run Process by calling into the Python module. This uses a Python module called fortran.py, which uses an extension module called "_fortran.cpython... .so", which are both generated from process_module.f90. The process_module module contains the code to actually run Process. -This file, process.py, is now analogous to process.f90, which contains the -Fortran "program" statement. This Python module effectively acts as the Fortran -"program". - Power Reactor Optimisation Code for Environmental and Safety Studies This is a systems code that evaluates various physics and @@ -24,9 +20,7 @@ The code was transferred to Culham Laboratory, Oxfordshire, UK, in April 1992, and the physics models were updated by P.J.Knight to include the findings of the Culham reactor studies documented in -Culham Report AEA FUS 172 (1992). The standard of the Fortran has -been thoroughly upgraded since that time, and a number of additional -models have been added. +Culham Report AEA FUS 172 (1992). During 2012, PROCESS was upgraded from FORTRAN 77 to Fortran 95, to facilitate the restructuring of the code into proper modules @@ -34,6 +28,8 @@ aid the inclusion of more advanced physics and engineering models under development as part of a number of EFDA-sponsored collaborations. +The code is now fully Python based. + Box file F/RS/CIRE5523/PWF (up to 15/01/96) Box file F/MI/PJK/PROCESS and F/PL/PJK/PROCESS (15/01/96 to 24/01/12) Box file T&M/PKNIGHT/PROCESS (from 24/01/12) @@ -353,7 +349,7 @@ def run(self): @staticmethod def init_module_vars(): - """Initialise all module variables in the Fortran. + """Initialise all module variables This "resets" all module variables to their initialised values, so each new run doesn't have any side-effects from previous runs. @@ -400,13 +396,12 @@ def set_input(self): "in the analysis folder", ) - # Set the input file in the Fortran self.data.globals.fileprefix = self.input_path.resolve() def set_output(self): """Set the output file name. - Set Path object on the Process object, and set the prefix in the Fortran. + Set Path object on the Process object """ self.output_path = Path(self.data.globals.output_prefix + "OUT.DAT") @@ -454,10 +449,8 @@ def show_errors(): @staticmethod def finish(): - """Run the finish subroutine to close files open in the Fortran. - - Files being handled by Fortran must be closed before attempting to - write to them using Python, otherwise only parts are written. + """Run the finish subroutine to close files that are open at the end of a run. + n. """ oheadr(constants.NOUT, "End of PROCESS Output") oheadr(constants.IOTTY, "End of PROCESS Output") @@ -594,14 +587,14 @@ def validate_user_model(self): class Models: """Creates instances of physics and engineering model classes. - Creates objects to interface with corresponding Fortran physics and + Creates objects to interface with corresponding physics and engineering modules. """ def __init__(self, data: DataStructure): """Create physics and engineering model objects. - This also initialises module variables in the Fortran for that module. + This also initialises module variables for each model. """ self.data = data diff --git a/process/models/pfcoil.py b/process/models/pfcoil.py index d738c46705..4836384555 100644 --- a/process/models/pfcoil.py +++ b/process/models/pfcoil.py @@ -48,7 +48,7 @@ class PFCoil(Model): """Calculate poloidal field coil system parameters.""" def __init__(self, cs_fatigue, cs_coil): - """Initialise Fortran module variables.""" + """Initialise the PF coil model.""" self.outfile = constants.NOUT # output file unit self.mfile = constants.MFILE # mfile file unit self.cs_fatigue = cs_fatigue @@ -1752,8 +1752,6 @@ def induct(self, output): noh = min(noh, nohmax) - # TODO In FNSF case, noh = -7! noh should always be positive. Fortran - # array allocation with -ve bound previously coerced to 0 noh = max(noh, 0) roh = np.zeros(noh) @@ -2960,7 +2958,7 @@ class CSCoil(Model): """Calculate central solenoid coil system parameters.""" def __init__(self, cs_fatigue): - """Initialise Fortran module variables.""" + """Initialise the CS coil model.""" self.outfile = constants.NOUT # output file unit`` self.mfile = constants.MFILE # mfile file unit self.cs_fatigue = cs_fatigue diff --git a/process/models/physics/physics.py b/process/models/physics/physics.py index a22c163cf9..65c880c2a2 100644 --- a/process/models/physics/physics.py +++ b/process/models/physics/physics.py @@ -1682,7 +1682,7 @@ def calculate_effective_charge_ionisation_profiles(self): def outplas(self): """Subroutine to output the plasma physics information - self.outfile : input integer : Fortran output unit identifier + self.outfile : file to write to This routine writes the plasma physics information to a file, in a tidy format. """ diff --git a/process/models/tfcoil/base.py b/process/models/tfcoil/base.py index dc7b0c8878..e0562f655c 100644 --- a/process/models/tfcoil/base.py +++ b/process/models/tfcoil/base.py @@ -107,7 +107,7 @@ class TFCoil(Model): """ def __init__(self): - """Initialise Fortran module variables.""" + """Initialise the TF coil model.""" self.outfile = constants.NOUT # output file unit def run(self): diff --git a/process/models/tfcoil/superconducting.py b/process/models/tfcoil/superconducting.py index 1af8bf61f1..151fa0540f 100644 --- a/process/models/tfcoil/superconducting.py +++ b/process/models/tfcoil/superconducting.py @@ -3379,11 +3379,6 @@ def tf_cable_in_conduit_averaged_turn_geometry( # Area of inter-turn insulation: single turn [m2] a_tf_turn_insulation = a_tf_turn - t_conductor**2 - # NOTE: Fortran has a_tf_turn_cable_space_no_void as an intent(out) variable - # that was outputting into data.tfcoil.a_tf_turn_cable_space_no_void. - # The local variable, however, appears to initially hold the value of - # data.tfcoil.a_tf_turn_cable_space_no_void despite not being intent(in). - # I have replicated this behaviour in Python for now. a_tf_turn_cable_space_no_void = copy.copy( data.tfcoil.a_tf_turn_cable_space_no_void ) diff --git a/tests/integration/test_vmcon.py b/tests/integration/test_vmcon.py index 112644e3e0..0fdd26e5d7 100644 --- a/tests/integration/test_vmcon.py +++ b/tests/integration/test_vmcon.py @@ -23,7 +23,7 @@ @pytest.fixture(autouse=True) def reinit(): - """Re-initialise Fortran module variables before each test is run.""" + """Re-initialise module variables before each test is run.""" init_all_module_vars() diff --git a/tests/unit/models/test_pfcoil.py b/tests/unit/models/test_pfcoil.py index 1a9f92bce9..7b4e2d96ca 100644 --- a/tests/unit/models/test_pfcoil.py +++ b/tests/unit/models/test_pfcoil.py @@ -53,7 +53,7 @@ def cs_coil(process_models): def test_init_pfcoil(pfcoil): - """Test initialisation of Fortran module variables. + """Test initialisation of module variables. :param pfcoil: PFCoil object :type pfcoil: process.pfcoil.PFCoil @@ -2753,9 +2753,6 @@ def test_efc(pfcoil: PFCoil, monkeypatch: pytest.MonkeyPatch): n_pf_coil_groups = 4 n_pf_coils_in_group = np.array([1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0]) - # This 2D array argument discovered via gdb prints as a 1D array, therefore - # needs to be reshaped into its original 2D. Fortran ordering is essential - # when passing greater-than-1D arrays from Python to Fortran r_pf_coil_middle_group_array = np.reshape( [ 6.7651653417201345, diff --git a/tracking/tracking_data.py b/tracking/tracking_data.py index ba6d05c0bb..d29ee107e3 100644 --- a/tracking/tracking_data.py +++ b/tracking/tracking_data.py @@ -243,8 +243,6 @@ def _generate_data(self): # tracking data for var in self.tracking_variables: if "." in var: - # a dotted variable is for variables that no longer exist in Fortran module variables - # see tracking_variables docstring try: _, var = var.split(".") # noqa: PLW2901 except (AttributeError, ValueError): From ee5a8f6bd2f3906237a1c97a87871f9fb4134a45 Mon Sep 17 00:00:00 2001 From: mn3981 Date: Wed, 3 Jun 2026 09:34:13 +0100 Subject: [PATCH 02/10] Remove Fortran references from documentation and update file extensions to Python --- .../source/cost-models/cost-models.md | 2 +- documentation/source/development/add-vars.md | 34 ++++++++----------- documentation/source/development/standards.md | 27 +++++++-------- .../source/fusion-devices/stellarator.md | 2 +- .../fusion_reactions/plasma_reactions.md | 4 +-- documentation/source/solver/solver-guide.md | 2 +- process/core/io/data_structure_dicts.py | 4 +-- process/data_structure/numerics.py | 3 +- process/data_structure/tfcoil_variables.py | 2 +- process/main.py | 7 +--- process/models/blankets/dcll.py | 2 +- process/models/blankets/hcpb.py | 1 - process/models/physics/physics.py | 4 --- process/models/power.py | 2 +- process/models/stellarator/coils/coils.py | 2 +- process/models/tfcoil/base.py | 2 -- .../models/physics/test_impurity_radiation.py | 2 +- tests/unit/models/physics/test_physics.py | 2 +- tests/unit/models/physics/test_plasma_geom.py | 2 +- tests/unit/models/test_availability.py | 5 ++- tests/unit/models/test_divertor.py | 2 +- tracking/tracking_data.py | 2 -- 22 files changed, 46 insertions(+), 69 deletions(-) diff --git a/documentation/source/cost-models/cost-models.md b/documentation/source/cost-models/cost-models.md index 4b3f0221fa..d985b0c7c5 100644 --- a/documentation/source/cost-models/cost-models.md +++ b/documentation/source/cost-models/cost-models.md @@ -4,7 +4,7 @@ Two cost models are available, determined by the switch `cost_model`. ## 1990 cost model (`cost_model = 0`) -This combines methods[^1] used in the TETRA code [^2] and the Generomak[^3] scheme. The costs are split into accounting categories[^4]. The best references for the algorithms used are[^5], and source file `costs.f90` in the code itself. The majority of the costed items have a unit cost associated with them. These values scale with (for example) power output, volume, component mass etc., and many are available to be changed via the input file. All costs and their algorithms correspond to 1990 dollars. +This combines methods[^1] used in the TETRA code [^2] and the Generomak[^3] scheme. The costs are split into accounting categories[^4]. The best references for the algorithms used are[^5], and source file `costs.py` in the code itself. The majority of the costed items have a unit cost associated with them. These values scale with (for example) power output, volume, component mass etc., and many are available to be changed via the input file. All costs and their algorithms correspond to 1990 dollars. The unit costs of the components of the fusion power core are relevant to "first-of-a-kind" items. That is to say, the items are assumed to be relatively expensive to build as they are effectively prototypes and specialised tools and machines have perhaps been made specially to create them. However, if a "production line" has been set up, and R & D progress has allowed more experience to be gained in constructing the power core components, the cost will be reduced as a result. Variable `fkind` may be used to multiply the raw unit costs of the fusion power core items (by a factor less than one) to simulate this cost reduction for an *Nth*-of-a-kind device. In other systems studies of fusion power plants[^6], values for this multiplier have ranged from 0.5 to 0.8. diff --git a/documentation/source/development/add-vars.md b/documentation/source/development/add-vars.md index f6cbd1a625..8c52f24acf 100644 --- a/documentation/source/development/add-vars.md +++ b/documentation/source/development/add-vars.md @@ -5,9 +5,6 @@ optimisation figure of merit and constraints to the `PROCESS` code. **At all times the [`PROCESS` style guide](../development/standards.md) must be used.** -!!! note - - As the code is quickly converging towards a wholly Python codebase the respective files may change in type from `.f90` to `.py`. ----------------- @@ -15,7 +12,7 @@ optimisation figure of merit and constraints to the `PROCESS` code. To add a `PROCESS` input, please follow below: -1. Choose the most relevant module `XX` and add the variable in the `XX_variables` defined in `XX_variables.f90`. +1. Choose the most relevant module `XX` and add the variable in the `XX_variables` defined in `XX_variables.py`. 2. Add a description of the input variable below the declaration, using the FORD formatting described in the standards section specifying the units. @@ -26,11 +23,10 @@ To add a `PROCESS` input, please follow below: Here is an example of the code to add: -Variable definition example in `tfcoil_variables.f90`: -```fortran - real(dp) :: rho_tf_joints - !! TF joints surfacic resistivity [ohm.m] - !! Feldmetal joints assumed. +Variable definition example in `tfcoil_variables.py`: +```python + e_tf_coil_magnetic_stored: float = 0.0 + """Stored magnetic energy in a single TF coil (J)""" ``` Variable initialization example in `tf_coil.py`: @@ -55,10 +51,10 @@ Code example in the `input.py` file: To add a `PROCESS` iteration variable please follow the steps below, in addition to the instructions for adding an input variable: -1. The parameter `IPNVARS` in module `numerics` of `numerics.f90` will normally be greater than the actual number of iteration variables, and does not need to be changed. +1. The parameter `IPNVARS` in module `numerics` of `numerics.py` will normally be greater than the actual number of iteration variables, and does not need to be changed. 2. Append a new iteration number key to the end of the `ITERATION_VARIABLES` dictionary in `iteration_variables.py`. The associated variable is the corresponding key value. 3. Set the variable origin file and then the associated lower and upper bounds -4. Update the `lablxc` description in `numerics.f90`. +4. Update the `lablxc` description in `numerics.py`. It should be noted that iteration variables must not be reset elsewhere in the code. That is, they may only be assigned new values when originally @@ -115,15 +111,13 @@ After following the instruction to add an input variable, you can make the varia `nsweep` comment example: -```fortran - - integer :: nsweep = 1 - !! nsweep /1/ : switch denoting quantity to scan: +```python + nsweep: int = None + """Switch denoting quantity to scan: