Skip to content

Commit 0889fef

Browse files
andyclaude
andcommitted
QE: say that a unit cell is required, instead of silently refusing to launch
Reported live: "drawing a molecule doesn't do anything when it comes to creating a periodic system" and "Launch doesn't do anything". pw.x is a plane-wave code and cannot run on a non-periodic structure. ai.qe already refused loudly, naming the Builder's "Periodic Builder" panel -- but only at input-generation time, after the user had set up the entire calculation. And until the previous commit that message was being discarded by CalcEd anyway. Now the requirement is declared per code: <RequiresPeriodic>true</RequiresPeriodic> which needed no parser change at all -- JCode::getValue() is a generic getElementsByTagName lookup -- and keeps the knowledge next to the code it describes rather than hardcoded in CalcEd. CalcEd holds such a calculation not-ready, and says why. That second part is the point: every OTHER reason a calculation is not ready is visible in the panel that owns it (no theory, an incomplete basis), but a missing unit cell is not, because nothing in CalcEd mentions cells at all. It belongs to the structure and is created in a different application. So the buttons just stayed greyed with no explanation, which is exactly what "Launch doesn't do anything" looked like from outside. Deliberately declarative rather than a QE special case: any future plane-wave or solid-state code gets the same behaviour by adding one line to its .edml. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EFMUNbw2UpRPmgsqviAowb
1 parent e1699e0 commit 0889fef

3 files changed

Lines changed: 67 additions & 0 deletions

File tree

‎data/client/cap/QuantumESPRESSO.edml‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@
111111
one-input/one-output), md, and phonons (ph.x is a separate
112112
executable). -->
113113
<Editor theorydialog="qetheory.py" runtypedialog="qeruntype.py">
114+
<!-- Plane waves cannot run without a cell, so CalcEd holds the
115+
calculation not-ready and says why, instead of letting the user
116+
complete the whole setup and discover it when ai.qe refuses at
117+
generation time. Read generically by JCode::getValue(), so no
118+
parser change was needed. -->
119+
<RequiresPeriodic>true</RequiresPeriodic>
120+
114121
<Theory category="PW" name="PW" needsBasis="false">
115122
<runtype>Energy</runtype>
116123
<runtype>Geometry</runtype>

‎src/apps/calced/CalcEd.C‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,10 +2030,51 @@ bool CalcEd::theoryNeedsBasis() const
20302030
return ret;
20312031
}
20322032

2033+
/**
2034+
* True when this code cannot run without a unit cell and the structure
2035+
* does not have one.
2036+
*
2037+
* Declared per code as <RequiresPeriodic>true</RequiresPeriodic> in its
2038+
* .edml. JCode::getValue() is a generic getElementsByTagName lookup, so
2039+
* this needed no parser change -- and being declarative keeps the
2040+
* knowledge next to the code it describes rather than hardcoded here.
2041+
*
2042+
* Quantum ESPRESSO is the case that motivated it: pw.x is a plane-wave
2043+
* code and cannot run on a non-periodic structure at all. ai.qe already
2044+
* refused loudly, naming the Builder's "Periodic Builder" panel -- but
2045+
* only at input-generation time, which is after the user has set up the
2046+
* whole calculation. Reported live as "drawing a molecule doesn't do
2047+
* anything when it comes to creating a periodic system" and "Launch
2048+
* doesn't do anything".
2049+
*/
2050+
bool CalcEd::requiresMissingCell() const
2051+
{
2052+
if (p_code == 0 || p_frag == 0) {
2053+
return false;
2054+
}
2055+
2056+
string flag;
2057+
if (!p_code->get_string("RequiresPeriodic", flag)) {
2058+
return false;
2059+
}
2060+
if (flag != "true" && flag != "TRUE" && flag != "yes" && flag != "1") {
2061+
return false;
2062+
}
2063+
2064+
return (p_frag->getLattice() == (LatticeDef*)0);
2065+
}
2066+
2067+
20332068
bool CalcEd::isReady() const
20342069
{
20352070
bool ret = false;
20362071

2072+
// A plane-wave code with no cell can never produce a valid deck, so
2073+
// it is not ready however complete the rest of the setup is.
2074+
if (requiresMissingCell()) {
2075+
return false;
2076+
}
2077+
20372078
if (p_iCalc->getState() < ResourceDescriptor::STATE_SUBMITTED
20382079
&& isDetailsReady()) {
20392080
if (!theoryNeedsBasis()) {
@@ -2361,6 +2402,24 @@ void CalcEd::enableLaunch()
23612402
if (ready) {
23622403
p_feedback->setRunState(ResourceDescriptor::STATE_READY);
23632404
} else {
2405+
// Say WHY, for the one not-ready reason the user cannot deduce
2406+
// from the setup panels. Everything else that blocks readiness
2407+
// (no theory, an incomplete basis) is visible in the dialog that
2408+
// owns it; a missing unit cell is not, because nothing in CalcEd
2409+
// mentions cells at all -- it belongs to the structure, and is
2410+
// created in a different application.
2411+
//
2412+
// Without this the Launch and Final Edit buttons simply stay
2413+
// greyed with no explanation, which is what "Launch doesn't do
2414+
// anything" looked like from the outside.
2415+
if (requiresMissingCell()) {
2416+
p_feedback->setMessage(
2417+
"This code requires a periodic unit cell, and this structure "
2418+
"has none.\n"
2419+
"Open the structure in the Builder, show the \"Periodic "
2420+
"Builder\" tool panel, and create a lattice.",
2421+
WxFeedback::ERROR);
2422+
}
23642423
if (p_iCalc->getState() == ResourceDescriptor::STATE_READY) {
23652424
p_feedback->setRunState(ResourceDescriptor::STATE_CREATED);
23662425
} else {

‎src/apps/calced/CalcEd.H‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ class CalcEd: public CalcEdGUI,
174174
bool isDetailsReady() const;
175175
bool theoryNeedsBasis() const;
176176
bool isReady() const;
177+
bool requiresMissingCell() const;
177178
bool isGbsValid();
178179

179180
// refresh & enable/disable & show/hide indicated field sets

0 commit comments

Comments
 (0)