From 602deb65d40f287620e9d3c82f03138fb5e96f1c Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 26 Apr 2020 11:47:29 +0100 Subject: [PATCH 1/7] Move printing options into TokamakEquilibrium.__init__() Previously was called in TokamakEquilibrium.makeRegions() which had the same effect as makeRegions is called from __init__, but it's clearer to call directly from __init__. --- hypnotoad/cases/tokamak.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hypnotoad/cases/tokamak.py b/hypnotoad/cases/tokamak.py index d89a4019..f4acee6f 100644 --- a/hypnotoad/cases/tokamak.py +++ b/hypnotoad/cases/tokamak.py @@ -236,6 +236,9 @@ class Options (self.user_options) super().__init__(**kwargs) + # Print the table of options + print(optionsTableString(self.user_options, self.default_options)) + if make_regions: # Create self.regions self.makeRegions() @@ -470,9 +473,6 @@ def psi_to_psinorm(psi): np.abs((self.user_options.psi_core - self.user_options.psi_sol) / 20.0), ) - # Print the table of options - print(optionsTableString(self.user_options, self.default_options)) - # Filter out the X-points not in range. # Keep only those with normalised psi < psinorm_sol self.psi_sep, self.x_points = zip( From 945afde9030eea62b02e69c631a9398efbeac734 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 26 Apr 2020 18:17:56 +0100 Subject: [PATCH 2/7] Allow offset of points nearest X-point from X-point to be modified Adds xpoint_offset option to control how far points that should be at the X-point are shifted to avoid the null. --- hypnotoad/cases/tokamak.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hypnotoad/cases/tokamak.py b/hypnotoad/cases/tokamak.py index f4acee6f..4e2802e5 100644 --- a/hypnotoad/cases/tokamak.py +++ b/hypnotoad/cases/tokamak.py @@ -68,6 +68,11 @@ class TokamakEquilibrium(Equilibrium): psi_sol_inner=None, # Default: psinorm_sol_inner psi_pf_lower=None, # Default: psinorm_pf_lower psi_pf_upper=None, # Default: psinorm_pf_upper + # + # Tolerance for positioning points that should be at X-point, but need to be + # slightly displaced from the null so code can follow Grad(psi). + # Number between 0. and 1. + xpoint_offset=0.5, ).push( Options( # These are HypnotoadOptions @@ -1179,7 +1184,9 @@ def psival(angle): ] # Add points to the beginning and end near (but not at) the X-points - diff = 0.5 + diff = self.user_options.xpoint_offset + if diff < 0.0 or diff > 1.0: + raise ValueError(f"xpoint_offset={diff} should be between 0 and 1.") region["points"] = ( [(1.0 - diff) * start_x + diff * points[0]] From 06cbd007e12d9f00f1557264abc50b05d730bf42 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 26 Apr 2020 18:19:52 +0100 Subject: [PATCH 3/7] Call read_geqdsk to recreate TokamakEquilibrium in run() for gui Some settings are needed in TokamakEquilibrium.__init(), so need to create a new object if they are changed before run(). --- hypnotoad/gui/gui.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hypnotoad/gui/gui.py b/hypnotoad/gui/gui.py index 658accc3..960792cc 100644 --- a/hypnotoad/gui/gui.py +++ b/hypnotoad/gui/gui.py @@ -323,6 +323,10 @@ def run(self): ) return + # Call read_geqdsk to recreate self.eq object in case any settings needed in + # __init__ have been changed + self.read_geqdsk() + self.statusbar.showMessage("Running...") self.mesh = BoutMesh(self.eq) self.mesh.calculateRZ() From f1170bf60f8393d02e4dfbedb3c52c663eb3afca Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 26 Apr 2020 18:21:19 +0100 Subject: [PATCH 4/7] Catch errors in HypnotoadGui.run() Allow settings to be adjusted to retry, instead of hypnotoad-gui closing on any error. --- hypnotoad/gui/gui.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hypnotoad/gui/gui.py b/hypnotoad/gui/gui.py index 960792cc..7fc755a9 100644 --- a/hypnotoad/gui/gui.py +++ b/hypnotoad/gui/gui.py @@ -328,7 +328,17 @@ def run(self): self.read_geqdsk() self.statusbar.showMessage("Running...") - self.mesh = BoutMesh(self.eq) + try: + self.mesh = BoutMesh(self.eq) + except (ValueError, SolutionError): + self.statusbar.showMessage( + "Error in grid generation, change settings and run again!" + ) + self.statusbar.setStyleSheet( + f"QLineEdit {{ background-color: {COLOURS['red']} }}" + ) + return + self.mesh.calculateRZ() self.statusbar.showMessage("Done!", 2000) From 0302f2f007d0cde5ab8dd8af37df846a4f7b472f Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 26 Apr 2020 18:55:04 +0100 Subject: [PATCH 5/7] Update whats-new.md --- doc/whats-new.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/whats-new.md b/doc/whats-new.md index 87e5aa8c..5fd83538 100644 --- a/doc/whats-new.md +++ b/doc/whats-new.md @@ -2,6 +2,16 @@ What's new ========== +0.1.1 (unreleased) +------------------ + +### New Features + +- Catch errors in HypnotoadGui.run(), allows changing settings and pressing Run + button again if there was an error in grid generation (#24)\ + By [John Omotani](https://github.com/johnomotani) + + 0.1.0 (24th April 2020) ----------------------- From 217955b1aff0c09adbada70f31f713e7666d9bd9 Mon Sep 17 00:00:00 2001 From: John Omotani Date: Sun, 26 Apr 2020 19:09:38 +0100 Subject: [PATCH 6/7] Import SolutionError in gui.py --- hypnotoad/gui/gui.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hypnotoad/gui/gui.py b/hypnotoad/gui/gui.py index 7fc755a9..c601fd81 100644 --- a/hypnotoad/gui/gui.py +++ b/hypnotoad/gui/gui.py @@ -22,6 +22,7 @@ from .matplotlib_widget import MatplotlibWidget from ..cases import tokamak from ..core.mesh import BoutMesh +from ..core.equilibrium import SolutionError from ..__init__ import __version__ From e60dac8941e2c0807120df81a1c35827bf8bb347 Mon Sep 17 00:00:00 2001 From: Peter Hill Date: Mon, 27 Apr 2020 10:33:55 +0100 Subject: [PATCH 7/7] GUI: Print exception in error dialog box --- hypnotoad/gui/gui.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/hypnotoad/gui/gui.py b/hypnotoad/gui/gui.py index c601fd81..53068c52 100644 --- a/hypnotoad/gui/gui.py +++ b/hypnotoad/gui/gui.py @@ -15,6 +15,7 @@ QCompleter, QTableWidgetItem, QHeaderView, + QErrorMessage, ) from Qt.QtCore import Qt @@ -298,9 +299,15 @@ def read_geqdsk(self): ) return - with open(geqdsk_filename, "rt") as f: - # Need to take a copy so that read_geqdsk doesn't delete used keys - self.eq = tokamak.read_geqdsk(f, options=copy.deepcopy(self.options)) + try: + with open(geqdsk_filename, "rt") as f: + # Need to take a copy so that read_geqdsk doesn't delete used keys + self.eq = tokamak.read_geqdsk(f, options=copy.deepcopy(self.options)) + except (ValueError, RuntimeError) as e: + error_message = QErrorMessage() + error_message.showMessage(str(e)) + error_message.exec_() + return self.plot_widget.clear() self.eq.plotPotential(ncontours=40, axis=self.plot_widget.axes) @@ -331,13 +338,10 @@ def run(self): self.statusbar.showMessage("Running...") try: self.mesh = BoutMesh(self.eq) - except (ValueError, SolutionError): - self.statusbar.showMessage( - "Error in grid generation, change settings and run again!" - ) - self.statusbar.setStyleSheet( - f"QLineEdit {{ background-color: {COLOURS['red']} }}" - ) + except (ValueError, SolutionError) as e: + error_message = QErrorMessage() + error_message.showMessage(str(e)) + error_message.exec_() return self.mesh.calculateRZ()