Skip to content

Commit

Permalink
Fix off-by-one error with MO rendering
Browse files Browse the repository at this point in the history
Signed-off-by: Geoff Hutchison <[email protected]>
  • Loading branch information
ghutchis committed Dec 26, 2024
1 parent c7e3710 commit 6b08c83
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 32 deletions.
59 changes: 42 additions & 17 deletions avogadro/qtplugins/surfaces/orbitals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void Orbitals::setMolecule(QtGui::Molecule* mol)

// Stuff we manage that will not be valid any longer
m_queue.clear();
// m_currentRunningCalculation = -1;
m_currentRunningCalculation = -1;

if (m_basis) {
delete m_basis;
Expand Down Expand Up @@ -105,6 +105,12 @@ void Orbitals::loadOrbitals()

if (!m_dialog) {
m_dialog = new OrbitalWidget(qobject_cast<QWidget*>(parent()), Qt::Window);
connect(m_dialog, SIGNAL(orbitalSelected(unsigned int)), this,
SLOT(renderOrbital(unsigned int)));
connect(m_dialog, SIGNAL(renderRequested(unsigned int, double)), this,
SLOT(calculateOrbitalFromWidget(unsigned int, double)));
connect(m_dialog, SIGNAL(calculateAll()), this,
SLOT(precalculateOrbitals()));
}

m_dialog->fillTable(m_basis);
Expand All @@ -129,20 +135,22 @@ void Orbitals::openDialog()
{
if (!m_dialog) {
m_dialog = new OrbitalWidget(qobject_cast<QWidget*>(parent()), Qt::Window);
connect(m_dialog, SIGNAL(orbitalSelected(unsigned int)), this,
SLOT(renderOrbital(unsigned int)));
connect(m_dialog, SIGNAL(renderRequested(unsigned int, double)), this,
SLOT(calculateOrbitalFromWidget(unsigned int, double)));
connect(m_dialog, SIGNAL(calculateAll()), this,
SLOT(precalculateOrbitals()));
}

connect(m_dialog, SIGNAL(orbitalSelected(unsigned int)), this,
SLOT(renderOrbital(unsigned int)));
connect(m_dialog, SIGNAL(renderRequested(unsigned int, double)), this,
SLOT(calculateOrbitalFromWidget(unsigned int, double)));
connect(m_dialog, SIGNAL(calculateAll()), this, SLOT(precalculateOrbitals()));

m_dialog->show();
m_dialog->raise();
}

void Orbitals::calculateOrbitalFromWidget(unsigned int orbital,
double resolution)
{
m_updateMesh = true;
addCalculationToQueue(orbital, resolution, m_dialog->isovalue(), 0);
checkQueue();
}
Expand All @@ -152,6 +160,8 @@ void Orbitals::precalculateOrbitals()
if (m_basis == nullptr)
return;

m_updateMesh = false;

// Determine HOMO
unsigned int homo = m_basis->homo();

Expand Down Expand Up @@ -183,7 +193,7 @@ void Orbitals::precalculateOrbitals()
qDebug() << " precalculate " << i << " priority " << priority;
#endif
addCalculationToQueue(
i + 1, // orbital
i, // orbital
OrbitalWidget::OrbitalQualityToDouble(m_dialog->defaultQuality()),
m_dialog->isovalue(), priority);

Expand Down Expand Up @@ -334,7 +344,11 @@ void Orbitals::calculateCubeDone()

auto* watcher = &m_gaussianConcurrent->watcher();
watcher->disconnect(this);
calculationComplete();

if (m_updateMesh) {
calculatePosMesh();
} else
calculationComplete();
}

void Orbitals::calculatePosMesh()
Expand Down Expand Up @@ -384,6 +398,8 @@ void Orbitals::calculateNegMeshDone()
{
disconnect(m_meshGenerator, 0, this, 0);

calculationComplete();

// ask for a repaint
m_molecule->emitChanged(QtGui::Molecule::Added);
}
Expand All @@ -404,9 +420,16 @@ void Orbitals::calculationComplete()
checkQueue();
}

void Orbitals::renderOrbital(unsigned int orbital)
void Orbitals::renderOrbital(unsigned int row)
{
if (row == 0)
return;

unsigned int orbital = row - 1;

#ifndef NDEBUG
qDebug() << "Rendering orbital " << orbital;
#endif

// Find the most recent calc matching the selected orbital:
calcInfo calc;
Expand All @@ -419,16 +442,18 @@ void Orbitals::renderOrbital(unsigned int orbital)
}

// calculate the meshes
m_currentRunningCalculation = index;
m_molecule->clearMeshes();
if (index == -1) {
qDebug() << "Orbital not found, or still calculating. Cannot render.";
return;
// need to calculate the cube first
calculateOrbitalFromWidget(orbital, OrbitalWidget::OrbitalQualityToDouble(
m_dialog->defaultQuality()));
} else {
// just need to update the meshes
m_currentRunningCalculation = index;
m_runningMutex->tryLock();
calculatePosMesh(); // will eventually call negMesh too
}

// clear previous meshes from the molecule
m_molecule->clearMeshes();
calculatePosMesh(); // will eventually call negMesh too

// add the orbital to the renderer
QStringList displayTypes;
displayTypes << tr("Meshes");
Expand Down
1 change: 1 addition & 0 deletions avogadro/qtplugins/surfaces/orbitals.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ private slots:
float m_isoValue = 0.01;
int m_smoothingPasses = 1;
int m_meshesLeft = 0;
bool m_updateMesh = false;

OrbitalWidget* m_dialog = nullptr;
// OrbitalSettingsDialog* m_orbitalSettingsDialog = nullptr;
Expand Down
29 changes: 14 additions & 15 deletions avogadro/qtplugins/surfaces/orbitaltablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ QVariant OrbitalTableModel::headerData(int section, Qt::Orientation orientation,
return tr("Orbital");
case C_Energy:
return tr("Energy (eV)");
case C_Status:
return tr("Status");
case C_Symmetry:
return tr("Symmetry");
case C_Status:
return tr("Status");
default:
case COUNT:
return QVariant();
Expand Down Expand Up @@ -174,7 +174,6 @@ bool OrbitalTableModel::setOrbitals(const Core::BasisSet* basis)
// (HOMO|LUMO)(+|-)[0-9]+
.arg((leqHOMO) ? tr("HOMO", "Highest Occupied MO") + num
: tr("LUMO", "Lowest Unoccupied MO") + num);
// qDebug() << desc;

Orbital* orb = new Orbital;
// Get the energy from the molecule property list, if available
Expand Down Expand Up @@ -223,77 +222,77 @@ bool OrbitalTableModel::clearOrbitals()
void OrbitalTableModel::setOrbitalProgressRange(int orbital, int min, int max,
int stage, int totalStages)
{
Orbital* orb = m_orbitals[orbital - 1];
Orbital* orb = m_orbitals[orbital];
orb->min = min;
orb->current = min;
orb->max = max;
orb->stage = stage;
orb->totalStages = totalStages;
// Update display
QModelIndex status = index(orbital - 1, int(C_Status), QModelIndex());
QModelIndex status = index(orbital, int(C_Status), QModelIndex());
emit dataChanged(status, status);
}

void OrbitalTableModel::incrementStage(int orbital, int newmin, int newmax)
{
Orbital* orb = m_orbitals[orbital - 1];
Orbital* orb = m_orbitals[orbital];
orb->stage++;
orb->min = newmin;
orb->current = newmin;
orb->max = newmax;
// Update display
QModelIndex status = index(orbital - 1, C_Status, QModelIndex());
QModelIndex status = index(orbital, C_Status, QModelIndex());
emit dataChanged(status, status);
}

void OrbitalTableModel::setOrbitalProgressValue(int orbital, int currentValue)
{
Orbital* orb = m_orbitals[orbital - 1];
Orbital* orb = m_orbitals[orbital];
orb->current = currentValue;
// Update display
QModelIndex status = index(orbital - 1, C_Status, QModelIndex());
QModelIndex status = index(orbital, C_Status, QModelIndex());
emit dataChanged(status, status);
}

void OrbitalTableModel::finishProgress(int orbital)
{
Orbital* orb = m_orbitals[orbital - 1];
Orbital* orb = m_orbitals[orbital];
orb->stage = 1;
orb->totalStages = 1;
orb->min = 0;
orb->current = 1;
orb->max = 1;

// Update display
QModelIndex status = index(orbital - 1, C_Status, QModelIndex());
QModelIndex status = index(orbital, C_Status, QModelIndex());
emit dataChanged(status, status);
}

void OrbitalTableModel::resetProgress(int orbital)
{
Orbital* orb = m_orbitals[orbital - 1];
Orbital* orb = m_orbitals[orbital];
orb->stage = 1;
orb->totalStages = 1;
orb->min = 0;
orb->current = 0;
orb->max = 0;

// Update display
QModelIndex status = index(orbital - 1, C_Status, QModelIndex());
QModelIndex status = index(orbital, C_Status, QModelIndex());
emit dataChanged(status, status);
}

void OrbitalTableModel::setProgressToZero(int orbital)
{
Orbital* orb = m_orbitals[orbital - 1];
Orbital* orb = m_orbitals[orbital];
orb->stage = 1;
orb->totalStages = 1;
orb->min = 0;
orb->current = 0;
orb->max = 1;

// Update display
QModelIndex status = index(orbital - 1, C_Status, QModelIndex());
QModelIndex status = index(orbital, C_Status, QModelIndex());
emit dataChanged(status, status);
}

Expand Down
9 changes: 9 additions & 0 deletions avogadro/qtplugins/surfaces/orbitalwidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,21 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerItem</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
Expand Down

1 comment on commit 6b08c83

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ERROR: clang-format-diff detected formatting issues. See the artifact for a patch or run clang-format on your branch.

Please sign in to comment.