diff --git a/src/module/module.cpp b/src/module/module.cpp index 51256a455f..b3b69304d0 100644 --- a/src/module/module.cpp +++ b/src/module/module.cpp @@ -46,6 +46,7 @@ EnumOptions moduleTypes_("ModuleType", {{ModuleTypes::A {ModuleTypes::NeutronSQ, "NeutronSQ"}, {ModuleTypes::OrientedSDF, "OrientedSDF"}, {ModuleTypes::QSpecies, "QSpecies"}, + {ModuleTypes::RingPopulations, "RingPopulations"}, {ModuleTypes::SDF, "SDF"}, {ModuleTypes::SiteRDF, "SiteRDF"}, {ModuleTypes::SQ, "SQ"}, diff --git a/src/module/types.h b/src/module/types.h index 5dfed308b0..327a3a1b2a 100644 --- a/src/module/types.h +++ b/src/module/types.h @@ -40,6 +40,7 @@ enum ModuleType NeutronSQ, OrientedSDF, QSpecies, + RingPopulations, SDF, SiteRDF, Skeleton, diff --git a/src/modules/registry.cpp b/src/modules/registry.cpp index 4e1dc0faf5..4f9fcdb5ca 100644 --- a/src/modules/registry.cpp +++ b/src/modules/registry.cpp @@ -31,6 +31,7 @@ #include "modules/neutronSQ/neutronSQ.h" #include "modules/orientedSDF/orientedSDF.h" #include "modules/qSpecies/qSpecies.h" +#include "modules/ringPopulations/ringPopulations.h" #include "modules/sdf/sdf.h" #include "modules/siteRDF/siteRDF.h" #include "modules/sq/sq.h" @@ -84,6 +85,8 @@ ModuleRegistry::ModuleRegistry() registerProducer(ModuleTypes::ModifierOSites, "Calculate the percentage FO, BO and NBO bonded to a modifier atom", "Analysis"); registerProducer(ModuleTypes::QSpecies, "Calculate QSpecies of a network former", "Analysis"); + registerProducer(ModuleTypes::RingPopulations, "Calculate the size of rings in a system", + "Analysis"); registerProducer(ModuleTypes::SDF, "Calculate spatial density functions around oriented sites", "Analysis"); registerProducer(ModuleTypes::SiteRDF, "Calculate radial distribution functions between sites", "Analysis"); registerProducer(ModuleTypes::SQ, "Transform g(r) into unweighted S(Q)", "Correlation Functions"); diff --git a/src/modules/ringPopulations/CMakeLists.txt b/src/modules/ringPopulations/CMakeLists.txt new file mode 100644 index 0000000000..0917753241 --- /dev/null +++ b/src/modules/ringPopulations/CMakeLists.txt @@ -0,0 +1 @@ +dissolve_add_module(ringPopulations.h ringPopulations) diff --git a/src/modules/ringPopulations/gui/CMakeLists.txt b/src/modules/ringPopulations/gui/CMakeLists.txt new file mode 100644 index 0000000000..068bb1a281 --- /dev/null +++ b/src/modules/ringPopulations/gui/CMakeLists.txt @@ -0,0 +1 @@ +dissolve_add_module_gui(ringPopulations) diff --git a/src/modules/ringPopulations/gui/ringPopulationsWidget.h b/src/modules/ringPopulations/gui/ringPopulationsWidget.h new file mode 100644 index 0000000000..55d91efbc2 --- /dev/null +++ b/src/modules/ringPopulations/gui/ringPopulationsWidget.h @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2024 Team Dissolve and contributors + +#pragma once + +#include "modules/ringPopulations/gui/ui_ringPopulationsWidget.h" +#include "modules/widget.h" + +// Forward Declarations +class RingPopulationsModule; +class DataViewer; + +// Module Widget +class RingPopulationsModuleWidget : public ModuleWidget +{ + // All Qt declarations derived from QObject must include this macro + Q_OBJECT + + private: + // Associated Module + RingPopulationsModule *module_; + + public: + RingPopulationsModuleWidget(QWidget *parent, RingPopulationsModule *module, Dissolve &dissolve); + + /* + * UI + */ + private: + // Main form declaration + Ui::RingPopulationsModuleWidget ui_; + + // DataViewer contained within this widget + DataViewer *ringPopulationsGraph_; + + public: + // Update controls within widget + void updateControls(const Flags &updateFlags = {}) override; +}; diff --git a/src/modules/ringPopulations/gui/ringPopulationsWidget.ui b/src/modules/ringPopulations/gui/ringPopulationsWidget.ui new file mode 100644 index 0000000000..63e4054a44 --- /dev/null +++ b/src/modules/ringPopulations/gui/ringPopulationsWidget.ui @@ -0,0 +1,286 @@ + + + RingPopulationsModuleWidget + + + + 0 + 0 + 597 + 422 + + + + + 0 + 0 + + + + + 8 + + + + RingPopulations Controls + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Oygen Sites + + + + 4 + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 0 + 0 + + + + Free Sites + + + false + + + false + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + Bridging Sites + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + + 0 + 0 + + + + Non-Bridging Sites + + + + 4 + + + 4 + + + 4 + + + 4 + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + true + + + + 0 + 0 + + + + Odd Sites + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + + Qt::Horizontal + + + + 140 + 20 + + + + + + + + + + + + DataWidget + QWidget +
gui/dataWidget.h
+ 1 +
+ + SampledDoubleLabel + QFrame +
gui/widgets/sampledDoubleLabel.h
+ 1 +
+
+ + +
diff --git a/src/modules/ringPopulations/gui/ringPopulationsWidgetFuncs.cpp b/src/modules/ringPopulations/gui/ringPopulationsWidgetFuncs.cpp new file mode 100644 index 0000000000..1af90bef76 --- /dev/null +++ b/src/modules/ringPopulations/gui/ringPopulationsWidgetFuncs.cpp @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2024 Team Dissolve and contributors + +#include "classes/configuration.h" +#include "gui/render/renderableData1D.h" +#include "main/dissolve.h" +#include "math/integerHistogram1D.h" +#include "math/integrator.h" +#include "modules/ringPopulations/gui/ringPopulationsWidget.h" +#include "modules/ringPopulations/ringPopulations.h" + +RingPopulationsModuleWidget::RingPopulationsModuleWidget(QWidget *parent, RingPopulationsModule *module, Dissolve &dissolve) + : ModuleWidget(parent, dissolve), module_(module) +{ + // Set up user interface + ui_.setupUi(this); + + // Set up RDF graph + ringPopulationsGraph_ = ui_.RingPopulationsPlotWidget->dataViewer(); + + auto &view = ringPopulationsGraph_->view(); + view.setViewType(View::FlatXYView); + view.axes().setTitle(0, "Qn"); + view.axes().setMax(0, 10.0); + view.axes().setTitle(1, "Normalised Frequency"); + view.axes().setMin(1, 0.0); + view.axes().setMax(1, 1.0); + view.setAutoFollowType(View::AllAutoFollow); + + refreshing_ = false; +} + +// Update controls within widget +void RingPopulationsModuleWidget::updateControls(const Flags &updateFlags) +{ + if (updateFlags.isSet(ModuleWidget::RecreateRenderablesFlag)) + ringPopulationsGraph_->clearRenderables(); + + if (ringPopulationsGraph_->renderables().empty()) + ringPopulationsGraph_->createRenderable(fmt::format("{}//QSpecies", module_->name()), "Q-Species"); + + // Validate renderables if they need it + ringPopulationsGraph_->validateRenderables(dissolve_.processingModuleData()); + + ui_.RingPopulationsPlotWidget->updateToolbar(); + + ringPopulationsGraph_->postRedisplay(); +} diff --git a/src/modules/ringPopulations/process.cpp b/src/modules/ringPopulations/process.cpp new file mode 100644 index 0000000000..ed0c7cc8b1 --- /dev/null +++ b/src/modules/ringPopulations/process.cpp @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2024 Team Dissolve and contributors + +#include "analyser/dataExporter.h" +#include "analyser/dataOperator1D.h" +#include "analyser/siteFilter.h" +#include "analyser/siteSelector.h" +#include "main/dissolve.h" +#include "math/integerHistogram1D.h" +#include "math/integrator.h" +#include "module/context.h" +#include "modules/ringPopulations/ringPopulations.h" + +// Run main processing +Module::ExecutionResult RingPopulationsModule::process(ModuleContext &moduleContext) +{ + auto &processingData = moduleContext.dissolve().processingModuleData(); + + // Select all potential ring forming sites + SiteSelector allRingFormerSites(targetConfiguration_, a_); + + // Select all bridging sites between rings + SiteSelector bridingingSites(targetConfiguration_, b_); + + /* + * Algorithm as suggested in Phys. Rev. B 1991, 44, 4925, section VI + * 1) Select an arbitrary vertex (atom) z + * 2) Generate each ring containing z, of max length m, and test if it is an SP ring + * 3) Delete z + * 4) Repeat 1) - 3) until no vertices remain. + */ + + // Step 1) + for (auto &z : allRingFormerSites.sites()) + { + int nOk, ringSize, diameter, scope; + bool odd; + + // Step 2) + for (int n = 0; n < maxRingSize_; ++n) + n + 1; + } + + return ExecutionResult::Success; +} diff --git a/src/modules/ringPopulations/ringPopulations.cpp b/src/modules/ringPopulations/ringPopulations.cpp new file mode 100644 index 0000000000..7419513930 --- /dev/null +++ b/src/modules/ringPopulations/ringPopulations.cpp @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2024 Team Dissolve and contributors + +#include "modules/ringPopulations/ringPopulations.h" +#include "generator/select.h" +#include "keywords/bool.h" +#include "keywords/configuration.h" +#include "keywords/fileAndFormat.h" +#include "keywords/optionalInt.h" +#include "keywords/range.h" +#include "keywords/speciesSiteVector.h" +#include "keywords/vec3Double.h" + +RingPopulationsModule::RingPopulationsModule() : Module(ModuleTypes::RingPopulations) +{ + /* + * Keywords + */ + + keywords_.addTarget("Configuration", "Set target configuration for the module", targetConfiguration_) + ->setEditSignals({KeywordBase::ClearModuleData, KeywordBase::RecreateRenderables}); + + keywords_.setOrganisation("Options", "Sites", "Specify sites representing the ring former and bidging site."); + keywords_.add("SiteA", "Set the site(s) which represent the ring formers", a_); + keywords_.add("SiteB", "Set the site(s) which represents the bridging sites", b_); + + keywords_.setOrganisation("Options", "Ranges", "Ranges over which to bin quantities from the calculation."); + keywords_.add("DistanceRange", + "Distance range (min, max) over which to calculate Q-Species from central site", distanceRange_, + 0.0, std::nullopt, Vec3Labels::MinMaxDeltaLabels); + keywords_.add("Max Ring Size", "Maximum Ring Size to compute", maxRingSize_, 1, std::nullopt, 1, + "Off"); + + keywords_.setOrganisation("Export"); + keywords_.add("Export", "File format and file name under which to save calculated QSpecies data", + exportFileAndFormat_, "EndExport"); +} diff --git a/src/modules/ringPopulations/ringPopulations.h b/src/modules/ringPopulations/ringPopulations.h new file mode 100644 index 0000000000..9f70fcc4ed --- /dev/null +++ b/src/modules/ringPopulations/ringPopulations.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright (c) 2024 Team Dissolve and contributors + +#pragma once + +#include "analyser/siteSelector.h" +#include "io/export/data1D.h" +#include "math/range.h" +#include "module/module.h" + +// Calculate Q-Species Module +class RingPopulationsModule : public Module +{ + public: + RingPopulationsModule(); + ~RingPopulationsModule() override = default; + + /* + * Definition + */ + private: + // Target configuration + Configuration *targetConfiguration_{nullptr}; + // Target SpeciesSite definitions + std::vector a_, b_; + // Whether to exclude correlations between sites on the same molecule + bool excludeSameMolecule_{false}; + // Distance range for calculation + Range distanceRange_{0.0, 2.5}; + // Maximum ring size to consider + std::optional maxRingSize_{10}; + // Export target + Data1DExportFileFormat exportFileAndFormat_; + bool export_{false}; + + /* + * Processing + */ + private: + // Run main processing + Module::ExecutionResult process(ModuleContext &moduleContext) override; +}; diff --git a/src/modules/widgetProducer.cpp b/src/modules/widgetProducer.cpp index 5f2a17a1ae..2b3ea8f378 100644 --- a/src/modules/widgetProducer.cpp +++ b/src/modules/widgetProducer.cpp @@ -44,6 +44,8 @@ #include "modules/orientedSDF/orientedSDF.h" #include "modules/qSpecies/gui/qSpeciesWidget.h" #include "modules/qSpecies/qSpecies.h" +#include "modules/ringPopulations/gui/ringPopulationsWidget.h" +#include "modules/ringPopulations/ringPopulations.h" #include "modules/sdf/gui/sdfWidget.h" #include "modules/sdf/sdf.h" #include "modules/siteRDF/gui/siteRDFWidget.h" @@ -81,6 +83,7 @@ ModuleWidgetProducer::ModuleWidgetProducer() registerProducer(); registerProducer(); registerProducer(); + registerProducer(); registerProducer(); registerProducer(); registerProducer();