From e9af3f0971fc8286b120990dc3a73ea02d6c092b Mon Sep 17 00:00:00 2001 From: Clair Mould <86794332+clmould@users.noreply.github.com> Date: Wed, 4 Oct 2023 17:33:49 +0100 Subject: [PATCH] update utility docs --- .../SankeyPowerFlow_from_large_tokamak.png | Bin 0 -> 46720 bytes documentation/proc-pages/io/utilities.md | 843 +++--------------- process/io/mfile_comparison.py | 4 +- process/io/plot_proc.py | 7 +- process/io/plot_sankey.py | 12 +- utilities/costs_bar.py | 4 +- utilities/costs_pie.py | 4 +- utilities/plot_stress_tf.py | 2 +- 8 files changed, 154 insertions(+), 722 deletions(-) create mode 100644 documentation/proc-pages/images/SankeyPowerFlow_from_large_tokamak.png diff --git a/documentation/proc-pages/images/SankeyPowerFlow_from_large_tokamak.png b/documentation/proc-pages/images/SankeyPowerFlow_from_large_tokamak.png new file mode 100644 index 0000000000000000000000000000000000000000..4dc694dd7e9d3e9ce7df3e82fc890db2e78e3735 GIT binary patch literal 46720 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%0DjeU%g#=fuTx_h4U`JD4V{}<=wd2zfc)XZ=0 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 OGBPmL&)8;v@jn2SG16TC literal 0 HcmV?d00001 diff --git a/documentation/proc-pages/io/utilities.md b/documentation/proc-pages/io/utilities.md index 81501b8f..d0ee6cec 100644 --- a/documentation/proc-pages/io/utilities.md +++ b/documentation/proc-pages/io/utilities.md @@ -4,164 +4,90 @@ The PROCESS Python utilities are located in the repository folder ``` -/utilities/ +process ``` +A number of utilities for `PROCESS` are available, for instance to modify the input file `IN.DAT`, or to extract and plot data from the `PROCESS` output. -A number of utilities for `PROCESS` are available, for instance to modify the input file `IN.DAT`, -run `PROCESS` until a feasible solution is found, or to extract and plot data from the `PROCESS` output. +The majority of utilities operate on `MFILE.DAT` files which are created by running `PROCESS` on an `IN.DAT` file. All executables use Python library functions either from the publicly available `numpy`, `scipy` -and `matplotlib` libraries of the `PROCESS` Python libraries. To used the `PROCESS` Python libraries -made their directory is in your Python path. +and `matplotlib` libraries or the `PROCESS` Python libraries. To use the `PROCESS` Python libraries, +make sure their directory is in your Python path. !!! Info "Python > 3" All Python code has been written for Python 3. -## Compare Input Files - -`in_dat_comparison.py` - -Tool for comparing two IN.DATs and outputting inputs in one file and not the other, inputs in both -with different values and inputs in both with the same value. - -| Argument | Description | -| ---- | --- | -| `-f` | Files to compare | -| `-s` | Save output to file called `input_comp.txt` | ## Compare MFILEs -`mfile_comparison.py` +`process/io/mfile_comparison.py` Tool for comparing two MFILEs and outputting significant differences in numerical values. +### Usage +```bash +python process/io/mfile_comparison.py [-f path/to/first_MFILE.DAT path/to/second_MFILE.DAT] [-s] [--acc] [--verbose] +``` +### Options | Argument | Description | | ---- | --- | +| `-h, --help` | show help message and exit | | `-f` | Files to compare | | `-s` | Save output to file called comp.txt | | `--acc` | Percentage difference threshold for reporting | | `--verbose` | Additional output | -## Convert MFILE to Catia CAD - -`cad_output.py` - -The PROCESS utility `cad_output.py` takes the `mfile.py` and produces an output file suitable for -using in CAD programs (for testing *Catia* was used). The output file is named `PROCESS.CAD` by -default. The output file provides a list of named parameters for input into *Catia*. Modification -for other CAD programs may be required. The options for the script are: - -``` -cad_output.py [-h] [-f FILENAME] [-o OUTPUT] [-s] - -Produce a CAD output file of the PROCESS MFILE file for a given scan. For info -contact james.morris2@ccfe.ac.uk - -optional arguments: --h, --help show this help message and exit --f FILENAME specify input filename --o OUTPUT specify output filename --s, --show show plot as well as saving figure -``` - -## `plot_proc.py` to CSV - -`output_data.py` - -A utility to output a set of data very similar to `plot_proc.py`, but to a comma-delimited -format for inclusion in spreadsheets. This is used by `archive.sh` to import data into the PROCESS -runs database. For other uses, it's best to use PLOT.DAT instead, as this is always generated by -PROCESS, and can be easily loaded into a spreadsheet. - -**Input**: `MFILE.DAT` (or as specified by user) - -**Output**: `process_summary.txt` (or as specified by user) - -**Configuration Options**: Optional arguments are: - -``` -usage: output_data.py [-h] [-f FILENAME] [-o OUTPUT] - -Produce a single-column comma-separated (.txt) summary for a given scan. For -info contact rich.kemp@ccfe.ac.uk or james.morris2@ccfe.ac.uk - -optional arguments: - -h, --help show this help message and exit - -f FILENAME specify input filename - -o OUTPUT specify output filename -``` - -### Create csv file summarising data for database - -`create_csv4database.py` - -This is essentially the same tool as `output_data.py`, but the format is frozen to assure -consistency for the PROCESS Runs database excel spreadsheet. - -## Create MCNP file from `MFILE.DAT` - -`mcnp_output.py` +### Output +Outputs variables and their values which differ significantly between the two MFILEs. -The utility `mcnp_output.py` makes a `MFILE.DAT` and converts it to a suitable format for MCNP -runs. The options for the script are: +## CSV Exporter ``` -mcnp_output.py [-h] [-f f] [-o o] [--ctf] - -Process MFILE.DAT into PROCESS.MCNP file. - -optional arguments: --h, --help show this help message and exit --f f File to read as MFILE.DAT --o o File to write as PROCESS.MCNP ---ctf True/False flag for CTF +process/io/mfile_to_csv.py ``` -## JSON Exporter - -```bash -./utilities/mfile_to_json.py -``` +This script reads from a PROCESS MFILE and writes values into a CSV file. The variable list is given in a .json file which is defined by the user; a pre-made one can be found in `process/io/mfile_to_csv_vars.json`. -This script outputs the contents of the MFILE to a JSON file. +### Usage ```bash -usage: mfile-to-json.py [-h] [-f filename] [-n N] [--radial_build] - [--vertical_build] [--all_build] [--verbose] +python process/io/mfile_to_csv.py [-h] [-f path/to/MFILE] [-v path/to/variable_list.json] ``` - +### Options | Argument | Description | | - | - | -| `-h, --help` | show this help message and exit | +| `-h, --help` | show help message and exit | | `-f, [filename]` | specify MFILE file path | -| `-n, [N]` | specify scan to plot (-1=last, 0=all) | -| `--radial-build` | only output radial build | -| `--vertical-build` | only output vertical build | -| `--all-build` | only output radial + vertical build | -| `--verbose` | output both variable name and description | +| `-v, VARFILE` | specify variable .json list file path | + +### Output +A `.csv` file will be saved to the directory of the input file. + -## PROCESS 2-Page Summary -> `/utilities/plot_proc.py` +## PROCESS 2-Page PDF Summary -A utility to produce a two-page summary of the output, including the major -parameters, poloidal and toroidal cross-sections, and temperature and density -profiles. +> `process/io/plot_proc.py` + +A utility to produce a two-page PDF summary of the output from PROCESS, including the major parameters, poloidal and toroidal cross-sections, and temperature and density profiles. + +### Usage ```bash -python plot_proc.py [-h] [-f FILENAME] [-s] +python process/io/plot_proc.py [-h] [-f path/to/MFILE.DAT] [-s] ``` -If no `-f` argument is provided it assumes a file named `MFILE.DAT` is in the -current directory. - -Produces a two-page PDF file called `SUMMARY.pdf` +If no `-f` argument is provided it assumes a file named `MFILE.DAT` is in the current directory. +### Options | Argument | Description | | - | - | | `-h --help` | show help message and exit -| `-f FILENAME` | specify input/output file prefix -| `-s, --show` | show plot as well as saving figure +| `-f path/to/MFILE.DAT` | specify input/output file prefix +| `-s, --show` | show plot + +### Output +Produces a two-page PDF file in the same directory as the input MFILE. The PDF file name has the same prefix as the input MFILE but ending in `SUMMARY.pdf` ### Parameters Displayed @@ -225,7 +151,7 @@ confinement scaling[^3] [^4] | | plasma current $I_P[MA]$ | | vaccuum magnetic field at in the plasma centre $B_T(R_0)$ | | safety factor at the 95\% flux surface $q_{95}$ | -| definitions of $\beta$ as given in \cite{kovari_physics} | +| definitions of $\beta$ as given in [^1] | | volume averaged electron temperature $\langle T_e\rangle$ and density $\langle n_e\rangle$ | | fraction of the line averaged electron density over the Greenwald density $\langle n_{e,line}\rangle / n_{GW}$ | | peaking of the electron temperature $T_{e,0}/\langle T_e\rangle$ and density $n_{e,0}/\langle n_{e,vol}\rangle$ | @@ -247,7 +173,7 @@ confinement scaling[^3] [^4] | ## Sankey Diagram -> `./utilities/plot_sankey.py` +> `process/io/plot_sankey.py` The power flows of the power plant will be extracted from MFILE.DAT and used to populate a Sankey diagram. The diagram will start from the initial fusion power and show the inputs @@ -257,22 +183,9 @@ heating back into the fusion power. ### Usage ``` -python plot_sankey.py [-h] [-e END] [-m MFILE] [-f] +python process/io/plot_sankey.py [-h] [-e END] [-m path/to/MFILE.DAT] ``` - -### Output - -A .pdf file is created called 'SankeyPowerFlow.pdf', and 'SankeyPowerFlow_full.pdf' if -the -f option is used, in the directory the utility was run. The full version is current -not working and will be implemented in the future. -N.B. Rounding to whole integer can cause errors of $\pm$1 between adjacent arrows. - -### Example Output - -
-![Sankey flow chart of 2018 baseline](/../images/sankey-power-flow.png){ width="100%"} -
Figure 1: Sankey flow chart of 2018 baseline.
-
+If no `-m` argument is provided it assumes a file named `MFILE.DAT` is in the current directory. ### Options @@ -281,286 +194,63 @@ N.B. Rounding to whole integer can cause errors of $\pm$1 between adjacent arrow | `-h --help` | show help message and exit | | `-e --end` | file format, default = pdf | | `-m --mfile` | mfile name, default = MFILE.DAT | -| `-f, --full` | Plot a full version | - -## Sobol Method -> `./utilities/sobol_method.py` - -Program to evaluate model sensistivity by Sobol's method at a given PROCESS design point. It uses -the variance based global sensistivity analaysis to calculate the first order and total Sobol indices. -More information on Sobol's method can be found, for example, in the testbook[1]. Note that this -utility has a significanity longer run time that a typical evalution of PROCESS design points. This -utilities requires the use of the Python library [SALib](https://salib.readthedocs.io/en/latest/index.html). - -[1] A. Saltelli, S. Tarantola, F. Campolongo, M. Ratto, T. Andres, J. Cariboni, D. Gatelli and -M. Saisana, (2008) "Global Sensitivity Analysis: The Primer" (New York: Wiley) - -### Usage - -```bash -usage: sobol_method.py [-h] [-f CONFIGFILE] [-i INPUTFILE] [-o OUTPUTVARNAME] - [-s SOLLIST] [-e ERRORLIST] [-c CONVLIST] - [-m OUTPUTMEAN] [-t ITER] -``` - -### Configuration File - -The configuration file `sobol_method_conf.json` used the JSON format and has the following style -``` -{ - "bounds": [ - [ - 1.1, - 1.3 - ], - [ - 3.4, - 3.6 - ], - [ - 520000000.0, - 640000000.0 - ], - [ - 0.475, - 0.525 - ] - ], - "names": [ - "hfact", - "boundl(18)", - "alstrtf", - "triang" - ], - "num_vars": 4 -} -``` - -The file specifies a dictionary that gives all the information for running the Morris method tool. -The number of variables considered in the Morris method with `num_vars`, the name of the variable -as it appears the PROCESS MFILE is listed under `names` and the upper and lower bounds of the flat -distribution is given in bounds. In addition the utility also uses `run_process.py` and therefore -can optionally use the configuation file `run_process.conf`. Additionally, an `IN.DAT` file -describing the relevant design point needs to be present. ### Output -This utility uses the `run_process.py` tool and therefore produces the same output files and in -addition the tool creates several file in a .txt format. The parameter sampling points generated in -the Sobol method sampling are saved the same folder as the program is run from as `param_values.txt`. -The output of Sobol's method is shpwn over four files created in the same folder as the `run_process.py` -utility working directory. Firstly, `output_solutions.txt` which contains a list of the final value of -the figure of merit of every PROCESS run done over the calucation of the Sobol indices. Then two -files `output_failed_solutions.txt` and `output_conv_solutions.txt` which list all PROCESS run -solutions that failed and succeeded to converge respectively. Finally, the file `sobol.txt` which -gives all the first order and total Sobol indices and their 95% confidence intervals. - -### Options - -| Argument | Description | -| - | - | -| `-h, --help` | show this help message and exit | -| `-f CONFIGFILE` | configuration file, default = run_process.conf | -| `-i INPUTFILE` | input parameters file, default = sobol_method_conf.json | -| `-o OUTPUTVARNAME` | PROCESS output analysed, default = capcost | -| `-s SOLLIST` | filename of PROCESS outputs, default = output_solutions.txt | -| `-e ERRORLIST` | filename of failed PROCESS output, default = output_failed_solutions.txt | -| `-c CONVLIST` | filename of converged PROCESS output, default = output_conv_solution.txt | -| `-m OUTPUTMEAN` | PROCESS mean model output value, default = 8056.98 (DEMO capcost) | -| `-t ITER` | number of model iteration sampled, default = 100 | - -## Sobol Plotting - -> `./utilities/sobol_plotting.py` - -Program to plot the output of the the Sobols sensistivity analysis at a given PROCESS design point. -It creates a bar chart showing both the first order and total Sobol indices for each variable and give -the 95% confidence intervals. - -### Usage - -```bash -usage: sobol_plotting.py [-h] [-f DATAFILE] [-o OUTPUTFILE] -``` - -### Configuration File - -The tool reads the data contained `sobol.txt` produced from the program `sobol_method.py`. The name of the -data file can be modified using the option DATAFILE. +A .pdf file is created called 'SankeyPowerFlow.pdf' in the directory the utility was run. +N.B. Rounding to whole integer can cause errors of $\pm$1 between adjacent arrows. -### Output +### Example Output -A .pdf file is created called `sobol_output.pdf`. The name of the produced pdf file can be specified -using the option OUTPUTFILE. +
+![Sankey flow chart of large tokamak scenario](../images/SankeyPowerFlow_from_large_tokamak.png) +
Figure 1: Sankey flow chart of power flows for the large tokamak scenario.
+
-### Options -| Argument | Description | -| - | - | -| `-h, --help` | show this help message and exit | -| `-f DATAFILE` | datafile for plotting, default = sobol.txt | -| `-o OUTPUTFILE` | filename of outputed pdf file, default = sobol_output.pdf | ## TF Stress distribution plots -> `./utilities/plot_stress_tf.py` +> `utilities/plot_stress_tf.py` Program to plot stress, strain and displacement radial distributions at the inboard mid-plane section of the TF coil. -This program uses the `SIG_TF.DAT` file, that store stress distributions of the VMCON point and stores the outputs +This program uses the `SIG_TF.json` file created by running `PROCESS`, that stores stress distributions of the VMCON point and stores the output plots in the `SIG_TF_plots/` folder, created if not existing. ### Discussion of the stress modelling assumptions -In case of a resisitive coil, the stress is calculated from a generalized plane strain model, hence provinding vertical +In case of a resisitive coil, the stress is calculated from a generalized plane strain model, hence providing vertical stress radial distribution, alongside the radial and the toroidal ones. This is not the case for superconducting magnets as a plane stress modelling is used for now. The reason is that a transverse orthotropic formulation of the generalized -plane strain, is needed to correctly take the difference of the casing in the vertical direction properly. This will be +plane strain is needed to correctly take the difference of the casing in the vertical direction properly. This will be done in the near future. ### Usage ```bash -usage: plot_stress_tf.py [-h] [-p [PLOT_SELEC]] [-sf [SAVE_FORMAT]] [-as [AXIS_FONT_SIZE]] +python utilities/plot_stress_tf.py [-h] [-f path/to/SIG_TF.json] [-p [PLOT_SELEC]] [-sf [SAVE_FORMAT]] [-as [AXIS_FONT_SIZE]] ``` ### Option | Argument | Description | | - | - | -| `-h, --help` | show this help message and exit | -| `-f, --input-file` | `SIG_TF.DAT` input file +| `-h, --help` | show help message and exit | +| `-f, --input-file` | `SIG_TF.json` input file | `-p, --plot_selec [PLOT_SELEC]` | Plot selection string : | | - | - if the string contains `sig`, plot the stress distributions | | - | - if the string contains `strain`, plot the strain distributions | | - | - if the string contains `disp`, plot the radial displacement distribution | -| - | - if the string contains `all`, plot stress and displecement distributions | +| - | - if the string contains `all`, plot stress and displacement distributions | | `-sf, --save_format [SAVE_FORMAT]` | output format (default='pdf') | | `-as, --axis_font_size [AXIS_FONT_SIZE]` | Axis label font size selection (default=18) | -## N-Dimensional Scanner Utility - -This suite of Python utilities allows the user to conduct systematic, multi-dimensional parameter -studies with PROCESS. It systematically varies a set of N user defined parameters within predefined -bounds. This final results can be evaluated using the corresponding visualisation tool and/or saved -in standard NetCDF format for further analysis. -The suite contains the following executables: - -* `ndscan.py` - executes the Nd-scan as specified in the configuration file. -* `ndscan_package_only.py` - creates a NetCDF output file from a previous Nd-scan run. -* `ndscan_and_package.py` - both executes the Nd-scan and creates the NetCDF output file. -* `ndscan_visualisation.py` - visualises the NetCDF output. - -**Input** `ndscan.json`, `IN.DAT` - -**Output**: All MFILES in subdirectory `MFILES`, packaged NetCDF output file as named in configuration -file (default `NdscanOutput.nc`). - -When running any of the ndscan tools, optional arguments are: - -``` -# to specify another location/name for the configfile -ndscan.py -f CONFIGFILE - -Use -h or --help for help -``` - -For the visualisation tool the corresponding NetCDF input file can also be specified with `-f`. Per -default `NdscanOutput.nc` is used. - -**Configuration Options**: The configuration file `ndscan.json` uses the JSON format (www.json.org) -and has the following style - -``` -{ - "axes": [ - { - "lowerbound": 7.5, - "steps": 16, - "upperbound": 9.0, - "varname": "rmajor" - }, - { - "lowerbound": 5.5, - "steps": 16, - "upperbound": 7.0, - "varname": "bt" - } - ], - "_comment": [ - "This field helps to describe the config file for users reading", - "Anything you write in here will be ignored by the code", - "Each axis has these configuration parameters available:", - "varname", - "lowerbound", - "upperbound", - "'steps': number of evaluations" - ], - "optionals": { - "remove_scanvars_from_ixc": true, - "smooth_itervars": true - }, - "description": "Description of the goals of this specific run", - "title": "NdscanOutput", - "author": "Me", - "output_vars": [ - "beta", - "pheat", - "powfmw", - "pradmw", - "powerht", - "cirpowfr", - "te", - "hfact", - "dnelimt", - "dene", - "rmajor", - "bt", - "pnetelmw", - "coe", - "fwbllife", - "capcost", - "palpmw", - "wallmw", - "taueff" - ] -} -``` -The only required input parameters in the configuration file are the scan axes, out of which at least -one has to be specified. For each axis a `varname` a `lowerbound`, an `upperbound` and the number of -`steps` > ` have to be specified. All other parameters in the configuration file are optional. The -parameters relevant for running the N-dimensional scan are: - -`_comment` Anything in the comment section (like all other undefined sections) is for the user only -and will be ignored by the program. - -`optional:remove_scanvars_from_ixc` Removes all scanning variables from the iteration variables of -the `IN.DAT` file (default = True). - -`optionals:smooth_itervars` Ensures that each next point starts from the last successful run. This -increases the run time, but improves the convergence and reduces errors. - -The parameters only relevant to the creation of the summary NetCDF file are: - -`author` The author will be copied into the NetCDF file. - -`description` The description will be copied into the NetCDF file. - -`title` Name of the output NetCDF file (default `NdscanOutput`) that is also copied into the title -of the NetCDF file. - -`output_vars` The variables that will be extracted from the MFILEs and stored in the NetCDF file. -(Only need when creating the NetCDF output file.) - -Additional parameters can be specified as in the `config` section for the `evaluate_uncertainties.py` tool. - -The resulting NetCDF file can be visualised using the `ndscan_visualisation.py` tool. It has an -interactive menu and is fairly self-explanatory. ## Turn output into input -`write_new_in_dat.py` +`utilities/write_new_in_dat.py` This program creates a new `IN.DAT` file with the initial values of all the iteration variables replaced by their results in `OUT.DAT`, if that output is a feasible solution. @@ -572,299 +262,106 @@ the new starting values. There is also an option to select the first feasible so **Output**: `new_IN.DAT` +### Usage ``` -usage: write_new_in_dat.py [-h] [-f MFILE.DAT] [-i IN.DAT] - -optional arguments: - -h, --help show this help message and exit - -lfp use the last feasible point from a scan (default) - -ffp use the first feasible point from a scan +python utilities/write_new_in_dat.py [-h] [-f path/to/MFILE.DAT] [-i path/to/IN.DAT] [-o path/to/new_IN.DAT] ``` -## Output plotting: create data file - -`make_plot_dat.py` - -Creates a `PLOT.DAT`-type file from `MFILE.DAT`. This is required by `plot_sweep.py`. +### Options -**Input**: `make_plot_dat.conf`, `MFILE.DAT` +| Argument | Description | +| - | - | +| `-h, --help` | show help message and exit | +| `-f` | file to read as MFILE.DAT | +| `-i` | file to read as IN.DAT | +| `-o` | file to write as new IN.DAT | +| `-lfp` | use the last feasible point from a scan (default) | +| `-ffp` | use the first feasible point from a scan | -**Output**: `make_plot_dat.out` -**Configuration Options**: Optional arguments are: -``` -# new variables for output -make_plot_dat.py -p rmajor -# writes make_plot_dat.out in columns -make_plot_dat.py --columns -# resets make_plot_dat.conf to PLOT.DAT layout -make_plot_dat.py --reset-config -# file to read as input -make_plot_dat.py -f MFILE.DAT -# run with default parameters -make_plot_dat.py --defaults -``` - -An example version of `make_plo_dat.conf` might look like this: - -``` -# make_plot_dat.out config file. -rmajor -aspect -rminor -bt -powfmw -pnetelmw -te -pdivt -sig_tf_case -sig_tf_wp -``` ## Plot scan results -`plot_mfile_sweep.py` +`process/io/plot_scans.py` -This utility plots normalised values of the iteration variables output by a parameter scan. Zero -indicates an iteration variable at its lower bound and 1 an iteration variable at its upper bound. +This utility plots the output of a PROCESS scan. PROCESS must be run on a scan-enabled input file to create an MFILE on which `plot_scans.py` can be run. More than one input file can be used and the different files will be plotted on the same graph. **Input**: `MFILE.DAT` -**Output** `sweep_fig.pdf` (default of as specified by the user) +**Output** `scan_var1_vs_var2.pdf` (var1 by default is `bmaxtf`, var2 specified by user) -Optional arguments are: - -``` -# creates sweep_fig.pdf with R0, te, aspect (same variable names as in MFILE.DAT) -python plot_mfile_sweep.py -p rmajor te aspect -# creates demo1.png with Te, n -python plot_mfile_sweep.py -o demo1.png -p te dene -# creates a sweep_fig.pdf with R0, aspect with a different MFILE.DAT -python plot_mfile_sweep.py -f diff_mfile.dat -p rmajor aspect -# Show plot to screen instead of saving with R0 and aspect -python plot_mfile_sweep.py -p rmajor aspect --show - -Use -h or --help for help -``` - -## Plot iteration variables and constraint residuals - -`diagnose_process.py` - -This utility aids the user to interpret PROCESS runs that do not find a feasible solution -(unless PROCESS has terminated prematurely). It reads the `MFILE.DAT` and plots the normalised -iteration variables, i.e. the iteration variable values normalised to their bounds such that 0 -indicates an iteration vraible at its lower bound and ` an iteration variable at its upper bound. -Furthermore, it shows the normalised constraint residuals. - -**Input**: `MFILE.DAT` - -**Output**: Displays plots on screen, still need to be saved by the user! (Remember to use `-Y` -or `-X`, if `ssh`ing into a remote machine!) - -Optional arguments are: +### Usage ``` -# allows to specify another location/name for the MFILE -python diagnose_process.py -f MFILE.DAT - -Use -h or --help for help +python process/io/plot_scans.py [-h] [-f path/to/MFILE(s)] [-yv 'output vars'] [-yv2 2nd axis output variable] ``` -## Plot two parameters from many MFILES - -`plot_comparison.py` - -``` -usage: plot_comparison.py [-h] [-x XAXIS] [-y YAXIS] [-e END] [f [f ...]] +### Options -Program to display the evolution of two variables in a selection of MFILEs. +| Argument | Description | +| - | - | +| `-h, --help` | show help message and exit | +| `-f` | file(s) to read as MFILE.DAT | +| `-yv` | select the output variables | +| `-yv2` | select the 2nd axis output variable | +| `-o` | Output directory for plots, defaults to current working directory. | +| `-sf` | output format (default='pdf') | +| `-as` | Axis label font size selection (default=18) | +| `-ln` | Label names for plot legend. If multiple input files used then list the same number of label names eg: -nl 'leg1 leg2', (default = MFile file name) | -positional arguments: - f list of MFiles to be plotted; default = MFILE.DAT -optional arguments: - -h, --help show this help message and exit - -x XAXIS, --xaxis XAXIS - x-axis, default=rmajor - -y YAXIS, --yaxis YAXIS - y-axis, default=powfmw - -e END, --end END file format default = pdf -``` ## Plot a pie chart of the cost breakdown -`cost_pie.py` +`utilities/costs_pie.py` -This utility plots the cost breakdown as a pie chart giving each component as a percentage. This allows for the most expensive areas to be easily identified. For the 1990 cost mdoel, an additional plot showing how direct , indirect and contingency costs contribute to the overall budget is shown. +This utility plots the cost breakdown as a pie chart giving each component as a percentage. This allows for the most expensive areas to be easily identified. For the 1990 cost model, an additional plot showing how direct, indirect and contingency costs contribute to the overall budget is shown. **Input**: `MFILE.DAT` **Output**: Displays plot of the cost breakdown to screen. For the 1990 cost model, the breakdown for direct, indirect and contingency are also shown. These can be saved with `-s` argument (`cost_pie.pdf` and `direct_cost_pie.pdf`). -Help information: - +### Usage ``` -usage: cost_pie.py [-h] [-f MFILE] [-s] - -Displays the cost breakdown as a pie chart. For more information contact -Stuart.Muldrew@ukaea.uk - -optional arguments: --h, --help show this help message and exit --f MFILE specify the MFILE (default=MFILE.DAT) --s, --save save as well as displaying figure +python utilities/costs_pie.py [-h] [-f path/to/MFILE] [-s] ``` +If no `-f` argument is provided it assumes a file named `MFILE.DAT` is in the current directory. -## Plot a bar chart of the cost breakdown - -`cost_bar.py` - -This utility plots the cost breakdown as a bar chart giving the cost of each component. This allows for the most expensive areas to be easily identified. For the 1900 cost model, an additional plt showing how the direct, indirect and contingency costs contribute to the overall bidget is shown. Multiple MFILEs can be specified allowing for different PROCESS runs to be compared on the same plot. An inflation factor can be specified using the `-inf` argument, which multipled all the costs by that value. - -**Input**: `MFILE.DAT` - -**Output**: Displays plot of the cost breakdown to screen. For the 1990 cost model, the breakdown for direct, indirect and contingency is also shown. These can be saved with `-s` argument (`cost_bar.pdf` and `direct_cost_bar.pdf`). - -Help information: - -``` -usage: cost_bar.py [-h] [-f f [f ...]] [-s] [-inf INF] +### Options -Displays the cost breakdown as a bar chart. Multiple MFILEs can be given and -will be plotted on the same chart. For more information contact -Stuart.Muldrew@ukaea.uk +| Argument | Description | +| - | - | +| `-h, --help` | show help message and exit | +| `-f MFILE` | specify the MFILE | +| `-s, --save` | save figure | -optional arguments: --h, --help show this help message and exit --f f [f ...] specify the MFILE(s) to plot --s, --save save as well as displaying figure --inf INF Inflation Factor (multiplies costs) -``` -## POPCON plot +## Plot a bar chart of the cost breakdown -`popcon.py` +`utilities/costs_bar.py` -This utility generates a POPCON plot from an MFILE that can be saved with the `-s` argument. `-x`, `-y` and `-z` allow the user to set the definition of temperature, density and power respectively that is plotted. Currently the impurity is set with an effective charge, and this can be parsed using `-zimp` (default is Argon). The routine also features a test case that can be run by supplying the `-t` argument only. +This utility plots the cost breakdown as a bar chart giving the cost of each component. This allows for the most expensive areas to be easily identified. For the 1990 cost model, an additional plot showing how the direct, indirect and contingency costs contribute to the overall budget is shown. Multiple MFILEs can be specified allowing for different PROCESS runs to be compared on the same plot. An inflation factor can be specified using the `-inf` argument, which multiplies all the costs by that value. **Input**: `MFILE.DAT` -**Output**: Displays POPCON plot to screen. This can be saved with `-s` argument (`popcon.pdf`). - -Help information: - -``` -usage: popcon.py [-h] [-f MFILE] [-s] [-t] [-x X] [-y Y] [-z Z] [-zimp ZIMP] - -Displays a POPCON plot for input MFILE. For more information contact -Stuart.Muldrew@ukaea.uk or Peter.Knight@ukaea.uk - -optional arguments: --h, --help show this help message and exit --f MFILE specify the MFILE (default=MFILE.DAT) --s, --save save as well as displaying figure --t, --test Test mode: ignores MFILE and runs with R Kembleton's test values --x X Temperature (x-axis): (0) Central (1) Volume (default=1) --y Y Density (y-axis): (0) Central (1) Volume (2) Line (default=1) --z Z Power (z-axis): (0) Aux for balance (1) Net (2) Fusion -(default=0) --zimp ZIMP Impurity charge (default=18 Ar) -``` - -## Profile plots - -`plot_profiles.py` - -This utility allows for plotting of the temperature and density profiles of a number of MFILEs. The options are described below: +**Output**: Displays plot of the cost breakdown to screen. For the 1990 cost model, the breakdown for direct, indirect and contingency is also shown. These can be saved with `-s` argument (`cost_bar.pdf` and `direct_cost_bar.pdf`). +### Usage ``` - arguments: - -h, --help show this help message and exit - -f MFILE [MFILE ...] specify the llist of MFILEs to use - -s, --save save as well as displaying the figure - -o, name of the output pdf file - -n N, scan number in MFILE to use +python utilities/costs_bar.py [-h] [-f f [f ...]] [-s] [-inf INF] ``` -## VMCON optimisation plots - -`plot_opti_process.py` - -Macro plotting a set of information about the `VMCON` optimisation from an output file called `OPT.DAT`. The file contains: -* The PROCESS indexes of the constraints and the variables used for the considered run. -* The variables described in [table 1](#table-1) stored for each `VMCON` iteration. Please notte that only one set of number is associated in per `VMCON` iteration. - - - -| Variable description | PROCESS code name | `VMCON` doc def | -| ------------- | ------------- | ------------- | -| Normalized figure of merit | `abs(obj)` | $f(x)$ | -| VMCON convergence criteria | `sum` | $\left| \nabla_x f(\vec{x}^{j-1})^T \cdot \vec{\delta}^{j} \right| + \sum^m_{i=1}\left| \lambda^j_i c_i(\vec{x}^{j-1}) \right|$ | -| Constraints residual quadratic sums | `sqsumsq` | $\sqrt{\sum^{m}_{i=1} c^{2}_i(\vec{x}^{j-1})}$ | -| Individual residual values | `conf(i)` | $c_i(\vec{x}^{j-1})$ | -| Normalized optimization variables values | `x(i)` | $\vec{x}^{j-1}$ | - -Table 1: *Variables stored in `OPT.DAT`* +### Options -The python plot routines proposes the following plots: +| Argument | Description | +| - | - | +| `-h, --help` | show help message and exit | +| `-f MFILE` | specify the MFILE(s) to plot | +| `-s, --save` | save figure | +| `-inf INF` | Inflation Factor (multiplies costs) | -1. Figure of merit plot
Evolution of the figure of merit with the `VMCON` index -2. Convergence plot
`VMCON` index evolution of: - * The `VMCON` convergence parameter - * The quadratic sum of the constraints residuals - * The maximum between the `VMCON` convergence parameter and the constraints residual quadratic sum, actually used to test the PROCESS convergence. -3. Dominant constraints plots
The last `VMCON` iteration is used order to rank the constrints with their residual values. This allows to plot the `VMCON` index evolution of: - * The $N_{const}^{dom}$ dominant constraints values ($N_{const}^{dom}$ can be used defined) - * The quadratic sum of the dominant constraints - * The total quadratic sum of the constraints
-The difference of the two quadratic sums allow to check of any other variables contribute to the constraints for any step of the optimisation -4. Selected constraint plot
Any constrints residual evolution can be plotted given its PROCESS ID number. The associated plot will contain: - * The selected constraint evolution - * The total quadratic sum of the constraints
-This allows a clearer visualisation of a given constraint evolution. -5. Major variable evolution
The variation amplitude of the optimisation variables $\max(\vec{x}^{j-1}) - \min(\vec{x}^{j-1})$ is used to rank the variables. This allows to plot the `VMCON` index evolution of the $N_{const}^{var}$ dominant variables ($N_{const}^{dom}$ can be used defined). -6. Selected variable pair trajectory plot
Any pair of variables can be selected using their PROCESS ID defined in vardes, to plot the evolution of their trajectory. The color of each points corresponds to the value of the PROCESS convergence criteris (on a base 10 lograithmic scale). -The use of the macro is described on the help option of the macro , shown for indicative purpose - -``` -usage: plot_opti_process.py [-h] [-p [PLOT_SELEC]] [-ndc [N_DOM_CONST]] -[-ndv [N_DOM_VAR]] [-ic [I_CONST]] -[-ixv [I_X_VAR]] [-iyv [I_Y_VAR]] -[-sf [SAVE_FORMAT]] [-as [AXIS_FONT_SIZE]] - -Plot optimization information - -optional arguments: --h, --help show this help message and exit --p [PLOT_SELEC], --plot_selec [PLOT_SELEC] -Plot selection string : - * If it containts 'FoM' -> Figure of Merit plot - * If it containts 'conv' -> convergence criteria plot - * If it containts 'domconst' -> dominant constraint plot - * If it containts 'allconst' -> a plot for each constraint stored in All_Const/ - * If it containts 'domvar' -> dominant variables plot - * If it containts 'allvar' -> a plot for each variable in All_Var/ - * If it containts 'all' -> all the mentionned plots (default value) --ndc [N_DOM_CONST], --n_dom_const [N_DOM_CONST] -number of plotted dominant constaints (default=3) --ndv [N_DOM_VAR], --n_dom_var [N_DOM_VAR] -number of plotted dominant variables (default=4) --ic [I_CONST], --i_const [I_CONST] -Selection of the constraint to be plotted (PROCESS number defined in vardes, default=-1) --ixv [I_X_VAR], --i_X_var [I_X_VAR] -X variable on pair plot selection (PROCESS number defined in vardes, default=-1) --iyv [I_Y_VAR], --i_Y_var [I_Y_VAR] -Y variable on pair plot selection (PROCESS number defined in vardes, default=-1) --sf [SAVE_FORMAT], --save_format [SAVE_FORMAT] -output format (default='eps') --as [AXIS_FONT_SIZE], --axis_font_size [AXIS_FONT_SIZE] -Axis label font size selection (default=14) -``` - -The output can be defined in any visual data format supported by pyplot, the label font size can set. Please not that to select individual constraints or variable pair plots, it is enough to precisse the `-ic` and the `-ixv/-iyv` pair, respectively. # Uncertainty Tools @@ -874,7 +371,7 @@ The uncertainty evaluation tool has a significantly longer run time than typical ## `evaluate_uncertainties.py` -This program evaluates the uncertainties of a single PROCESS design point by use of Monte Carlo method as described in[^5]. It is recommended to submit this script as a [batch job](#batch-jobs) to Freia when 1000s of sample points are required. +This program evaluates the uncertainties of a single PROCESS design point by use of Monte Carlo method as described in[^5] by default, and can also use the Morris method and Sobol techniques. It is recommended to submit this script as a [batch job](#batch-jobs) to Freia when 1000s of sample points are required. ### Input @@ -927,7 +424,7 @@ The configuration file `config_evaluate_uncertainties.json` uses the [JSON forma ... ``` -By convention, we have designated metadata about the PROCESS runs as having a preceding underscore to distinguish these values from the other configuration data used directly by the tools or PROCESS itself. Furthermore, all the optional attributes that can be changed when running PROCESS from most Python utilities, e.g. `run_process.py`, can be specified in the "config" section. All these values have default values and do not need to be set. +By convention, we have designated metadata about the PROCESS runs as having a preceding underscore to distinguish these values from the other configuration data used directly by the tools or PROCESS itself. Furthermore, all the optional attributes that can be changed when running PROCESS from most Python utilities can be specified in the "config" section. All these values have default values and do not need to be set. - `runtitle`: is a one line description of the purpose of the run to be saved in `README.txt` in the working directory as well as the `runtitle` parameter in the `OUT.DAT` and `MFILE.DAT` files. Per default it is empty. @@ -965,117 +462,65 @@ By convention, we have designated metadata about the PROCESS runs as having a pr - `uncertainties_data.h5`: This file contains the output variables of each successfully converged PROCESS run generated by the `evaluate_uncertainties.py` script. PROCESS output variables can be plotted using using the `hdf_to_scatter_plot.py` script. This file uses the [HDF format](https://www.hdfgroup.org/solutions/hdf5/) and requires [software](https://www.hdfgroup.org/downloads/hdfview/) to view its contents in a human legible format. -- `UQ_error_summary.txt`: This file is an ascii text file summarising all values of the uncertain parameter inputs, the normalised values of iteration variables (labelled "n_"variable name) and whether their runs have found a feasible solution (`ifail=1`), have encountered any process erros (`ifail=-1`, `error_status=3`) or whether they have not found a feasible solution. This file can be used to analyse parameter spaces prone to errors. +- `README.txt`, `process.log`, `MFILE.DAT`, `OUT.DAT`, `SIG_TF.DAT`, `SIG_TF.json`, `OPT.DAT`, `PLOT.DAT`: Typical PROCESS output generated by the last run. -- `README.txt`, `process.log`, `MFILE.DAT`, `OUT.DAT`, `SIG_TF.DAT`, `OPT.DAT`, `PLOT.DAT`: Typical PROCESS output generated by the last run. - -### Running the script +### Usage The `evaluate_uncertainties.py` script is run with with the option `-f` to specify the path to the `config_evaluate_uncertainties.json` file: ``` -python3 process/uncertainties/evaluate_uncertainties.py -f process/uncertainties/config_evaluate_uncertainties.json +python process/uncertainties/evaluate_uncertainties.py -f path/to/config_evaluate_uncertainties.json -m method ``` -The uncertainty analysis technique used can be specified using '`-m monte_carlo/sobol_method/morris_method`' but the default is Monte Carlo. Use `-h` or `--help` for help. - -## `display_uncertainties.py` - -Note: The untertainties tool no longer produces an .nc file as output and this script has not been updated to reflect this change. -This is a utility to display the output file `uncertainties.nc` created by the `evaluate_uncertainties.py` tool described above. - -By default, if run in the working directory of an uncertainty evaluation, it creates a scatter lot of each user defined output parameter against the next parameter in the list. It also hows the 1D histograms of each parameter distribution. If two specific variables are given as arguments, the tool plots only these two against each other. - -**Input**: `uncertainties.nc` - -**Output**: `Uncertainties_varname1_varname2.pdf` - -Usage: - -``` -display_uncertainties.py [-h] [-f FILENAME] [-e END] [v [v ...]] - -Program to display uncertainties of a given PROCESS design point. +### Options -positional arguments: - v list of variables to be plotted; default = all +| Argument | Description | +| - | - | +| `-h, --help` | show help message and exit | +| `-f CONFIGFILE` | specify the path to the config file | +| `-m METHOD` | type of uncertainty analysis performed, default = monte_carlo, other options = sobol_method, morris_method | -optional arguments: - -h, --help show this help message and exit - -f FILENAME, --filename FILENAME - uncertainties data file, default = uncertainties.nc - -e END, --end END file format default = .pdf -``` +The uncertainty analysis technique used can be specified using '`-m monte_carlo/sobol_method/morris_method`' but the default is Monte Carlo. Use `-h` or `--help` for help. -## `diagnose_uncertainties.py` -This is a python facility to display the input parameter distributions in the final runs vs. the ones specified in the input file. This can be used to determine whether the input distributions are sufficiently sampled or whether the resulting distributions are skewed due to unfeasible designs being excluded. +## Sobol Plotting -**Input** `uncertainties.nc`, `evaluate_uncertainties.json` +> `process/uncertainties/sobol_plotting.py` -**Output** `Uncertainties_Diagnostic_varname.pdf` +Program to plot the output of the the Sobols sensitivity analysis at a given PROCESS design point. +It creates a bar chart showing both the first order and total Sobol indices for each variable and gives +the 95% confidence intervals. -Usage: +### Usage +```bash +python process/uncertainties/sobol_plotting.py [-h] [-f path/to/DATAFILE] [-o OUTPUTFILE] ``` -diagnose_uncertainties.py [-h] [-e END] [-u UNCERTAINTIES] [-f FILENAME] - -Program to check the final uncertainty distributions in the input parameters. - -optional arguments: - -h, --help show this help message and exit - -e END, --end END file format default =pdf - -u UNCERTAINTIES, --uncertainties UNCERTAINTIES - uncertainties config file default = - evaluate_uncertainties.json - -f FILENAME, --filename FILENAME - uncertainties data file, default =uncertainties.nc -``` - -# Miscellaneous - -## `fit_profile.py` +If no `-f` argument is provided it assumes a file named `sobol.txt` is in the current directory. -This is a python tool to fit a general temperature or density profile as given by the pedestalised profile parameterisation (`ipedestal=1`) to an ascii table. It is using a least squares method and it fitting the position of the pedestal as well as the peaking factors. Optional arguments are - -``` - -h, --help show this help message and exit - -f FILENAME, --filename FILENAME - ascii file containing data in columns, default = - profile.txt - -r RHO, --rho RHO column of the normalised radius rho=r/a, default = 0 - -n DENSITY, --density DENSITY - column of the density profile, default = 1 - -t TEMPERATURE, --temperature TEMPERATURE - column of the temperature profile, default = 2 - -rn RHOPEDN, --rhopedn RHOPEDN - user defined initial guess of the density pedestal - position, if outside [0,1] starts at 0.9, default = - 0.9 - -rt RHOPEDT, --rhopedt RHOPEDT - user defined initial guess of the temperature pedestal - position, if outside [0,1], starts at 0.9, default = - 0.9 -``` +### Options -If the column of the density or temperature data does not exist, it is ignored. A warning is issued. +| Argument | Description | +| - | - | +| `-h, --help` | show help message and exit | +| `-f DATAFILE` | path to datafile for plotting, default = sobol.txt | +| `-o OUTPUTFILE` | filename of outputed pdf file, default = sobol_output.pdf | -## `create_dicts.py` +### Configuration File -This automatically generates the `process_dicts.py` file used by PROCESS utility programs. It does this by scanning the Fortran source code. The standard output should be rejected, using +The tool reads the data contained `sobol.txt` produced from running `evaluate_uncertainties.py` with the `sobol_method`. The name and location of the data file can be modified using the option DATAFILE. -`create_dicts.py > process_dicts.py` +### Output -## Line Length Checker +A .pdf file is created called `sobol_output.pdf`. The name of the produced pdf file can be specified +using the option OUTPUTFILE. -`line_length_standard.py` -Script to check line length of repository files ## References [^1]: M. Kovari, R. Kemp, H. Lux, P. Knight, J. Morris, D. J. Ward *"PROCESS: a systems code for fusion power plants - Part 1: Physics"*, Fusion Engineering and Design 89, 30543069 (2014), http://dx.doi.org/10.1016/j.fusengdes.2014.09.018 [^2]: M. Kovari, F. Fox, C. Harrington, R. Kembleton, P. Knight, H. Lux, J. Morris *"PROCESS: a systems code for fusion power plants - Part 2: Engineering"*, Fus. Eng. & Des. 104, 9-20 (2016) [^3]: H. Lux, R. Kemp, D.J. Ward, M. Sertoli *"Impurity radiation in DEMO systems modelling"*, Fus. Eng. & Des. 101, 42-51 (2015) -[^4]: H. Lux, R. Kemp, E. Fable, R. Wenninger, *"Radiation and con nement in 0D fusion systems codes"*, PPCF, 58, 7, 075001 (2016) +[^4]: H. Lux, R. Kemp, E. Fable, R. Wenninger, *"Radiation and confinement in 0D fusion systems codes"*, PPCF, 58, 7, 075001 (2016) [^5]: H. Lux, R. Kemp, R. Wenninger, W. Biel, G. Federici, W. Morris, H. Zohm, "Uncertainties in power plant design point evaluations", Fusion Engineering and Design, Vol 123, 63-66, 2017 diff --git a/process/io/mfile_comparison.py b/process/io/mfile_comparison.py index ea7b40d7..7a470cfd 100755 --- a/process/io/mfile_comparison.py +++ b/process/io/mfile_comparison.py @@ -472,8 +472,8 @@ def main(arg): parser = argparse.ArgumentParser( description="Produce a comparison " "between two PROCESS " - "MFILEs. User Can speicify " - "level of differences to show" + "MFILEs. User Can specify " + "level of differences to show. " "For info contact " "james.morris2@ccfe.ac.uk" ) diff --git a/process/io/plot_proc.py b/process/io/plot_proc.py index 6014a86a..06d07af3 100755 --- a/process/io/plot_proc.py +++ b/process/io/plot_proc.py @@ -2826,9 +2826,7 @@ def parse_args(args): help="specify PLASMOD profile file", ) - parser.add_argument( - "-s", "--show", help="show plot as well as saving figure", action="store_true" - ) + parser.add_argument("-s", "--show", help="show plot", action="store_true") parser.add_argument("-n", type=int, help="Which scan to plot?") @@ -3117,8 +3115,7 @@ def main(args=None): # show fig if option used if args.show: - plt.show(page1) - plt.show(page2) + plt.show(block=True) # This bit doesn't work - the argument is not recognised for some reason.: # if args.svg: diff --git a/process/io/plot_sankey.py b/process/io/plot_sankey.py index e5843a35..1d0ee371 100755 --- a/process/io/plot_sankey.py +++ b/process/io/plot_sankey.py @@ -12,7 +12,7 @@ import matplotlib import argparse from pylab import show, savefig -from process.io.sankey_funcs import plot_full_sankey, plot_sankey +from process.io.sankey_funcs import plot_sankey matplotlib.use("Agg") @@ -32,19 +32,13 @@ def main(args=None): "-m", "--mfile", default="MFILE.DAT", help="mfile name, default = MFILE.DAT" ) - PARSER.add_argument("-f", "--full", action="store_true", help="Plot full version") - ARGS = PARSER.parse_args(args) ######################################################### # main program - if ARGS.full: - plot_full_sankey(ARGS.mfile) - savefig("SankeyPowerFlow_full." + ARGS.end) - else: - plot_sankey(ARGS.mfile) - savefig("SankeyPowerFlow." + ARGS.end) + plot_sankey(ARGS.mfile) + savefig("SankeyPowerFlow." + ARGS.end) show() diff --git a/utilities/costs_bar.py b/utilities/costs_bar.py index ad594249..ef13702e 100644 --- a/utilities/costs_bar.py +++ b/utilities/costs_bar.py @@ -353,9 +353,7 @@ def comp_step(): "-f", metavar="f", type=str, nargs="+", help="specify the MFILE(s) to plot" ) - parser.add_argument( - "-s", "--save", help="save as well as displaying figure", action="store_true" - ) + parser.add_argument("-s", "--save", help="save figure", action="store_true") parser.add_argument("-inf", type=float, help="Inflation Factor (multiplies costs)") diff --git a/utilities/costs_pie.py b/utilities/costs_pie.py index 239e776b..3984ccaa 100644 --- a/utilities/costs_pie.py +++ b/utilities/costs_pie.py @@ -302,9 +302,7 @@ def step_cost_model(): help="specify the MFILE (default=MFILE.DAT)", ) - parser.add_argument( - "-s", "--save", help="save as well as displaying figure", action="store_true" - ) + parser.add_argument("-s", "--save", help="save figure", action="store_true") args = parser.parse_args() diff --git a/utilities/plot_stress_tf.py b/utilities/plot_stress_tf.py index 6a609c02..31ccfca5 100644 --- a/utilities/plot_stress_tf.py +++ b/utilities/plot_stress_tf.py @@ -35,7 +35,7 @@ "--plot_selec", nargs="?", default="all", - help="Plot selection string :\n - If it containts 'sig' -> Stress radial dependency \n - If it containts 'strain' -> Strain \n - If it containts 'disp' -> Displacement \n - If it containts 'all' -> all the mentionned plots (default value)", + help="Plot selection string :\n - If it containts 'sig' -> Stress radial dependency \n - If it containts 'strain' -> Strain \n - If it containts 'disp' -> Displacement \n - If it containts 'all' -> all the mentioned plots (default value)", ) parser.add_argument( "-sf",