Skip to content

Commit

Permalink
Add migrated files
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 6b08c83 commit c398d05
Show file tree
Hide file tree
Showing 4 changed files with 437 additions and 0 deletions.
150 changes: 150 additions & 0 deletions avogadro/qtgui/gaussiansetconcurrent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/******************************************************************************
This source file is part of the Avogadro project.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#include "gaussiansetconcurrent.h"

#include <avogadro/core/gaussianset.h>
#include <avogadro/core/gaussiansettools.h>
#include <avogadro/core/molecule.h>
#include <avogadro/core/mutex.h>

#include <avogadro/core/cube.h>

#include <QtConcurrent/QtConcurrentMap>

namespace Avogadro::QtGui {

using Core::BasisSet;
using Core::Cube;
using Core::GaussianSet;
using Core::GaussianSetTools;
using Core::Molecule;

template <typename Derived>
class BasisSetConcurrent
{
void setMolecule(Molecule* mol)
{
static_cast<Derived*>(this)->setMolecule(mol);
}
};

struct GaussianShell
{
GaussianSetTools* tools; // A pointer to the tools, can't write to member vars
Cube* tCube; // The target cube, used to initialise temp cubes too
unsigned int pos; // The index of the point to calculate the MO for
unsigned int state; // The MO number to calculate
};

GaussianSetConcurrent::GaussianSetConcurrent(QObject* p)
: QObject(p), m_gaussianShells(nullptr), m_set(nullptr), m_tools(nullptr)
{
// Watch for the future
connect(&m_watcher, SIGNAL(finished()), this, SLOT(calculationComplete()));
}

GaussianSetConcurrent::~GaussianSetConcurrent()
{
delete m_gaussianShells;
}

void GaussianSetConcurrent::setMolecule(Core::Molecule* mol)
{
if (!mol)
return;
m_set = dynamic_cast<GaussianSet*>(mol->basisSet());

delete m_tools;
m_tools = new GaussianSetTools(mol);
}

bool GaussianSetConcurrent::calculateMolecularOrbital(Core::Cube* cube,
unsigned int state,
bool beta)
{
// We can do some initial set up of the tools here to set electron type.
if (!beta)
m_tools->setElectronType(BasisSet::Alpha);
else
m_tools->setElectronType(BasisSet::Beta);

return setUpCalculation(cube, state, GaussianSetConcurrent::processOrbital);
}

bool GaussianSetConcurrent::calculateElectronDensity(Core::Cube* cube)
{
const MatrixX& matrix = m_set->densityMatrix();
if (matrix.rows() == 0 || matrix.cols() == 0) {
// we don't have a density matrix, so calculate one
m_set->generateDensityMatrix();
}

return setUpCalculation(cube, 0, GaussianSetConcurrent::processDensity);
}

bool GaussianSetConcurrent::calculateSpinDensity(Core::Cube* cube)
{
return setUpCalculation(cube, 0, GaussianSetConcurrent::processSpinDensity);
}

void GaussianSetConcurrent::calculationComplete()
{
(*m_gaussianShells)[0].tCube->lock()->unlock();
delete m_gaussianShells;
m_gaussianShells = nullptr;
emit finished();
}

bool GaussianSetConcurrent::setUpCalculation(Core::Cube* cube,
unsigned int state,
void (*func)(GaussianShell&))
{
if (!m_set || !m_tools)
return false;

m_set->initCalculation();

// Set up the points we want to calculate the density at.
m_gaussianShells =
new QVector<GaussianShell>(static_cast<int>(cube->data()->size()));

for (int i = 0; i < m_gaussianShells->size(); ++i) {
(*m_gaussianShells)[i].tools = m_tools;
(*m_gaussianShells)[i].tCube = cube;
(*m_gaussianShells)[i].pos = i;
(*m_gaussianShells)[i].state = state;
}

// Lock the cube until we are done.
cube->lock()->lock();

// The main part of the mapped reduced function...
m_future = QtConcurrent::map(*m_gaussianShells, func);
// Connect our watcher to our future
m_watcher.setFuture(m_future);

return true;
}

void GaussianSetConcurrent::processOrbital(GaussianShell& shell)
{
Vector3 pos = shell.tCube->position(shell.pos);
shell.tCube->setValue(
shell.pos, shell.tools->calculateMolecularOrbital(pos, shell.state));
}

void GaussianSetConcurrent::processDensity(GaussianShell& shell)
{
Vector3 pos = shell.tCube->position(shell.pos);
shell.tCube->setValue(shell.pos, shell.tools->calculateElectronDensity(pos));
}

void GaussianSetConcurrent::processSpinDensity(GaussianShell& shell)
{
Vector3 pos = shell.tCube->position(shell.pos);
shell.tCube->setValue(shell.pos, shell.tools->calculateSpinDensity(pos));
}
} // namespace Avogadro::QtGui
82 changes: 82 additions & 0 deletions avogadro/qtgui/gaussiansetconcurrent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/******************************************************************************
This source file is part of the Avogadro project.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#ifndef AVOGADRO_QTGUI_GAUSSIANSETCONCURRENT_H
#define AVOGADRO_QTGUI_GAUSSIANSETCONCURRENT_H

#include "avogadroqtguiexport.h"

#include <QtCore/QFuture>
#include <QtCore/QFutureWatcher>
#include <QtCore/QObject>

namespace Avogadro {

namespace Core {
class Cube;
class Molecule;
class GaussianSet;
class GaussianSetTools;
} // namespace Core

namespace QtGui {

struct GaussianShell;

/**
* @brief The GaussianSetConcurrent class uses GaussianSetTools to calculate
* values of electronic structure properties from quantum output read in.
* @author Marcus D. Hanwell
*/

class AVOGADROQTGUI_EXPORT GaussianSetConcurrent : public QObject
{
Q_OBJECT

public:
explicit GaussianSetConcurrent(QObject* p = nullptr);
~GaussianSetConcurrent() override;

void setMolecule(Core::Molecule* mol);

bool calculateMolecularOrbital(Core::Cube* cube, unsigned int state,
bool beta = false);
bool calculateElectronDensity(Core::Cube* cube);
bool calculateSpinDensity(Core::Cube* cube);

QFutureWatcher<void>& watcher() { return m_watcher; }

signals:
/**
* Emitted when the calculation is complete.
*/
void finished();

private slots:
/**
* Slot to set the cube data once Qt Concurrent is done
*/
void calculationComplete();

private:
QFuture<void> m_future;
QFutureWatcher<void> m_watcher;
Core::Cube* m_cube;
QVector<GaussianShell>* m_gaussianShells;

Core::GaussianSet* m_set;
Core::GaussianSetTools* m_tools;

bool setUpCalculation(Core::Cube* cube, unsigned int state,
void (*func)(GaussianShell&));

static void processOrbital(GaussianShell& shell);
static void processDensity(GaussianShell& shell);
static void processSpinDensity(GaussianShell& shell);
};
} // namespace QtGui
} // namespace Avogadro

#endif // GAUSSIANSETCONCURRENT_H
124 changes: 124 additions & 0 deletions avogadro/qtgui/slatersetconcurrent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/******************************************************************************
This source file is part of the Avogadro project.
This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#include "slatersetconcurrent.h"

#include <avogadro/core/molecule.h>
#include <avogadro/core/slaterset.h>
#include <avogadro/core/slatersettools.h>

#include <avogadro/core/cube.h>
#include <avogadro/core/mutex.h>

#include <QtConcurrent/QtConcurrentMap>

namespace Avogadro::QtGui {

using Core::Cube;
using Core::SlaterSet;
using Core::SlaterSetTools;

struct SlaterShell
{
SlaterSetTools* tools; // A pointer to the tools, cannot write to member vars
Cube* tCube; // The target cube, used to initialise temp cubes too
unsigned int pos; // The index of the point to calculate the MO for
unsigned int state; // The MO number to calculate
};

SlaterSetConcurrent::SlaterSetConcurrent(QObject* p)
: QObject(p), m_shells(nullptr), m_set(nullptr), m_tools(nullptr)
{
// Watch for the future
connect(&m_watcher, SIGNAL(finished()), this, SLOT(calculationComplete()));
}

SlaterSetConcurrent::~SlaterSetConcurrent()
{
delete m_shells;
}

void SlaterSetConcurrent::setMolecule(Core::Molecule* mol)
{
if (!mol)
return;
m_set = dynamic_cast<SlaterSet*>(mol->basisSet());

delete m_tools;
m_tools = new SlaterSetTools(mol);
}

bool SlaterSetConcurrent::calculateMolecularOrbital(Core::Cube* cube,
unsigned int state)
{
return setUpCalculation(cube, state, SlaterSetConcurrent::processOrbital);
}

bool SlaterSetConcurrent::calculateElectronDensity(Core::Cube* cube)
{
return setUpCalculation(cube, 0, SlaterSetConcurrent::processDensity);
}

bool SlaterSetConcurrent::calculateSpinDensity(Core::Cube* cube)
{
return setUpCalculation(cube, 0, SlaterSetConcurrent::processSpinDensity);
}

void SlaterSetConcurrent::calculationComplete()
{
(*m_shells)[0].tCube->lock()->unlock();
delete m_shells;
m_shells = nullptr;
emit finished();
}

bool SlaterSetConcurrent::setUpCalculation(Core::Cube* cube, unsigned int state,
void (*func)(SlaterShell&))
{
if (!m_set || !m_tools)
return false;

m_set->initCalculation();

// Set up the points we want to calculate the density at.
m_shells = new QVector<SlaterShell>(static_cast<int>(cube->data()->size()));

for (int i = 0; i < m_shells->size(); ++i) {
(*m_shells)[i].tools = m_tools;
(*m_shells)[i].tCube = cube;
(*m_shells)[i].pos = i;
(*m_shells)[i].state = state;
}

// Lock the cube until we are done.
cube->lock()->lock();

// The main part of the mapped reduced function...
m_future = QtConcurrent::map(*m_shells, func);
// Connect our watcher to our future
m_watcher.setFuture(m_future);

return true;
}

void SlaterSetConcurrent::processOrbital(SlaterShell& shell)
{
Vector3 pos = shell.tCube->position(shell.pos);
shell.tCube->setValue(
shell.pos, shell.tools->calculateMolecularOrbital(pos, shell.state));
}

void SlaterSetConcurrent::processDensity(SlaterShell& shell)
{
Vector3 pos = shell.tCube->position(shell.pos);
shell.tCube->setValue(shell.pos, shell.tools->calculateElectronDensity(pos));
}

void SlaterSetConcurrent::processSpinDensity(SlaterShell& shell)
{
Vector3 pos = shell.tCube->position(shell.pos);
shell.tCube->setValue(shell.pos, shell.tools->calculateSpinDensity(pos));
}
} // namespace Avogadro::QtGui
Loading

1 comment on commit c398d05

@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.